ZigBee學(xué)習(xí)筆記(一)

●通過ZigBee協(xié)議棧實現(xiàn)一個簡單的無線數(shù)據(jù)通信的時候怎么做绘沉?

①組網(wǎng):調(diào)用協(xié)議棧的組網(wǎng)函數(shù)、加入網(wǎng)絡(luò)函數(shù),實現(xiàn)網(wǎng)絡(luò)的建立與節(jié)點的加入米丘。

②發(fā)送:發(fā)送節(jié)點調(diào)用協(xié)議棧的無線數(shù)據(jù)發(fā)送函數(shù)赶撰,實現(xiàn)無線數(shù)據(jù)發(fā)送舌镶。

③接收:接收節(jié)點調(diào)用協(xié)議棧的無線數(shù)據(jù)接收函數(shù),實現(xiàn)無線數(shù)據(jù)接收豪娜。

ZigBee的工作流程

●無線數(shù)據(jù)發(fā)送函數(shù)

AF_DataRequest(

&SampleApp_Periodic_DstAddr,?//發(fā)送目的地址+端點地址和傳送模式

&SampleApp_epDesc,?//源(答復(fù)或確認(rèn))終端的描述(比如操作系統(tǒng)中任務(wù)ID等)源EP

SAMPLEAPP_PERIODIC_CLUSTERID, //被Profile指定的有效的集群號

2, // 發(fā)送數(shù)據(jù)長度len

SendData, // 發(fā)送數(shù)據(jù)緩沖區(qū)

&SampleApp_TransID,?// 任務(wù)ID號

AF_DISCV_ROUTE,?// 有效位掩碼的發(fā)送選項

AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )? //傳送跳數(shù)餐胀,通常設(shè)置為AF_DEFAULT_RADIUS


協(xié)議棧工程文件

●osal_init_system(); 系統(tǒng)初始化函數(shù),我們關(guān)注其中的osalInitTask();

void osalInitTasks( void )

{

uint8 taskID = 0;?// 分配內(nèi)存瘤载,返回指向緩沖區(qū)的指針

tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);?// 設(shè)置所分配的內(nèi)存空間單元值為0

osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));// 任務(wù)優(yōu)先級由高向低依次排列否灾,高優(yōu)先級對應(yīng)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

//用戶創(chuàng)建的任務(wù)

SampleApp_Init( taskID );? // SampleApp_Init _Init(5) 健提,用戶需考慮

}


●osal_start_system(); 運(yùn)行操作系統(tǒng)。關(guān)注osal_run_system();

void osal_run_system( void )

{

? uint8 idx = 0;

? osalTimeUpdate(); ?//掃描哪個事件被觸發(fā)伟叛,然后置相應(yīng)的標(biāo)志位

? Hal_ProcessPoll(); ?//輪詢TIMER 與UART

? do {

? ? if (tasksEvents[idx])? // Task is highest priority that is ready.

? ? {

? ? ? ?break; ?//得到待處理的最高優(yōu)先級任務(wù)索引號 idx

? ? }

? } while (++idx < tasksCnt);

if (idx < tasksCnt)

{

? uint16 events;

? halIntState_t intState;

? HAL_ENTER_CRITICAL_SECTION(intState); ?//進(jìn)入臨界區(qū)私痹,保護(hù)

? events = tasksEvents[idx]; ?//提取需要處理的任務(wù)中的事件

? tasksEvents[idx] = 0;? // 清除本次任務(wù)的事件

? HAL_EXIT_CRITICAL_SECTION(intState); ?//退出臨界區(qū)

? 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); ?//退出臨界區(qū)

}

#if defined( POWER_SAVING )

? else? // Complete pass through all task events with no activity?

? {

? ? osal_pwrmgr_powerconserve();? // Put the processor/system into sleep

? }

#endif

/* Yield in case cooperative scheduling is being used. */

#if defined (configUSE_PREEMPTION) && (configUSE_PREEMPTION == 0)

? {

? ? osal_task_yield();

#endif

}


●SampleApp_Init(); 用戶應(yīng)用任務(wù)初始化函數(shù)。

void SampleApp_Init( uint8 task_id )

