1. 程式人生 > >uC/OSIII學習筆記(一)訊息傳遞

uC/OSIII學習筆記(一)訊息傳遞

  • 任務或ISR與另一個任務間進行資訊交換,這種資訊交換叫做作業間的通訊
  • 有兩種方法實現這種通訊:全域性變數和改善訊息;
  • 如果使用全域性變數,任務或ISR就必須確保獨佔這個變數;
  • 如果防止被ISR 巢狀,那麼就只有關中斷這種方法來保護這個變數;
  • 如果是任務間共享該變數,那麼可以通過關中斷、鎖排程器、訊號量、mutex 保護該變數。

    * 需注意的是:任務與ISR 通訊只能通過全域性變數。如果全域性變數被ISR 改變,任務將不會知道全域性變數被改變,除非該任務檢測該變數或者ISR 標記任務告知該變數被改變。*

訊息可以被髮送到媒介——訊息佇列中,也可以直接傳送給任務,因為uC/OS-III 中每個任務都有其內建的訊息佇列。如果多個任務等待這個訊息時就將該訊息傳送到外部的訊息佇列。當只有一個任務等待該訊息時直接將訊息傳送給任務。

任務等待訊息到達時,不佔用CPU。

1-1 訊息

訊息中包含一個指向資料的指標、該資料的大小、時間戳變數。該指標可以指向資料區域甚至是一個函式。當然,訊息的傳送方和訊息的接收方都應該知道訊息所包含的意義。換句話說,接收方知道接收發到訊息的含義。

訊息的內容(即資料)通常保留在其作用域中因為傳送的是資料的地址而不是資料。換句話說,資料不是被拷貝併發送給任務,而是告訴任務資料的地址,並讓任務自己去訪問

1-2 訊息佇列

訊息佇列是核心物件。事實上,可以分配任意個訊息佇列(只要處理器的RAM 足夠的話)。
通過訊息佇列使用者可以做很多事情,如圖15-1.然而,ISR 中只能呼叫OSQPost()。

訊息佇列是先入先出模式(FIFO)。然而,uC/OS-III 也可以將其設定為後入先出模式(LIFO)。若任務或ISR 傳送緊急訊息給另一個任務時,後入先出模式是非常有用的,在這種情況下,該緊急訊息繞過訊息佇列中的其他訊息。訊息佇列的長度可以在執行時設定。

如上圖,接收任務旁的沙漏表示該任務可以設定等待期限。如果任務沒有在規定時間內接收到該訊息,uC/OS-III 會返回一個錯誤代號表示任務被就緒不是因為接收到訊息,而是等待超時。

訊息佇列中存放了等待該訊息的任務。多個任務可以在訊息佇列中等待訊息,如圖15-2 所示。當一個訊息被髮送到訊息佇列時,等待該訊息的高優先順序任務接收這個訊息。訊息傳送者可以廣播這個訊息給訊息佇列中的所有任務。在這種情況下,如果接收到訊息中有優先順序高於訊息傳送者優先順序的任務,uC/OS-III 就會切換到這個高優先順序的任務。注意:不是每個任務都需要設定等待期限,有些任務可能需要永遠等待這個訊息。