Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
Python 2.7.9
組込みCでの移植も考えて、RPi上でC実装をしている。
ナノ秒とミリ秒待つ処理はどのように実装するのか?
参考
指定された時間だけ停止する @ c-lang.net
情報感謝です。
code v0.1
上記の情報を参考に、以下を実装してみた。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MILLI_SEC (1000000)
void wait_millisecond(int wait_msec)
{
int loop;
struct timespec req = {0, MILLI_SEC};
for(loop=0; loop < wait_msec; loop++) {
nanosleep(&req, NULL);
}
}
void wait_nanosecond(int wait_nsec)
{
int loop;
struct timespec req = {0, 1};
for(loop=0; loop < wait_nsec; loop++) {
nanosleep(&req, NULL);
}
}
int main(void)
{
printf("start\n");
wait_nanosecond(10);
printf("next\n");
wait_millisecond(3000);
printf("end\n");
return 0;
}
$ ./test_delay_180301
start
next
end
期待通りの「待ち」処理になっているようだ。
nanosleep()の失敗時(-1が返る)の対応はしていない。
code > 外部ソース化
以下のように外部ソース化した。
- wait_msec_nsec_180301.h
- wait_msec_nsec_180301.c
- test_delay_180301.c
#ifndef __WAIT_MSEC_NSEC_180301_H
#define __WAIT_MSEC_NSEC_180301_H
void Wait_millisecond(int wait_msec);
void Wait_nanosecond(int wait_nsec);
#endif
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
/*
* v0.1 2018/03/01
* - add Wait_nanosecond()
* - add Wait_millisecond()
* - add [MILLI_SEC]
*/
#define MILLI_SEC (1000000)
void Wait_millisecond(int wait_msec)
{
int loop;
struct timespec req = {0, MILLI_SEC};
for(loop=0; loop < wait_msec; loop++) {
nanosleep(&req, NULL);
}
}
void Wait_nanosecond(int wait_nsec)
{
int loop;
struct timespec req = {0, 1};
for(loop=0; loop < wait_nsec; loop++) {
nanosleep(&req, NULL);
}
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "wait_msec_nsec_180301.h"
int main(void)
{
printf("start\n");
Wait_nanosecond(10);
printf("next\n");
Wait_millisecond(3000);
printf("end\n");
return 0;
}
$ gcc wait_msec_nsec_180301.c test_delay_180301.c
$ ./a.out
start
next
end
時間精度
RPiのGPIO26でH,LレベルをWait_millisecond(5)で変化させてみた。
それをオシロスコープで測定 (Tektronix TPS 2024)。
5.6msecの変化となった。
bug
Wait_nanosecond(50);
実行時にオシロスコープでは4msecの変化となるバグがあるようだ。
Wait_microsecond(5);
を追加し、実行時にオシロスコープでは560usecの変化であった。
Wait_millisecond()のみ使用可能
Wait_millisecond()のみが使用可能のようだ。
関連: 電子工作 > RPi / GPIO / デジボル > 周波数計測ができない > 100HzはOK, それより速いのがおかしい > time.sleep()後の待ちの蓄積だろうか?
The Linux kernels tend to have a higher tick rate, where the intervals are generally closer to 1 millisecond.
1msec程度までしかだめかもしれない。
3.8kHz (260usec)
nanosleep()でtv_nsec=1とした場合の時間は、RPiにて260usecであることがオシロスコープの測定から分かった。
(環境によって変わるかもしれない)。
260usec は 3846Hz = 3.8kHz
クロックで考えると、この半分の1.9kHzとなる。
(クロックのようにH,Lを繰り返した時、最初が260usecで、以降は160usecの間隔になった)。
I2C通信で一般的に使われるのは100kHzや400kHz。