[Armadillo:06915] Re: POSIXタイマー割り込みタイミング
Takenoshita Koyo
email@hidden
2011年 3月 23日 (水) 22:20:13 JST
竹之下です。
タイマーの扱いと、シグナルの扱いは難しいですね。
色々な問題が絡み合っているので、インラインで書きます。
email@hidden さんは書きました:
> arnadillo-9にてPOSIXタイマーを100msec設定で動作させてみたところ、割り込み周期が不定な動きをしている様子だったので、ログで確認したところ、
>
> ->20msec
> ->80msec
> ->0msec
> ->20msec
> ->80msec
> ->0msec
>
> と、3つを1つの周期として定期的に変なタイミングでタイマーイベントが発生していました。
> 同じモジュールをPC上のdebianで動作させたところ、概ね100msecでイベントが発生していました(一部不定周期が見られますが)。
> ※ テキスト添付します。
>
> armadillo9にて定周期でイベントを発生させるために、特に設定が必要であれば、助言いただけると大変助かります。
>
> タイマー設定部分のソースは下記のとおりです。
>
>
> よろしくお願いします。
>
> #define SIGIO_READ SIGRTMIN +1
>
> /* timer create */
> memset( &sigact, 0, sizeof sigact ) ;
> memset( &sigev, 0, sizeof sigev ) ;
>
> sigact.sa_sigaction = timer_handler ;
> sigact.sa_flags = SA_SIGINFO | SA_RESTART ;
SA_RESTART は BSDシグナルの挙動を模倣するものなので、
必要がなければ、付けなくても良いと思います。
以下のページが詳しく説明してくれています。
http://www.nurs.or.jp/~sug/soft/super/signal.htm
> sigemptyset(&sigact.sa_mask);
> if( sigaction( SIGIO_READ, &sigact, NULL ) < 0 ){
> return FALSE ;
> }
>
> sigev.sigev_notify = SIGEV_SIGNAL ;
> sigev.sigev_signo = SIGIO_READ ;
> if( timer_create( CLOCK_REALTIME, &sigev, &timerId ) < 0 ){
CLOCK_REALTIME はシステム時刻の影響を受けてしまいますので、
CLOCK_MONOTONIC の方が良いと思います。
man timer_create を参照してください。
http://www.kernel.org/doc/man-pages/online/pages/man2/timer_create.2.html
> return FALSE ;
> }
>
> itval.it_interval.tv_sec = 0 ; /* every time up sec */
> itval.it_interval.tv_nsec = 100 *1000 *1000;/* 100msec */
> itval.it_value.tv_sec = 10 ; /* first time up sec */
> itval.it_value.tv_nsec = 0 ; /* 100msec */
> if( timer_settime( timerId, 0, &itval, NULL ) < 0 ){
第2引数に TIMER_ABSTIME を指定すると、絶対間隔でタイマー割り込みが発生します。
今回の用途では、指定するべきでしょう。
man timer_settime を参照してください。
http://linux.die.net/man/3/timer_settime
> return FALSE ;
> }
> printf("\n\n complete timer setup\n");
>
> while(1){
> } ;
>
> void timer_handler( int signum, siginfo_t *info, void *ctx )
> {
> if( signum != SIGIO_READ ){
> return ;
> }
>
> if( info->si_code != SI_TIMER )
> return ;
>
> int w_start ;
>
> printf("\n\n timer_handler() \n" ) ;
シグナルハンドラ内で printf 関数を使用すると、デッドロックが発生する可能性があります。
以下のページが詳しく説明してくれています。
http://d.hatena.ne.jp/yupo5656/20040712/p2
> printf(" signum = %d define = %d \n", signum, SIGIO_READ ) ;
> w_start = clock() ;
clock()は、プロセスが使用したプロセッサ時間を得る関数です。
これでは実時間が分かりませんので、clock_gettime(CLOCK_MONOTONIC, )を使うと良いです。
これも、man ページをご参照ください。
> printf(" time = %d.%03d msec -------------> \n", w_start /1000, w_start %1000 ) ;
以上の点に気をつけたプログラムを添付します。
[PC ~]$ arm-linux-gcc -Wall test.c -o test -lrt
としてコンパイルしてください。
負荷次第ですが、大体、100msec(0.1 sec)単位で動いています。
[email@hidden (ttyAM0) /home/ftp/pub]# ./test
complete timer setup
000: 3282.910287000
001: 3283.000127000
002: 3283.100066000
003: 3283.200049000
004: 3283.300041000
005: 3283.400039000
006: 3283.500127000
007: 3283.600092000
008: 3283.700051000
009: 3283.801311000
010: 3283.977836000 <- ここだけ大きくずれてる?
011: 3284.000080000 <- TIMER_ABSTIME を付けているので、絶対周期はずれない
012: 3284.100060000
013: 3284.200045000
014: 3284.300037000
(後略)
--
Koyo Takenoshita
-------------- next part --------------
テキスト形式以外の添付ファイルを保管しました...
ファイル名: test.c
型: text/x-csrc
サイズ: 1593 バイト
説明: 無し
URL: <http://lists.atmark-techno.com/pipermail/armadillo/attachments/20110323/164276c9/attachment.c>
armadillo メーリングリストの案内