2011-02-16 119 views
1

所以我有一個嵌入式Linux設備,通過串口連接到電機控制器。我正在編寫一個接口庫,它使得其他程序會調用很多很好的通用函數。其中一個是運行程序,它是目前控制器的閃存盤上的功能:最好的方法來寫一個超時的功能(posix C)

int run_motor_program(int serial_fd, char *label, timeout); 

此函數的一般僞代碼是:

call write(serial_fd, "start program at `label`") 
perform a couple read()'s/write()'s to check whether program has started on the motor controller 
do 
    /* some stuff */ 
while(program is running AND timeout hasn't exceeded) 
If the timeout exceeded, kill motor and return timeout error 

在上述函數的定義的超時被用於在馬達控制器上運行程序時出現問題。如果電機控制器卡在比預期更長的迴路中,我需要停止編程的能力。

的唯一途徑,我知道保持超時的軌跡是:

1)調用函數gettimeofday()之前和在循環過程,看是否經過時間是在調用

2通電>超時值) clock_gettime()基本上與1相同。

3)在循環中使用timer_create()和timer_getoverrun()來檢查時間是否已經過去(這似乎是最優雅的解決方案,但是我似乎無法獲得timer_getoverrun()與SIGEV_NONE [我不想使用信號])。

其中哪些(或者如果有人有任何其他建議)是處理函數中包含超時的最佳方法?我真的只需要分辨率達到毫秒。

回答

1

我傾向於自己做選項1。如果不需要亞秒粒度,那麼我將使用time。通常情況下,工作是檢查IO,因此我還使用配置了超時的select

+0

選項1是我的想法。`gettimeofday()`和`time()`的問題是,如果我(或NTP)在我的函數被調用時改變了系統時間,它將隨着超時而改變。對於這個函數,`select()`沒有幫助,因爲我沒有在串口文件描述符上等待數據。 – Ryan 2011-02-16 03:46:48

0

您可以考慮使用其中一種報警信號機制。最簡單和最老的是alarm(),它在指定的秒數之後調度SIGALRM信號。如果你有一個SIGALRM的信號處理程序,你的程序不會死,但可以讓你從錯誤中恢復。

alarm()的主要限制是它在整秒內處理。有很多亞秒或分秒的替代品。你應該看看setitimer()。您可能會使用nanosleep(),但您可能還需要使用線程,因爲nanosleep()會阻止調用線程。這將其提升到複雜性等級。有像pthread_cond_timedwait()這樣的調用也可以用於線程化程序。

您的原型int run_motor_program(int serial_fd, char *label, timeout);不會編譯;您需要定義超時參數的類型。您還需要確定您的參數意味着什麼 - 無論是間隔還是持續時間(超時前運行電機的秒數),還是結束時間(程序必須是Unix時間停止)。有不同的亞秒級結構,你必須談判。您的選擇很可能受您用於實現超時的系統調用的影響。

+0

我沒有在上面的原型中爲超時定義的類型,因爲我還沒有決定如何去做。有沒有發送超時的「標準」或「更常見」的方式?我知道select()使用struct timeval加載的秒數/微秒數來等待。 – Ryan 2011-02-16 03:41:54

相關問題