我试图将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;
}
答案 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++;
。
如果您打算将延迟与多任务处理过程异步,这显然不会很好地配合其他任务。