{

SampleApp_TaskID = task_id;? //osal分配的任務(wù)ID隨著用戶添加任務(wù)的增多而改變

SampleApp_NwkState = DEV_INIT;//設(shè)備狀態(tài)設(shè)定為ZDO層中定義的初始化狀態(tài)

SampleApp_TransID = 0;? ? ? ? //消息發(fā)送ID(多消息時有順序之分)

// Device hardware initialization can be added here or in main() (Zmain.c).

// If the hardware is application specific - add it here.

// If the hardware is other parts of the device add it in main().

#if defined ( BUILD_ALL_DEVICES )

// The "Demo" target is setup to have BUILD_ALL_DEVICES and HOLD_AUTO_START

// We are looking at a jumper (defined in SampleAppHw.c) to be jumpered

// together - if they are - we will start up a coordinator. Otherwise,

// the device will start as a router.

if ( readCoordinatorJumper() )

zgDeviceLogicalType = ZG_DEVICETYPE_COORDINATOR;

else

zgDeviceLogicalType = ZG_DEVICETYPE_ROUTER;

#endif // BUILD_ALL_DEVICES

//該段的意思是统刮,如果設(shè)置了HOLD_AUTO_START宏定義紊遵,將會在啟動芯片的時候會暫停啟動

//流程,只有外部觸發(fā)以后才會啟動芯片侥蒙。其實就是需要一個按鈕觸發(fā)它的啟動流程暗膜。

#if defined ( HOLD_AUTO_START )

// HOLD_AUTO_START is a compile option that will surpress ZDApp

//? from starting the device and wait for the application to

//? start the device.

ZDOInitDevice(0);

#endif

// Setup for the periodic message's destination address 設(shè)置發(fā)送數(shù)據(jù)的方式和目的地址尋址模式

// Broadcast to everyone 發(fā)送模式:廣播發(fā)送

SampleApp_Periodic_DstAddr.addrMode = (afAddrMode_t)AddrBroadcast;//廣播

SampleApp_Periodic_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端點號

SampleApp_Periodic_DstAddr.addr.shortAddr = 0xFFFF;//指定目的網(wǎng)絡(luò)地址為廣播地址

// Setup for the flash command's destination address - Group 1 組播發(fā)送

SampleApp_Flash_DstAddr.addrMode = (afAddrMode_t)afAddrGroup; //組尋址

SampleApp_Flash_DstAddr.endPoint = SAMPLEAPP_ENDPOINT; //指定端點號

SampleApp_Flash_DstAddr.addr.shortAddr = SAMPLEAPP_FLASH_GROUP;//組號0x0001

// Fill out the endpoint description. 定義本設(shè)備用來通信的APS層端點描述符

SampleApp_epDesc.endPoint = SAMPLEAPP_ENDPOINT; //指定端點號

SampleApp_epDesc.task_id = &SampleApp_TaskID;? //SampleApp 描述符的任務(wù)ID

SampleApp_epDesc.simpleDesc

= (SimpleDescriptionFormat_t *)&SampleApp_SimpleDesc;//SampleApp簡單描述符

SampleApp_epDesc.latencyReq = noLatencyReqs;? ? //延時策略

// Register the endpoint description with the AF

afRegister( &SampleApp_epDesc );? ? //向AF層登記描述符

// Register for all key events - This app will handle all key events

RegisterForKeys( SampleApp_TaskID ); // 登記所有的按鍵事件

// By default, all devices start out in Group 1

SampleApp_Group.ID = 0x0001;//組號

osal_memcpy( SampleApp_Group.name, "Group 1", 7? );//設(shè)定組名

aps_AddGroup( SAMPLEAPP_ENDPOINT, &SampleApp_Group );//把該組登記添加到APS中

#if defined ( LCD_SUPPORTED )

HalLcdWriteString( "SampleApp", HAL_LCD_LINE_1 ); //如果支持LCD,顯示提示信息

#endif

}


●SampleApp_ProcessEvent(); 用戶應(yīng)用任務(wù)的事件處理函數(shù)鞭衩。

uint16 SampleApp_ProcessEvent( uint8 task_id, uint16 events )

