我在下面有一个小代码。我使用此代码unsigned output[38]
从嵌入式板的 GPIO 输出一些 1 和 0 ( )。
我的问题:两个输出值(1、0 或 0、1)之间的时间应该是416 微秒clock_nanosleep
,正如我在下面的代码中定义的那样,我还使用sched_priority()
了更好的时间分辨率。但是,示波器(下图)测量显示两个输出值之间的时间为770 微秒。我想知道为什么我的信号之间有这么多的不准确?
PS。该板(beagleboard)具有 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 或数据输出是很好的。