完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32 之 RAM/ROM-启动-升级
一、 文章概述 STM32(包括其它所有单片机、ARM等),我们能看到的只是其中一部分运行代码,包括自行编写(x.c,x.h)、库(x.libx.a)、启动文件(startup_xxx.s)等。还有其它一些IDE环境自带的启动代码(如图一,可从MAP文件中查看到) 对于以上所有代码编译后的东西,再经过链接等步骤加工后,形成一种叫二进制可执行文件(x.bin)。bin文件按照对于的ROM地址烧写到芯片中,即可运行。 二、 ROM存储结构 对于STM32来说,BIN文件在ROM中的存储结构,则主要包括几大部分data段、bss段、heap段、stack段、code段、中断向量表段、复位启动入口(包括主堆栈指针初始值)等。 我们从头开始了解一下流程。 首先,便是这“复位启动入口”。这入口指明了两个人的身份-PC和SP。也就是这入口接下来得继续走下去的路。图二便是复位启动入口的代码。 由于STM32是小端的存储模式,所以“08 C3 00 20”便指明了主堆栈指针SP=0x2000C308,“A1 41 00 08”便指明了程序指针PC=0x080041a1。由图一MAP可看出,0x080041a1便是startup_xxx.s的入口。图三是由实际仿真窗口捕捉的代码,确实是startup_xxx.s文件的SystemInit()函数。 此处为何PC=?,SP=?SystemInit()之后,又干了什么? 其次,便是中断向量表。中断向量表,即相应中断产生时,程序指针跳转到此处向量表,由向量表再跳转至相应的中断处理。表面上看,它没啥特殊,但是如果你的程序起始地址存在偏移时(与0x08000000)比如增加Bootloader时,那这向量表的意义就很大很大了。你可以想象一个问题,你的Bootloader(简称bl)有中断吧,你的主程序(简称app)有中断吧,那如何让你的Bl和app跑自己的中断呢? 这个时候,在bl和app做跳转时,有个特别重要的对接会议要开一下,商讨一下app的这个表在哪里,这个东西叫SCB。程序初始化时预设,运行时也可重设。 再次,就是code段了。这个就不用多说了,就是你的app代码。 再再次,就是data段,存放已初始化的全局变量、静态变量(不管初始化还是未初始化)。此处嘛,容易与RAM的data段混在一起。我提个问题,大概就能明白了,你有一个初始化的全局变量A=10,而运行时,A是在RAM里边的,同时RAM又是掉电不保存的,那么这个A=10是如何保证的呢? 原因就在这里,“复位启动入口”的SystemInit()完事之后,有个加载过程叫“加载数据段”(_scatterload_copy),之后才转到_main处运行。这个加载过程,便是将这段ROM的data段数据,拷贝到对应的RAM,从而保证上电后A=10之类的承诺。 这个地方,既重要,也不重要。做升级时,如果你的下载,掉了这一段,不会影响你的代码运行,只是会影响到与这些全局变量和静态变量的判断。 最后,就是bss段了,是存放未初始化的全局变量。这个在我看来,没啥特殊。若有特殊,后面遇到再补上。 三、 RAM分配 直接上图 从内存上看,已经很明了了,先是data段,再是bss段,然后是heap(堆),最后是stack(栈)。 Data段,就是已初始化的全局变量和静态变量(未初始化、初始化),需要从code段加载。Bss就是未初始化的全局变量。这两个都属于静态内存分配,是程序编译时已经决定大小的。 Heap段,就是传说中的堆,大小是固定,但是怎么用,用多少,就是我们决定的了,因为它就是malloc和free的那块内存。 Stack段,就是很熟悉的那个栈,很像个客栈对吧。对,它就是个客栈,包含了同样的属性-临时。这一块内存,是函数跳转、局部变量等用到的。函数跳转时,是怎么回来的呢?回来之后,是怎么保证原来的变量值能继续运行呢?局部变量为什么出了作用域就用不了了呢?所有的这些,都是栈的作用。 说到这里,罗嗦几句。Heap分配太小,那你会经常malloc不到内存。Stack分配太小,那你会经常程序跑飞。 四、 启动 到这里,相信大家已经明白了,把上面的流程组合起来,就是完整的启动流程。 1、上电复位,设置PC,SP 2、跳转到SystemInit(),其中初始化了时钟、SCB(即中断向量表) 3、跳转到_scatterload_copy,完成databss段的加载工作 4、跳转到main 五、 升级 升级过程遇到的问题: 1、keil总是停止在某个地方,无法全速运行和单步运行,但是在汇编窗口,却可以单步运行。 可能原因:keil中使用断点的地方太多,把所有断点去掉后再试。 2、BL中中断响应正常,但是APP中断却不响应。特别是某些地方使用了HAL_GetTick(); 原因:由于Bl中使用了disable_irq(),造成跳转到APP后无法正常中断(如果没有调用enable_irq())。 3、APP经常复位。 原因:由于BL中开了IWDG,又由于IWDG开启后无法再次关闭,IWDG只有在程序复位后才会失效。 升级过程后面再补上。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1874 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1658 浏览 1 评论
1143 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
759 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1720 浏览 2 评论
1963浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
789浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
611浏览 3评论
628浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
590浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-1-11 15:18 , Processed in 0.886282 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号