Another initialization function written STM32

Design ideas

Using the characteristics of the compiler, at compile time each program module initialization function sequence stored in the specified memory address, then the program is running this function from the main memory area sequentially calls the initialization function of each module, each module automatically initialization, while enhancing the high cohesion and low coupling characteristics of the process, improves the quality of the software.

 

Test Environment

  • Tool chain: Keil5

  • Development Board: STM32F103ZE


 

Modify the linker script

Edit link object script is: in the STM32 memory, leaving a suitable size (size adjusted according to their needs), used to store the initialization function of each module

1.1 Memory Allocation

In a new project in Keil, compiled Objects file in the project directory folder will automatically generate a link that ends .sct script, which reads as follows:


; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************



LR_IROM1 0x08000000 0x00080000 { ; load region size_region

ER_IROM1 0x08000000 0x00080000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

.ANY (+XO)

}



; 此区域(RW_IRAM1)使用所有的内存64Kb

RW_IRAM1 0x20000000 0x00010000 { ; RW data

.ANY (+RW +ZI)

}

}

We modify it: RWIRAM1 to 48K, RWIRAM2 to 16K, wherein each module RW_IRAM2 for sequentially storing initialization function.

; *************************************************************

; *** Scatter-Loading Description File generated by uVision ***

; *************************************************************



LR_IROM1 0x08000000 0x00080000 { ; load region size_region

ER_IROM1 0x08000000 0x00080000 { ; load address = execution address

*.o (RESET, +First)

*(InRoot$$Sections)

.ANY (+RO)

.ANY (+XO)

}



;RW_IRAM1为48K,供应用程序使用

RW_IRAM1 0x20000000 0x0000c000 { ; RW data

.ANY (+RW +ZI)

}



;RW_IRAM2为16K,用于存放各个模块的初始化函数

RW_IRAM2 0x2000c000 0x00004000 { ; RW data

*.o(RAMCODE)

}

}

Tips: keil modified method of linking script is shown in FIG.

1.2 the specified function stored in the specified memory area

Above we were on the STM32 memory allocation, 16K memory size RW_IRAM2 used as a storage area initialization function, then how can assign functions into this area do?

Method is as follows:

// 初始化函数的原型,函数原型可根据实际需求调整

typedef void (*init_function_list)(uint8_t taskID);



// 通过MODULE_INIT(func),func函数在编译时将会被链接到RAMCODE内存区,既我们为初始化函数预先分配的内存区域

#define _init __attribute__((used, section("RAMCODE")))

#define MODULE_INIT(func) init_function_list _fn_##func _init = func

After all the initialization functions are written into a specific area of ​​memory, we only need to know the starting and ending addresses of this area, you can call unified traverse all initialization function, in order to achieve the initialization of each module.

Module initialization sequence has requested how to do? Sometimes a normal module must be used in a module after the initialization, such as a module need to print Log, then the Log module must be initialized before it. How to solve it? Actually very simple, unified call upon initialization function, we are called according to the memory address order, then Log module initialization function on the front of it.

In Keil you can do:

1.3 Example of use

Talk is cheap. Show me the code.

Click to download the complete source code example of engineering: https://github.com/FanHongchuang/module_init

  • module1.c,module2.c,module3.c 为3个独立的模块,其初始化函数都为内部函数(使用static修饰),符合高内聚低耦合的软件设计思想

  • main.c中,do_init函数直接通过初始化函数的内存地址,对初始化函数逐个进行调用

简单示例代码如下:

module1.c

static void module1_init(uint8_t taskID)

{

// write your code ...

}



MODULE_INIT(module1_init);

module2.c

static void module3_init(uint8_t taskID)

{

// write your code ...

}



MODULE_INIT(module3_init);

main.c

void do_init(void)

{

uint8_t taskID = 0;

init_function_list *call = (init_function_list *)&Image$$RW_IRAM2$$Base;

init_function_list *end = (init_function_list *)&Image$$RW_IRAM2$$Limit;

do

{

(*call)(taskID++);

call++;

}while(call < end);

}





int main()

{

// init all module in the function

do_init();



// write your code ...



while(1)

{

// write your code ...

}
 
发布了155 篇原创文章 · 获赞 62 · 访问量 23万+

Guess you like

Origin blog.csdn.net/aa120515692/article/details/104265697