zigbee 2:OSAL概要

本文详细解析了操作系统抽象层(OSAL)的工作原理及其在任务调度中的应用。介绍了OSAL的任务函数指针数组tasksArr[]及事件触发机制,通过实例说明了消息发送与接收的具体流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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[]赋值。
    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()一样偏移后操作。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值