Z-STACK 协议栈学习 -- OSAL
期间参加了一次天池的比赛,然后就来了项目,,,(无力),比赛的内容也忘得差不多了,有时间再补上。
项目需要用zigbee做通信,为了开发得快一点这里就使用了Z-Stack,这是一个近似于小型操作系统管理的协议栈。我们先来看以下它的工作流程。
一、OSAL
OSAL管理着开发板上的各种资源,是一个为操作系统,他的工作流程如下。
首先我们需要知道整个协议栈程序的开端,程序的开端在Zmain文件夹的Zmian.c文件中,在这个c文件中可以看到一段如下的程序:
int main( void )
{
// Turn off interrupts
osal_int_disable( INTS_ALL );
// Initialization for board related stuff such as LEDs
HAL_BOARD_INIT();
// Initialize board I/O
InitBoard( OB_COLD );
// Initialze HAL drivers
HalDriverInit();
// Initialize NV System
osal_nv_init( NULL );
// Initialize the MAC
ZMacInit();
// Determine the extended address
zmain_ext_addr();
#if defined ZCL_KEY_ESTABLISH
// Initialize the Certicom certificate information.
zmain_cert_init();
#endif
// Initialize basic NV items
zgInit();
#ifndef NONWK
// Since the AF isn't a task, call it's initialization routine
afInit();
#endif
// Initialize the operating system
osal_init_system();
// Allow interrupts
osal_int_enable( INTS_ALL );
SysTickSetup();
// Final board initialization
InitBoard( OB_READY );
/* Display the device info on the LCD */
#ifdef LCD_SUPPORTED
zmain_dev_info();
zmain_lcd_init();
#endif
#ifdef WDT_IN_PM1
/* If WDT is used, this is a good place to enable it. */
WatchDogEnable( WDTIMX );
#endif
osal_start_system(); // No Return from here
return 0; // Shouldn't get here.
} // main()
在这段程序中可以看到各种带有init的函数,这些函数都是用于做初始化的,比如 HAL_BOARD_INIT()是板外设的初始化。HalDriverInit()是驱动程序的初始化。这些直接跳过,直接看osal_start_system()这个函数,这个函数是用于启动操作系统的。双击它按F12进入该函数,可以看到函数中有这样一段程序:
for(;;) // Forever Loop
#endif
{
osal_run_system();
#ifdef USE_ICALL
ICall_wait(ICALL_TIMEOUT_FOREVER);
#endif /* USE_ICALL */
}
可以看到,这是一个死循环,在死循环中有一个运行操作系统的函数osal_run_system(),我们的协议栈就是在这个循环中不断运行的。
OK,双击osal_run_system()函数按F12进入,看到这样一段程序:
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);
}
这段程序中首先是是一个do while的循环,判断了一个数组是否非零,这个数组很重要,我们把它叫做事件数组,它的元素都是16位的UINT16型数据,这个数组的元素个数等于我们定义的任务的数量(这里又提到了一个任务的概念,稍后解释)。
当这个数组非零时表示着以idx为编号的任务有事件要处理,那么就跳出循环,处理事件。继续向下执行语句直到这一句 events = (tasksArr[idx])( idx, events ),这条语句的意思是调用编号为idx的任务的任务处理函数,处理的事件是events,这里最后有一个赋值的操作,就是将(tasksArr[idx])( idx, events )的值赋给events,这是因为处理函数的返回值是events(在任务处理函数中每处理一个事件都会做一个抑或操作,表示事件已经处理过)。
以上就是OSAL的运行流程,下一篇我们来看一下事件的处理过程。
上一篇: git 批量删除分支
下一篇: Git 常用命令速查