一,前言
不識廬山真面目,只緣生在此山中。光看細節代碼不瞭解架構或者需求的話,很多東西都看不全面,而我的目的主要是瞭解設計思想爲我所用,而不是瞭解c語言編程技巧。所以先中需求下手,然後再去看代碼。主要是用來做閉環驗證,驗證我理解的需求是否正確而已,順便看看c語言去實現這樣的需求中用到的結構體及其算法的設計。
二,threadx OS通信機制
- 信號燈(量)
主要用來做任務間同步或資源保護。主要包括二進制信號燈和計數信號燈。
執行獲取操作會將信號燈數量減一。 如果信號燈爲 0,獲取操作不會成功。 獲取操作的逆操作是放置操作。 該操作會將信號燈數量加一。 - 互斥量
主要用來做共享資源保護。
互斥實質上是二進制信號燈。 - 事件集
主要用來通知事件。 - 消息隊列
主要用來傳遞信息。
消息隊列中可以駐留一個或多個消息。比如FIFO或LIFO方式。 - 郵箱
主要用來傳遞信息。
保留單個消息的消息隊列通常稱爲郵箱。新的消息會覆蓋原有消息。
以上說明了應用也說明了各類通信機制的區別點。
三,計數信號燈的源碼分析
所有這些任務間通信機制的代碼實現都是在關閉中斷的情況下執行的。接着這些通信機制中的代碼應該是短小的。其實光看上面的需求也確實是比較簡單的代碼。
比如獲取信號的函數_txe_semaphore_get->_tx_semaphore_get
“執行獲取操作會將信號燈數量減一。 如果信號燈爲 0,獲取操作不會成功。”
信號燈結構體
從結構體來看主要是id,名稱,計數值和掛起列表。然後就是標配的雙鏈表。最後是擴展的調試信息。
typedef struct TX_SEMAPHORE_STRUCT
{
/* Define the semaphore ID used for error checking. */
ULONG tx_semaphore_id;
/* Define the semaphore's name. */
CHAR *tx_semaphore_name;
/* Define the actual semaphore count. A zero means that no semaphore
instance is available. */
ULONG tx_semaphore_count;
/* Define the semaphore suspension list head along with a count of
how many threads are suspended. */
struct TX_THREAD_STRUCT
*tx_semaphore_suspension_list;
UINT tx_semaphore_suspended_count;
/* Define the created list next and previous pointers. */
struct TX_SEMAPHORE_STRUCT
*tx_semaphore_created_next,
*tx_semaphore_created_previous;
#ifdef TX_SEMAPHORE_ENABLE_PERFORMANCE_INFO
/* Define the number of semaphore puts. */
ULONG tx_semaphore_performance_put_count;
/* Define the number of semaphore gets. */
ULONG tx_semaphore_performance_get_count;
/* Define the number of semaphore suspensions. */
ULONG tx_semaphore_performance_suspension_count;
/* Define the number of semaphore timeouts. */
ULONG tx_semaphore_performance_timeout_count;
#endif
#ifndef TX_DISABLE_NOTIFY_CALLBACKS
/* Define the application callback routine used to notify the application when
the a semaphore is put. */
VOID (*tx_semaphore_put_notify)(struct TX_SEMAPHORE_STRUCT *semaphore_ptr);
#endif
/* Define the port extension in the semaphore control block. This
is typically defined to whitespace in tx_port.h. */
TX_SEMAPHORE_EXTENSION
} TX_SEMAPHORE;
從結構和代碼的設計有2點值得我學習
- 宏定義開關添加調試信息。我設計代碼一般不會考慮到調試信息的設計。但是加個宏開關就可以方便的添加調試信息了。
- 結構體定義中用宏定義
TX_SEMAPHORE_EXTENSION
,便於擴展,若不需要的時候則設置爲空。比如可以添加user callback函數支持擴展。鉤子函數一添加,就能有回調函數功能了。當然此處按註釋可以看出不是callback函數。而且上面的callback函數用的是宏開關方式。
四,小結
所以c代碼都是數據結構加算法,OS的通信機制就是按需求實現c代碼即可。OS通信機制代碼爲什麼沒有設計的很複雜,原因就是它是在關全局中斷中執行的。另外,我想到一個問題,就是通信機制能否可以將5類結構體抽象再合併爲僅1個結構體,或再創造發明其它類的通信機制。我理解是可行的。只是拆分結構體後,從功能角度來說顆粒度就變小了,邏輯更簡單,代碼執行效率更高了,這才更符合RTOS的時時性。不過我以前看到過一個事件通知的描述好像就是好幾個功能的合集,這不清楚它代碼是如何優化性能的。