在MCU 固定FLASH地址写入BIN文件并调用其中API的方法

前言:接到了一个新的需求,需要我把BLE协议栈做成单独的BIN存放在芯片固定的FLASH地址中。而不是用传统的点lib文件。这样的好处也是显而易见的。于是我在网上找了一些资料,并成功实现。
参考资料:STM32实现固件分区

  1. 建立新的工程。
    驱动正常能被调用即可。
  2. 确定驱动文件中的API,在S文件中排序并确定位置。
    S文件中,具体写法如下
                PRESERVE8
                THUMB
; Vector Table Mapped to Address 0 at Reset
                AREA    AREA_NAME, DATA, READONLY
                EXPORT  __Vectors
                EXPORT  __Vectors_End
                EXPORT  __Vectors_Size
__Vectors       DCD     API0_RWZI_Init              ;初始化RW段和ZI段 Î
				DCD     API1
				DCD 	API2
__Vectors_End

__Vectors_Size  EQU  __Vectors_End - __Vectors

                AREA    |.text|, CODE, READONLY
				EXPORT  API0_RWZI_Init              [WEAK]
				EXPORT  API1            	  [WEAK]
				EXPORT  API2            	  [WEAK]
					
FirmwareInit  	
LF_BR_TEST
GetCount
                B   .
                END

注意,AREA_NAME是本段FLASH的段名,这会在sct文件中有所体现。
APIX函数就是本段BIN文件提供给application使用的API。其中API0_RWZI_Init函数较为重要,用于初始化RW段和ZI段(我对此的理解还不够彻底)。通过S文件,我们需要的API的地址就会按照四个字节的大小按顺序排在该段FLASH中。如FLASH的起始地址是0x4000,那么第一个API的地址会存在0x4000中,但需要注意的是,API的地址并不是0x4000,而是0x4000所存储的具体数值,就是API的真正地址。

  1. 确定驱动文件的BIN文件在FLASH中的地址与大小,以此更新sct文件。
LR_IROM1 0X00004000 0X38000{;ADDR:0X00004000 SIZE:224K
ER_IROM1 0X00004000 0X38000{
*.o(AREA_NAME,+First)
.ANY (+RO)	
}
RW_IRAM1 0X20000000 0X00000800{
.ANY(+RW +ZI)	
}
}

Sct文件需要根据自己的需求确定地址,大小等。
4. 在驱动文件的工程中新增一个函数去初始化目标地址中的RO和RW,ZI文件。
5. 在应用工程中,已知存放函数地址的地址,用强转去获取函数地址

#define FirmwareInit_ADDR   *(uint32_t *)0X00004000//FLASH的地址
#define FirmwareInit		(*(void(*)(void))(FirmwareInit_ADDR))

完成

你可能感兴趣的:(工作,高效代码,单片机,嵌入式硬件)