MCU variable loading process

Time:2022-1-9

preface

When developing MCU code, we often have some doubts about how variables enter the RAM area of MCU after compilation, especially when developing with keil. Later, after contacting gcc compiler and self-developed MCU, I finally understood this problem. In fact, the compiled variables are placed behind the code in the bin file (data is stored in bin, and BSS stores length information in Bin). When the program runs, it will actively load the data of this area into the RAM area in turn.

principle

After the code is written and compiled, the variables in the data area of the code will be placed behind the code, and the variables in the BSS area will only be stored in bin. Of course, this rule is also determined by the link file. An example is shown below
image
After the program runs, there will be an assembly code in the code before it officially enters the C environment. The main function is to copy the data area memory into RAM in turn. After the copy is completed. Set the memory of the following area with the same length as the description of the BSS area to 0.

This also shows why the value of the BSS area is set to 0 because there is no type in memory. If you do not set all 0, no other value can confirm the value of the actual type. (for example, if it is set to 1, different types will correspond to different values. Int is 0x1111 and short is 0X11)

But we don’t see such code in keil. Keil’s assembly code is as follows:

Reset_Handler   PROC
                EXPORT  Reset_Handler             [WEAK]
                IMPORT  SystemInit
                IMPORT  __main
                LDR     R0, =SystemInit
                BLX     R0
                LDR     R0, =__main
                BX      R0
                ENDP

After this code is executed, it will jump to__ It is executed in the main function. The main thing to note is that it does not directly jump to the main function we have written. In__ Main has many operations, including loading variables into RAM area. After execution, we will jump to the main function developed by ourselves for execution.

Example analysis

The following code is the code for loading variables under the gcc compiler. There are several variables. The starting address of data in bin file, the starting and ending addresses of data in RAM area, and the starting and ending addresses of BSS in RAM area are obtained from LD file.
After running the following code, all variables in the program are loaded into the RAM area.

/*
 *  The ranges of copy from/to are specified by following symbols
 *    __etext: LMA of start of the section to copy from. Usually end of text
 *    __data_start__: VMA of start of the section to copy to
 *    __data_end__: VMA of end of the section to copy to
 *
 *  All addresses must be aligned to 4 bytes boundary.
 */
    lrw     r1, __ Erodata // the starting address of data in the bin file
    lrw     r2, __ data_ start__  //  Starting address of data in RAM
    lrw     r3, __ data_ end__    //  End address of data in RAM

    Subu R3, R2 // R3 is the length of data
    Cmpnei R3, 0 // judge whether the length is 0
    bf      .L_loop0_done

.L_ Loop0: // move the data in the bin file to ram in turn
    ldw     r0, (r1, 0)          
    stw     r0, (r2, 0)         
    addi    r1, 4
    addi    r2, 4
    subi    r3, 4
    cmpnei  r3, 0
    bt      .L_loop0

.L_loop0_done:

/*
 *  The BSS section is specified by following symbols
 *    __bss_start__: start of the BSS section.
 *    __bss_end__: end of the BSS section.
 *
 *  Both addresses must be aligned to 4 bytes boundary.
 */
    lrw     r1, __bss_start__
    lrw     r2, __bss_end__

    movi    r0, 0

    subu    r2, r1
    cmpnei  r2, 0
    bf      .L_loop1_done

.L_ Loop1: // copy the data in BSS to 0
    stw     r0, (r1, 0)
    addi    r1, 4
    subi    r2, 4
    cmpnei  r2, 0
    bt      .L_loop1
.L_loop1_done:

Recommended Today

The whole tutorial of docker installation and use, installation / complete command / dockerfile image production / docker container arrangement and one click installation of nginx + redis + MySQL / visualizer portal (version 2022)

官网: https://docs.docker.com/ 官网: https://www.docker.com/ docker 镜像市场: https://hub.docker.com/ 一、docker 说明 1.1、docker 核心 1、Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源,Docker 是一个 CS 架构软件。 2、Docker 是一个虚拟化轻量级linux服务器,可以解决我们在开发环境中运行配置问题 3.、Docker的主要目标是‘build ,ship and run any app,anywhere’,一次封装,到处运行 4、容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。 1.2、docker 版本问题 .Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版) 和 EE(Enterprise Edition: 企业版),我们用社区版就可以了。 1.3、docker 架构( 3大核心) · 1、Images 镜像 (等于软件) · 2、Registry […]