Zigbee标准中规定只有协调器在未加入其它网络时才能发起PAN网络,某个节点在要调用网络发起函数之前,要对这个节点是否已经加入网络和节点类型进行判断。
- if( ! nib->joined) /* 先判断是否已经加入网络 */
- {
- if (aib->desig_coord) /* 再判断节点类型 */
- {
- nwk_form_req(aib->chan_mask, DEFAULT_SCAN_DURATION); /*协调器调用这个函数 */
- }
- else
- {
- nwk_disc_req(aib->chan_mask, DEFAULT_SCAN_DURATION); /*终端或者路由调用这个函数 */
- }
- }
- else
- {
- if(aib->desig_coord)
- {
- CONSOLE_PRINT("ZDO_CMD_ZDO_START: Error already formed\r\n>");
- }
- else
- {
- CONSOLE_PRINT("ZDO_CMD_ZDO_START: Error already joined\r\n>");
- }
- }
PAN网络建立的过程是,通过能量扫描、主动扫描,判断每个信道的能量值(energy value)并找到一个可用的信道(energy value最小);然后确定一个不与其它相冲突的PAN ID 。在能量扫描和完全扫描之前,需要填充 mac_pcb 、nwk_pcb里面的参数,以控制能量扫描和主动扫描中的选择语句。nwk_form_req()实现如下:
- void nwk_form_req(U32 channel_mask, U8 scan_duration)
- {
- nwk_pcb_t *nwk_pcb = nwk_pcb_get();
- mac_pcb_t *mac_pcb = mac_pcb_get();
- mac_pcb->channel_mask = nwk_pcb->channel_mask = channel_mask;
- mac_pcb->duration = nwk_pcb->duration = scan_duration;
- mac_pcb->scan_type = MAC_ACTIVE_SCAN;
- nwk_pcb->nlme_state = NLME_NWK_FORMATION;
- mac_scan_energy();
- mac_scan(NULL);
- }
能量扫描负责RF芯片物理链路层的每一个信道,比如zigbee联盟定义了27个物理信道,其中2.4GHz频段有16个,780Mhz中(中国专属)有4个。AT86RF212支持780MHz频段,所以,能量扫描会挨个对这4个频段进行扫描(这四个频段是 780-769、782-769、784-769、786-769),以递增的方式对所测量的能量值进行信道排序,抛弃那些能量值超出了可允 许能量水平的信道,选择可允许能量水平的信道并标注这些信道是可用信道
。“扫描”就是读取AT86RF212的PHY_ED_LEVEL寄存器,依次存储每个读出的值。
我们先介绍下AT86RF212的能量测试(ED)。
RF212的ED测试可用作信道选择算法的一部分。在IEEE802.15.4标准信道的带宽内预计接收信号功率,而不是用于识别信道中的解码信号。一般,用8个符号周期的RSSI平均值计算ED值。两种方式开始ED测试:手动和自动。
手动ED测试需在RX_ON或者BUSY_RX状态中执行。在寄存器PHY_ED_LEVEL写入任意值,便可开始手动ED测试,在之后的8个符号周期外加12 us 处理时间(即140us)可访问到当前接受帧的有效ED值。AT86RF212的ED值有效范围为 0x00 到 0x54。
此外,The energy measurements are taken for a specified interval, which is counted by a timer. And ,The energy scan measurements are blocking functions, meaning that we stay in this function until all channels are scanned.
- void mac_scan_energy()
- {
- mac_pcb_t *pcb = mac_pcb_get();
- memset(pcb->energy_list, 0, sizeof(pcb->energy_list));
- for (i=0; i<4; i++)
- {
- U8 channel;
- pcb->curr_scan_channel = i;
- pcb->mac_state = MLME_SCAN;
- switch(i)
- {
- case 0:
- channel = PHY_CHANNEL_0; break; //#define PHY_CHANNEL_0 (780-769)
- case 1:
- channel = PHY_CHANNEL_1; break; //#define PHY_CHANNEL_1 (782-769)
- case 2:
- channel = PHY_CHANNEL_2; break; //#define PHY_CHANNEL_2 (784-769)
- case 3:
- channel = PHY_CHANNEL_3; break; //#define PHY_CHANNEL_3 (786-769)
- default: break;
- }
- drvr_set_chinese_channel(channel);//Sets the at86rf212 chinese channel.
- drvr_set_trx_state(RX_ON);
-
- /* set the timer so that we know when to stop the energy scan */
- timer_set(&pcb->mlme_tmr.etimer.timer, MAC_SCAN_TIME(pcb->duration));
- /* poll the etimer in a busy wait as we constantly(不断地) get the rssi values. */
- while (!timer_expired(&pcb->mlme_tmr.etimer.timer))
- {
- hal_register_write(PHY_ED_LEVEL, 0);
- delay_us(140);
- curr_ed =hal_register_read(PHY_ED_LEVEL);
- if (curr_ed > pcb->energy_list[i])
- {
- pcb->energy_list[i] = curr_ed; /* keep the max value that we find. */
- }
- }
- pcb->mac_state = MLME_IDLE;
- }
- drvr_set_trx_state(RX_AACK_ON); // set the trx in auto ack mode .
- }
我现在忽然觉得,代码是表达逻辑思维的最好语言,真的。
【转】协调器启动网络(一),布布扣,bubuko.com
【转】协调器启动网络(一)
原文:http://blog.csdn.net/u010670794/article/details/20850997