开发平台(Platform): (Ex: Win10, Linux, ...)
Raspberry pi model B+ / Raspberry pi 3 model B
编译器(Ex: GCC, clang, VC++...)+目标环境(跟开发平台不同的话需列出)
gcc 4.9
问题(Question):
之前希望能固定数据读取的周期,像这样:
while(...)
{
ReadData();
_usleep(3600); // 用nanosleep实作,不过单位换成us。
}
ReadData()是读取sensor的函式,它有可能读取1-5个sensor
(共用一个I2C,所以要设lock),
因为每个sensor更新资料的周期又不一样
void ReadData()
{
if (out_of_data0) readSensor0();
if (out_of_data1) readSensor1();
if (out_of_data2) readSensor2();
if (out_of_data3) readSensor3();
if (out_of_data4) readSensor4();
}
其中Sensor0跟Sensor1的周期最短,到没啥问题。
问题是Sensor2/Sensor3/Sensor4周期比较长,读取也需要200-400us。
只读0/1跟5个全读的所需时间有可能会差到500-600us。
之前为了固定住ReadData()的周期,我是这样实作的:
....
pthread_create(thread2, readSensor2); //细节不多写,会意就好
pthread_create(thread3, readSensor3);
pthread_create(thread4, readSensor4);
void ReadData()
{
readSensor0();
readSensor1();
if (out_of_data2) pthread_cond_signal(&cond[thread1]); // 唤醒thread2
if (out_of_data3) pthread_cond_signal(&cond[thread1]); // 唤醒thread3
if (out_of_data4) pthread_cond_signal(&cond[thread1]); // 唤醒thread4
_usleep(3600);
}
(这几个thread被设成读取完自动睡回去,等待下次被唤醒)
意思就是说,做完readSensor0/readSensor1就暂停然后开始计时,
计时的同时被唤醒的readSensor2/readSensor3/readSensor4可以开始工作。
这招让我的周期变化<1ms
(使用Preempt RT的情况,我想用xenomai应该会更好,等我程式完成的差不多就试)。
不过我不太满足就是,想找个可以用lock-free的方法。
试过一个方法是这样:
void ReadData()
{
uint64_t time1 = get_nsec(); //使用clock_gettime得到当前时间
if (out_of_data0) readSensor0();
if (out_of_data1) readSensor1();
if (out_of_data2) readSensor2();
if (out_of_data3) readSensor3();
if (out_of_data4) readSensor4();
uint64_t time2 = get_nsec();
_usleep(4000-(int)(time2-time1));
}
就是按两次码表,把执行的时间算出来,然后周期扣掉执行时间就是该暂停的时间。
结果发现clock_gettime太频繁会得到奇怪的结果(不稳定)。
不然还有一个办法:把整个ReadData()丢到可以被唤醒的thread去
void ReadData()
{
if (out_of_data0) readSensor0();
if (out_of_data1) readSensor1();
if (out_of_data2) readSensor2();
if (out_of_data3) readSensor3();
if (out_of_data4) readSensor4();
}
void period()
{
while(....)
{
pthread_cond_signal(&cond[thread_of_ReadData]);
_usleep(4000);
}
}
不过有个极小的风险是如果这个thread没有在暂停的时间内跑完就....
请问还有别的方法可以让周期的误差更低?
补充说明(Supplement):
四轴的程式龟速改写中,不要催....