STM32 实现类似手机运行APP的方法(篇一:位置无关和系统函数调用)

tech2023-09-08  83

目录

一、原理二、环境三、编译器配置

一、原理

运行APP的原理是把程序从存储器加载到内存中,然后调用其入口函数运行,这样做是因为一般存储器(如SD卡,硬盘等)CPU无法直接寻址,必须先加载到内存等可以直接寻址的存储器上才能运行。 单片机的FLASH也可以直接寻址,所以存储在单片机FLASH中的程序不用加载到内存也可以运行。 既然要运行APP,有两个问题需要解决:一、如何告知APP,其需要调用的系统函数的地址;二、加载到内存的区域是动态分配的,这意味着每次加载的内存地址不固定,这需要APP代码的运行与其加载位置无关,本文就是解决这两个问题。

这篇文章给了我很大的启发:

https://www.cnblogs.com/ppym/p/3669747.html https://www.cnblogs.com/ppym/p/3672155.html

二、环境

本文使用的硬件及 软件环境: CPU:STM32F429 SDRAM:16MB 操作系统:RT-thread GUI:支持触屏和按键交互的GUI 集成编译环境:Keil5

三、编译器配置

本实验分为两个工程:一个是系统工程,这段代码运行在FLASH中,提供APP使用的API;另一个是APP工程,编写APP程序。 系统工程配置: 在Misc control栏中填写如下字符串,这是用来输出系统工程中函数的地址供APP工程使用

--symdefs=syscall.sym

系统工程配置完毕。 APP工程配置: APP工程配置比较复杂,主要为了实现代码的地址无关性。 在“C/C++"选项卡中的Misc controls栏填写如下字符串:

--apcs /rwpi/ropi --diag_suppress=177,550,1294

其中–apcs /rwpi/ropi 是编译地址无关代码的命令 –diag_suppress=177,550,1294 是使编译器不发出177,550,1294这几个警告,这条不是必须的。 在"Linker"页选项卡中的Misc controls栏填写如下字符串:

--no_scanlib --ropi --rwpi --entry=my_main --first=my_main --no_startup "Objects\UserApp\syscall.sym"

其中 --no_scanlib 是让连接器不要去搜索c语言库,使用syscall.sym文件提供的函数, –ropi --rwpi 是链接地址无关的命令, –entry=my_main --first=my_main 这是定义APP的入口函数是my_main,并且把my_main函数定义在APP文件的最开始位置,便于系统调用, –no_startup 不需要生成初始化运行环境的代码,初始化运行环境在系统调用时执行, “Objects\UserApp\syscall.sym” 符号表文件,这是由系统工程编译时生成的,根据实际文件位置修改。 另外:linker选项卡的设置严格按照截图来设置,任意一项设置不正确就会导致编译不通过或无法运行。

然后其他的编译器配置和普通的单片机工程一样,这里不赘述。

最新回复(0)