CC2540/CC2541/CC254x之OSAL消息队列

OSAL消息队列


事件是驱动任务去执行某些操作的条件,当系统中产生了一个事件,OSAL将这个事件传递给相应的任务后,任务才能执行一个相应的操作(调用事件处理函数去处理)。

 

通常某些事件发生时,又伴随着一些附件信息的产生,例如:从天线接收到数据后,会产生消息,但是任务的事件处理函数在处理这个事件的时候,还需要得到天线接收到的数据。

 

因此,这就需要将事件和数据封装成一个消息,将消息发送到消息队列,然后在事件处理函数中就可以使用osal_msg_receive,从消息队列中得到该消息。如下代码可以从消息队列中得到一个消息:

pMsg = osal_msg_receive( simpleBLEPeripheral_TaskID )


OSAL维护了一个消息队列,每一个消息都会被放到这个消息队列中去,当任务接收到事件后,可以从消息队列中获取属于自己的消息,然后调用消息处理函数进行相应的处理。

 

OSAL中消息队列如下所示:



每个消息都包含一个消息头osal_msg_hdr_t和自定义的消息,osal_msg_hdr_t结构体的定义为:

typedef struct
{
  void   *next;
  uint16 len;
  uint8  dest_id;
} osal_msg_hdr_t;



OSAL添加新任务


我们结合示例工程simpleBLEPeripheral来讲解,打开Projects\ble\SimpleBLEPeripheral\Source目录下的OSAL_SimpleBLEPeripheral.c文件可以找到数组tasksArr[]和初始化函数osalInitTasks()

1.tasksArr[]数组里存放了所有任务的事件处理函数的地址。

2.osalInitTasks()函数是OSAL的任务初始化函数,所有任务的初始化工作都在这里完成,并且自动给每个任务分配一个任务ID。

 

因此,要添加新任务,我们只需要编写两个函数:

1.新任务的初始化函数。

2.新任务的事件处理函数。

 

将新任务的初始化函数添加在osalInitTasks()函数的最后,如下代码所示:

void osalInitTasks( void )
{
	uint8 taskID = 0;

	tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
	osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));

	/* LL Task */
	LL_Init( taskID++ );

	/* Hal Task */
	Hal_Init( taskID++ );

	/* HCI Task */
	HCI_Init( taskID++ );

#if defined ( OSAL_CBTIMER_NUM_TASKS )
	/* Callback Timer Tasks */
	osal_CbTimerInit( taskID );
	taskID += OSAL_CBTIMER_NUM_TASKS;
#endif

	/* L2CAP Task */
	L2CAP_Init( taskID++ );

	/* GAP Task */
	GAP_Init( taskID++ );

	/* GATT Task */
	GATT_Init( taskID++ );

	/* SM Task */
	SM_Init( taskID++ );

	/* Profiles */
	GAPRole_Init( taskID++ );
	GAPBondMgr_Init( taskID++ );

	GATTServApp_Init( taskID++ );

	/* Application */
	SimpleBLEPeripheral_Init( taskID );
}

将新任务的事件处理函数的地址加入tasksArr[]数组的最后,如下所示:

const pTaskEventHandlerFn tasksArr[] =
{
	LL_ProcessEvent,                                                  // task 0
	Hal_ProcessEvent,                                                 // task 1
	HCI_ProcessEvent,                                                 // task 2
#if defined ( OSAL_CBTIMER_NUM_TASKS )
	OSAL_CBTIMER_PROCESS_EVENT( osal_CbTimerProcessEvent ),           // task 3
#endif
	L2CAP_ProcessEvent,                                               // task 4
	GAP_ProcessEvent,                                                 // task 5
	GATT_ProcessEvent,                                                // task 6
	SM_ProcessEvent,                                                  // task 7
	GAPRole_ProcessEvent,                                             // task 8
	GAPBondMgr_ProcessEvent,                                          // task 9
	GATTServApp_ProcessEvent,                                         // task 10
	SimpleBLEPeripheral_ProcessEvent                                  // task 11
};


在此例中,将SimpleBLEPeripheral_ProcessEvent函数添加到了tasksArr[]数组的末尾,将SimpleBLEPeripheral_Init( taskID );函数也添加到了osalInitTasks()任务初始化函数的末尾了。

 

所以,需要注意一下两点:

1.tasksArr[]数组里各事件处理函数的排列顺序要与osalInitTasks()函数中调用各任务初始化函数的顺序保持一致,只有这样才能够保证每个任务的事件处理函数能够接收到正确的任务ID(在osalInitTasks()函数中分配的)

2.为了保证osalInitTasks()函数所分配的任务ID,需要给每一个任务定义一个全局变量来保存这个ID,在Projects\ble\SimpleBLEPeripheral\Source目录下的simpleBLEPeripheral.c文件中定义了一个全局变量simpleBLEPeripheral_TaskID,并且在SimpleBLEPeripheral_Init()初始化函数中对其赋值,所赋的值就是osalInitTasks()函数中调用SimpleBLEPeripheral_Init()初始化函数时传入的值。


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值