由于协议栈跑在平台硬件上,所以,在协议栈初始化之前,一般先完成的是平台初始化,比如时钟、中断、定时器、串口设置,还有RF模块、led、按键什么。另外,几乎所有的Zigbee协议栈都需要使用操作系统,来支撑各个任务间的来回调用,Z-stack中OSAL机制,Freakz的Contiki,都是类似的思想。所以,在完成平台硬件初始化之后、协议栈初始化之前,还需要完成OS相关的初始化。应用于嵌入式系统的OS,一般都很"mini",对多线程的实现并不复杂,比如ucosii,只需要按照固定的格式填充调用接口就可以了,嵌入式系统的OS的初始化也不复杂,下面是Freakz中contiki的初始化。
<
- /*第一步*/
- void process_init(void)
- {
- lastevent = PROCESS_EVENT_MAX;
- nevents = fevent = 0;
- process_current = process_list = NULL;
- }
- /*第二步*/
- void autostart_start(struct process * const processes[])
- {
- int i;
- for(i = 0; processes[i] != NULL; ++i) {
- process_start(processes[i], NULL);
- }
- }
- /*第三步*/
- void ctimer_init(void) /*ctimer是contiki里很重要的概念,具体说来就是一种定时器模型:Active timer,calls a function when it expires.*/
- {
- initialized = 0;
- list_init(ctimer_list);
- process_start(&ctimer_process, NULL);
- }
Z-stack的OSAL初始化过程也差不多,由于好久没搞cc2530,就不贴代码了。
完成平台和OS的初始化后,就是协议栈的初始化了,Zigbee协议栈的初始化是件挺复杂的工作。协议栈的初始化就是各个Layer的初始化,aps、af、zdo、nwk、mac。实际顺序如下:
- aps_init();
- nwk_init();
- mac_init();
- af_init();
- zdo_init();
在这些函数之前还有一些内存管理的工作要做。
/* 对nv_save_tbl[]的初始化。zigbee协议栈中的长地址、短地址、节点属性等重要数据需要保存下来, nv_save_tbl 用来保存这些数据。*/
- memset((void*)nv_save_tbl,0,sizeof(nv_save_tbl));
- nv_save_tbl[0].start_addr = (uint32_t)save_flag; /* static const uint8_t save_flag[] = "saved"; */
- nv_save_tbl[0].len = sizeof(save_flag);
- nv_save_tbl[item].start_addr = (uint32_t)&aib;
- nv_save_tbl[item].len = (uint16_t)(sizeof(aps_aib_t));
/* The memory pointer pool contains an array of all the memory pointers that
are available to the stack. Each memory pointer can contain one block
of memory allocated from the heap. Needless to say, if we run out of
memory pointers, then that is just as bad as running out of memory. */
- memset(mem_ptr_pool, 0, MAX_MEM_PTR_POOL * sizeof(mem_ptr_t));
/* Init the frame buffer pool . buf_pool[] is the frame buffer data structure that is used for TX and RX.
*/
- for (i=0; i<MAX_BUF_POOL_SIZE; i++)
- {
- memset(&buf_pool[i], 0, sizeof(buffer_t));
- }
<