{

afIncomingMSGPacket_t *MSGpkt;

(void)task_id;? // Intentionally unreferenced parameter

if ( events & SYS_EVENT_MSG ) //接收系統(tǒng)消息再進(jìn)行判斷

{

//接收屬于本應(yīng)用任務(wù)SampleApp的消息学搜,以SampleApp_TaskID標(biāo)記

MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );

while ( MSGpkt )

{

switch ( MSGpkt->hdr.event )

{

// Received when a key is pressed

case KEY_CHANGE://按鍵事件

SampleApp_HandleKeys( ((keyChange_t *)MSGpkt)->state, ((keyChange_t *)MSGpkt)->keys );

break;

// Received when a messages is received (OTA) for this endpoint

case AF_INCOMING_MSG_CMD://接收數(shù)據(jù)事件,調(diào)用函數(shù)AF_DataRequest()接收數(shù)據(jù)

SampleApp_MessageMSGCB( MSGpkt );//調(diào)用回調(diào)函數(shù)對收到的數(shù)據(jù)進(jìn)行處理

break;

// Received whenever the device changes state in the network

case ZDO_STATE_CHANGE:

//只要網(wǎng)絡(luò)狀態(tài)發(fā)生改變娃善,就通過ZDO_STATE_CHANGE事件通知所有的任務(wù)。

//同時完成對協(xié)調(diào)器瑞佩,路由器聚磺,終端的設(shè)置

SampleApp_NwkState = (devStates_t)(MSGpkt->hdr.status);

//if ( (SampleApp_NwkState == DEV_ZB_COORD)//實驗中協(xié)調(diào)器只接收數(shù)據(jù)所以取消發(fā)送事件

if ( (SampleApp_NwkState == DEV_ROUTER) || (SampleApp_NwkState == DEV_END_DEVICE) )

{

// Start sending the periodic message in a regular interval.

//這個定時器只是為發(fā)送周期信息開啟的,設(shè)備啟動初始化后從這里開始

//觸發(fā)第一個周期信息的發(fā)送炬丸,然后周而復(fù)始下去

osal_start_timerEx( SampleApp_TaskID,

SAMPLEAPP_SEND_PERIODIC_MSG_EVT,

SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT );

}

else

{

// Device is no longer in the network

}

break;

default:

break;

}

// Release the memory 事件處理完了瘫寝,釋放消息占用的內(nèi)存

osal_msg_deallocate( (uint8 *)MSGpkt );

// Next - if one is available 指針指向下一個放在緩沖區(qū)的待處理的事件,

//返回while ( MSGpkt )重新處理事件稠炬,直到緩沖區(qū)沒有等待處理事件為止

MSGpkt = (afIncomingMSGPacket_t *)osal_msg_receive( SampleApp_TaskID );

}

// return unprocessed events 返回未處理的事件

return (events ^ SYS_EVENT_MSG);

}

// Send a message out - This event is generated by a timer

//? (setup in SampleApp_Init()).

if ( events & SAMPLEAPP_SEND_PERIODIC_MSG_EVT )

{

// Send the periodic message 處理周期性事件焕阿,

//利用SampleApp_SendPeriodicMessage()處理完當(dāng)前的周期性事件,然后啟動定時器

//開啟下一個周期性事情首启,這樣一種循環(huán)下去捣鲸,也即是上面說的周期性事件了,

//可以做為傳感器定時采集闽坡、上傳任務(wù)

SampleApp_SendPeriodicMessage();

// Setup to send message again in normal period (+ a little jitter)

osal_start_timerEx( SampleApp_TaskID, SAMPLEAPP_SEND_PERIODIC_MSG_EVT,

(SAMPLEAPP_SEND_PERIODIC_MSG_TIMEOUT + (osal_rand() & 0x00FF)) );

// return unprocessed events 返回未處理的事件

return (events ^ SAMPLEAPP_SEND_PERIODIC_MSG_EVT);

}

// Discard unknown events

return 0;

}


● SampleApp_MessageMSGCB();分析接收數(shù)據(jù)函數(shù)。

void SampleApp_MessageMSGCB( afIncomingMSGPacket_t *pkt )

{

uint16 flashTime;

byte buf[3];

switch ( pkt->clusterId ) //判斷簇ID

{

case SAMPLEAPP_PERIODIC_CLUSTERID: //收到廣播數(shù)據(jù)

osal_memset(buf, 0 , 3);

osal_memcpy(buf, pkt->cmd.Data, 2); //復(fù)制數(shù)據(jù)到緩沖區(qū)中

if(buf[0]=='D' && buf[1]=='1')? ? ? //判斷收到的數(shù)據(jù)是否為"D1"

{

HalLedBlink(HAL_LED_1, 0, 50, 500);//如果是則Led1間隔500ms閃爍

#if defined(ZDO_COORDINATOR) //協(xié)調(diào)器收到"D1"后,返回"D1"給終端愁溜,讓終端Led1也閃爍

SampleApp_SendPeriodicMessage();

#endif

}

else

{

HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);

}

break;

case SAMPLEAPP_FLASH_CLUSTERID: //收到組播數(shù)據(jù)

flashTime = BUILD_UINT16(pkt->cmd.Data[1], pkt->cmd.Data[2] );

HalLedBlink( HAL_LED_4, 4, 50, (flashTime / 4) );

break;

}

}


