完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
设计思想
利用编译器的特性,在程序编译时将各模块初始化函数顺序存放到内存的指定地址,然后在程序运行时main函数从这块内存区域中,依次调用各模块的初始化函数,自动完成各个模块的初始化工作,同时增强了程序的高内聚低耦合特性,提高了软件的质量。 试验环境
修改链接脚本 修改链接脚本的目的是:在STM32的内存中,留出一块合适的大小(大小根据自己的需求调整),用来存放各个模块的初始化函数 1.1 内存分配 在Keil中新建一个工程,编译后在工程目录下的Objects文件夹中会自动生成一个以.sct结尾的链接脚本,其内容如下: ; ************************************************************* ; *** 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) } } 我们将其修改:RWIRAM1为48K,RWIRAM2为16K,其中RW_IRAM2用来顺序存放各模块的初始化函数。 ; ************************************************************* ; *** 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) } } 友情提示:keil中链接脚本的修改方法如下图所示 1.2 将指定的函数存放到指定的内存区域 上面我们对STM32的内存进行了分配,16K大小的RW_IRAM2内存区域将用作存储初始化函数,那么怎么才能将指定的函数放进这个区域呢? 实现方法如下: // 初始化函数的原型,函数原型可根据实际需求调整 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 将所有的初始化函数都写进特定内存区域后,我们只需知道这个区域的起止地址,就可以统一遍历调用所有的初始化函数,从而实现对各个模块的初始化。 模块的初始化有顺序要求怎么办?有时一个模块的正常使用必须在某个模块初始化之后,比如一个模块需要打印Log,那么Log模块必须在它之前被初始化。怎么解决呢?其实很简单,统一调用初始化函数时,我们是根据内存地址顺序调用的,那么将Log模块的初始化函数放在其前面就可以了。 在Keil中可以这么做: 1.3 使用举例 Talk is cheap. Show me the code. 完整示例工程源码点击下载:https://github.com/FanHongchuang/module_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 ... } |
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
4130 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
3221 浏览 1 评论
2747 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
2175 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
14939 浏览 2 评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
3084浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
1894浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
2064浏览 3评论
1976浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
2166浏览 3评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 05:34 , Processed in 0.917507 second(s), Total 72, Slave 55 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
836