完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
好记性不如烂笔头,记录点滴移植经历,一方面便于总结提炼,二是分享,让别人少走有些弯路。
首先谈一下对FreeRTOS的印象,FreeRTOS还是非常简单的, 要比RT-Thread,Nuttx,SlixOS等偏重型的系统轻量不少,所以FreeRTOS一般不会用在带MMU的重型方案上,而是比较多的应用在如工业控制或者家电等嵌入式场合,在支撑中大规模方案的能力上,FreeRTOS相对比较弱。 下面开始技术流水账: 整体的移植框架如下: 下面说下具体的移植步骤: 搭建构建环境,准备利用melis上已经建好的环境,借”鸡“生”蛋“。目标是移植FreeRTOS 系统,所以这部分不重点记录,总之,环境已建好。 用不用***i? 暂时先用,后续优化掉,因为与Melis相比,FreeRTOS构建的系统相对简单很多,不用支持MMU,整个FreeRTOS系统加上应用都可以运行在M模式,***i也就失去的存在的必要,但是还是决定先保留着,移植完成后再优化掉。主要考虑三点,1.环境和***i之间有依赖,包括链接脚本,一些汇编等等,不想这个时候动它,2.SBI本身提供了一些vendor的扩展接口,这些东西暂时还不确定将来会不会用到,如果省去,万一需要还得以某种形式加回来,麻烦。所以暂时先用SBI启动,后续逐渐做减法。3.利用***i中已经封装好的串口驱动,最小系统启动。用SBI启动,需要都SBI固件做一些小小的修改,改动如下: diff --git a/firmware/fw_jump.S b/firmware/fw_jump.S index afbcec0..79b3de8 100644 --- a/firmware/fw_jump.S +++ b/firmware/fw_jump.S @@ -84,7 +84,7 @@ fw_next_addr: * The next address should be returned in ‘a0’ */ fw_next_mode: - li a0, PRV_S + li a0, PRV_M ret 修改fw_next_addr 的实现,使用返回的next状态为PRV_M,也就是下阶段是M-Mode,非Linux and Melis运行的S-Mode.,验证如下:0x40010600是OS _star地址,可以正确从SBI跳出,进入这个地址,表示可以进行接下来的CPU引导了。 下图代表当前处理器功能组件的打开状态,可以看到I/D cache以及PMU相关机制已经开启。 mxstatus bit 30 bit 31为 0b11,表示系统运行在machine 模式。 开发链接脚本,确定最终链接后ELF文件的Layout分布,不启用MMU,所以整体上VA=PA,如下图: 关于启动流程的考量 列表所有ISA定义的寄存器都在确定的状态,这里面包括GPRS和FPU. 初始化TLB,但M模式不访问页表,这里是为了在S模式中访问内存高地址,因为通过MMU映射后,物理内存可以访问40位,而不仅仅是VPA定义的39位。 由于页表建立在TLB中,而非内存中,所以这里是直接初始化TLB,TLB中的页表不能被刷出,因为物理内存没有页表项。(这很容易满足,映射和访问范围小于TLB能映射的容量,TLB条目不会被换出,当然,如果存在TLB lock选项,就更有保证了。) 不同于Linux内核对FPU的访问畏首畏尾,为了让FreeRTOS全速奔跑,这里准备全面支持内核FPU单元加速,采用SR_SD来表示FPU寄存器组的状态实现lazy save/restore.(使用-mabi=lp64d or -mabi=lb64v编译,linux内核只能使用-mabi=lp64编译,用户态才有的选择), 初始化bringup 堆栈,填满”ebreak“指令,以防不测。 传递给内核参数包括启动时间,misa以及***i的位置,SBI后面会优化掉。 工欲善其事,必先利其器,关于打印,进到c之后,最想看到的当然是打印,每个问题都调试汇编效率还是比较低的。这里准备使用newlibc中的printf打印函数,底层对接_write_r到***i中已经调试好的串口驱动。这中间遇到一个小插曲,在调用printf进行输出的时候,竟然进入了异常 handle_exception里面。 分析发现,原来_write_r是使用的S模式下的SBI封装,调用了ecall指令,这种方式在S模式下当然是可以的,但是问题是,我们准备在M模式下跑FreeRTOS, 所以程序本身就和SBI一样运行于M模式,而M模式的mtvec寄存器已经在上面的流程里面被修改为了新的handle_exception,这里面当然不会处理SBI请求,解决的办法是,将基于”ecall“指令的SBI调用修改为直接对***i函数的调用。分析过程见下图: 1.强制在handle_exceptions入口停住,打印 mepc 2.发现mepc指向0x4001b65a,反编译elf文件找到对应位置,发现是”ecall“指令: 移植SBI中的打印驱动进系统,得到: 开发arch timer中断功能,使用clic中的compare and value寄存器来作为时钟心跳源,value被24M驱动,当value和compare 相等时,中断被触发,这个时候需要在中断处理中设置下一个触发点的compare值,增量计算方法是24000000/CONFIG_HZ,即每两次中断之间的周期数。首先参考linux做法,在trap_init中开启Machine Mode的Timer中断和External 中断 的capability. 5.开启clic arch timer,注意Mtime和Compare寄存器类似于MIPS中的tick产生机制,这是SIFive的设计,很多vendor Follow. 6.完整流程为下图,最后一步触发调度器 7:需要定制的接口包括 xPortStartScheduler, pxPortInitialiseStack, vPortSetupTimerInterrupt, xPortStartFirstTask四个接口,注意arch timer中断的挂接。 任务调度现场的Context布局 12.实现portasmHANDLE_INTERRUPT, vPortSetupTimerInterrupt定义,用于启用定时器中断和外设中断的处理接口, configCPU_CLOCK_HZ, configTICK_RATE_HZ设置tick中断周期 13:实现异常和中断处理,将上述的定时器中断接口和外设中断接口挂接到异常处理流程中。 14:注意,中断现场的堆栈组织和任务调度现场的堆栈组织是一样的,也和任务初始化的时候堆栈排布一致,由于抢占调度和主动调度都是通过异常路径进入的,这样在freeRTOS里面的处理非常一致,不用区分是中断调度现场还是任务主动出让的调度现场,如下图: 主调度器调度逻辑: 15:移植结果: 总结:FreeRTOS作为一个老牌的RTOS,它的可移植性是非常友好的,在移植之前,梳理好几个重要的执行流,比如启动流,主调度器流以及中断流,然后按照FreeRTOS的运行机理将主要的这几个执行流挂接到平台上,基本就实现了整个移植过程。 关于 ICE, 之前用过不少ICE, 感觉有一个共同点,就是很多高成本一点的ICE仿真器都会内置一个XILINX的FPGA里面,ICE的主要作用是将PC调试指令转换为JTAG时序信号,有很多现成的转换芯片比如FT232,XILINX这里也是起到协议转换的作用,但是FPGA的逻辑断电侯会消失,ICE是如何保证调试逻辑不消失的呢?经过了解,ICE里面一般内置了一个Flash或者EEPROM,用于存放固化的逻辑,类似于FPGA物理验证阶段使用的bitfile,每次上电FPGA都会从EEPROM里面load bitfile设计逻辑。不过有点扯淡的是,虽然CKLink Pro用的XINLINX FPGA作主控,但CKLink Lite却出奇的省,仅仅用了STM32做主控。从价格也可以看出两者的明显不同,前者淘宝1200, 后者只有200,主控一换,1000块出去了。 Jlink 不能用,原因还是因为THEAD用了自家的调试IP,但是应该有一种可行的破解方法,就是抓出cklink协议然后修改OpenOCD,使在同样的GDB命令下,OpenOCD驱动JLink产生同样的输出,因该是个可行的办法. |
|
|
|
只有小组成员才能发言,加入小组>>
全志T113双核异构处理器的使用基于Tina Linux5.0——RTOS编译开发说明
504 浏览 0 评论
1100 浏览 1 评论
2933 浏览 0 评论
为了学习内核开发,大佬手搓了一个轻量级操作系统YiYiYa OS
2876 浏览 0 评论
1288 浏览 0 评论
【开源硬件大赛】基于全志V853设计的全功能BTB学习开发板
3450浏览 8评论
3102浏览 5评论
1876浏览 4评论
全志V85x硬件设计大赛作品精选第二期,快来Pick你心目中的最佳方案
88835浏览 3评论
3610浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-21 21:58 , Processed in 0.646132 second(s), Total 98, Slave 81 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号