基于STM32F103C8的迷你游戏机:外部API调用内部驱动及Bin链接咨询
STM32F103C8游戏开发库访问内部驱动及多Bin链接方案
一、外部API访问内部隐藏驱动的实现
1. 静态库封装驱动细节
把核心驱动代码(屏幕、音频、输入的底层实现)编译为静态库(.a文件),仅对外提供包含API声明的头文件。游戏开发库只需包含头文件并链接该静态库,即可调用驱动功能,完全看不到驱动的具体实现代码。
- 示例:驱动头文件
driver_public.h声明API:void lcd_init(void); void audio_play_tone(uint16_t freq, uint32_t duration); uint8_t input_get_key_state(void); - 驱动的
.c源文件编译进静态库libdriver_core.a,不对外分发。
2. 固定地址函数指针表
如果核心驱动已固化在Flash的固定区域(比如Bootloader分区),可在驱动Bin中预先定义一个函数指针结构体,并将其放在指定内存地址。游戏开发库直接通过该地址访问指针表调用驱动函数。
- 驱动端定义并导出指针表:
typedef struct { void (*lcd_init)(void); void (*audio_play)(uint16_t, uint32_t); uint8_t (*input_get_key)(void); } CoreDriverAPI; const CoreDriverAPI g_core_api __attribute__((section(".driver_api"))) = { lcd_init, audio_play_tone, input_get_key_state }; - 通过链接脚本指定
.driver_api段的地址为0x08004000,游戏库端直接访问:#define CORE_API_ADDR ((const CoreDriverAPI*)0x08004000) // 调用示例 CORE_API_ADDR->lcd_init();
3. 外部符号声明与地址绑定
在游戏开发库的代码中,用extern声明驱动API,然后通过链接脚本直接绑定这些符号到核心驱动Bin的实际地址,无需暴露驱动源码。
- 游戏库代码中声明:
extern void lcd_init(void); - 游戏库的链接脚本中指定符号地址:
PROVIDE(lcd_init = 0x08004008); // 对应驱动中lcd_init函数的实际Flash地址
二、不同Bin文件之间的链接与协同运行
1. 划分Flash内存分区
首先为STM32F103C8的Flash规划明确的分区,确保各Bin文件运行地址不重叠:
- 示例分区(根据实际Flash大小调整,F103C8为64KB Flash):
- 核心驱动Bin:
0x08000000 - 0x08003FFF(16KB) - 游戏开发库Bin:
0x08004000 - 0x0800BFFF(32KB) - 游戏应用Bin:
0x0800C000 - 0x0800FFFF(16KB)
- 核心驱动Bin:
- 每个Bin编译时,通过链接脚本指定自身的
FLASH起始地址和大小。
2. 链接脚本导出/导入符号
核心驱动Bin编译时,在链接脚本中导出需要外部调用的函数或变量地址;游戏库/游戏Bin则通过链接脚本导入这些符号,实现跨Bin调用。
- 驱动端链接脚本导出符号:
SECTIONS { .driver_symbols : { PROVIDE(_lcd_init = lcd_init); PROVIDE(_audio_play = audio_play_tone); } > FLASH } - 游戏库端链接脚本导入符号:
EXTERN(_lcd_init, _audio_play);
3. 跨Bin函数调用的地址映射
如果需要在运行时动态调用其他Bin的函数,可直接通过函数地址强制转换实现:
// 假设驱动中audio_play_tone的地址是0x08001020 typedef void (*AudioPlayFunc)(uint16_t, uint32_t); #define AUDIO_PLAY ((AudioPlayFunc)0x08001020) // 调用示例 AUDIO_PLAY(440, 1000);
4. 多Bin合并编译(可选)
若需将核心驱动、游戏库打包为一个Bin分发,可使用ARM工具链的ld命令链接多个Bin或目标文件,通过链接脚本指定各部分地址:
arm-none-eabi-ld -T combined_link.ld driver.bin game_lib.o -o combined.elf arm-none-eabi-objcopy -O binary combined.elf final.bin
内容的提问来源于stack exchange,提问作者Daniel Belaish
相关产品推荐
相关产品推荐

