[問題] 如何固定每個迴圈的執行週期?
開發平台(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):
四軸的程式龜速改寫中,不要催....
--
※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 90.41.211.206
※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1478376452.A.BE6.html
※ 編輯: wtchen (90.41.211.206), 11/06/2016 04:25:19
推
11/06 04:22, , 1F
11/06 04:22, 1F
→
11/06 04:22, , 2F
11/06 04:22, 2F
→
11/06 04:23, , 3F
11/06 04:23, 3F
→
11/06 04:25, , 4F
11/06 04:25, 4F
→
11/06 04:27, , 5F
11/06 04:27, 5F
→
11/06 04:29, , 6F
11/06 04:29, 6F
→
11/06 04:31, , 7F
11/06 04:31, 7F
→
11/06 04:32, , 8F
11/06 04:32, 8F
→
11/06 04:32, , 9F
11/06 04:32, 9F
→
11/06 04:33, , 10F
11/06 04:33, 10F
→
11/06 04:34, , 11F
11/06 04:34, 11F
→
11/06 04:35, , 12F
11/06 04:35, 12F
推
11/06 04:36, , 13F
11/06 04:36, 13F
→
11/06 04:37, , 14F
11/06 04:37, 14F
→
11/06 04:38, , 15F
11/06 04:38, 15F
→
11/06 04:40, , 16F
11/06 04:40, 16F
推
11/06 04:40, , 17F
11/06 04:40, 17F
→
11/06 04:40, , 18F
11/06 04:40, 18F
→
11/06 04:41, , 19F
11/06 04:41, 19F
→
11/06 04:41, , 20F
11/06 04:41, 20F
→
11/06 04:42, , 21F
11/06 04:42, 21F
→
11/06 05:55, , 22F
11/06 05:55, 22F
→
11/06 05:56, , 23F
11/06 05:56, 23F
→
11/06 05:56, , 24F
11/06 05:56, 24F
推
11/06 06:01, , 25F
11/06 06:01, 25F
→
11/06 06:01, , 26F
11/06 06:01, 26F
→
11/06 06:01, , 27F
11/06 06:01, 27F
→
11/06 06:01, , 28F
11/06 06:01, 28F
→
11/06 06:01, , 29F
11/06 06:01, 29F
→
11/06 06:01, , 30F
11/06 06:01, 30F
→
11/06 06:02, , 31F
11/06 06:02, 31F
→
11/06 06:02, , 32F
11/06 06:02, 32F
→
11/06 06:02, , 33F
11/06 06:02, 33F
不是不行,是因為我一定得用測量clock_gettime測量每個loop的時間
只要我clock_gettime的間隔太短會出問題
大概try了一下,至少間隔要在1ms以上才會穩定
→
11/06 11:39, , 34F
11/06 11:39, 34F
推
11/06 12:31, , 35F
11/06 12:31, 35F
→
11/06 12:31, , 36F
11/06 12:31, 36F
→
11/06 12:33, , 37F
11/06 12:33, 37F
→
11/06 14:27, , 38F
11/06 14:27, 38F
→
11/06 14:28, , 39F
11/06 14:28, 39F
→
11/06 14:28, , 40F
11/06 14:28, 40F
→
11/06 14:29, , 41F
11/06 14:29, 41F
→
11/06 14:30, , 42F
11/06 14:30, 42F
→
11/06 14:32, , 43F
11/06 14:32, 43F
→
11/06 14:32, , 44F
11/06 14:32, 44F
→
11/06 14:45, , 45F
11/06 14:45, 45F
→
11/06 14:45, , 46F
11/06 14:45, 46F
→
11/06 14:46, , 47F
11/06 14:46, 47F
→
11/06 14:46, , 48F
11/06 14:46, 48F
→
11/06 17:16, , 49F
11/06 17:16, 49F
※ 編輯: wtchen (90.41.211.206), 11/07/2016 01:29:00
→
11/07 01:32, , 50F
11/07 01:32, 50F
※ 編輯: wtchen (90.41.211.206), 11/07/2016 01:34:15
討論串 (同標題文章)
C_and_CPP 近期熱門文章
PTT數位生活區 即時熱門文章