很多系統在設計的時候都會選擇訊息驅動的系統調度模型。這樣的模型在交換器以及許多通訊產品的軟體設計中被大規模使用,對於小型的沒有作業系統的嵌入應用而言,這樣的模型是很具有生命力的。
調度系統,可以分為若干模組,根據系統的實際需要可以設定若干模組,定義發到各個模組的訊息類型,所有的訊息都有相同的訊息頭。
struct msg_hdr_t {
int moduleID ; /* 訊息要發送到的模組 ID */
int msg; /* 訊息類型 */
int len ; /* 訊息長度 */
struct msg_hdr_t * next ; /* 指向訊息佇列中下一條訊息 */
};
訊息驅動的系統可以分為三個部分:1、發訊息;2、收訊息;3、調度訊息。所有的訊息都放在一個訊息佇列上,根據註冊的訊息處理函數的先後來決定模組的優先順序。
發送訊息的時候,首先先要分配訊息,在嵌入式系統中可以根據實際的情況,採用固定的訊息長度,這樣可以簡化記憶體配置。通常一個系統運行過程中,可能沒有處理的訊息是可以計算的,那麼就可以計算出需要分配的記憶體的大小。
void * msg_allocate( int len ) /* 輸入參數為訊息體的長度,返回是訊息體的首地址*/
{
struct msg_hdr_t * hdr ;
if(len <= 0) {
return NULL;
}
hdr = (struct msg_hdr_t *) mem_alloc( len + sizeof(struct msg_hdr_t));
if(hdr) {
hdr->len = len;
hdr->next = NULL;
hdr->moduleID = MODULE_ID_INVALID;
return (void *) ((hdr + 1)) ;
}
return NULL;
}
可以根據實際自己的實現替換 mem_alloc, 從而可以指定自己定製的記憶體配置方法。
int msg_send(int module, void * msg_ptr)
{
/* sanity check */
if(msg_ptr == NULL || FALSE == msg_valid_module(module)) {
msg_deletion(msg_ptr);
return ERROR_INVALID_PARAMETER;
}
if(MSG_NEXT(msg_ptr) != NULL || MSG_MODULE_ID(msg_ptr) != MODULE_ID_INVALID){
msg_deletion(msg_ptr);
return ERROR_INVALID_PARAMETER;
}
MSG_MODULE_ID(msg_ptr) = module;
msg_enqueue(msg_ptr);
msg_set_event(module, HAVE_MSG_FLAGS);
}
訊息發送函數的參數分別是要發送到的模組ID,以及訊息體。在每一個訊息處理函數中,要調用msg_deletion對收到的訊息進行釋放。
對於訊息頭的操作是通過下面四個宏來完成的:
MSG_MODULE_ID: 取訊息要發送到的模組的ID
MSG_LEN: 訊息體長度
MSG_NEX: 下一個訊息
MSG_MSG: 訊息類型
具體實現,可以從原始碼處下載。