2015-02-03 星期二 9:55:20
这几天看了先板子的资料和OSAL,主要记录下OSAL。
1、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[]赋值。123456789101112131415uint8 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
123456789101112131415161718192021uint8 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()一样偏移后操作。