背景:
芯片开发阶段,有个硬件有个配置一直无法生效,后面发现是软件写入使能还未能生效,硬件就开始配置了,导致不成功。
加个延时就可解决,只是知道应该在纳秒级别,但具体十位还是百位级别,不太清楚了,所以就让我搞个代码测试下——写入一次寄存器需要的时间。
1、Linux内核获取时间的函数do_gettimeofday
- 不得不提用户空间函数gettimeofday,
可以看下百科https://baike.baidu.com/item/gettimeofday/3369586?fr=aladdin - 获得的时间精确到微秒(1e-6 s)量级
- 相关结构体
/*tv_sec为当前时间距1970年1月1日的秒数,tv_usec为不足一秒的微秒数*/
struct timeval {
time_t tv_sec; /* seconds */ 秒
suseconds_t tv_usec; /* microseconds */ 微秒
};
代码
#include <linux/time.h>
void PrintWriteRegisterTime(void)
{
int i;
struct timeval time = {
.tv_sec=0, /*单位:s*/
.tv_usec=0 /*单位:um*/
};
int firsttime = 0, secondtime = 0;
do_gettimeofday(&time); /*第一次获取系统时间*/
firsttime = time.tv_sec * 10000000 + time.tv_usec;
for(i = 0;i < 50000;i++){
SET_IOP_WORK_EN(); /*写寄存器操作(函数不做具体展示)*/
}
do_gettimeofday(&time); /*第二次获取时间*/
secondtime = time.tv_sec * 1000000 + time.tv_usec;
printk("time of write to register : %d(ns)\n",(secondtime - firsttime) * 1000 / 50000);
return;
}
另外,写了个proc文件(有时间再更新吧)来调试,结果如下:
可以看到我们的CPU写一次寄存器的时间在430ns-440ns左右,在配置前加个这样的时延就OK了。
2、用户态gettimeofday测试一条打印的时间
很简单、直接来代码了。
#include <stdio.h>
#include <sys/time.h>
void main(void){
int i = 0;
struct timeval time;
for(;i < 10; i++){
gettimeofday(&time,NULL);
printf("time is :%d(s) %d(us)\n",time.tv_sec,time.tv_usec);
}
}
结果:
time is :1627529863(s) 996367(us)
time is :1627529863(s) 996442(us)
time is :1627529863(s) 996444(us)
time is :1627529863(s) 996445(us)
time is :1627529863(s) 996447(us)
time is :1627529863(s) 996448(us)
time is :1627529863(s) 996450(us)
time is :1627529863(s) 996460(us)
time is :1627529863(s) 996462(us)
time is :1627529863(s) 996464(us)
可以看到我使用的电脑,打印一条的间隔是平均2us左右.