首先看的是main函数
里面有两个关于OSAL的函数
1、 osal_init_system(); //初始化系统
2、 osal_start_system(); //启动系统
首先分析一下系统的初始化
系统初始化里包含了几部分内容
1、内存分配管理的初始化
2、定时器的初始化
3、电源管理初始化
4、系统任务初始化 osalInitTasks();
我这里是先看的系统任务初始化,先了解任整个系统的运行流程
在osalInitTasks()
首先是
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
函数中有两个变量 tasksEvents 初步看是个任务事件指针 暂时不知道干什么用的
tasksCnt 任务数 定义如下:const uint8 tasksCnt = sizeof( tasksArr ) / sizeof( tasksArr[0] );
tasksCnt是tasksArr 这个数组的大小 暂时不知道是干什么的
先看下tasksArr的定义
// The order in this table must be identical to the task initialization calls below in osalInitTask.
const pTaskEventHandlerFn tasksArr[] = {
macEventLoop,
nwk_event_loop,
Hal_ProcessEvent,
#if defined( MT_TASK )
MT_ProcessEvent,
#endif
APS_event_loop,
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_ProcessEvent,
#endif
ZDApp_event_loop,
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
ZDNwkMgr_event_loop,
#endif
ShyApp_ProcessEvent
};
typedef unsigned short (*pTaskEventHandlerFn)( unsigned char task_id, unsigned short event );
由上面可以看出tasksArr 是一个函数指针数组 初始化了所用到任务的函数入口指针。
macTaskInit( taskID++ );
nwk_init( taskID++ );
Hal_Init( taskID++ );
#if defined( MT_TASK )
MT_TaskInit( taskID++ );
#endif
APS_Init( taskID++ );
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_Init( taskID++ );
#endif
ZDApp_Init( taskID++ );
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
ZDNwkMgr_Init( taskID++ );
#endif
ShyApp_Init( taskID );
然后就是出事话任务并每个任务分配一个ID号。我们可以发现分配的ID号正好对应任务数组的下标。
然后返回 进入void osal_start_system( void )启动系统的函数
do {
if (tasksEvents[idx]) // Task is highest priority that is ready.
{
break;
}
} while (++idx < tasksCnt);
在这里循环的判断任务事件标志是否为0,如果不为0 就跳出
if (idx < tasksCnt)
{
uint16 events;
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);
events = tasksEvents[idx];
tasksEvents[idx] = 0; // Clear the Events for this task.
HAL_EXIT_CRITICAL_SECTION(intState);
events = (tasksArr[idx])( idx, events );
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[idx] |= events; // Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState);
}
跳出后就调用相应事件对应的任务号的任务。并将事件标志作为参数传入。
UINT16 ShyApp_ProcessEvent( byte task_id, UINT16 events )
{
afIncomingMSGPacket_t *MSGpkt;
afDataConfirm_t *afDataConfirm;
// Data Confirmation message fields
byte sentEP;
ZStatus_t sentStatus;
byte sentTransID; // This should match the value sent
(void)task_id; // Intentionally unreferenced parameter
if ( events & SYS_EVENT_MSG )
{
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ShyApp_TaskID );
while ( MSGpkt )
{
switch ( MSGpkt->hdr.event )
{
case ZDO_CB_MSG:
ShyApp_ProcessZDOMsgs( (zdoIncomingMsg_t *)MSGpkt );
break;
case KEY_CHANGE:
ShyApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );
break;
case AF_DATA_CONFIRM_CMD:
// This message is received as a confirmation of a data packet sent.
// The status is of ZStatus_t type [defined in ZComDef.h]
// The message fields are defined in AF.h
afDataConfirm = (afDataConfirm_t *)MSGpkt;
sentEP = afDataConfirm->endpoint;
sentStatus = afDataConfirm->hdr.status;
sentTransID = afDataConfirm->transID;
(void)sentEP;
(void)sentTransID;
// Action taken when confirmation is received.
if ( sentStatus != ZSuccess )
{
// The data wasn't delivered -- Do something
}
break;
case AF_INCOMING_MSG_CMD:
ShyApp_MessageMSGCB( MSGpkt );
break;
case ZDO_STATE_CHANGE:
ShyApp_NwkState = (devStates_t)(MSGpkt->hdr.status);
// if ( (ShyApp_NwkState == DEV_ZB_COORD)
// || (ShyApp_NwkState == DEV_ROUTER)
// || (ShyApp_NwkState == DEV_END_DEVICE) )
// {
// // Start sending "the" message in a regular interval.
// osal_start_timerEx( ShyApp_TaskID,
// ShyApp_SEND_MSG_EVT,
// ShyApp_SEND_MSG_TIMEOUT );
// }
// Release the memory
osal_msg_deallocate( (uint8 *)MSGpkt );
// Next
MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( ShyApp_TaskID );
}
// return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
// Send a message out - This event is generated by a timer
// (setup in ShyApp_Init()).
if ( events & ShyApp_SEND_MSG_EVT )
{
// Send "the" message
ShyApp_SendTheMessage();
// Setup to send message again
osal_start_timerEx( ShyApp_TaskID,
ShyApp_SEND_MSG_EVT,
ShyApp_SEND_MSG_TIMEOUT );
// return unprocessed events
return (events ^ ShyApp_SEND_MSG_EVT);
}
// Discard unknown events
return 0;
}
找个任务处理函数分析,首先是按位与 判断当前是哪个事件,不同的事件对应不同的处理方式。
到这里系统大致的运行流程基本搞明白了。
OSAL 是一个基于事件处理机制的简易的系统。根据如果有任务事件就去处理相应的任务。如果没有事件则不处理。不停的这样循环。