大家好,又见面了,我是你们的朋友全栈君。
ZigBee
的任务轮询如下图:
打开协议栈文件夹Texas Instruments\Projects\zstack
,里面包含了TI
公司的例程和工具。再打开Samples
文件夹:
Samples
文件夹里面有三个例子,即GenericApp
、SampleApp
、SimpleApp
。在这里我们选择SampleApp
对协议栈的工作流程进行讲解。打开SampleApp\CC2530DB
下的工程文件SampleApp.eww
,留意左边的工程目录,我们暂时只需要关注Zmain
文件夹和App
文件夹。
任何程序都在main
函数开始运行,Z-STACK
也不例外。打开Zmain.C
,找到main
函数。大概浏览一下main
函数的代码:
int main ( void ) {
osal_int_disable ( INTS_ALL ); /* Turn off interrupts 关闭所有中断 */
HAL_BOARD_INIT(); /* Initialization for board related stuff such as LEDs */
zmain_vdd_check(); /* Make sure supply voltage is high enough to run 检查芯片电压是否正常 */
InitBoard ( OB_COLD ); /* Initialize board I/O 初始化I/O、LED、Timer等 */
HalDriverInit(); /* Initialze HAL drivers 初始化芯片各硬件模块 */
osal_nv_init ( NULL ); /* Initialize NV System 初始化Flash存储器 */
ZmacInit(); /* Initialize the MAC 初始化MAC层 */
zmain_ext_addr(); /* Determine the extended address 确定“IEEE 64”位地址 */
zgInit(); /* Initialize basic NV items 初始化非易失变量 */
#ifndef NONWK
afInit(); /* Since the AF isn't a task, call it's initialization routine */
#endif
osal_init_system(); /* Initialize the operating system 初始化操作系统 */
osal_int_enable ( INTS_ALL ); /* Allow interrupts 使能全部中断 */
InitBoard ( OB_READY ); /* Final board initialization 初始化按键 */
zmain_dev_info(); /* Display information about this device 显示设备信息 */
#ifdef LCD_SUPPORTED /* Display the device info on the LCD */
zmain_lcd_init();
#endif
#ifdef WDT_IN_PM1
WatchDogEnable ( WDTIMX ); /* If WDT is used, this is a good place to enable it. */
#endif
osal_start_system(); /* No Return from here 执行操作系统,进去后不会返回 */
return 0; /* Shouldn't get here. */
}
我们重点了解2
个函数:初始化操作系统osal_init_system
,运行操作系统osal_start_system
。先来看osal_init_system
系统初始化函数。进入该函数,发现里面有6
个初始化函数,这里只关心osalInitTasks
任务初始化函数:
void osalInitTasks ( void ) {
uint8 taskID = 0;
tasksEvents = ( uint16 * ) osal_mem_alloc ( sizeof ( uint16 ) * tasksCnt ); /* 分配内存,返回指向缓冲区的指针 */
osal_memset ( tasksEvents, 0, ( sizeof ( uint16 ) * tasksCnt ) ); /* 设置所分配的内存空间单元值为0 */
/* 任务优先级由高向低依次排列,高优先级对应taskID的值反而小 */
macTaskInit ( taskID++ ); /* macTaskInit(0),用户不需考虑 */
nwk_init ( taskID++ ); /* nwk_init(1),用户不需考虑 */
Hal_Init ( taskID++ ); /* Hal_Init(2),用户需考虑 */
#if defined( MT_TASK )
MT_TaskInit ( taskID++ );
#endif
APS_Init ( taskID++ ); /* APS_Init(3),用户不需考虑 */
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_Init ( taskID++ );
#endif
ZDApp_Init ( taskID++ ); /* ZDApp_Init(4),用户需考虑 */
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
ZDNwkMgr_Init ( taskID ++ );
#endif
SampleApp_Init ( taskID ); /* SampleApp_Init(5),用户需考虑 */
}
我们可以这样理解,函数对taskID
这个东西进行初始化,每初始化一个任务,taskID
加一。大家看到了注释后面有些写着用户需要考虑,有些则写着用户不需考虑。写着需要考虑的,用户可以根据自己的硬件平台进行设置;写着不需考虑的,则是不能修改的。
我们再来看第二个函数osal_start_system
运行操作系统。TI
对该函数的描述为This function is the main loop function of the task system. It will look through all task events and call the task_event_processor() function for the task with the event. If there are no events (for all tasks), this function puts the processor into Sleep. This Function doesn't return.
,翻译成中文是这个是任务系统轮询的主要函数,它会查找发生的事件,然后调用相应的事件执行函数。如果没有事件登记要发生,那么就进入睡眠模式。这个函数是永远不会返回的
。
void osal_start_system ( void ) {
#if !defined ( ZBIT ) && !defined ( UBIT )
for ( ;; ) /* Forever Loop */
#endif
{
uint8 idx = 0;
osalTimeUpdate(); /* 这里是在扫描哪个事件被触发了,然后置相应的标志位 */
Hal_ProcessPoll(); /* This replaces MT_SerialPoll() and osal_check_timer(). */
Do {
if ( tasksEvents[idx] ) {
/* Task is highest priority that is ready. */
break; /* 得到待处理的最高优先级任务索引号idx */
}
} 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 ); /* 退出临界区 */
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 ); /* 退出临界区 */
}
#if defined( POWER_SAVING )
else {
/* Complete pass through all task events with no activity? */
osal_pwrmgr_powerconserve(); /* Put the processor/system into sleep */
}
#endif
}
}
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/140214.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...