在C MIPS环境中延迟1微秒

时间:2014-11-27 05:13:05

标签: c mips clock u8glib

我试图将u8glib(图形库)移植到MIPS处理器,OpenWrt路由器。 这是一个example手臂环境。

因此,我必须实现的一个例程是:

delay_micro_seconds(uint32_t us)

由于这是一个高分辨率的时间单位,我怎样才能在我的环境中可靠地完成这项工作?我尝试了以下方法,但我甚至不确定如何验证它:

nanosleep((struct timespec[]){{0, 1000}}, NULL);

如何验证此方法?如果它是一个糟糕的方法,我怎么能在C中可靠地延迟1微秒?

编辑:我已经尝试了这个,但我得到了奇怪的输出,我预计两个打印的差异是1000 * 10次迭代= 10,000,但它实际上更接近670,000纳秒:

   int main(int argc, char **argv)
   {
    long res, resb;
    struct timespec ts, tsb;
    int i;

    res = clock_gettime(CLOCK_REALTIME, &ts);

    for(i=0;i<10;i++){
            nanosleep((struct timespec[]){{0,1000}}, NULL);
    }

    resb = clock_gettime(CLOCK_REALTIME, &tsb);

    if (0 == res) printf("%ld %ld\n", ts.tv_sec, ts.tv_nsec);
    else perror("clock_gettime");
    if (0 == resb) printf("%ld %ld\n", tsb.tv_sec, tsb.tv_nsec);
    else perror("clock_gettime"); //getting 670k delta instead of 10k for tv_nsec
    return 0;
    } 

2 个答案:

答案 0 :(得分:2)

我假设您的代码将在Linux下运行。

首先,使用clock_getres(2)查找时钟的分辨率。 然后,使用clock_nanosleep(2)可以使睡眠更准确。

要验证睡眠,我建议您使用clock_gettime(2)

检查已用时间
res = clock_gettime(CLOCK_REALTIME, &ts);
if (0 == res) printf("%ld %ld\n", ts.tv_sec, ts.tv_nsec);
else perror("clock_gettime");

clock_nanosleep(CLOCK_REALTIME, 0, &delay, NULL);

res = clock_gettime(CLOCK_REALTIME, &ts);
if (0 == res) printf("%ld %ld\n", ts.tv_sec, ts.tv_nsec);
else perror("clock_gettime");

此外,如有必要,您可以使用更高的HZ配置重新编译内核。 阅读time(7)手册页会很有帮助。特别是,软件时钟,HZ和jiffies 高分辨率计时器部分。 虽然我的手册页说mips架构下不支持高分辨率计时器,但我只是用谷歌搜索它,mips-linux显然支持HRT。

答案 1 :(得分:1)

这睡眠同步吗? (我不熟悉你的平台)

验证

  • 如果您有可用的开发工具,是否包含任何分析工具?它们至少可以帮助您测量执行时间。

  • 您还可以在测试程序中循环 sleep 调用1000次以上。在进入循环之前,从系统时钟获取时间戳。循环完成循环后,再取一个时间戳并与第一个时间戳进行比较。请记住,循环本身会有一些时间开销,但除此之外,这将让您知道 sleep 的精确度(过冲或下冲)。 (如果你在1微秒睡眠功能周围循环1,000,000次,你会发现它接近1秒钟。

替代

睡眠功能对于它们的分辨率并不总是完美,但它们保证使用简单,并且总能让您接近他们所说的内容。有许多语句的运行速度比微秒快a++;

  • 使用与上面类似的方法,您可以使用FOR循环轻松制作自制的同步计时器,其中包含一些无意义的语句。一旦你发现了最接近1微秒的迭代次数,它就永远不会改变,你可以用它对一个函数进行硬编码。

如果您打算将延迟与多任务处理过程异步,这显然不会很好地配合其他任务。