繼續說任務間的通信。
本次的任務是在ISR中發送一個消息給任務,ucos的代碼中的是非常之簡潔和容易理解啊。創建,釋放,等待,非常好理解,不再贅述。
說說我遇到的問題,數據幀接收完之后,向消息隊列發送了消息,任務中等待接收,設置為阻塞模式,代碼非常簡單。
//ISR中釋放 OSQPost((OS_Q *)&Msg_Que_Uart2, (void *)&end_flag, (OS_MSG_SIZE )1, (OS_OPT )OS_OPT_POST_FIFO, (OS_ERR *)&err); //任務中請求 while (DEF_TRUE) { pEndflag = OSQPend ((OS_Q *)&Msg_Que_Uart2, (OS_TICK )0, (OS_OPT )OS_OPT_PEND_BLOCKING, (OS_MSG_SIZE *)&size, (CPU_TS *)NULL, (OS_ERR *)&err); GPSorBD_Data_read(); OSTimeDlyHMSM(0, 0, 0, 10, OS_OPT_TIME_HMSM_STRICT, &err); }
代碼真是無比簡潔,看起來倍舒服。然而就是這幾行代碼還遇到了一個大問題,花費了兩天時間才解決這個問題。調試的時候請求那邊死活收不到釋放那邊的消息內容,一直是0,進去看消息隊列的結構體
struct os_msg_q { /* OS_MSG_Q */ OS_MSG *InPtr; /* Pointer to next OS_MSG to be inserted in the queue */ OS_MSG *OutPtr; /* Pointer to next OS_MSG to be extracted from the queue */ OS_MSG_QTY NbrEntriesSize; /* Maximum allowable number of entries in the queue */ OS_MSG_QTY NbrEntries; /* Current number of entries in the queue */ OS_MSG_QTY NbrEntriesMax; /* Peak number of entries in the queue */ };
我定義的消息隊列只接受一個字節的內容,只有接收到以后,下一個消息才能傳進來。調試中NbrEntries這個值(指的是當前隊列中的消息數量)一直為0,也就是釋放信號量那邊的數據一直沒有傳送過來。百思不得其解。
我嘗試着把釋放消息這段放到任務中間去,變成任務與任務之間的消息傳遞,通信正常了。應該是中斷中傳送的數據沒有送到,為什么呢,請注意仔細的看消息內容的這段定義:消息的內容必須一直保持可見性,可見性是指代表消息的變量必須在接收消息的任務代碼范圍內有效。這是因為發布的數據采用的是指針傳遞,也就是引用傳遞,並不是值傳遞。也就是說,發布的消息本身並不產生拷貝,我們可以使用動態內存分配的方式來給消息分配一個內存塊,或者,也可以傳遞一個指向全局變量、全局數據結構、全局數組或者函數的指針。