下篇文张讲解一个无线控制LED案列,这章了解系统运行的结构。
第一Z-Stack 软件架构
Z-Stack 由 main()函数开始执行,main()函数共做了 2 件事:一是系统初始化,另外一件是开始执行轮转查询式操作系统,
FS_Zstack\ZMain.c
ZSEG int main( void )
{
osal_int_disable( INTS_ALL ); // 关闭所有中断
HAL_BOARD_INIT(); // 初始化系统时钟
zmain_vdd_check(); // 检查芯片电压是否正常
zmain_ram_init(); // 初始化堆栈
InitBoard( OB_COLD ); // 初始化I/O,LED、Timer等
HalDriverInit(); // 初始化芯片各硬件模块
osal_nv_init( NULL ); // 初始化 Flash存储器
zmain_ext_addr(); // 确定 IEEE地址
zgInit(); //初始化非易失变量
ZMacInit(); // 初始化MAC 层
osal_init_system(); //初始化操作系统
osal_int_enable( INTS_ALL ); //使能全部中断
InitBoard( OB_READY ); //初始化按键
zmain_dev_info(); //显示设备信息
osal_start_system(); //执行操作系统
}
第二Z-Stack 操作系统初始化
OSAL.c
byte osal_init_system( void )
{
osal_mem_init(); // Initialize the Memory Allocation System
osal_qHead = NULL; // Initialize the message queue
osalTimerInit(); // Initiaize the timers
osal_pwrmgr_init(); // Initialize the Power Management System
osalInitTasks(); //初始化系统的任务
osal_mem_kick(); // Setup efficient search for the first free block of heap.
return ( ZSUCCESS );
}
着重分析初始化系统任务,需要考虑的是自己用的时候有些地方是需要修改的。
sapi .c
void osalInitTasks( void )
{
uint8 taskID = 0;
//分配内存,返回指向缓冲区的指针
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
//设置所分配的内存空间单元值为 0
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
//任务优先级由高向低依次排列,高优先级对应 taskID 的值反而小
macTaskInit( taskID++ ); //macTaskInit(0),用户不需考虑
nwk_init( taskID++ ); //nwk_init(1),用户不需考虑
Hal_Init( taskID++ ); //Hal_Init(2),用户需考虑
APS_Init( taskID++ ); //APS_Init(3),用户不需考虑
ZDApp_Init( taskID++ ); //ZDApp_Init(4),用户需考虑
SAPI_Init( taskID ); //SAPI_Init(5),用户需考虑
}
第三操作系统执行过程
Z-Stack 中操作系统是基于优先级的轮转查询式操作系统详细执行过程如下:
FS_Zstack\OSAL.c
void osal_start_system( void )
{
for(;;) // 死循环
{
do {
if (tasksEvents[idx])
{
break; // 得到待处理的最高优先级任务索引号idx
}
} while (++idx < tasksCnt);
if (idx < tasksCnt)
{
HAL_ENTER_CRITICAL_SECTION(intState); //进入临界区
events = tasksEvents[idx]; //提取需要处理的任务中的事件
tasksEvents[idx] = 0; // 清除本次任务的事件
HAL_EXIT_CRITICAL_SECTION(intState); //退出临界区
events = (tasksArr[idx])( idx, events ); //通过指针调用任务处理函数
HAL_ENTER_CRITICAL_SECTION(intState); //进入临界区
tasksEvents[idx] |= events; // 保存未处理的事件
HAL_EXIT_CRITICAL_SECTION(intState); //退出临界区
}
}
}
sapi .c
const pTaskEventHandlerFn tasksArr[] = {
macEventLoop, //用户不需要考虑
nwk_event_loop, //用户不需要考虑
Hal_ProcessEvent, //用户可以考虑
APS_event_loop, //用户不需要考虑
ZDApp_event_loop, //用户可以考虑
SAPI_ProcessEvent //用户可以考虑
};