OSAL的消息機制觸發事件流程


定時器觸發事件一般為程序內部觸發,若外部觸發事件,可以用系統消息觸發,以按鍵觸發為例。

在初始化時候,InitBoard()中,注冊了按鍵回調函數

HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback);

該函數中注冊按鍵回調函數到pHalKeyProcessFunction,並啟動定時器事件,IDHALID,事件為按鍵事件,調用HalKeyPoll(),啟動按鍵輪詢,等待按鍵觸發。

halProcessKeyInterrupt()通過HAL_ISR_FUNCTION()注冊到OSAL的中斷機制中,此部分代碼沒有公開,可能是底層按鍵觸發中斷,然后調用halProcessKeyInterrupt()上報事件,HalKeyPoll()中調用初始化時候注冊的按鍵回調函數(pHalKeyProcessFunction) ()進行處理;

在回調函數中,調用OnBoard_SendKeys()函數發送系統消息,消息結構如下

typedef struct

{

  void   *next;

  uint16 len;

  uint8  dest_id;

} osal_msg_hdr_t;

 

typedef struct

{

  uint8  event;

  uint8  status;

} osal_event_hdr_t;

 

typedef struct

{

  osal_event_hdr_t hdr;

  uint8             state;  

  uint8             keys; 

} keyChange_t;

 

 

回調函數OnBoard_SendKeys()原型如下:

 
         
 1 /*********************************************************************
 2 
 3  * @fn      OnBoard_SendKeys
 4 
 5  *
 6 
 7  * @brief   Send "Key Pressed" message to application.
 8 
 9  *
10 
11  * @param   keys  - keys that were pressed
12 
13  *          state - shifted
14 
15  *
16 
17  * @return  status
18 
19  *********************************************************************/
20 
21 uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
22 
23 {
24 
25   keyChange_t *msgPtr;
26 
27   if ( registeredKeysTaskID != NO_TASK_ID )
28 
29   {
30 
31     // Send the address to the task
32 
33     msgPtr = (keyChange_t *)osal_msg_allocate( sizeof(keyChange_t) );
34 
35     if ( msgPtr )
36 
37     {
38 
39       msgPtr->hdr.event = KEY_CHANGE;
40 
41       msgPtr->state = state;
42 
43       msgPtr->keys = keys;
44 
45 
46       osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
47 
48     }
49 
50     return ( SUCCESS );
51 
52   }
53 
54   else
55 
56     return ( FAILURE );
57 
58 }
 
         

 

 

 

 

OnBoard_SendKeys()函數中,調用osal_msg_allocate()函數申請一塊內存,

 1 /*********************************************************************
 2 
 3  * @fn      osal_msg_allocate
 4 
 5  *
 6 
 7  * @brief
 8 
 9  *
10 
11  *    This function is called by a task to allocate a message buffer
12 
13  *    into which the task will encode the particular message it wishes
14 
15  *    to send.  This common buffer scheme is used to strictly limit the
16 
17  *    creation of message buffers within the system due to RAM size
18 
19  *    limitations on the microprocessor.   Note that all message buffers
20 
21  *    are a fixed size (at least initially).  The parameter len is kept
22 
23  *    in case a message pool with varying fixed message sizes is later
24 
25  *    created (for example, a pool of message buffers of size LARGE,
26 
27  *    MEDIUM and SMALL could be maintained and allocated based on request
28 
29  *    from the tasks).
30 
31  *
32 
33  *
34 
35  * @param   uint8 len  - wanted buffer length
36 
37  *
38 
39  *
40 
41  * @return  pointer to allocated buffer or NULL if allocation failed.
42 
43  */
44 
45 uint8 * osal_msg_allocate( uint16 len )
46 
47 {
48 
49   osal_msg_hdr_t *hdr;
50 
51  
52   if ( len == 0 )
53 
54     return ( NULL );
55 
56  
57 
58   hdr = (osal_msg_hdr_t *) osal_mem_alloc( (short)(len + sizeof( osal_msg_hdr_t )) );
59 
60   if ( hdr )
61 
62   {
63 
64     hdr->next = NULL;
65 
66     hdr->len = len;
67 
68     hdr->dest_id = TASK_NO_TASK;
69 
70     return ( (uint8 *) (hdr + 1) );
71 
72   }
73 
74   else
75 
76     return ( NULL );
77 
78 }

 

 

其內存布局如下:

 

 

    申請成功后,返回值為keyChange_t部分的首地址,因此在隨后的消息檢查,填充等操作中會有結構體指針減一的操作

 

消息創建完成后,調用osal_msg_send()將消息發送出去,該函數調用osal_msg_enqueue_push(),將消息發送至OSAL消息鏈表,並調用osal_set_event( destination_task, SYS_EVENT_MSG );向目標任務發送一個系統消息事件,在主循環中調用目標任務的回調函數,進入系統消息處理分支接收並解析處理消息。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM