gpt4 book ai didi

c - C中的精确计时

转载 作者:IT王子 更新时间:2023-10-29 00:07:40 24 4
gpt4 key购买 nike

我在下面有一些代码。我使用此代码从嵌入式板的 GPIO 输出一些 1 和 0(unsigned output[38])。

我的问题:两个输出值(1、0 或 0、1)之间的时间应该是 416 微秒,正如我在下面代码的 clock_nanosleep 上定义的那样,我还使用了sched_priority() 以获得更好的时间分辨率。然而,示波器(下图)测量显示两个输出值之间的时间为 770 usec 。我想知道为什么我的信号之间有那么多不准确?

附言。该板(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);

}
}
}

enter image description here

编辑: 几天来我一直在阅读 clock_nanosleep() 或其他 nanosleep、usleep 等不能保证准时醒来的内容。他们通常提供让代码在定义的时间内休眠,但唤醒进程取决于 CPU。我发现绝对时间提供了更好的分辨率(TIMER_ABSTIME 标志)。我找到了与 Maxime 建议相同的解决方案。但是,当 for 循环完成时,我的信号出现故障。在我看来,在嵌入式平台上创建 PWM 或数据输出对任何 sleep 功能都不利。最好花一些时间学习平台提供的 CPU 定时器,以生成具有良好准确性的 PWM 或数据输出。

最佳答案

我不知道调用 clock_getres() 如何解决您的问题。在手册页中说只能读取时钟的分辨率。

正如Geoff所说,使用绝对 sleep 时钟应该是更好的解决方案。这可以避免来自其他代码的意外时间延迟。

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
}

我在少数程序上使用它来在以太网网络上生成一些常规消息。并且运行良好。

关于c - C中的精确计时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14765301/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com