● SampleApp_MessageMSGCB();分析接收數(shù)據(jù)函數(shù)疾嗅。

void SampleApp_SendPeriodicMessage( void )

{

byte SendData[3]="D1";

// 調(diào)用AF_DataRequest將數(shù)據(jù)無線廣播出去

if( AF_DataRequest( &SampleApp_Periodic_DstAddr,//發(fā)送目的地址+端點地址和傳送模式

&SampleApp_epDesc,//源(答復(fù)或確認(rèn))終端的描述(比如操作系統(tǒng)中任務(wù)ID等)源EP

SAMPLEAPP_PERIODIC_CLUSTERID, //被Profile指定的有效的集群號

2,? ? ? // 發(fā)送數(shù)據(jù)長度

SendData,// 發(fā)送數(shù)據(jù)緩沖區(qū)

&SampleApp_TransID,? ? // 任務(wù)ID號

AF_DISCV_ROUTE,? ? ? // 有效位掩碼的發(fā)送選項

AF_DEFAULT_RADIUS ) == afStatus_SUCCESS )? //傳送跳數(shù),通常設(shè)置為AF_DEFAULT_RADIUS

{

}

else

{

HalLedSet(HAL_LED_1, HAL_LED_MODE_ON);

// Error occurred in request to send.

}

}


最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末冕象,一起剝皮案震驚了整個濱河市代承,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌渐扮,老刑警劉巖论悴,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異墓律,居然都是意外死亡膀估,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門耻讽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來察纯,“玉大人,你說我怎么就攤上這事针肥”牵” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵慰枕,是天一觀的道長具则。 經(jīng)常有香客問我,道長具帮,這世上最難降的妖魔是什么博肋? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任低斋,我火速辦了婚禮,結(jié)果婚禮上束昵,老公的妹妹穿的比我還像新娘拔稳。我一直安慰自己,他們只是感情好锹雏,可當(dāng)我...
    茶點故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布巴比。 她就那樣靜靜地躺著,像睡著了一般礁遵。 火紅的嫁衣襯著肌膚如雪轻绞。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天佣耐,我揣著相機(jī)與錄音政勃,去河邊找鬼。 笑死兼砖,一個胖子當(dāng)著我的面吹牛奸远,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播讽挟,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼懒叛,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了耽梅?” 一聲冷哼從身側(cè)響起薛窥,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎眼姐,沒想到半個月后诅迷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡众旗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年罢杉,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片贡歧。...
    茶點故事閱讀 40,021評論 1 350
  • 序言:一個原本活蹦亂跳的男人離奇死亡屑那,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出艘款,到底是詐尸還是另有隱情持际,我是刑警寧澤,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布哗咆,位于F島的核電站蜘欲,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏晌柬。R本人自食惡果不足惜姥份,卻給世界環(huán)境...
    茶點故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一郭脂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧澈歉,春花似錦展鸡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至涡尘,卻和暖如春忍弛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背考抄。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工细疚, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人川梅。 一個月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓疯兼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親贫途。 傳聞我的和親對象是個殘疾皇子吧彪,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 點播即點對點通信,也就是在兩個設(shè)備之間進(jìn)行通信,不允許有第三個設(shè)備收到信息潮饱。點播描述的就是網(wǎng)絡(luò)中兩個節(jié)點之間相互通...
    羽墨志閱讀 3,626評論 0 1
  • NAME dnsmasq - A lightweight DHCP and caching DNS server....
    ximitc閱讀 2,860評論 0 0
  • 單身父親 離婚后,一個人帶著兒子胃榕,心情變得很不好盛险,兒子推翻了桌子,弄碎了一只杯子勋又,往往都會讓我大發(fā)雷霆苦掘,他仿佛成了...
    阮小籍閱讀 1,161評論 14 7
  • 她和他是什么時候開始的? 又是什么時候結(jié)束了的? 識于微時楔壤,他是一個郵遞員鹤啡,每天將信放到郵箱上。 她是一個小文員蹲嚣,...
    沐竺閱讀 593評論 0 2
  • ——期中考試工作總結(jié) 第一次月考結(jié)束后说贝,我把辦公桌搬進(jìn)了教室。不是為了什么噱頭慎颗,拄個枴來回奔波于辦公室和教室之間乡恕,...
    亮子說閱讀 704評論 3 1