RT-Thread操作系统的FreeRTOS兼容层

github地址 https://github.com/rt-thread-packages/freertos-wrapper   期待您的star  
本项目是2022年开源之夏,rt-thread社区项目。已经于2022年9月由唐照洲(美国佐治亚理工学院,大四)顺利结项完成。freertos兼容层目前已经落地到rt-thread对esp32-idf(唐照洲)和core-v-mcu(王顺)两款sdk的兼容项目中。
1 概述 这是一个针对rt-thread国产操作系统的freertos操作系统兼容层,可以让原有基于freertos操作系统的项目快速、无感地迁移到rt-thread操作系统上,实现在rt-thread操作系统上无感的使用freertos的api,同时可以使用rt-thread的丰富组件。项目基于freertos v10.4.6版本。
1.1 rt-thread的其他rtos兼容层
rt-thread操作系统的μcos-iii兼容层:https://github.com/mysterywolf/rt-thread-wrapper-of-ucos-iii
rt-thread操作系统的μcos-ii兼容层:https://github.com/mysterywolf/rt-thread-wrapper-of-ucos-ii
rt-thread操作系统的rtx(即cmsis-rtos1)兼容层:https://github.com/rt-thread-packages/cmsis_rtos1
rt-thread操作系统的rtx5(即cmsis-rtos2)兼容层:https://github.com/rt-thread-packages/cmsis_rtos2
rt-thread操作系统的arduino生态兼容层:https://github.com/rtduino/rtduino
2 freertos的api支持情况及使用注意事项
api支持情况详见,readme 链接如下:
https://github.com/rt-thread-packages/freertos-wrapper
(请复制至外部浏览器打开)
兼容层对freertos的支持情况记录在issue中记录。一些支持的函数在功能和使用方法上和freertos略有不同,在迁移过程中需要注意。
2.1线程、消息队列与互斥量
2.1.1 vtasksuspend
vtasksuspend只支持挂起当前运行的线程,在使用时xtasktosuspend参数必须为null。否则会触发断言。
2.1.2 xqueuesendtofront
xqueuesendtofront不支持设置超时,使用时xtickstowait参数会被忽略,消息队列没有空间时会立即返回errqueue_full。
2.1.3 xqueuecreatestatic
静态消息队列需要参考以下的例子创建,确保为消息队列分配的内存足够大:
1#define queue_length 10 2#define item_size sizeof( uint32_t ) 3 4/* 以下是在原版freertos分配内存的方法,由于rt-thread消息队列内部的实现与freertos不同,这样分配的内存不够存放item_size个消息 */ 5//uint8_t ucqueuestorage[ queue_length * item_size ]; 6/* 要使用queue_buffer_size宏分配内存 */ 7uint8_t ucqueuestorage[ queue_buffer_size(queue_length, item_size)]; 8staticqueue_t xqueuebuffer; 9queuehandle_t xqueue1;10xqueue1 = xqueuecreate( queue_length, item_size, &( ucqueuestorage[ 0 ] ), &xqueuebuffer ); 2.1.4 mutex和recursive mutex freertos提供了两种互斥量,mutex和recursive mutex。recursive mutex可以由同一个线程重复获取,mutex不可以。rt-thread提供的互斥量是可以重复获取的,因此兼容层也不对mutex和recursive mutex做区分。
用xsemaphorecreatemutex和xsemaphorecreaterecursivemutex创建的互斥量都是可以重复获取的。
2.2 定时器
和freertos不同,rt-thread不使用一个消息队列向定时器线程传递命令。使用兼容层时任何需要设置超时的定时器函数,如xtimerstart( xtimer, xtickstowait ),xtickstowait参数会被忽略,函数会立即完成命令并返回。
2.3 fromisr函数
freertos为一些函数提供了在中断中使用的fromisr版本,如果这些函数唤醒了更高优先级的线程,需要手动调度,如下所示:
1basetype_t xhigherpriorittaskwoken = pdfalse;2xqueuesendtofrontfromisr( xrxqueue, &cin, &xhigherprioritytaskwoken );3if( xhigherprioritytaskwoken )4{5  taskyield ();6} rt-thread不为函数提供fromisr版本,函数可以在中断调用并在内部完成调度。因此在兼容层中使用fromisr函数后不需要手动调度,xhigherprioritytaskwoken总会被设置成pdfalse。
2.4 内存堆
兼容层保留了freertos的五种内存分配算法,默认使用heap_3,pvportmalloc/vportfree内部调用rt_kernel_malloc/rt_kernel_free在rt-thread内部的内存堆分配。这种情况下内存堆的大小由rt-thread bsp配置决定,无法在freertosconfig.h中通过configtotal_heap_size设置。若使用其他算法,需要修改freertos/ssconscript,选择相应的源文件
1#可将heap_3.c替换成heap_1.c等2src += glob(os.path.join(portable, memmang, heap_3.c)) 在freertos/portable/rt-thread/freertosconfig.h中通过configtotal_heap_size设置内存堆大小。应用调用pvportmalloc/vportfree会在一块独立于rt-thread,大小为configtotal_heap_size的内存堆中分配,rt-thread内部的内存堆仍然存在,兼容层函数内部分配内存都在rt-thread的内存堆完成。
2.5 线程优先级
rt-threa线程优先级数值越小时优先级越高,而freertos线程优先级数值越大优先级越高。在使用兼容层的freertos api,如xtaskcreate,使用freertos的规则为线程指定优先级即可。若在应用中将rt-thread和freertos api混合使用,在指定线程优先级时要特别注意。可以使用以下两个宏对rt-thread和freertos线程优先级做转换:
1#define freertos_priority_to_rtthread(priority)    ( configmax_priorities - 1 - ( priority ) )2#define rtthread_priority_to_freertos(priority)    ( rt_thread_priority_max - 1 - ( priority ) ) 2.6 线程堆栈大小 freertos线程堆栈大小的单位为sizeof(stacktype_t),rt-thread线程堆栈大小为sizeof(rt_uint8_t)。使用freertos api创建线程时一定要遵守freertos的规则,切勿混淆。
2.7 vtaskstartscheduler
由于rt-thread和freertos的内核启动流程不同,使用兼容层时,main函数是在一个线程中运行,该线程优先级为config_rt_main_thread_priority。(此选项通过scons配置,数值越小优先级越高。),此时调度器已经开启。一般的freertos应用采用以下的方式创建线程:
1xtaskcreate(pxtask1code, ......);2xtaskcreate(pxtask2code, ......);3......4vtaskstartscheduler(); 使用兼容层时,任何使用xtaskcreate创建的线程若优先级比config_rt_main_thread_priority更高,会立即开始执行。vtaskstartscheduler只是为了提供对应用的兼容,没有任何实际效果。在使用兼容层时,创建线程要特别注意,确保在调用xtaskcreate时,该线程所需的所有资源已经完成初始化,可以正常运行。
3 使用方法
通过env工具将兼容层加入到工程中:
1rt-thread online packages2    system packages --->3        [*] freertos wrapper --->4            version (latest) 使用scons --menuconfig配置rt-thread内核,以下选项会影响到freertos兼容层:
1rt_using_timer_soft /* 使用freertos定时器时必须开启*/2rt_timer_thread_prio  /* 定时器线程优先级。与freertos相反,该选项数值越小优先级越高 */3rt_timer_thread_stack_size  /* 定时器线程栈大小,单位为sizeof(rt_uint8_t) */4rt_using_mutex  /* 使用freertos互斥量时必须开启*/5rt_using_semaphore  /* 使用freertos信号量时必须开启*/6rt_using_heap /* 使用freertos动态内存分配时必须开启*/7rt_tick_per_second  /* 相当于freertos configtick_rate_hz */8rt_thread_priority_max /* 相当于freertos configmax_priorities */9rt_name_max /* 相当于freertos configmax_task_name_len */ 在freertos/portable/rt-thread提供了freertosconfig.h模版。大部分内容不可以修改或依赖rt-thread内核的配置,可以手动修改的内容如下:
1/* 可以选择不使用recursive mutex */ 2#ifdef rt_using_mutex 3    #define configuse_recursive_mutexes         1 4    #define configuse_mutexes                   1 5#endif 6 7/* 可以选择不使用counting semaphore */ 8#ifdef rt_using_semaphore 9    #define configuse_counting_semaphores       110#endif1112/* 若不使用heap_3,可以通过configtotal_heap_size配置内存堆大小 */13#define configsupport_static_allocation         114#ifdef rt_using_heap15    #define configsupport_dynamic_allocation    116    #define configtotal_heap_size               1024017    #define configapplication_allocated_heap    018#endif1920#define configminimal_stack_size                1282122/* 可以选择的函数和功能 */23#define include_vtaskpriorityset                124#define include_uxtaskpriorityget               125#define include_vtaskdelete                     126#define include_vtasksuspend                    127#define include_xtaskdelayuntil                 128#define include_vtaskdelay                      129#define include_xtaskgetidletaskhandle          130#define include_xtaskabortdelay                 131#define include_xsemaphoregetmutexholder        132#define include_xtaskgethandle                  133#define include_uxtaskgetstackhighwatermark     134#define include_uxtaskgetstackhighwatermark2    135#define include_etaskgetstate                   136#define include_xtaskresumefromisr              137#define include_xtaskgetschedulerstate          138#define include_xtaskgetcurrenttaskhandle       139#define configuse_application_task_tag          140#define configuse_task_notifications            141#define configtask_notification_array_entries   3 在test目录下提供了一些例程,可以将它们加入bsp目录下的applications文件夹中。使用scons编译并烧录后,可以连接串口,输入相应的msh命令,观察例程的执行结果:
1msh />queue_dynamic 2task 1 receive data 0 from queue 3task 1 receive data 1 from queue 4task 1 receive data 2 from queue 5task 1 receive data 3 from queue 6task 1 receive data 4 from queue 7task 1 receive data 5 from queue 8task 1 receive data 6 from queue 9task 1 receive data 7 from queue10task 1 receive data 8 from queue11task 1 receive data 9 from queue12task 1 receive data 10 from queue 4 参考资料  
rt-thread文档 
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/readme
freertos文档
https://www.freertos.org/a00106.html
github地址 https://github.com/rt-thread-packages/freertos-wrapper   期待您的star  
———————end———————
你可以添加微信:rtthread2020 为好友,注明:公司+姓名,拉进rt-thread官方微信交流群!
原文标题:rt-thread操作系统的freertos兼容层
文章出处:【微信公众号:rtthread物联网操作系统】欢迎添加关注!文章转载请注明出处。

