在没有MMU功能的单片机上实现动态应用程序加载

2019-04-15 19:13发布

在没有mmu的cpu上实现动态加载的功能。
mmu:拥有虚拟地址映射的功能。



在没有mmu的设备上实现动态加载是可能的,两种方法。
1)我们知道局部变量占用的是堆栈的内存,全局变量和静态变量占用的是静态存储区,而静态存储区的地址是一个绝对的地址。
所以要想实现动态模块的加载,我们不能够去使用全局变量和静态变量,解决方案是通过内存申请来解决。还有一个问题就是在使用函数指针的时候,其实也是一个绝对
的地址,那我们需要怎么办呢,其实可以通过运行时去动态注册的方法实现,不过这里可能用到汇编指令来得到pc所指向的函数的值,这个方法有一个缺点,所有的函数
都需要一次显性的注册,以便得到真实的入口地址。那么如何实现动态加载的模块呢,如果使用keil会生成一个axf文件,其实这一个文件是一个elf格式的,里面包含了
我们需要调用的函数的信息。字符串常量的问题,当然不能直接使用常量,const关键字不能用,使用字符串常量只能换成动态变量。



2)在编译器方面实现,在生成的加载文件中,为每一个地址添加一个重定向,在加载应用的使用去更改这一个重定向的地址,其实uclinx貌似就是这么实现的。


3) 发现一种新的方式,keil在编译的时候,会为每一个文件生成一个.o文件,这个.o文件是带重定向的。利用这个.o文件,我是实现动态调动,但是有个一问题,
这个.o文件很分散,如果调用了其它文件内的函数,就必须也重定向其它的文件,相当于重新弄一个链接器




4)最新研究发现,像keil和iar这些编译器编译出来都会生成一个.o和.axf,其实这个文件就是.elf格式的,通过观察发现,这个.axf文件是最终文件,已经被链接过,
早就已经不带重定向信息,而那些零散的.o文件却是带重定位信息的,这移位中我们可以利用重定位来实现动态加载,而在今天的自己去实验了,发现正的可以,现在
内心有点激动,不过虽然这些.o文件带有重定位信息,但是非常的零散,需要写很多代码讲其组合起来,不过这些都不是问题,至少在没有MMU的单片机上实现动态加载
是可以实现的,只是可能比带MMU的单片机要复杂一些。正好之前写过rtos,后面我会把这些代码写完整融入的rtos中,以后是不是意味着我可以把程序放到sd卡中,然后
在自己的操作系统中去加载就行了,想想还有点小激动。
下面的图片,是我重定向了一段简单的代码,一个函数计算字符串长度+1,另一个函数得到这个长度,直接查看内存发现结果正确,哈哈哈哈哈哈哈哈。
QQ:549654313