以下に小さなコードがあります。unsigned output[38]
このコードを使用して、組み込みボードのGPIOからいくつかの1と0()を出力します。
私の質問:2つの出力値(1、0または0、1)の間の時間は、以下のコードで定義するように416マイクロ秒である必要があります。また、より良い時間分解能のために使用しました。ただし、オシロスコープ(下の写真)の測定では、2つの出力値の間の時間は770usecであることが示されています。なぜ信号間にそれほど不正確なのかしら?clock_nanosleep
sched_priority()
PS。ボード(ビーグルボード)にはLinux 3.2.0-23-omap#36-Ubuntu Tue Apr 10 20:24:21 UTC 2012 armv7l armv7l armv7l GNU / Linuxカーネルがあり、750 MHzのCPUを搭載しており、top
CPUはほとんど表示されません(〜1 %)とメモリ(〜0.5%)は、コードを実行する前に消費されます。校正に問題のない電子オシロスコープを使用しています。
#include <stdio.h>
#include <stdlib.h> //exit();
#include <sched.h>
#include <time.h>
void msg_send();
struct sched_param sp;
int main(void){
sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
sched_setscheduler(0, SCHED_FIFO, &sp);
msg_send();
return 0;
}
void msg_send(){
unsigned output[38] = {0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,1};
FILE *fp8;
if ((fp8 = fopen("/sys/class/gpio/export", "w")) == NULL){ //echo 139 > export
fprintf(stderr,"Cannot open export file: line844.\n"); fclose(fp8);exit(1);
}
fprintf(fp8, "%d", 139); //pin 3
fclose(fp8);
if ((fp8 = fopen("/sys/class/gpio/gpio139/direction", "rb+")) == NULL){
fprintf(stderr,"Cannot open direction file - GPIO139 - line851.\n");fclose(fp8); exit(1);
}
fprintf(fp8, "out");
fclose(fp8);
if((fp8 = fopen("/sys/class/gpio/gpio139/value", "w")) == NULL) {
fprintf(stderr,"error in openning value\n"); fclose(fp8); exit(1);
}
struct timespec req = { .tv_sec=0, .tv_nsec = 416000 }; //416 usec
/* here is the part that my question focus*/
while(1){
for(i=0;i<38;i++){
rewind(fp8);
fprintf(fp8, "%d", output[i]);
clock_nanosleep(CLOCK_MONOTONIC ,0, &req, NULL);
}
}
}
編集:私はclock_nanosleep()または他のnanosleep、usleepなどが時間通りに起きることを保証しないことを何日も読んでいます。これらは通常、定義された時間コードをスリープ状態にすることを提供しますが、プロセスのウェイクアップはCPUに依存します。私が見つけたのは、絶対時間がより良い解像度(TIMER_ABSTIME
フラグ)を提供するということです。Maximeが提案するのと同じ解決策を見つけました。ただし、forループが終了すると、信号に不具合が発生します。私の意見では、組み込みプラットフォームでPWMまたはデータ出力を作成することは、スリープ機能には適していません。プラットフォームが提供するCPUタイマーを学習して、精度の高いPWMまたはデータ出力を生成することをお勧めします。