OAD

一.查询版本信息

     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 (Object Attributes Dataset) 是一个用于物体属性识别的数据集,旨在帮助研究者探索图像中的细粒度特征以及其语义含义。该数据集包含了多种不同类别的对象及其对应的多维度属性标注[^1]。 #### 下载方式 对于无法通过自动脚本获取数据的情况,建议手动下载并放置到项目目录下。由于网络环境差异可能导致官方源访问困难,可以考虑寻找镜像站点或其他公开资源进行下载。确保下载后的文件结构与预期一致,通常应包含: - 图片文件夹:存储所有训练测试所需的原始图片 - 属性标签文件:记录每张图片对应的具体属性信息 - 划分列表:定义哪些样本属于训练集/验证集/测试集 ```bash # 假设解压后得到如下结构 oad_dataset/ ├── images/ │ └── *.jpg # 所有图片 └── annotations/ ├── oad_labels.txt # 属性标签 └── splits.mat # 训练测试划分 ``` #### 使用指南 在加载自定义路径下的 OAD 数据集时,可能需要调整代码逻辑来匹配实际存在的文件布局。如果原作者提供了特定于 CelebA 的读取函数,则需修改这些部分以适应新的输入格式。例如,在 PyTorch 中可以通过继承 `torch.utils.data.Dataset` 类来自定义一个新的数据迭代器[^2]。 ```python from torch.utils import data as DataUtils class CustomOADDataset(DataUtils.Dataset): def __init__(self, root_dir, transform=None): super().__init__() self.root_dir = root_dir self.transform = transform with open(os.path.join(root_dir,'annotations','oad_labels.txt')) as f: lines=f.readlines() self.samples=[line.strip().split() for line in lines] def __len__(self): return len(self.samples) def __getitem__(self, idx): img_path=os.path.join(self.root_dir,"images",self.samples[idx][0]) label=np.array([int(x)for x in self.samples[idx][1:]]) image=Image.open(img_path).convert('RGB') if self.transform is not None: image=self.transform(image) sample={'image':image,'label':label} return sample ``` #### 相关文献推荐 关于 OAD 数据集的研究工作主要集中在计算机视觉领域内的细粒度分类任务上。一些代表性的工作探讨了如何利用深度学习模型有效地捕捉目标物体内蕴特性,并应用于跨模态检索等领域内[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值