在FR8016H芯片上实现RT-thread的移植
1、启动分析
首先该款soc麻雀虽小不仅五脏俱全,而且外设及其丰富。硬件厂商不光提供了各种硬件、外设,而且固件功能也非常丰富,不仅有BootLoader而且很多驱动代码也都固化,给开发这带来了很多便利。
由于该芯片的固件很丰富,再加上app的启动代码也是以二进制的形式提供的,这对移植操作系统有一定的难度,下面根据实测对该芯片的启动进行猜测分析。
.bss 范围由链接脚本ER_ZI指定.data段范围在ram中由ER_RW指定,如果使用keil的启动代码那么加载地址由链接器决定。注意:固化在rom的系统代码可能也会用到变量,因此这些变量的地址定义在了syscall.txt中。
同样有些固化在rom的系统函数,他们的绝对地址也是有syscall.txt提供的,大部分系统函数都是在rom空间运行,有些函数在boot启动时搬移到了ram中,syscall.txt中指出了这些代码的运行地址。
所有代码默认是只读属性,一般加载和运行地址均在flash中,如果对函数重新指定的了段,armcc编译器会自动在启动代码中对这些函数进行加载。
该main固化在rom,固化rom中的代码如何知道app_main的地址呢?那就得通过jump_table了,jump_table定义在lib中,并且指定段名加载到固定的起始地址为0x01000000的flash空间(它在ram空间0x20000080有一个副本__jump_table),从jump_table_t结构体中看出有个enty成员,猜它就是APP_main的地址,果然查看二进制bin发现就是其地址。
app_main则是boot之后跳转到用户烧入镜像的第一条指令入口,它是厂商提供共的二进制库中的函数。它的大致流程如下
2、rt-thread移植
rt-thread移植有两个方案,方案一以rt-thread为主体,将FR8016H芯片作为一个bsp放入其工程中,方案二将rt-thread作为一个部件和厂商提供lib放在一起并且使用厂商的启动代码。
方案一的实现:
1)、定义一个段“jump_table”,用于存放struct jump_table_t结构体,该段必须固定在0x01000000起始的位置;
2)、适配启动代码,主要有中断向量表,reset_handle复位isr、systick_handle以及系统初始化函数systeminit(主要初始化核相 关,例如中断向量表重定位、时钟锁相环设置、mmu、cahce、systemtick等)
3)、初始化板级驱动,实现rt_hw_board_init()函数(主要是片外的一些驱动初始化,例如uart、adc等)
4)、app应用程序编写,实现具体应用。
上述实现是基于一个cortex-m3核的芯片工程,因此rt-thread工程配置就不多说了。
主要实现截图:
方案二的实现:
由于使用了厂商提供的启动代码,因此我们不需要实现jump_table。其他我们可以保留大部分的原厂代码,需要重新实现的有SVC_Handler、PendSV_Handler、SysTick_Handler。
在rt-config.h中我们选择user_device,不使用它的驱动框架,应为我们很多驱动在启动时已经初始化好了,接着我们需要为其组件提供驱动接口,例如console组件我们需要提供串口输出rt_hw_console_output接口,输入接口rt_hw_console_getchar。
os初始化时离不开动态资源的申请操作,所以我们还需要进行内存初始化rt_system_heap_init,为其划分内存空间。
在user_entry_after_ble_init函数中我们首先重新设置msp,接着调用rtt的初始化接口rtthread_startup,开始rtt的初始化。
最后编写应用代码。
主要实现截图:
方案一的实现,可以向社区提交,若FR8016H芯片卖的好说不定会被社区接受,但是有很多驱动需要补齐,工作量比较大。方案二,可以从rtt主线foke一个分支进行维护,这样改动小,原厂提供的功能都能直接使用。
最后上两个keil5的工程截图
全部回复 1
- 0 主题
- 1 帖子
- 123 积分
身份:LV1 技术小白
E币:121
发消息
点个赞!
>>资料:基于物联网技术的智能停车系统设计与实现