一. 基本概念 1.IAP IAP是In Applica tion Programming的首字母缩写,IAP是用户自己的程序在运行过程中对User Flash的部分区域进行烧写,目的是为了在产品发布后可以方便地通过预留的 通信口对产品中的 固件程序进行更新升级。 通常在用户需要实现IAP功能时,即用户程序运行中作自身的更新操作,需要在设计固件程序时编写两个项目代码,第一个项目程序不执行正常的功能操作,而只是通过某种通信管道(如USB、 USART)接收程序或数据,执行对第二部分代码的更新;第二个项目代码才是真正的功能代码。 2.Bootloader 在上述IAP的概念中,bootloader就是其第一个项目程序。bootloader主要实现的功能:从串口、USB等媒介接收数据;存储和搬运数据;程序跳转等功能。 3.App程序 对IAP概念中,对第二个项目代码的一种称呼。 4.Ymodem YModem协议是由XModem协议演变而来的,每包数据可以达到1024字节,是一个非常高效的文件传输协议。
7
|
|
|
|
解释:
第一字节:1.为SOH,有效数据包大小为128字节;
2.为STX,有效数据包大小为1024字节。
第二字节:数据包的编号,第一帧数据,编号为00。
第三字节:数据包编号的反码,第一帧数据,为FF。
有效数据区:根据第一个字节的内容,有效数据区大小为128字节或1024字节。
倒数第二个字节:CRC校验高位。
最后一个字节:CRC校验低位。
注:参加CRC校验的只有有效数据区。
第一帧数据结构: SOH 00 FFFoo.cNUL[123] CRC(high) CRC(low) 其中:Foo.c为传输文件的文件名;有效数据区的剩余字节用0补足。(就是’ ’). 在超级终端中,在文件名后,还有文件大小的信息。结构为: SOH00FFFoo.c’ ’+文件字节数+’’+’0’…CRC(high) CRC(low),字节数后为空格。 第二帧,有效数据区内存放的是正式的数据。
|
|
|
|
|
一. Smt32-bootloader设计思路 本bootloader的主要作用是,通过串口进行程序的升级。 1. Nandflash分区情况
|
|
|
|
|
2. 大致流程 板子开机后,由用户触发进入程序更新界面。 a.通过串口接收上位机发送的bin文件,并存储在分区C。 b.接收完bin文件后,将分区C中的bin文件搬运到分区B,并将搬运的状态保存在分区D。 c.bin文件全部搬运到分区B后,重置中断向量表,并实现程序跳转。 d.如果在步骤b,搬运代码的过程中,出现意外状况,导致搬运中断,则在下次开机后,会再次重新搬运,直到搬运成功。
|
|
|
|
|
一. 具体实现 3.1各类设置 1.定义芯片flash大小 方法a.在FlashàConfigure flashtools…àC/C++-àDefine中定义宏, 比如STM32F10X_HD(stm32单片机的内置flash为大容量) 方法b.在stm32f10x.h文件中, #if !defined(STM32F10X_LD) && !defined (STM32F10X_LD_VL) && !defined(STM32F10X_MD) && !defined (STM32F10X_MD_VL) && !defined(STM32F10X_HD) && !defined (STM32F10X_HD_VL) && !defined(STM32F10X_XL) && !defined (STM32F10X_CL) #define STM32F10X_HD #endif 设置红色的宏。 使用方法a和方法b都可以设置。选择不同的宏,则内嵌的nand flash的总大小及每页的大小是不一样的。并且对于内嵌的nand flash,其擦除是以页为单位的,而不是块。
|
|
|
|
|
2.设置程序下载的地址 1.在FlashàConfigure flash tools…àTarget中,
设置IROM1的Start和Size。 2.system_stm32f10x.c文件中, #defineVECT_TAB_OFFSET 0x00000设置中断向量表的偏移地址。(以flash的起始地址为基准) 所以bootloader程序和app程序的这两个设置都是不一样的。
|
|
|
|
|
3.2程序跳转实现 typedef void (*iapfun)(void); iapfun jump2app; __asmvoid MSR_MSP(u32 addr) { MSR MSP, r0 //set Main Stack value BX r14 } voidCloseIQHard(void) { GPIO_DeInit(GPIOA); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,DISABLE); //关使能PA端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,DISABLE); //关辅助时能时钟 __disable_irq(); // 关闭总中断 //关中断 } voidBootloaderJump2App(uint32_t appxaddr) { BSPClose(); CloseIQHard(); if(((*(vu32*)appxaddr)&0x2FFE0000)==0x20000000)//检查栈顶地址是否合法. { jump2app =(iapfun)*(vu32*)(appxaddr+4); //用户代码区第二个字为程序开始地址(复位地址) MSR_MSP(*(vu32*)appxaddr);//初始化APP堆栈指针(用户代码区的第一个字用于存放栈顶地址) jump2app(); //跳转到APP. } } 在void BootloaderJump2App(uint32_t appxaddr),其中appxaddr为需要跳转到的flash地址。 因为在跳转程序中,将总中断关闭,所以在应用程序中,要将总中断打开。
|
|
|
|
|
注:串口下载的具体流程: 串口接收文件使用Ymodem协议。使用串口中断接收。首先根据第一帧数据判断文件的大小,然后进行flash的擦陈。接收正式数据时,先接收一帧数据并校验,然后在将数据存储到flash中,再接收下一帧数据。
|
|
|
|
|
四. 注意事项 1.超级终端的使用 a.设置连接选项时,将校验选为“无”,否则可能会收不到数据。
|
|
|
|
|
谢谢大家捧场
|
|
|
|
|
楼主,我想请教下,我想通过超级终端给第一块单片机(stm32)升级(串口1),接着再用第一块板子的串口2,与第二块板子的串口1相连。第一块板子作为主机,给第二块板子下程序,这个可以实现吗?
|
|
|
|
|
可以实现。可以由不同的操作分别触发第一块单片机的发送和接收功能;
|
|
|
|
|
我想请教一下楼主,如何将BIIN文件中的数据取出来打包成数据帧?
我的项目中下位机是DSP,编译器只能生成HEX文件,我用工具将HEX文件转成了BIN文件,然后上位机准备用LABVIEW来做,但是在设计上位机的时候发现因为不了解BIN文件的数据存储结构,因此无法把BIN文件中的数据转存到数组中
|
|
|
|
|