2013-12-12 629 views
0

我有一個特定的任務例程,它以特定的順序執行一些操作,並且這些操作處理很少的volatile變量。有一個特定的中斷異步更新這些易失性變量。因此,如果發生這樣的中斷,任務例程應該重新啓動。通常FreeRTOS將恢復任務,但這會導致錯誤的派生值,因此需要重新啓動例程。我也無法將任務例程保留在關鍵部分,因爲我不應該錯過任何中斷。在FreeRTOS中重新啓動任務

FreeRTOS中有一種方法可以實現這一點嗎?像vtaskRestart API一樣。我可以刪除任務並重新創建它,但是這增加了很多內存管理複雜性,我想避免這些複雜性。目前我唯一的選擇是在例程中添加一個檢查標誌以查看是否發生了上下文切換,如果是,則重新啓動,否則繼續。

谷歌搜索沒有獲取任何線索。似乎人們從來不會遇到這樣的問題,或者可能是因爲這種設計很差。在FreeRTOS論壇上,很少有人要求重啓任務似乎沒有這個問題。 stackoverflow在freertos + task +重新啓動時沒有結果。所以,這可能是第一個標籤組合的帖子;)

有人可以告訴我,如果這是直接可能的FreeRTOS?

回答

0

您可以將信號量用於此目的。如果您決定使用信號量,則應該執行以下步驟。

  • 首先,你應該創建一個二進制信號量。
  • 信號量必須在中斷程序中給出 xSemaphoreGiveFromISR(Example_xSemaphore,& xHigherPriorityTaskWoken );
  • 而且,你必須檢查任務中的信號量。

    空隙vExample_Task(無效* pvParameters) {
    爲(;;){
    如果(xSemaphoreTake(Example_xSemaphore,Example_PROCESS_TIME)== pdTRUE) {

    } } }

+0

感謝parloid的迴應。我理解這個機制,事實上我的任務是使用二進制信號量,並且在這個semTake上,任務被阻塞,直到中斷釋放信號以使任務繼續。但是,我不明白這將如何解決我的問題。我應該在哪裏嘗試採取信號量,並阻止我的任務?更新我的變量的中斷可能來或不會來,而這些變量正在處理。我正在尋找一種機制,在發生特定中斷時必須重新啓動例程。 –

0

爲此目的,您應該使用隊列並使用隊列窺視函數來產生易失性數據。

我正在使用它,因爲我有一個實時計時器,這樣我就可以將時間用於我的所有任務,而沒有任何阻塞。

這是怎麼回事: 聲明隊列:

xQueueHandle  RTC_Time_Queue; 

創建1種元素的隊列:

RTC_Time_Queue = xQueueCreate(1, sizeof(your volatile struct)); 

覆蓋隊列每次你中斷髮生:

xQueueOverwriteFromISR(RTC_Time_Queue, (void*) &time); 

並從其他任務偷看隊列:

xQueuePeek(RTC_GetReadQueue(), (void*) &TheTime, 0); 

xQueuePeek末尾的0意味着如果隊列爲空,您不想等待。隊列窺視不會刪除隊列中的值,因此每當您查看並且代碼永遠不會停止時它就會出現。

此外,您應該避免讓變量從ISR和RTOS代碼訪問,因爲您可能會收到意外的損壞。

+0

感謝達米安,但這看起來像是一個很好的替代揮發性變量,否則我不知道這是否能解決我描述的問題。這裏再一次,我不知道什麼時候該完成任務。假設我在做計算的時候這樣做了,但是如果在完成計算之後並根據此計算採取行動之前得到這些中斷,該怎麼辦?因此我不確定我如何使用QueuePeek來解決這個問題。感謝您的輸入。 –

+0

我看到你的問題,我有一個類似的問題,我想重新啓動一個任務,但我還沒有真正找到一個好的解決方案。最終,您可以刪除並重新創建任務。 – Damien