第一次寫博客,覺得應該把學習的心得體會記下來!長期更新。希望能幫助到新手少走彎路,也希望能提出問題,大家一起討論,一起進步。轉載請標明出處。謝 謝 http://blog.csdn.net/libin55/article/details/51203727
簡要說明:
一、協議棧組網原理
現科普一下星型組網的原理吧!二、星型網絡結構
二、協議棧移植
三、協議棧應用部分
void main (void)
{
bspIState_t intState;
#ifdef FREQUENCY_AGILITY
memset(sSample, 0x0, sizeof(sSample));
#endif
BSP_Init();
/* If an on-the-fly device address is generated it must be done before the
* call to SMPL_Init(). If the address is set here the ROM value will not
* be used. If SMPL_Init() runs before this IOCTL is used the IOCTL call
* will not take effect. One shot only. The IOCTL call below is conformal.
*/
#ifdef I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE
{
addr_t lAddr;
createRandomAddress(&lAddr);
SMPL_Ioctl(IOCTL_OBJ_ADDR, IOCTL_ACT_SET, &lAddr);
}
#endif /* I_WANT_TO_CHANGE_DEFAULT_ROM_DEVICE_ADDRESS_PSEUDO_CODE */
SMPL_Init(sCB); //初始化通信系統和simpliciti的協議棧
/* green and red LEDs on solid to indicate waiting for a Join. */
if (!BSP_LED2_IS_ON())
{
toggleLED(2);
}
if (!BSP_LED1_IS_ON())
{
toggleLED(1);
}
/* main work loop */
while (1)
{
/* manage FHSS schedule if FHSS is active */
FHSS_ACTIVE( nwk_pllBackgrounder( false ) );
/* Wait for the Join semaphore to be set by the receipt of a Join frame from a
* device that supports an End Device.
*
* An external method could be used as well. A button press could be connected
* to an ISR and the ISR could set a semaphore that is checked by a function
* call here, or a command shell running in support of a serial connection
* could set a semaphore that is checked by a function call.
*/
if (sJoinSem && (sNumCurrentPeers < NUM_CONNECTIONS))
{
/* listen for a new connection */
while (1)
{
if (SMPL_SUCCESS == SMPL_LinkListen(&sLID[sNumCurrentPeers]))
{
break;
}
/* Implement fail-to-link policy here. otherwise, listen again. */
}
sNumCurrentPeers++;
BSP_ENTER_CRITICAL_SECTION(intState);
sJoinSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
/* Have we received a frame on one of the ED connections?
* No critical section -- it doesn't really matter much if we miss a poll
*/
if (sPeerFrameSem)
{
uint8_t msg[MAX_APP_PAYLOAD], len, i;
/* process all frames waiting */
for (i=0; i<sNumCurrentPeers; ++i)
{
if (SMPL_SUCCESS == SMPL_Receive(sLID[i], msg, &len))
{
processMessage(sLID[i], msg, len);
BSP_ENTER_CRITICAL_SECTION(intState);
sPeerFrameSem--;
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
}
if (BSP_BUTTON1())
{
SPIN_ABOUT_A_QUARTER_SECOND; /* debounce */
changeChannel();
}
else
{
checkChangeChannel();
}
BSP_ENTER_CRITICAL_SECTION(intState);
if (sBlinky)
{
if (++sBlinky >= 0xF)
{
sBlinky = 1;
toggleLED(1);
toggleLED(2);
}
}
BSP_EXIT_CRITICAL_SECTION(intState);
}
}
main函數最開始是初始化板級支持包Bsp_Init();
接着初始化協議棧SMPL_Init(sCB);
這裏sCB對應的是回調函數,針對AP來說這個是必須加的,因爲AP(協調器)是肯定要接收ED(節點)的數據的。而對於只上報的節點設備,sCB就可以忽略。
整個程序的核心在接收中斷裏,很龐大,簡單解說就是通過數據幀剝離出端口,後面調用回調函數sCB,嚮應用層提示本幀數據是Join幀還是通用的數據幀。在main.c裏面定義了兩個全局變量。
static volatile uint8_t sPeerFrameSem = 0; /* 數據幀標識,每接收到一楨新數據就會通過回調加一,然後主循環查詢進行數據的讀取
static volatile uint8_t sJoinSem = 0; /* Join幀標識變量,ED請求加入時會通過回調加一,主循環查詢後進行LINK的監聽*/
static uint8_t sCB(linkID_t lid)
{
if (lid)
{
sPeerFrameSem++;
sBlinky = 0;
}
else
{
sJoinSem++;
}
/* leave frame to be read by application. */
return 0;
}
所以在mian函數裏面,一直輪詢sPeerFrameSem和sJoinSem兩個變量。