OAD
来源:互联网 发布:个人相册网站源码 编辑:程序博客网 时间:2024/04/30 16:31
一.查询版本信息
1.注册imagidentify通知
2.往其中写0x00(基本上是任意值都可以).
3.设备notify当前image header :如:0200007c 41414141(版本为A)
image header的格式:
typedef struct {
#if defined FEATURE_OAD_SECURE
// Secure OAD uses the Signature for image validation instead of calculating a CRC, but the use
// of CRC==CRC-Shadow for quick boot-up determination of a validated image is still used.
uint16 crc0; // CRC must not be 0x0000 or 0xFFFF.CRC校验
#endif
uint16 crc1; // CRC-shadow must be 0xFFFF.
// User-defined Image Version Number - default logic uses simple a '!=' comparison to start an OAD.
uint16 ver;//版本
uint16 len; // Image length in 4-byte blocks (i.e. HAL_FLASH_WORD_SIZE blocks).长度
uint8 uid[4]; // User-defined Image Identification bytes.
uint8 res[4]; // Reserved space for future use.
} img_hdr_t;
二.传输过程
1.写新的image 信息到identify,获得版本信息,大小等信息用来确认是否真的需要跟新,以及为下一步和bin文件内容比对校验。
2.将bin文件拆包发送到到block。
3.完成接受之后重启系统
代码分析:
static bStatus_t oadImgIdentifyWrite( uint16 connHandle, uint8 *pValue )
{
img_hdr_t rxHdr;
img_hdr_t ImgHdr;
//低位在前,高位在后。
rxHdr.ver = BUILD_UINT16( pValue[0], pValue[1] );//版本
rxHdr.len = BUILD_UINT16( pValue[2], pValue[3] );//
(void)osal_memcpy(rxHdr.uid, pValue+4, sizeof(rxHdr.uid));
HalFlashRead(OAD_IMG_R_PAGE, OAD_IMG_HDR_OSET, (uint8 *)&ImgHdr, sizeof(img_hdr_t));//读取版本信息
oadBlkTot = rxHdr.len / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE);//
if ( (OAD_IMG_ID( ImgHdr.ver ) != OAD_IMG_ID( rxHdr.ver )) && // TBD: add customer criteria for initiating OAD here.
//版本信息要不一样
//(rxHdr.ver!=0)&&//jia
(oadBlkTot <= OAD_BLOCK_MAX) &&//7936
//长度小于最大长度
(oadBlkTot != 0) )
//且不为0
{
oadBlkNum = 0;
oadImgBlockReq(connHandle, 0);//请求一个块 从0开始,并notify oadBlkNum
}
else
{
oadImgIdentifyReq(connHandle, &ImgHdr);//否则发送当前版本信息
}
return ( SUCCESS );
}
/*********************************************************************
* @fn oadImgBlockWrite
*
* @brief Process the Image Block Write.
*
* @param connHandle - connection message was received on
* @param pValue - pointer to data to be written
*
* @return status
*/
static bStatus_t oadImgBlockWrite( uint16 connHandle, uint8 *pValue )
{
uint16 blkNum = BUILD_UINT16( pValue[0], pValue[1] );
// make sure this is the image we're expecting确定这个image是想要的
if ( blkNum == 0 )
//这个要参考bin文件的格式组成,
/*组成:标记(7)+Image开始地址(1)+Image长度(1)
记录0地址+记录0长+记录0校验和+记录0内容(文件内容)
记录1地址+记录1长+记录1校验和+记录1内容(文件内容)*/
{
img_hdr_t ImgHdr;
uint16 ver = BUILD_UINT16( pValue[6], pValue[7] );//如果是第一个包,那么会包含版本号和长度等信息
uint16 blkTot = BUILD_UINT16( pValue[8], pValue[9] ) / (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE);
HalFlashRead(OAD_IMG_R_PAGE, OAD_IMG_HDR_OSET, (uint8 *)&ImgHdr, sizeof(img_hdr_t));
//以下为比对之前从Img Identify中获取到的内容,若有不相同,则说明信息不对,返回错误
if ( ( oadBlkNum != blkNum ) ||
( oadBlkTot != blkTot ) ||
( OAD_IMG_ID( ImgHdr.ver ) == OAD_IMG_ID( ver ) ) )//版本信息一样
{
return ( ATT_ERR_WRITE_NOT_PERMITTED );
}
}
if (oadBlkNum == blkNum)//之后每次判断传的包数量是否一致
{
//计算方式:page*2048/4 =addr
uint16 addr = oadBlkNum * (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE) +
(OAD_IMG_D_PAGE * OAD_FLASH_PAGE_MULT);
oadBlkNum++;
#if defined FEATURE_OAD_SECURE
if (blkNum == 0)
{
// Stop attack with crc0==crc1 by forcing crc1=0xffff.
pValue[4] = 0xFF;
pValue[5] = 0xFF;
}
#endif
#if defined HAL_IMAGE_B
// Skip the Image-B area which lies between the lower & upper Image-A parts.跳过中间存放imageA 的部分
if (addr >= (OAD_IMG_B_PAGE * OAD_FLASH_PAGE_MULT))
{
addr += OAD_IMG_B_AREA * OAD_FLASH_PAGE_MULT;
}
#endif
if ((addr % OAD_FLASH_PAGE_MULT) == 0)
{
HalFlashErase(addr / OAD_FLASH_PAGE_MULT);
}
HalFlashWrite(addr, pValue+2, (OAD_BLOCK_SIZE / HAL_FLASH_WORD_SIZE));//
}
if (oadBlkNum == oadBlkTot) // If the OAD Image is complete.完成传输
{
#if defined FEATURE_OAD_SECURE
HAL_SYSTEM_RESET(); // Only the secure OAD boot loader has the security key to decrypt.
#else
if (checkDL())//校验
{
#if !defined HAL_IMAGE_A
// The BIM always checks for a valid Image-B before Image-A,
// so Image-A never has to invalidate itself.
uint16 crc[2] = { 0x0000, 0xFFFF };
uint16 addr = OAD_IMG_R_PAGE * OAD_FLASH_PAGE_MULT + OAD_IMG_CRC_OSET / HAL_FLASH_WORD_SIZE;
HalFlashWrite(addr, (uint8 *)crc, 1);
#endif
//HAL_SYSTEM_RESET();重启
}
#endif
}
else // Request the next OAD Image block.
{
oadImgBlockReq(connHandle, oadBlkNum);//调用notify,将oadBlkNum通知上去
}
return ( SUCCESS );
}
- OAD
- OAD 空中升级
- CC2541 OAD总结
- SimpleBLEPeripheral OAD Profile
- 【BLE】CC2541之OAD
- 【BLE】CC2541之OAD
- CC2541之OAD
- TI CC2541 OAD流程
- 跳绳OAD升级流程
- CC2640R2F offchips oad
- CC2541之OAD问题总结
- 【BLE】CC2541之Large OAD
- CC26XX之OAD(转)
- CC2640 之外部flash OAD
- CC2541 空中升级(OAD)
- cc2540/cc2541 OAD与SNV
- 【CC2640R2】CC2640R2F OAD 用户指导
- 关于iOS 蓝牙OAD升级
- 九度OJ 1084:整数拆分 (递归)
- iOS开发拓展篇—音频处理(音乐播放器3)
- SparkPi源码解读
- Spark out of memory相关问题
- 【FAQ】appium npm install error:network read ECONNRESET,bad network settings!
- OAD
- SQL Server 随机查询一条数据
- 2015北京面试记录
- iOS开发拓展篇—音频处理(音乐播放器4)
- Servlet和JSP的区别
- Nginx安装加载ssl错误
- iOS开发拓展篇—音频处理(音乐播放器5)
- 20151024_003_C#基础知识(File / FileStream / StreamReader/StreamWriter)
- linux heap堆分配