
下面我有一个小代码。 我用这个代码从embedded式主板的GPIO输出一些1和0( unsigned output[38] )。
我的问题:两个输出值(1,0或0,1)之间的时间应该是416微秒,因为我在clock_nanosleep下面定义了代码,我还使用sched_priority()来获得更好的时间分辨率。 但是,示波器(图片下方)的测量结果显示两个输出值之间的时间间隔为770秒 。 我想知道为什么信号之间有那么多的不准确?
PS。 板(beagleboard)有linux 3.2.0-23-omap#36 -Ubuntu 2012年4月10日20:24:21 UTC 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,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 valuen"); 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,output[i]); clock_nanosleep(CLOCK_MONOTONIC,&req,NulL); } } }
cudaEventRecord()在Visual Studio cpu代码上时间不正确
如何在特定的本地时间运行Delphi Win32应用程序?
mySQL查询 – 插入数据unix_timestamp(Now())问题
如何在windows中获得实时
如何获得linux gettimeofday()的微秒时间,它的准确度是多less?
编辑:我一直在阅读的clock_nanosleep()或其他nanosleep,睡觉等不能保证按时醒来的日子。 他们通常提供睡眠代码的时间,但醒来的过程取决于cpu。 我发现绝对时间提供了一个更好的解决scheme( TIMER_ABSTIME标志)。 我find了和Maxime一样的解决scheme。 然而,当循环完成时,我的信号有一个小故障。 在我看来,任何睡眠function都不适合在embedded式平台上创buildPWM或数据输出。 花些时间学习平台提供的cpu定时器以生成具有良好精度的PWM或数据输出是很好的。
如何loggingunix命令所用的时间?
为什么clock_gettime如此不稳定?
如何捕获几个命令的输出?
我怎样才能解决两个不同的linux服务器之间的系统时间偏移?
什么是timeGetTime最好的替代品,以避免环绕?
我无法弄清楚如何调用clock_getres()可以解决您的问题。 在手册页中,据说只读取时钟的分辨率。
正如杰夫所说,使用绝对睡眠时钟应该是一个更好的解决方案。 这可以避免来自其他代码的不需要的时间延迟。
struct timespec Time; clock_gettime(CLOCK_REALTIME,&(Time)); while(1){ Time.tv_nsec += 416000; if(Time.tv_nsec > 999999999){ (Time.tv_sec)++; Time.tv_nsec -= 1000000000; } clock_nanosleep(CLOCK_REALTIME,TIMER_ABSTIME,&(Time),NulL); //Do something }
我正在使用这个几个程序来生成以太网上的一些常规消息。 它工作正常。
如果你正在做对时间敏感的I / O,你可能不应该使用stdio.h的东西,而是因为stdio所做的缓冲,而不是使用I / O系统调用。 看起来你可能会得到最差的缓冲效果,因为你的程序执行这些步骤:
填充缓冲区
睡觉
倒带,我相信会刷新缓冲区
你想要的是内核在睡眠时为写入服务,而不是在睡眠之后刷新缓冲区,而你必须等待内核来处理它。
我认为你最好的选择是使用open("/sys/class/gpio/gpio139/value",O_WRONLY|O_DIRECT)来减少由于缓存造成的延迟。
如果仍然需要刷新缓冲区以强制写入,则可能需要使用clock_gettime来计算刷新数据的时间,并从睡眠时间中减去该时间。 或者,将所需的时间间隔添加到clock_gettime的结果中,并将其传递到clock_nanosleep并使用TIMER_ABSTIME标志等待绝对时间的发生。
我猜想问题是clock_nanosleep正在休眠416微秒,并且循环中的其他命令以及循环和clock_nanosleep体系结构本身都需要354微秒。 *** 作系统也可能提出要求。
如果设置sleep = 0,你会得到什么样的时间间隔?
你是在计算机还是PLC上运行?
对评论的回应
似乎你在硬件/软件方面有一些意想不到的事情 – 这可能是一个找不到的东西。
我有两个建议取决于期限的关键:
低关键性 – 在你的程序中放置一个数字,使循环占用你想要的时间。 但是,如果这是一个瞬态或时间/温度相关的影响,你将需要定期检查漂移。
高临界性 – 在硬件中建立一个温度稳定的振荡器。 这些可以从现货上买到。
总结以上是内存溢出为你收集整理的精确的时间在C全部内容,希望文章能够帮你解决精确的时间在C所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)