This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
CC1352P协调器,加入一个不支持Zigbee 3.0的节点,超时触发BDB_TC_LK_EXCH_PROCESS_EXCH_FAIL事件后,在bdb_TCJoiningDeviceFree中释放入网节点信息。在bdb_TCJoiningDeviceFree中运行到OsalPort_free( descCurrent )这一步时,协调器死机,进入Error_raiseX函数,并且在if (Error_policy_D == Error_SPIN) 中陷入死循环。
同一块开发板,在多个不同版本的SDK上面验证,均出现该现象。同样的程序,移植到CC2652P模块上就不会出现该问题。
我这边找到原因了,系bdb_TCProcessJoiningList释放设备记录导致,在队列中先释放指针,再从指针中获取下一个地址,或导致协调器获取到一个错误的指针。
很奇怪,在CC1352P开发板上有这个问题,但是在我们自己的CC2652模块上没有该问题。
void bdb_TCProcessJoiningList(void) { bdb_joiningDeviceList_t* tempJoiningDescNode; if(bdb_joiningDeviceList) { tempJoiningDescNode = bdb_joiningDeviceList; while(tempJoiningDescNode) { if(tempJoiningDescNode->NodeJoinTimeout) { tempJoiningDescNode->NodeJoinTimeout--; } if(tempJoiningDescNode->NodeJoinTimeout == 0) { uint8_t isTCLKExchangeRequired = bdb_doTrustCenterRequireKeyExchange(); //Check if the key exchange is required if(isTCLKExchangeRequired) { AddrMgrEntry_t entry; entry.user = ADDRMGR_USER_DEFAULT; OsalPort_memcpy(entry.extAddr,tempJoiningDescNode->bdbJoiningNodeEui64, Z_EXTADDR_LEN); if(AddrMgrEntryLookupExt(&entry)) { ZDSecMgrAPSRemove(entry.nwkAddr,entry.extAddr,tempJoiningDescNode->parentAddr); } } // If we are here, a joining device has been expired due to timeout either because it is a // legacy device (does not perform key exchange), it is an Z3.0 device that did not perform // key exchange intentionally, or it is a Z3.0 device that has failed to perform key exchange. // Depending on our TC settings, below we decide if this joiner should be removed from the // security manager uint16_t keyNvIndex; uint16_t index; APSME_TCLinkKeyNVEntry_t TCLKDevEntry; uint8_t found; //search for the entry in the TCLK table keyNvIndex = APSME_SearchTCLinkKeyEntry(tempJoiningDescNode->bdbJoiningNodeEui64,&found, &TCLKDevEntry); uint16_t nwkAddr; //Look up nwkAddr before it is cleared by ZDSecMgrAddrClear AddrMgrNwkAddrLookup(tempJoiningDescNode->bdbJoiningNodeEui64, &nwkAddr); // If TC is mandating key exchange, remove devices that have not successfully performed key exchange. // Keep entries for ZG_PROVISIONAL_KEY so install code derived key is maintained, so joiner can reattempt join // If we got here and have a ZG_VERIFIED_KEY (unexpected), do not remove this entry either if( (isTCLKExchangeRequired == true) && (TCLKDevEntry.keyAttributes != ZG_PROVISIONAL_KEY) && (TCLKDevEntry.keyAttributes != ZG_VERIFIED_KEY) ) { //Remove the entry in address manager ZDSecMgrAddrClear(tempJoiningDescNode->bdbJoiningNodeEui64); //If found, erase it. if(found == TRUE) { memset(&TCLKDevEntry,0,sizeof(APSME_TCLinkKeyNVEntry_t)); TCLKDevEntry.keyAttributes = ZG_DEFAULT_KEY; //Increase the shift by one. Validate the maximum shift of the seed which is 15 index = keyNvIndex; TCLinkKeyRAMEntry[index].rxFrmCntr = 0; TCLinkKeyRAMEntry[index].txFrmCntr = 0; TCLinkKeyRAMEntry[index].entryUsed = FALSE; //Update the entry osal_nv_write_ex( ZCD_NV_EX_TCLK_TABLE, keyNvIndex, sizeof(APSME_TCLinkKeyNVEntry_t), &TCLKDevEntry ); } } if(pfnTCLinkKeyExchangeProcessCB) { bdb_TCLinkKeyExchProcess_t bdb_TCLinkKeyExchProcess; OsalPort_memcpy(bdb_TCLinkKeyExchProcess.extAddr,tempJoiningDescNode->bdbJoiningNodeEui64, Z_EXTADDR_LEN); bdb_TCLinkKeyExchProcess.nwkAddr = nwkAddr; bdb_TCLinkKeyExchProcess.status = BDB_TC_LK_EXCH_PROCESS_EXCH_FAIL; bdb_SendMsg(bdb_TaskID, BDB_TC_LINK_KEY_EXCHANGE_PROCESS, BDB_MSG_EVENT_SUCCESS,sizeof(bdb_TCLinkKeyExchProcess_t),(uint8_t*)&bdb_TCLinkKeyExchProcess); } //Free the device from the list //The next pointer needs to be obtained before the previous pointer is released, fixed by Luoyiming at 2025-03-06 bdb_joiningDeviceList_t* joiningDeviceToRemove = tempJoiningDescNode; tempJoiningDescNode = tempJoiningDescNode->nextDev; bdb_TCJoiningDeviceFree(joiningDeviceToRemove); } else { //The next pointer can only be obtained when the previous pointer has not been released, fixed by Luoyiming at 2025-03-06 tempJoiningDescNode = tempJoiningDescNode->nextDev; } } } //we are done with the list if(bdb_joiningDeviceList == NULL) { OsalPortTimers_stopTimer(bdb_TaskID,BDB_TC_JOIN_TIMEOUT); } }