4515DO-DS3BS002DP传感器检测洁净实验室压差的方法
如何制作带超声波传感器的无限远镜
电子激光射击分组对抗系统的原理以及系统特点是什么?
工信部苗圩:5G未来的应用场景主要体验在车联网和远程医疗方面
手环加速度传感器原理及选型技巧
RT-Thread操作系统的FreeRTOS兼容层
前谷歌自动驾驶明星工程师承认窃取谷歌商业机密 将面临长达30个月的监禁及以及1.79亿美元违约金
苹果手机对于充电接口是如何规划的
嵌入式系统的SD控制器设计实现
移轴镜头实拍技巧2 拍摄出长腿美人
上海发布《三年行动计划》,2025年工业机器人密度达到360台/万人
Bourns 推出具有变革性 EdgMOV™ 压敏电阻系列 提供节省空间的浪涌保护解决方案
软件工程师的从业要求有哪些
Achronix和Signoff半导体携手为人工智能机器学习应用提供FPGA和eFPGA IP设计服务
联发科:天玑9300加持,今年旗舰级手机SoC营收将达10亿美元
“小冰之父”是如何看待微软小冰发展的?
区块链技术在制药行业中有哪些潜在的应用
盘点全新realme Watch S Pro亮点
什么是PLC中的F1-20P简易编程器
A家爆款笔记本齐聚ChinaJoy 元气偶像助阵嗨翻全场