IAP与OTA(一)

IAP与OTA(概论)

前言

第一次接触IAP的时候还是在玩正点原子的精英板的时候,当时没觉得IAP有啥了不起,直到工作中,才发现这项技术是开天辟地之举,因为此前公司的一个项目没有实现IAP功能,又由于客户的一次临时变更,导致需要批量更新软件,那可是几百个模块,为了避免客户端停线,这几百个模块的更新任务就落在我一个人身上。要说直接烧录器怼上去就烧录那也没什么,关键是PCBA被装进盒子里,盒子的卡扣又很难拆开,而且有一些是已经装在座椅骨架上就更麻烦了。然而,这不是让我去了解IAP这项技术的原因。真正的原因是公司的一个带有IAP功能的项目。是基于LIN总线的IAP功能,可能是比亚迪要求的比较复杂或者开发周期过短,这个功能是委外开发的,花了不少米。一个月黑风高的晚上,我记得很清楚,刚关上灯,电话就过来了,比亚迪有车要马上更新软件明天发走。出发到现场已经是凌晨1点了。你敢信,只更新两个模块居然耗到了3点,本来是线束一拔,插头一怼,咔咔两下升级完事走人,偏偏第二个不知怎么的每次更新的进度条到90%多就报错,项目开发阶段很不稳定,就很无语,因为项目本身不是我负责的,所以对这种情况我也无能为力,只能一次次的尝试。估计客户当时就在想:“这小伙能力真不行”。后来啊,我痛定思痛,一定要开发一个给力点的bootloader出来。

简介

什么是IAP?什么是OTA?在我印象里其实就只知道IAP,第一次IAP使用就是用串口给开发板升级APP。顶多基于不同的总线,像LIN,CAN等。于是我请教了一下从业十几年的老师傅,是不是IAP就是他们口中的OTA功能。他居然不知道IAP是什么东西。在他们口中,用LIN总线进行代码更新就叫OTA。经过查阅资料,OTA,叫空中下载技术,通过无线网络进行烧录,有点物联网那味。IAP是有线的(CAN、LIN、串口)。

问题点

1.如何解析上位机打包传过来的hex数据
2.如何将hex数据烧录到指定的flash区域
3.如何实现跳转到指定区域执行

1、那要看我们是基于哪种总线来进行的app升级。
像LIN总线,一帧也就传输8(2、4、8,通常为8)个字节的数据,肯定需要有上层协议来规定每一帧的数据表示的是什么,数据块大小,要烧录的地址,是肯定响应还是否定响应等待。不至于我上位机乱发一通,我不管三七二十一直接烧录到flash,那不对。这个上层协议即UDS诊断协议(下一张会介绍到)。

如果是基于CAN(0~8字节)或者CANfd(0-8,12, 16, 20, 24, 32, 48, 64字节),其实也是一样的,也需要UDS协议来规范每一帧数据到底表示的是什么。

如果是基于串口的话,有一些例程是直接定义一个比较大的数组,直接收到什么就往里边填什么,之后再把数组写入flash,也有一些是使用Ymodem 文件传输协议来对代码进行更新的。

2、这就涉及到写flash,读flash,擦除flash。每款芯片都各有不同,想stm32f405,它可以向某个地址按照1/2/4/8字节依次写入,之后地址在递增。也有一些像KF32A156这样子的,直接向某个地址写入数据,数据量最少要是1K字节,少于1K会报错写flash失败,具体芯片具体分析。写内部flash一般都会有对应的库函数调用

//stm32f405代码
//将数据写入flash
uint8_t LIN_BOOT_WriteDataToFlash(uint32_t StartAddr,uint8_t *pData,uint32_t DataLen)
{
	  HAL_StatusTypeDef FLASHStatus;
	  uint32_t *pDataTemp=(uint32_t *)pData;
	  uint32_t i;
	  __set_PRIMASK(1);//关闭中断
	  HAL_FLASH_Unlock();
  if(StartAddr<APP_VALID_FLAG_ADDR){
	    return 2;
  }
  for(i=0;i<(DataLen>>2);i++)
  {
  		
	    FLASHStatus = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD,StartAddr, *pDataTemp);//wuboyu:FLASH_TYPEPROGRAM_WORD四字节写入,起始地址为StartAddr,写入pDataTemp这个变量里边的值
	    if (FLASHStatus == HAL_OK){
	      StartAddr += 4;//wuboyu:地址加4
	      pDataTemp++;
	    }else{ 
	      HAL_FLASH_Lock();
	      __set_PRIMASK(0);
	      return 1;
	    }
  }
  HAL_FLASH_Lock();
  __set_PRIMASK(0);
  return	0;
}
//KF32A156MQV
void flash_test(void)
{
	memset(BOOT_REQ_FLAG, 0x00, 1024);
	BOOT_REQ_FLAG[0]=0xAA;
	BOOT_REQ_FLAG[1]=0x55;
	BOOT_REQ_FLAG[2]=0xAA;
	BOOT_REQ_FLAG[3]=0x55;
	FlashRetVal = FlashWriteNKBytes(0xc000, 1024, (uint8_t *)BOOT_REQ_FLAG);//wuboyu:向0xc00地址一次性写入1024字节,数据是BOOT_REQ_FLAG里边的
	 if (FlashRetVal == 0x00)
	 {
		printf("Write 1 Kbytes success\r\n\r\n");
	 }
	 else
	 {
		printf("Write 1 Kbytes err [%d]\r\n\r\n", FlashRetVal);
	 }
	 printf("The data is : %x.\r\n",*((uint32_t *)0xc000));//wuboyu:读取0xc00地址的四个字节,或者用读取库函数读取对应的数也可以
}

3、这个问题可以参照我之前的文章
boot跳转到app

  • 18
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值