2015-02-03 星期二 9:55:20
这几天看了先板子的资料和OSAL,主要记录下OSAL。
概要
看了代码,OSAL确实只能称之为操作系统抽象层,就是选择执行函数指针数组tasksArr[]里的pfunc,并没有切入到硬件SP中去操作(push/pop)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
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
GenericApp_ProcessEvent
};
|
在osal_run_system()中调用tasksArr[]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
void
osal_run_system(
void
)
{
......
do
{
if
(tasksEvents[idx])
// Task is highest priority that is ready.
{
break
;
}
}
while
(++idx < tasksCnt);
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);
activeTaskID = idx;
events = (tasksArr[idx])( idx, events );
activeTaskID = TASK_NO_TASK;
HAL_ENTER_CRITICAL_SECTION(intState);
tasksEvents[idx] |= events;
// Add back unprocessed events to the current task.
HAL_EXIT_CRITICAL_SECTION(intState);
}
......
}
|
事件触发
对tasksEvents[]赋值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
uint8 osal_set_event( uint8 task_id, uint16 event_flag )
{
if
( task_id < tasksCnt )
{
halIntState_t intState;
HAL_ENTER_CRITICAL_SECTION(intState);
// Hold off interrupts
tasksEvents[task_id] |= event_flag;
// Stuff the event bit(s)
HAL_EXIT_CRITICAL_SECTION(intState);
// Release interrupts
return
( SUCCESS );
}
else
{
return
( INVALID_TASK );
}
}
|
MSG
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
uint8 OnBoard_SendKeys( uint8 keys, uint8 state )
{
keyChange_t *msgPtr;
if
( registeredKeysTaskID != NO_TASK_ID )
{
// Send the address to the task
msgPtr = (keyChange_t *)osal_msg_allocate(
sizeof
(keyChange_t) );
if
( msgPtr )
{
msgPtr->hdr.event = KEY_CHANGE;
msgPtr->state = state;
msgPtr->keys = keys;
osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr );
}
return
( ZSuccess );
}
else
return
( ZFailure );
}
|
osal_msg_allocate()返回的内存地址(return ( (uint8 *) (hdr + 1) )) 为addr_key,所以msgPtr指向addr_key。
对msgPtr赋值后,再传递给osal_msg_send(),最终把指向addr_key的内存挂在msg queue的尾部。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
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 );
}
|
在osal_msg_send()中,OSAL_MSG_ID( msg_ptr ) = destination_task; 先将msg_ptr(指向addr_key)偏移到addr_msg后再赋值。
在osal_msg_enqueue()中,挂在msg queue的尾部是指向addr_key的内存。
在osal_msg_receive()中,读取对应的msg(指向addr_key)后再和osal_msg_send()一样偏移后操作。