Zigbee协议栈工作流程
http://shop60221214.taobao.com
SAPI_ProcessEvent }; 这个函数列表在 osalInitTask 里严格按顺序初始化,否则就乱套了 这里我们只关心按键任务处理函数 Hal_ProcessEvent 找到这个函数:在文件 hal_drivers.c uint16 Hal_ProcessEvent( uint8 task_id, uint16 events ) { ……………
} else // !OB_COLD {
/* Initialize Key stuff */ OnboardKeyIntEnable = HAL_KEY_INTERRUPT_DISABLE; HalKeyConfig( OnboardKeyIntEnable, OnBoard_KeyCallback); } } 看一下红色部分函数,找到原型函数(右键,Go to Definiton of …..) void HalKeyConfig (bool interruptEnable, halKeyCBack_t cback) 注 册 了 OnBoard_KeyCallback 作 为 回 调 函 数 , 也 就 是 按 键 处 理 函 数 , OnBoard_KeyCallback 这个函数位于 OnBoard.c 文件里, 再看一下这个函数: 找到这个语句: if ( OnBoard_SendKeys( keys, shift ) != ZSuccess ) 可见,当按键按下以后,会调用 OnBoard_SendKey 函数,生成了任务号
每次任务处理,都有一个时隙,如果处理不完,则保留该任务,到下一个周期再进行处 理。您可以通过设置断点来观察程序的运行情况,单步跟踪是没有用的,因为,整个协议栈 是消息处理机制,采用定时器控制的,单步运行无法控制定时器。下面以按键处理说明消息 处理机制,其它都是一样的,另外,不要深究无线数据是如何接收和发送的,协议栈有好多 分层,底层是 802.15.4,深究下去没必要,你只管 API 函数就行了。
6
希望微控工作室
附:zigbee 试验内容
http://shop60221214.taobao.com
7
希望微控工作室
http://shop60221214.taobao.com
8
2
希望微控工作室
http://shop60221214.taobao.com
这个函数里,找到 osal_msg_send( registeredKeysTaskID, (uint8 *)msgPtr ); 这个函数将按键发送到消息处理循环。 再看这个函数里的 //消息队列管理 osal_msg_enqueue( &osal_qHead, msg_ptr ); //设置按键事件 osal_set_event( destination_task, SYS_EVENT_MSG ); 在设置按键这个函数里,我们看到: tasksEvents[task_id] |= event_flag;
2、按键消息处理
注册回调函数。回调函数就是中断服务程序,每次中断发生之后,系统调用该函数,因 此,该函数在程序初始化的时候,就已经完成了注册。
主函数 ZMain.c 里的 InitBoard( OB_COLD ); void InitBoard( uint8 level ) {
if ( level == OB_COLD )
if (events & HAL_KEY_EVENT) {
#if (defined HAL_KEY) && (HAL_KEY == TRUE) /* Check for keys */
5
希望微控工作室
HalKeyPoll();
http://shop60221214.taobao.com
/* if interrupt disabled, do next polling */ if (!Hal_KeyIntEnable) {
(2)Hal_ProcessPoll(); 主要用于轮询串口
(3)events = tasksEvents[idx]; //从任务列表里获得要处理的事件,这个数组存放的是从序号 为 0 到 tasksCn,t 每个任务在本次循环中是否要被运行,需要运行的任务其值非 0,否则为 0。
(4)events = (tasksArr[idx])( idx, events ); tasksArr[idx] 是一个函数数组,存放了对应每个任务的入口地址,只有在 tasksEvents
中记录的需要运行的任务,在本次循环中才会被调用到,这就是事件处理函数,整个协议的 核心部分。tasksArr 定义如下:
const pTaskEventHandlerFn tasksArr[] = {
4
希望微控工作室
macEventLoop, nwk_event_loop, Hal_ProcessEvent, #if defined( MT_TASK ) MT_ProcessEvent, #endif APS_event_loop, ZDApp_event_loop,
1
希望微控工作室
ຫໍສະໝຸດ Baidu
http://shop60221214.taobao.com
{ // Interrupts off osal_int_disable( INTS_ALL ); // Turn all LEDs off HalLedSet( HAL_LED_ALL, HAL_LED_MODE_OFF ); // Check for Brown-Out reset ChkReset();
3
希望微控工作室
(4)events = (tasksArr[idx])( idx, events );
http://shop60221214.taobao.com
(5)tasksEvents[idx] |= events; // 任务没有处理完
(1)osalTimeUpdate(); 这个函数用于更新时隙,看一下原代码,可知,嘀嗒周期为 320us
希望微控工作室
http://shop60221214.taobao.com
Zigbee 协议栈工作流程
1、消息处理流程
首先,简介一下消息处理机制,一般都利用回调函数实现的,当某一个事件发生,比如 按键,它就会调用 按键的回调函数(或者叫响应函数),通过回调函数生成一个任务,并通 过任务发送 osal_msg_send 函数,发送消息处理循环,并注册事件,等待处理。应用层的事 件处理函数检测到事件后,调用相应的处理函数。
osal_start_timerEx( Hal_TaskID, HAL_KEY_EVENT, 100); } #endif // HAL_KEY
return events ^ HAL_KEY_EVENT; } …………………
} HalKeyPoll();这函数使用查询功能实现检测按键,并获得了键值,然后调用按键的回调函数 OnBoard_KeyCallback,将按键事件发送出去,送到应用层去处理。
由此可见,按键消息被添加进任务列表,等待任务处理
下面回到 void osal_start_system( void ) 函数里,主程序初始化完成后,就是开始了系 统运行,因此,介绍一下这里的函数。去掉一些辅助的代码,就剩下:
(1)osalTimeUpdate(); (2)Hal_ProcessPoll(); (3)events = tasksEvents[idx];