osal_msg_send()函數使用







osal_msg_send()函數使用:
想要在應用層APP中建立自己的事件處理,需要用到osal_msg_send( )函數。

轉載自:http://hi.baidu.com/c51rf/item/c7e0ba12d473d2721109b56a
怎麼往OSAL中的任務中添加一個事件。這麼說有點空洞,所以假設一個實驗,然後大家跟着走一個流程看看。

假設的實驗是在當串口有值輸入時,lcd屏幕清屏並顯示我的標誌位。

串口回調函數用的基本是上次做過解釋的串口回調函數(可以看看以前的博文http://blog.sina.com.cn/s/blog_4c8287230100cyfk.html)。現在來看看實驗步驟吧。首先是定義一個事件的標誌(注意不要與系統自帶的標誌一樣),我這裏用的是

#define king_come 0x11

接着定義一個事件結構體,

typedef struct
{
osal_event_hdr_t hdr; //事件頭指針
uint8 mark; //標誌位

} myUartMsg_t;

然後是對事件結構的一系列說明,我做到一個函數裏了,其實不是必須這樣的。

void xy_come(void)
{
//事件內存分配,添加事件之前一定要進行內存分配

myUartMsg_t *myUartMsg;
myUartMsg= (myUartMsg_t *)osal_msg_allocate( sizeof( myUartMsg_t ) );//重要
//事件名稱定義

myUartMsg->hdr.event = king_come;
myUartMsg->mark= right_come; //定義標誌位

osal_msg_send( SampleApp_TaskID, (uint8 *)myUartMsg);
}

這樣基本是完成了一個事件的定義,下面我們就來應用這個事件。

爲了滿足我們的實驗,首先在串口回調函數中加入上面的事件說明函數

void xy_uartCB (uint8 port,uint8 event)
{
uint8 temp[8];
HalUARTRead(HAL_UART_PORT_0,temp,8); //芯片通過串口讀數據
right_come = 1;
xy_come();
}

然後在事件處理函數中添加這個事件的處理程序

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )
{
……
case king_come:
if(right_come == 1)
{
ClearScreen();
Print8(HAL_LCD_LINE_2,20,"king_come.",1);
right_come = 0;
}
break;

……

}

好了,這樣就向任務中添加了一個事件了。基本的流程就是先定義一個事件的標示,事件的結構,再在需要用到該事件的地方對事件的參數進行賦值。最後在事件處理函數裏添加對事件的處理子程序。知道了之後總是覺得很簡單,謝謝羣裏的Yicher!!


下面這段寫的也是關於osal_msg_send()的例子,感覺比上面的講得更清楚些,轉載自:

http://hi.baidu.com/ghostyu/item/a507c71d7e2dad5d2b3e2211

osal_msg_send 以及OSAL消息發送示例

TI z-stack協議棧中加入了RTOS,所以整個協議棧的各層功能的實現是以OS的Task形式調用的

一、用於發送消息的函數爲osal_msg_send

原型:OSAL.c中

uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr );

參數destination_task爲要接收此Message的目標任務ID,msg_ptr 爲所要發送的消息Message指針。

uint8 osal_msg_send( uint8 destination_task, uint8 *msg_ptr )

{

  if ( msg_ptr == NULL )

    return ( INVALID_MSG_POINTER );

  if ( destination_task >= tasksCnt )

  {

    osal_msg_deallocate( msg_ptr );

    return ( INVALID_TASK );

  }

 

  // Check the message header

  if ( OSAL_MSG_NEXT( msg_ptr ) != NULL ||

       OSAL_MSG_ID( msg_ptr ) != TASK_NO_TASK )

  {

    osal_msg_deallocate( msg_ptr );

    return ( INVALID_MSG_POINTER );

  }

  OSAL_MSG_ID( msg_ptr ) = destination_task;

  // queue message

  osal_msg_enqueue( &osal_qHead, msg_ptr );

  // Signal the task that a message is waiting

  osal_set_event( destination_task, SYS_EVENT_MSG );

  return ( SUCCESS );

}

發送Message,此OS做了兩件事:

1,將此Message加入“消息隊列”  :osal_msg_enqueue( &osal_qHead, msg_ptr );

2,設置系統消息事件,等待目標任務響應:osal_set_event( destination_task, SYS_EVENT_MSG );

但是爲了了代碼的可靠性,在此之前加入了判斷目標任務ID以及Message的合法性的語句。

 

二,如何向SampleApp_ProcessEvent發送與接收消息?

簡單示例:通過按鍵事件(即在處理所有按鍵事件的case下面),向SampleApp_ProcessEvent中發送自定義的LED閃爍的Message。

準備工作與步驟如下:

Message定義。

在ZComDef.h中定義了系統用到的Message的宏定義,如

#define  ZDO_STATE_CHANGE  0xD1

#define AF_INCOMING_MSG_CMD       0x1A

注意下面一條註釋:

// OSAL System Message IDs/Events Reserved for applications (user applications)

// 0xE0 – 0xFC

所以應用程序定義的Message只能從0xE0 – 0xFC

因此:

1、在註釋下面定一條Message 宏定義偏移量:

#define __MSG_OFFSET  0xE0        //避免自定的Marco與系統重複,所以加兩條下劃線。

2、如果自定的Message中只在SampleApp中使用,則在SampleApp.h中定義,否則應在ZComDef.h中

2.1在SampleApp.h中定義

#define MYMSG_LED_BLIND  __MSG_OFFSET+0x00

2.2自定義消息的格式結構體,用於消息的發送,以及攜帶數據,在定義的頭文件在2.1節中

typedef struct{  osal_event_hdr_t hdr;  //事件頭  uint8 state;    //閃爍次數} LedBlind_t;

3、在SampleApp_ProcessEvent函數中的switch ( MSGpkt->hdr.event )下添加一條case-break語句

switch ( MSGpkt->hdr.event )

...

case MYMSG_LED_BLIND :

  HalLedBlink( HAL_LED_1, ((LedBlind_t *)MSGpkt)->state, 50,1000 );  //LED1,閃爍次數((LedBlind_t *)MSGpkt)->state,每次佔空比50%,週期1000ms

  break;

...

然後在case KEY_CHANGE:下添加一條發送MYMSG_LED_BLIND閃爍的Message,在發送消息前要定義一個消息指針,並且使用osal_msg_allocate爲指針分配內存

...

case KEY_CHANGE:

   ...

    LedBlind_t *msgPtr;

    msgPtr = (LedBlind_t *)osal_msg_allocate( sizeof(LedBlind_t) );

    if(msgPtr)

    {

       msgPtr->hdr.event=MYMSG_LED_BLIND;//消息

       msgPtr->state=0x04;//閃爍次數 

       osal_msg_send(SampleApp_TaskID, (uint8 *)msgPtr );

    }

   ...

 

 以上代碼只是演示消息的發送與接收,沒有實用價值,因爲可直接在按鍵部分加入HalLedBlink()函數,不用這麼繞一大圈子


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章