历史上的今天
今天是:2025年08月17日(星期日)
2018年08月17日 | 基于STM32F103ZET6的UART通讯实现
2018-08-17 来源:eefocus
一、什么是IAP,为什么要IAP
IAP即为In Application Programming(在应用中编程),一般情况下,以STM32F10x系列芯片为主控制器的设备在出厂时就已经使用J-Link仿真器将应用代码烧录了,如果在设备使用过程中需要进行应用代码的更换、升级等操作的话,则可能需要将设备返回原厂并拆解出来再使用J-Link重新烧录代码,这就增加了很多不必要的麻烦。站在用户的角度来说,就是能让用户自己来更换设备里边的代码程序而厂家这边只需要提供给用户一个代码文件即可。
而IAP却能很好的解决掉这个难题,一片STM32芯片的Code(代码)区内一般只有一个用户程序。而IAP方案则是将代码区划分为两部分,两部分区域各存放一个程序,一个叫bootloader(引导加载程序),另一个较user application(用户应用程序)。bootloader在出厂时就固定下来了,在需要变更user application时只需要通过触发bootloader对userapplication的擦除和重新写入即可完成用户应用的更换。如图1-1所示
图 1-1 |
图2-1 |
在只有一个程序的情况下,程序执行的走向应该如图2-2所示(借用网友的原图)。
图2-2 |
若在STM32F103x中使用IAP方案,则内置的Flash分配情况大致如下图2-3。
图2-3 |
图2-2 |
3、初始化按键。 (使用按键触发方式,上电时如果按键被按下则进行用户程序更新操作)
6、擦除用户程序(擦除0x08008000—0x0807ffff地址空间Flash)。
10、跳转到用户程序(强制将PC指针跳转到0x08008000+4处)。
3、如何改变代码存放的地址空间(因为BootLoader要存放在0x08000000处,用户程序要存放在0x08008000处,而默认的代码存放的地址空间为0x08000000)。
5、串口接收的用户代码数据是什么样的代码数据,是一种什么样的文件。
FLASH_SetLatency(FLASH_Latency_2); //因为系统时钟为72M所以要设置两个时钟周期的延时
if(FLASH_ErasePage(FLASH_ADDR+i*2048) != FLASH_COMPLETE) //一定要判断是否擦除成功
unsigned char buf[1024]; //假设待写入的代码数据
temp = (buf[2*i+1]<<8) | buf[2*i]; //2个字节整合为1个半字
if(FLASH_ProgramHalfWord(ADDR,temp) != FLASH_COMPLETE) //判断是否写入成功
ADDR +=2; //地址要加2,因为每次写入的是2个字节(1个半字)
FLASH_Lock(); //Flash 上锁,一个固件库函数即可实现。
2、关于中断向量表的偏移设置,对于BootLoader程序只需设置中断向量表的指向在0x08000000处,对于用户程序需要设置中断向量表的指向在0x08008000处即可。
①在BootLoader程序的中断向量表指向设置中应有这么一句:
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0); //设置中断向量表指向
其中NVIC_VectTab_FLASH是个宏定义,的值为0x08000000。
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x8000); //设置中断向量表指向
3、确认代码存放的地址空间,在IAR和在Keil中的设置是不同的,网上有在Keil中设置的方法,设立介绍在IAR软件环境下的设置方法。
图3-1 |
②在工程中打开stm32f10x_flash.icf该文件,修改两个参数即可改变代码存放的地址空间,图下图3-2所示。
图3-2 |
4、关于PC指针的强制跳转,想在BootLoader程序中将PC指针跳转到用户代码处,可选择下面的操作
typedef void (*pFunction)(void);
pFunction Jump_To_Application;
#define ApplicationAddress 0x08008000
if (((*(__IO uint32_t*)ApplicationAddress) & 0x2FFE0000 ) == 0x20000000) //--------①
JumpAddress = *(__IO uint32_t*) (ApplicationAddress + 4); //--------②
Jump_To_Application = (pFunction) JumpAddress; //--------③
__set_MSP(*(__IO uint32_t*) ApplicationAddress); //--------④
Jump_To_Application(); //--------⑤
①因为用户程序开始位置(0x08008000处)的前4个字节存放的是堆栈的地址,堆栈地址必定是指向RAM空间的,而STM32的RAM空间起始地址为0x20000000,所以要进行判断。
③令Jump_To_Application这个函数指针指向复位函数入口地址。
④堆栈的初始化,重新设定栈顶代地址,把栈顶地址设置为用户代码指向的栈顶地址。
5、通过串口来接收代码数据,就是PC机通过串口将代码数据发送到STM32中去。这里就涉及到两个问题:
②数据传输的过程需要遵循的协议,什么时候开始,什么时候结束。
图3-3 |
总的来说STM32的IAP方案实现需要在进行用户程序之前加一段Bootloader程序,BootLoader程序的作用就是:
②删除原有的用户程序,读取*.bin文件数据并将数据重新写入新的用户程序。
上一篇:STM32系统时钟设置,采用外部有源晶振相关配置问题
下一篇:STM32复位与时钟
史海拾趣
|
来自:http://www.embedinfo.com/wen-list.asp?id=381 我不是最优秀的嵌入式开发人员,但我是优秀的,至少我每天都在不懈努力着…… 以前是用51做东西的,虽然没有大的研究成果但自己研究的小产品也在被使用着,谈不上 ...… 查看全部问答> |
|
CString strFilePath = _T(\"\\\\硬盘\\\\AccountFile.dll\"); HANDLE m_hAccountFile = CreateFile(strFilePath,GENERIC_READ|GENE ...… 查看全部问答> |
|
各位大哥好: 我使用的是显示屏是480X234的分辨率.windows CE桌面显示正常,但是右键->显示属性的时候,对话框太大,无法浏览完整的对话框,请问怎么设置系统对话框的大小?小弟刚刚注册,分全供上了,谢谢!!!… 查看全部问答> |
|
我想找一块使用时间比较长的成熟开发板,带SD卡驱动,USB接口和液晶显示功能就可以了,提供相关PCB制板文件,这是其一 其二,想在上面再扩展个心电采集电路部分,调通该部分功能 如有对以上擅长者,有合作意向请联系本人 QQ:12665590 … 查看全部问答> |
|
近日在看linux下的嵌入式平台下的usb设备驱动,苦读代码之后始终没找到写入中断信号的地方,我在想中断信号是不是自己由usb控制器对控制数据解码后产生的呢? 问题: 中断信号是USB控制器的硬件产生的,还是由软件读取那8个字节的控制数据产生的? ...… 查看全部问答> |
|
问了 2个问题 STM32F107的以太网 用的NICHeLITE 协议栈 主讲的年青帅哥(外)说中文的很溜,可听估计还是差些 也许是我问问题没说清楚 感觉整场会 ADC的主讲比较精彩 交流也很激烈 新的3in1 还有个像游戏机一样的 ...… 查看全部问答> |
|
是典型的高速处理器与慢速外设之间的通信问题,我的设想是尽可能减少硬件而实现通信.现在DSP的频率为40MHz,还可以降些下来,但是不能降得过低,最好是不降,因为还要与别的DSP通信. 而慢速外设的频率只有100KHz.相差实在太远,不知道有没有折衷的办法既 ...… 查看全部问答> |












