完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
`RT-Thread Nano是一个极简的硬实时内核,系统完全开源,是一款可裁剪的、抢占式实时多任务的 RTOS。它还具备体积小、启动快速、实时性高、占用资源小等特点,可用于家电、消费电子、医疗设备、工控等领域大量使用的 32 位 ARM 入门级 MCU 的场合。 适用于系统资源紧张或是项目功能较为简单,仅需使用RTOS内核,无需丰富功能的场景,且开发时无需额外的辅助工具。
图1 RT-Thread Nano 的软件框图 RT-Thread已经适配MM32系列MCU,并且在 RT-Thread 嵌入式开源社区可以下载相关代码,在接下来的章节中将与大家一起学习RT-Thread相关功能,在本章节中我们将一起学习如何在MDK5 上创建一个 RT-Thread RTOS 的小系统工程及创建多任务。 主要分为以下几个步骤: 1 准备一个基础的 keil MDK 工程,并获取 RT-Thread Nano pack 安装包并进行安装。 2 在基础工程中添加 RT-Thread Nano 源码。 3 适配 Nano,主要从 中断、时钟、内存这几个方面进行适配,实现移植。 4 验证移植结果:编写第一个应用代码,基于 RT-Thread Nano 闪烁 LED。 5 最后可对 Nano 进行配置:Nano 是可裁剪的,通过配置文件 rtconfig.h 实现对系统的裁剪。 01 Pack安装 RT-Thread同MM32 MCU的Pack安装方法类似,提供两种安装方式:1、在IDE内安装;2、在RT-Thread官网下载pack驱动包,手动安装。 MM32 MCU的Pack安装方法在MM32 MCU官网(www.mm32mcu.com)都有介绍,在此不做过多的描述,今天主要介绍RT-Thread的Pack安装方法。 1.在线安装 RT-Thread Nano 以软件包的方式集成在 Keil MDK中,打开MDK5,点击工具栏的Pack Installer图标。 图2 Pack获取窗口 点击右侧的Pack,展开General,可以找到rt-thread::rthread,点击对应的Action的Install,就可以在线安装Pack了。安装成功后Action栏显示”Up to date”。如下图示: 图3 在线安装Pack 2.手动安装 我们也可以从官网(https://www.rt-thread.org/download/mdk/)下载安装离线文件,下载结束后双击文件进行安装: 图4 手动安装Pack 02 基础工程搭建 在开始创建 RT-Thread 小系统之前,我们需要准备一个能正常运行的裸机工程。作为示例,这边使用的是基于 MM32L0xx一个 LED 闪烁程序(可在官网例程包下在blink例程)。 程序的主要架构截图如下: 图5 MM32 MCU裸机例程 03 添加 RT-Thread 到工程 基于一个可以运行的裸机程序,我们来添加 RT-Thread 到工程。如下图,点击 Manage Run-Time Environment。 图6 Manage Run-Time Environment 在 Manage Rum-Time Environment 里”Software Component”栏找到 RTOS,Variant 栏选择 RT-Thread,然后勾选 kernel,点击“OK”将 RT-Thread 内核添加到工程中。 图7 添加RTOS内核 在 Project 中,可以看到 RT-Thread RTOS 已经添加,展开 RTOS,可以看到这些文件被添加到工程: 图8 RTOS添加成功界面 Cortex-M 芯片内核移植代码: context_rvds.s cpuport.c kernel文件 clock.c components.c device.c idle.c ipc.c irq.c kservice.c mem.c object.c scheduler.c thread.c timer.c 应用代码及配置文件: board.c rtconfig.h 04 适配 RT-Thread Nano 下面我们要再MM32L0xx上进行适配RT-thread,主要涉及中断及异常处理、系统时钟配置、内存堆栈初始化等,在官网的提供的例程中只需要在调用了底层库函数的文件中包含MM32的基本头文件hal_conf.h即可,里面包含上上述的配置内容,具体的细节可以参考RT-thread官网资料。 05 创建线程 初步的工程搭建已经完成,我们现在来制作一个简单的多任务的例程。 参考RT-Thread给出的例程我们来创建3个线程: //创建LED1的线程 void led1_entry(void *parameter) { while (1) { GPIO_SetBits(GPIOB, GPIO_Pin_5); rt_thread_delay(50); GPIO_ResetBits(GPIOB, GPIO_Pin_5); rt_thread_delay(100); } } //创建LED2的线程 void led2_entry(void *parameter) { while (1) { GPIO_SetBits(GPIOB, GPIO_Pin_6); rt_thread_delay(20); GPIO_ResetBits(GPIOB, GPIO_Pin_6); rt_thread_delay(40); } } //创建LED3的线程 void led3_entry(void *parameter) { while (1) { GPIO_SetBits(GPIOB, GPIO_Pin_7); rt_thread_delay(30); GPIO_ResetBits(GPIOB, GPIO_Pin_7); rt_thread_delay(80); } } 注意:任务中的延时必须是OS系统rt-thread_delay。 设置每个任务的启动: void led1_test(void) { rt_err_t result; result = rt_thread_init(&thread1, "led1", led1_entry, RT_NULL, &thread1_stack[0], 512, 1, 10); if(result == RT_EOK) rt_thread_startup(&thread1); } void led2_test(void) { rt_err_t result; result = rt_thread_init(&thread2, "led2", led2_entry, RT_NULL, &thread2_stack[0], 512, 2, 10); if(result == RT_EOK) rt_thread_startup(&thread2); } void led3_test(void) { rt_err_t result; result = rt_thread_init(&thread3, "led3", led3_entry, RT_NULL, &thread3_stack[0], 512, 3, 10); if(result == RT_EOK) rt_thread_startup(&thread3); } 可别忘了给三个任务分配相应的堆栈: static char thread1_stack[512],thread2_stack[512],thread3_stack[512]; static struct rt_thread thread1,thread2,thread3; 在分配任务堆栈时需要注意合理分配堆栈大小,太小了容易出现堆栈溢出的情况,同时合理设置各个任务的优先级避免有些任务无法切换到。 最后在主函数中启动3个任务即可: int main(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE); GPIO_InitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_2MHz; GPIO_Init(GPIOB, &GPIO_InitStruct); led1_test(); led2_test(); led3_test(); return 0; } 编译程序没有错误后下载到芯片就可以看到基于 RT-Thread 的程序运行起来了。 06 结果验证 图9 测试波形 从逻辑仪器上看,3个任务不同的时间进行了调度。 注意事项: 当添加 RT-Thread之后,裸机中的main()函数会自动变成RT-Thread系统中 main 线程的入口函数。由于线程不能一直独占CPU,所以此时在 main() 中使用 while(1) 时,需要有释放CPU的动作,比如使用rt_thread_mdelay()系列的函数释放CPU使用权。 2020灵动MM32协作大会 2020年9月10日 9:00 深圳星河丽思卡尔顿酒店 “2020灵动MM32协作大会”重磅开启!大会内容: 新品发布 技术分享 市场分析行业专家热点剖析 合作伙伴现场秀、互动小游戏 热销“MM32 INSIDE”应用案例展演等 更多精彩等着您,欢迎扫码报名参会! ` |
|
相关推荐
|
|
只有小组成员才能发言,加入小组>>
2249个成员聚集在这个小组
加入小组灵动微电子MM32全系列MCU产品应用手册,库函数和例程和选型表
11692 浏览 3 评论
【MM32 eMiniBoard试用连载】+基于OLED12864的GUI---U8G2
5927 浏览 1 评论
【MM32 eMiniBoard试用连载】移植RT-Thread至MM32L373PS
10960 浏览 0 评论
【MM32 eMiniBoard测评报告】+ 开箱 + 初探
4575 浏览 1 评论
灵动微课堂(第106讲) | MM32 USB功能学习笔记 —— WinUSB设备
4300 浏览 1 评论
[MM32软件] MM32F002使用内部flash存储数据怎么操作?
973浏览 1评论
798浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-25 16:59 , Processed in 0.451257 second(s), Total 39, Slave 31 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号