STM32 RAM / ROM distribution - start - Upgrade

STM32 of RAM / ROM- start - Upgrade

First, the article outlines
STM32 (including all other microcontrollers, ARM, etc.), we can see only part of running code, including self-written (xc, xh), library (x.lib \ xa), the startup file (startup_xxx.s )Wait. There are other IDE environment own boot code (as one can see from the MAP file)
Figure I
things for all of the above code is compiled, and then after the step of processing the links, called a binary executable form ( x.bin). bin file for programming ROM address according to the chip, can run.

Two, ROM memory structure
for STM32 is, the BIN file structure stored in the ROM, the data section includes several parts, BSS segment, heap segment, Stack section, code section, the interrupt vector table section, an inlet reset start (including primary stack pointer initial value) and the like.
We look at the process from the beginning.
First of all, this is the "Reset boot entry." This entry specifies the identity of two people -PC and SP. This is the entrance road was going was next. Figure II is an inlet reset start code.
Figure II
Since STM32 little endian storage mode, "08 C3 00 20" will indicate the primary stack pointer SP = 0x2000C308, "A1 41 00 08" indicates the program pointer will be PC = 0x080041a1. As can be seen from the view of a MAP, 0x080041a1 is startup_xxx.s the inlet. Figure III is actually captured by the emulation window codes, indeed SystemInit startup_xxx.s file () function.
Figure III
Why PC = ?, after SP =? SystemInit (), what they did here?

其次,便是中断向量表。中断向量表,即相应中断产生时,程序指针跳转到此处向量表,由向量表再跳转至相应的中断处理。表面上看,它没啥特殊,但是如果你的程序起始地址存在偏移时(与0x08000000)比如增加Bootloader时,那这向量表的意义就很大很大了。你可以想象一个问题,你的Bootloader(简称bl)有中断吧,你的主程序(简称app)有中断吧,那如何让你的Bl和app跑自己的中断呢?
这个时候,在bl和app做跳转时,有个特别重要的对接会议要开一下,商讨一下app的这个表在哪里,这个东西叫SCB。程序初始化时预设,运行时也可重设。
Figure IV

再次,就是code段了。这个就不用多说了,就是你的app代码。
再再次,就是data段,存放已初始化的全局变量、静态变量(不管初始化还是未初始化)。此处嘛,容易与RAM的data段混在一起。我提个问题,大概就能明白了,你有一个初始化的全局变量A=10,而运行时,A是在RAM里边的,同时RAM又是掉电不保存的,那么这个A=10是如何保证的呢?
原因就在这里,“复位启动入口”的SystemInit()完事之后,有个加载过程叫“加载数据段”(_scatterload_copy),之后才转到_main处运行。这个加载过程,便是将这段ROM的data段数据,拷贝到对应的RAM,从而保证上电后A=10之类的承诺。
这个地方,既重要,也不重要。做升级时,如果你的下载,掉了这一段,不会影响你的代码运行,只是会影响到与这些全局变量和静态变量的判断。

最后,就是bss段了,是存放未初始化的全局变量。这个在我看来,没啥特殊。若有特殊,后面遇到再补上。

三、 RAM分配
直接上图

Figure V
从内存上看,已经很明了了,先是data段,再是bss段,然后是heap(堆),最后是stack(栈)。
Data段,就是已初始化的全局变量和静态变量(未初始化、初始化),需要从code段加载。Bss就是未初始化的全局变量。这两个都属于静态内存分配,是程序编译时已经决定大小的。
Heap段,就是传说中的堆,大小是固定,但是怎么用,用多少,就是我们决定的了,因为它就是malloc和free的那块内存。
Stack段,就是很熟悉的那个栈,很像个客栈对吧。对,它就是个客栈,包含了同样的属性-临时。这一块内存,是函数跳转、局部变量等用到的。函数跳转时,是怎么回来的呢?回来之后,是怎么保证原来的变量值能继续运行呢?局部变量为什么出了作用域就用不了了呢?所有的这些,都是栈的作用。

说到这里,罗嗦几句。Heap分配太小,那你会经常malloc不到内存。Stack分配太小,那你会经常程序跑飞。

四、 启动
到这里,相信大家已经明白了,把上面的流程组合起来,就是完整的启动流程。
1、上电复位,设置PC,SP
2、跳转到SystemInit(),其中初始化了时钟、SCB(即中断向量表)
3、跳转到_scatterload_copy,完成data\bss段的加载工作
4、跳转到main

V. upgrade
problems encountered during the upgrade process:
1, Keil always stop somewhere, can not run at full speed and single-step operation, but in the compilation window, but you can single-step operation.
Possible reasons: Too many breakpoints used keil place, try again after removing all breakpoints.
2, BL interrupt normal response, but not APP interrupt response. In particular, some places use HAL_GetTick ();
reason: Because Bl used in disable_irq (), causing not work after the jump to APP interrupt (if not called enable_irq ()).
3, APP reset often.
Reason: Due to the BL opened IWDG, and because you can not turn off again after IWDG, IWDG will only expire after program reset.
On supplemented later in the upgrade process.

Published 20 original articles · won praise 16 · views 40000 +

Guess you like

Origin blog.csdn.net/tianjueyiyi/article/details/90600051