osal_msg_send()函数使用

来源:互联网 发布:设施设备管理软件 编辑:程序博客网 时间:2024/05/29 20:05







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()函数,不用这么绕一大圈子


0 0
原创粉丝点击