Other Parts Discussed in Thread: CC2538, Z-STACK
cc2538出厂的时候自带uart升级boot吗?
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.
说实话,server端的源码我都没看过,每次测试出现问题我们都怀疑是server端的问题,老大就是一口咬定server没问题,翻来覆去的改linux gateway的代码。日了狗了,浪费了好多时间。谢谢大神指导。
有个问题请教一下:zclOTA_Srv_QueryNextImageReq()函数中获取的filed应该是client传递过来的(也就是在sample_app_ota.cfg中写入的zigbee文件),从而可以获取field.version;改version跟cc2538中version(默认0x00000001)对比,但是我不知道这个值怎么获取。
由于IAR编译出来的OTA firmware是BEBE-2538-AAAA0000.zigbee和BEBE-2538-BBBB1000.zigbee,对应的版本号分别是0xAAAA0000,和0xBBBB1000,所以不要修改,直接拿其做判断就可以了,参考下我的代码:
zclOTA_FileID_t remoteFileId;
memset(&remoteFileId,0x00,sizeof(remoteFileId));
memcpy(&remoteFileId,&pParam->fileId,sizeof(pParam->fileId));
dbg_print(PRINT_LEVEL_INFO,"zclOTA_Srv_QueryNextImageReq: remote manufacturer: 0x%x type 0x%x file version 0x%x\n",
remoteFileId.manufacturer, remoteFileId.type,
remoteFileId.version);
// Request the next image for this device from image database
status = OtaServer_GetImage(&pParam->fileId, &imageSize,
pParam->hardwareVersion, NULL, options, pSrcAddr);
dbg_print(PRINT_LEVEL_INFO,"zclOTA_Srv_QueryNextImageReq: Match image for manufacturer: 0x%x type 0x%x file version 0x%x returned with status 0x%x\n",
pParam->fileId.manufacturer, pParam->fileId.type,
pParam->fileId.version, status);
//sanity check remote and will upgrade firmware version(Image A or Image B) prevent incorrect firmware
if((remoteFileId.version == 0x1 && pParam->fileId.version == 0xAAAA0000)||
(remoteFileId.version == 0xAAAA0000 && pParam->fileId.version == 0xAAAA0000) ||
(remoteFileId.version == 0xBBBB1000 && pParam->fileId.version == 0xBBBB1000))
{
//if remote version equal current version,we must be not upgrade firmware(ping-ponging for CC2538 soc)
queryRsp.status = ZOtaImageInvalid;
dbg_print(PRINT_LEVEL_INFO,"zclOTA_Srv_QueryNextImageReq: current firmware not suitable 0x%X ,upgrade abort\n",pSrcAddr->addr.shortAddr);
goto Ended;
}else{
//perfect
}2个问题:
1、memcpy(&remoteFileId,&pParam->fileId,sizeof(pParam->fileId)); 这样可以获取remoteFileID吗?
2、对于版本判断的逻辑,有个小错误,spec中规定ota本地更新版本必须要大于远程版本,假如更新版本为0xAAAABBBB,其值介于0xAAAA0000和0xBBBB1000之间,你的逻辑判断是可以进行ota的,但却与spec规定相悖;相当于人为引入了错误。
最后,非常感谢大神的无私分享!
1、首先,spec规定是死的,人是活的。CC2538由于使用了ping-ponging这种OTA升级方式,如果严格按照spec的来,每个新的版本号必须大于旧的,那么就会出现Image A 版本00,版本01,版本02..... 同样Image B也会出现版本01,版本02,版本03......,这给firmware的管理带来很大的难度,一定会出现这一次必须用Image B的02版本,下一次必须用Image A的03版本,02版本是不行的。
2、可能TI也认识到了这一点,所以在client接收“image response”的处理函数zclOTA_ProcessQueryNextImageRsp里面,并没有判断version版本号,而是只判断了type和manufacturer,这里的type无非是0x2538或者0x2530,manufacturer无非定义好的0xBEBE。
// verify manufacturer id and image type
if ( ( param.fileId.type == zclOTA_ImageType ) &&
( param.fileId.manufacturer == zclOTA_ManufacturerId ) )
{
// store file version and image size
zclOTA_DownloadedFileVersion = param.fileId.version;
zclOTA_DownloadedImageSize = param.imageSize;
// initialize other variables
zclOTA_FileOffset = 0;
zclOTA_ClientPdState = ZCL_OTA_PD_MAGIC_0_STATE;
// set state to 'in progress'
zclOTA_ImageUpgradeStatus = OTA_STATUS_IN_PROGRESS;
// store server address
zclOTA_serverAddr = pInMsg->msg->srcAddr;
// Store the file ID
osal_memcpy ( &zclOTA_CurrentDlFileId, ¶m.fileId, sizeof ( zclOTA_FileID_t ) );
// send image block request
osal_start_timerEx ( zclOTA_TaskID, ZCL_OTA_IMAGE_BLOCK_REQ_DELAY_EVT, zclOTA_MinBlockReqDelay );
status = ZCL_STATUS_CMD_HAS_RSP;
// Request the IEEE address of the server to put into the
// ATTRID_UPGRADE_SERVER_ID attribute
ZDP_IEEEAddrReq ( pInMsg->msg->srcAddr.addr.shortAddr, ZDP_ADDR_REQTYPE_SINGLE, 0, 0 );
osal_stop_timerEx ( zclOTA_TaskID, ZCL_OTA_IMAGE_QUERY_TO_EVT );
}
}
3.能不能获取到remoteFileID,我们随便找一个Z-Stack 3.0的 OTA dongle工程分析一下,找到MT_OTA.c文件,可以看到,OTA client发送给OTA server的“image request”一定让MT_OtaGetImage函数来处理,这个函数里面是添加了fileID这一项的,最后把请求发送Z-Tool控制台,这里我们认为Linux gateway扮演了控制台的角色,只是由于2014年释出的zigbee Linux geteway并不适应最新的Z-Stack 3.0 ZNP工程,所以我做了两件事情,一、不得不把OTA dongle里面的OTA移植到最新的Z-Stack 3.0 ZNP工程里面,而且让它工作,另外添加了“image notify”功能,默认是不带的;二、把zigbee Linux gateway里面的OTA server源码单独移植出来使用,这样就脱离了复杂且容易出bug的gateway代码。目前测试下来没有问题,已经实现了OTA server升级各个client。
uint8 MT_OtaGetImage(afAddrType_t *pAddr, zclOTA_FileID_t *pFileId, uint16 hwVer,
uint8 *ieee, uint8 options)
{
uint8 msgLen;
uint8 *pBuf;
uint8 *p;
// Get length
msgLen = MT_OTA_GET_IMG_MSG_LEN;
// Allocate a buffer
if ((p = pBuf = MT_TransportAlloc(0, msgLen)) != NULL)
{
// build header
*p++ = msgLen;
*p++ = (uint8) MT_RPC_CMD_AREQ | (uint8) MT_RPC_SYS_OTA;
*p++ = MT_OTA_NEXT_IMG_REQ;
// Add the file ID
p = OTA_FileIdToStream(pFileId, p);
// Add the device address
p = OTA_AfAddrToStream(pAddr, p);
// Add the options
*p++ = options;
// Add the hardware ID (optional)
*p++ = LO_UINT16(hwVer);
*p = HI_UINT16(hwVer);
if (ieee)
osal_memcpy(p, ieee, Z_EXTADDR_LEN);
// Send command to server
MT_TransportSend(pBuf);
return ZSuccess;
}
return ZMemError;
}
4.也许正如@VV所说,TI还在开发新的zigbee Linux gateway以适应最新的Z-Stack 3.0协议栈,但至少到目前为止,还没有释出任何代码,所以基本上还得依赖旧的版本来开发,或者使用简单的znp-host-framework代替多进程且容易出问题的zigbee Linux gateway,最后,理解了整个zigbee端的代码和gateway端的代码,做起来都得心应手。
1、仔细思考了下,感觉你这个设计思路很赞!本质就是固定2个更新版本,AAAA0000和BBBB1000,排除同一个版本重复更新的干扰,反复更新即可;相比于spec的规定,确实减少了很多版本命名方面的麻烦,perfect!
2、我还没有用Z-Stack 3.0,沿用老版本Z-Stack Home 1.2.2a.44539
3、对于获取remoteFileID问题,说一下我的理解:首先定位到zcl_otaserverlnc.c中zclOTA_Srv_QueryNextImageReq(),当app端没有执行“O”(OTA update)操作前,pParam->fileID.version获取的是远程clien端固件默认version(0x00000001),将值保存到remotefileID.version,当执行“O”操作时,pParam->fileID.version获取的是本地image database里面的固件version(0xAAAA0000或者0xBBBB1000);不知我这样理解是否正确?
另:你第3条中说的移植ota_dongle的ota到znp以及移植otaserver,不是太明白。
我在zcl_otaserver_lnx.c中的zclOTA_Srv_QueryNextImageReq()函数里面,参考你的代码,添加对版本判断的内容,为什么编译后,重新执行./zigbeeHAgw,还是不能规避重复更新。
我是编译整个源码包,然后tar解包,使用新生成的zigbeeHAgw脚本。
Hi,
1、OTA调试又遇到了问题:2538原始固件为版本为0x01,我打算更新的固件版本为BEBE-2538-0000000B.zigbee,client端会发送request请求更新BEBE-2538-0000000B.zigbee,但是server端给client端的response却是BEBE-2538-0000001A.zigbee,这个通过sniffer已经抓到了解析的数据包;百思不得其解,求大神帮忙看看。
2、OTA重复更新问题,我参照你提供的代码进行修改,测试还是不行,这个也不知道原因在哪里。谢谢了!
问题已解决。不是代码问题,是源码有问题,编译生成的可执行文件的数目不够,重新换了干净的源码,测试ok。谢谢!