打印
[活动专区]

【AT-START-F425测评】+一周目:步入RTOS新世界之一步步移植RTTN

[复制链接]
464|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
gddddd|  楼主 | 2022-3-4 16:08 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
TE, AD, os, AC, AN, ar
本帖最后由 gddddd 于 2022-3-8 09:09 编辑

一周目:步入RTOS新世界之一步步移植RTTN

    依照惯例,首先感谢雅特力公司!感谢21IC电子论坛!联合举办了这么优秀的活动,我有幸参与并获得雅特力公司赠送的AT-START-F425开发板,不甚荣幸!
    在单片机领域,裸机前后台的模式和RTOS的实时模式一直以来都不分伯仲,各有各的强项,不过本着开发相对便利的原因,RTOS也越来越多的应用在资源相对更加丰富的MCU中,AT32F425怎么看也算资源丰富的,有usb、有can、有dma、ram不算小,flash也还行,那就动手上个RTOS吧!    RTTN(RT-Thread Nano的简写,完全是因为帖子标题不够写了,才简写的,手动狗头)是RTOS界不可多得的好苗子(主要还是这个好移植),特别是Nano版身轻如燕,和AT32F425是天造地设的一对!那么马上。。。插腚、开机(有人知道这个梗吗?B站的小伙伴可能会知道)
    这里利用官方AT32F425固件库中template工程予以移植,注意勾选上 Use MicroLIB 选项。首先是在KEIL上安装好RT-Thread Nano Pack,可以下载离线安装包,这种手动方式安装很方便的,下载地址:https://www.rt-thread.org/download/mdk/RealThread.RT-Thread.3.1.5.pack
    接下来将 RT-Thread 添加到工程,点击 Manage Run-Time Environment 图标,在"Software Component"栏找到 RTOS,Variant 栏选择 RT-Thread,然后勾选 kernel,点击 "OK" 就添加 RT-Thread 内核到工程了,顺手把shell也勾选上,基于串口命令行的shell很实用。


    下面开始适配 RT-Thread Nano
    第一步:
    先屏蔽at32f425_int.c中三个函数(HardFault_Handler、PendSV_Handler、SysTick_Handler),因为这三个函数均在RT-Thread Nano中予以定义需要避免重定义。
    第二步:
    屏蔽board.c中的47行#error "TODO 1: OS Tick Configuration.",因为会使用FinSH 组件进入串口的控制台命令调试模式,所以后续适配中这样的错误提示还有三处(board.c中68行、75行,finsh_port.c中24行),均需屏蔽掉后再按需添加程序代码。
    第三步:
    在board.c中增加SysTick_Handler函数,内容就一行调用rt_os_tick_callback函数即可。然后在rt_hw_board_init函数中增加系统、时钟初始化的函数,增加 OS Tick 的频率配置,即将main.c中的system_clock_config、at32_board_init、button_exint_init三个函数移过来,注意需引用一下对应的头文件(main.c中搬过来)再填上一句OS Tick的配置SysTick_Config(96000000 / RT_TICK_PER_SECOND),好了这一小块就基本完工了,注意还修改一下main.c中的延时函数改为RT-Thread Nano的专用函数rt_thread_mdelay(特别注意button_isr中的延时千万千万别用rt_thread_mdelay,也就是中断中不能使用rt_thread_mdelay,因为rt_thread_mdelay会触发任务切换导致直接进入rt_hw_hard_fault_exception,也不能使用本身的delay_ms,因为delay_ms是利用的SysTick实现会破坏OS Tick导致死锁,这个也不难自建一个delay函数空跑跑指令就好。当然这个例程中断里面用延时,我也是一个大写的服字,说好的中断处理要越快越好呢,还能不能愉快的玩耍了:P),引用好#include <rtthread.h>,这样如果不考虑shell的话,其实已经跑起来RT-Thread Nano了,其实移植还是非常简单的有木有。
    第四步:
    打开rtconfig.h中的115行#define RT_USING_CONSOLE和126行#include "finsh_config.h",用来启用 FinSH 组件,然后实现三个相关的重要函数内容,即board.c中的uart_init函数(初始化串口),board.c中的rt_hw_console_output函数(从串口输出一个字符串),finsh_port.c中的rt_hw_console_getchar函数(从串口获取一个字符)。
    首先来进行uart_init串口初始化,这里我们使用串口1,但一定不要直接用uart_print_init(115200),这个例程中的uart_print_init函数只有TX没有RX,也就是只能发送不能接收,那就不能愉快的和shell交互了,所以自己写一段串口1的初始化程序,这里也不需要开启串口1的中断,回头在rt_hw_console_getchar
函数轮询就可以,主要是程序更简单明了。


    再来实现rt_hw_console_output函数,主要是注意 RT-Thread Nano 系统中已有的打印均以\n结尾,而并非 \r\n,所以在字符输出时,需要在输出 \n 之前输出一个 \r,完成回车与换行,否则系统打印出来的信息将只有换行。


    最后是实现rt_hw_console_getchar函数,这个就更简单了,每隔10毫秒轮询一次有没输入的字符,有输入就全部接收过来。


    第五步:
    到此RTOS系统的移植基本结束了,再添加上两个任务,不让原例程的跑马灯孤零零的运行,搞完之后就完结撒花了(又是一个B站的梗,撒花什么的我最喜欢看了)。。。当然并没有!


    RT-Thread Nano移植是完成了,但仅仅移植RTOS系统,不考量一下在RTOS中的工作效率显然是不够的,那么还是祭出MCU跑分大杀器Coremark,看看RTOS下的跑分能有多强,加上系统后的跑分也更有实际意义。网上关于Coremark的移植文章很多,这里我也不再赘述。
    捡重要的说两点:
    一是RT-Thread Nano的rt_kprintf函数是不支持浮点数的,而Coremark的跑分结果输出是按浮点数来的(关闭浮点也可以但得分相对来说误差大一些),所以需要动一点小手术,如改为ee_printf("Total time (secs): %d\n",(int)time_in_secs(total_time))也就是将double强制转换为int来显示,计算精度还是予以保留,这样最后得分的结果相对精确。
    二是将coremark.h的78行记得修改成ee_u8 check_data_types(void),否则编译会报警告也不符合无错强迫症的风格。最终Coremark的得分有252分,每MHz也有2.625分,这个成绩非常不错,把STM32F103那是拿捏得死死地,属于吊打,按在地上摩擦!VERY GOOD!


    最后附上本周目源代码,下次再见!
RT-Thread Nano3.1.5.zip (362.45 KB)

    次回预告:《二周目:DIY超轻量RTOS,自己用就要轻飘飘》
    次回的次回预告:《三周目:很便宜的CMSIS-DAP对标BluePill板》
    敬请期待!


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

9

主题

378

帖子

1

粉丝