嵌入式OS入门笔记-以RTX为案例:二.快速移植到RTX

嵌入式OS入门笔记-以RTX为案例:二.快速移植到RTX


本篇笔记将简单介绍RTX,包括基本架构,如何在Keil中配置。需要安装ARM-MDK和一块硬件板,笔记以STM32F4Discovery为例子。


1.为什么要用RTOS?
尽管把所有程序放在一个大的循环里顺序执行,总是可能的(甚至很多时候是足够的胜任任务的),但是这样做有好几个明显的缺点:
过分依赖中断 ISR(Interrupt Service Routine, 中断服务例程)
同步不同的ISR不容易
可预测性和延展性很差(大量的ISR,甚至是中断嵌套)
对局部的修改会对整个系统有水花效应(没有模块化,牵一发而动全身)
RTOS主要是把要执行的运算包装在小的task里面,这样好的好处是:
更好的程序流(program flow)和反应
多任务(尽管这是假象)
简单的ISR,强的决定性
更好的进程间通信
更好的资源管理
最关键的是,开发成本低!

一个不成文的小经验:如果源程序大于1MB,那就有必要用RTOS了!


2.为什么不要用RTOS?
当然,也有很多情况下我们不希望用RTOS的:
项目简单
不想学RTOS
RTOS尽管性能方便出色,但不是最优的!(好比用汇编还是用C,有经验的程序员可以写出比编译器效率更高的代码,可是编译器大大简化开发过程。)如果需要极致的性能优化,那可能RTOS不是你的第一选择,毕竟RTOS是有内存和运行overhead的。
开发RTOS很耗时间
不是所有RTOS都是免费的

3.为什么RTX?
为什么选RTX不选别的RTOS,例如FreeRTOS?
免费(royalty-free,买断式的授权)
好上手
对硬件要求低
和ARM软硬件兼容性好(ARM-MDK自带)
可以查看源代码
其实主要还是看应用,RTX在行业里声誉还是很好的,稳定性强,开发成本低,而且基本功能齐全。

4.RTX的结构

RTX其实是Keil Real-Time Library (RTL)的核心,这个RTL有很多部分的,都是在RTX kernel基础上库。 RTX Kernel本身的话,结构大概如下图:


主要的组件有:mutex互斥锁,memory pool内存池,mailbox邮箱,time(timer)定时器, event事件, semaphore旗语或信号灯,task management进程管理等等和最核心的Scheduler排程器(进程调度器)。

5.移植到RTX上很简单!

移植一个现有的ARM-MDK工程到RTX上非常简单:
1.在工程配置中选择RTX Kernel作为你的操作系统,如下图:
 

2.在你的main.c里添加头文件RTL.H:
#include <RTL.h> 
3.复制RTX_Conf_CM.文件到你的工程里。这个文件可以在<<YourKeil Directory>>\ARM\RL\RTX\Config 路径下找到。
4.将你原有的函数改造成task,就是在函数返回类型前添加标记 __task (双下划线) 例如:
__task void task(void){  
for(;;){  //...     }  
}  

5.初始化RTX并创建第一个task,例如:
os_sys_init(task);
基本就这样,具体的关于Task的API,后面的笔记会继续介绍。


6.几个相关的文件
完成上述几步后,你会发现你的工程里主要多了这三个文件:
RTL.h
RTL_Conf_CM.c
RTX_lib.c
第一个是整个RTL的API函数签名。第二个是RTX的配置文件,你可以通过configuration wizard提供的GUI去配置你的OS。最后一个是内核的配置文件,有一些可以实时调用的配置函数。


7.RTX的配置
这里多说说第二个文件,你可以使用text editor去修改代码,也可以使用configuration wizard,如下图:
 
这里先逐项简单介绍这里的选项:
并行的task数
用户设定堆栈的task数
预设堆栈大小
检查是否堆栈溢出
是否在kernel mode下运行?这个意思是一般的task是否也在kernel mode下运行,一般不勾选。
硬件时钟,CM系列的Core SysTick就是专门为OS所设置的,所以如果你原来就有用到这个timer的话,你的移植可能会出现问题。
硬件时钟频率
一个tick的时间,预设是10ms,这个和delay函数和排程器有关
是否轮转式排程?
轮转式排程的时间片,如果是5,那就是5*10ms=50ms(和tick值有关)
用户时钟数
ISR队列的大小
一般主要调的就时钟频率和排程的设置。


8.题外话-CMSIS-RTOS 和 RTX
uVision5提供的RTOS是CMSIS-RTOS,有点让人觉得摸不着头脑。其实CMSIS-RTOS是在RTX上的另一层封装。这样做的意义在于,建立在不同RTOS(例如RTX和FreeRTOS)的项目可以用同一套API。对于大部分ARM的核来说,其实其底层就是RTX。
 
所以其实本质上是一个东西,只是API名称不同。使用CMSIS-RTOS 的好处就是稍微强的移植性。但是考虑到ARM的市场占有和他们RTX本身的兼容性,不用CMSIS-RTOS好像更好。而且两层封装,很容易把人弄晕。


当然,如果有需要,可以参考官方文档:移植RTX到CMSIS-RTOS。


文章转载自:http://blog.csdn.net/raym0ndkwan/article/details/32859989


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/466044.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

再解析下内核自旋锁和优先级翻转问题

[内核同步]自旋锁spin_lock、spin_lock_irq 和 spin_lock_irqsave 分析漫画|Linux 并发、竞态、互斥锁、自旋锁、信号量都是什么鬼&#xff1f;Linux内核自旋锁之前写的自旋锁的文章&#xff0c;现在再加一篇&#xff0c;可能单纯的一两次说明不能把问题说清楚。所以再写一篇文…

有许多话不能说

说的问题是一个大问题。人&#xff0c;长了嘴巴&#xff0c;除了吃饭便是说话。当然还有代替鼻孔呼吸、排除呼吸道污秽等功能&#xff0c;但均不可与说同日而语。涉及说&#xff0c;就有说的内容问题&#xff0c;据观察&#xff0c;有许多话是不能说的。 好话不能说&#xff0c…

ios 逆向编程(环境搭建)

首先如果你想要逆向其他的APP 动态的查看 或者修改人家APP里面的东西 1&#xff0c; 首先要有一台越狱的手机 最好是9.1以下的&#xff0c;因为9.2以上&#xff08;包括9.2&#xff09;就不能完美越狱了 2&#xff0c;手机也要5s以上的&#xff08;因为从5S开始支持arm64架构&…

嵌入式OS入门笔记-以RTX为案例:三.初探进程

嵌入式OS入门笔记-以RTX为案例&#xff1a;三.初探进程1.理论 进程&#xff0c;英文称呼很多Process, Task 等等&#xff0c;一般通用操作系统称Process的比较多&#xff0c;各种称呼涵义稍微有不一样。一般而言&#xff0c;进程是对一个运行单元的抽象&#xff0c;主要包括…

图文方式管理Linux服务器(Webmin)

客户让做webmin&#xff0c;才知道linux下也有界面的管理了 对于大部分使用计算机的人来说&#xff0c;linux的印象就是一大堆的命令字符以及黑黑的显示屏。虽然现在Linux的桌面版有了长足的进步&#xff0c;界面已和Windows不相上下了&#xff0e;但对于Linux服务器来说&am…

最大、最小堆的实现

最大最小堆 堆是一种经过排序的完全二叉树&#xff0c;其中任一非终端节点的数据值均不大于&#xff08;或不小于&#xff09;其左子节点和右子节点的值。 最大堆和最小堆是二叉堆的两种形式。 最大堆&#xff1a;根结点的键值是所有堆结点键值中最大者。 最小堆&#xff1a;根…

嵌入式OS入门笔记-以RTX为案例:四.简单的时间管理

嵌入式OS入门笔记-以RTX为案例&#xff1a;四.简单的时间管理 上一节简单记录了进程task。有了进程以后&#xff0c;我们需要关心怎么样分配CPU资源&#xff08;或者运行时间&#xff09;给每个进程。那么就要引入排程&#xff08;scheduling&#xff09;的概念。排程一般都是O…

我等这个含蓄的技术男当上了CEO

大家好&#xff0c;祝大家五一节日快乐&#xff01;今天没有写技术文章&#xff0c;今天想吹一个人&#xff0c;他是我的朋友&#xff0c;他做公众号很久了&#xff0c;技术文章写的也不错&#xff0c;但是阅读和关注量一直没有上来&#xff0c;我之前好几次在公众号上转发了他…

Oracle的列转行问题

Oracle的列转行问题Oracle中使用语句将行数据转换称不同的列表示&#xff0c;或者将不同的列数据写到同一列的不同行上的行列转换问题是一个非常传统的话题。网络上流传了很多将行数据转换称列数据的方法和应用实例&#xff0c;一般通过decode或者case函数与聚合函数联合实现功…

Linux CAN通信

Linux CAN通信 实现了Linux下的CAN通信——初始化&#xff0c;发两个送和接收&#xff08;采用队列形式&#xff09;&#xff0c;使用两个线程&#xff0c;还有一个超时响应目前未写。接收部分使用select实现。 #ifndef _CAN_H_ #define _CAN_H_#include <stdio.h> #incl…

(四)Kinect人脸识别

kinect可以通过摄动摄像头不仅可以获取人脸位置旋转信息&#xff0c;也可以获取脸部轮廓的三维坐标 可以参考插件中的场景KinectFaceTrackingDemo1-4&#xff0c;在kinectManager基础上需要脚本FacetrackingManager。 1&#xff09;通过KinectManager kinectManager KinectMan…

广东总冠军

lets go tiger 看这篇文章之前&#xff0c;先看看我们看球的视频 恭喜广东拿下总冠军&#xff01; 恭喜胡明轩夺得FMVP&#xff01; 我当时预测的是周鹏或者胡明轩拿下FMVP&#xff0c;最后是胡明轩&#xff0c;广东后场三条枪表现都非常亮眼。如果是上一场广东夺冠&#xff0c…

Spring切入点表达式常用写法

Spring切入点表达式常用写法自从使用AspectJ风格切面配置&#xff0c;使得Spring的切面配置大大简化&#xff0c;但是AspectJ是另外一个开源项目&#xff0c;其规则表达式的语法也稍稍有些怪异。下面给出一些常见示例的写法&#xff1a;比如&#xff0c;下面是一个对Service包上…

每日一题(1) —— 数组计算

判断下面代码是否可执行&#xff1f;如果可执行&#xff0c;执行结果是多少&#xff1f; #include <stdio.h>int main(void) {int array[10] {0, 2, 3, 4, 5, 6, 7, 8, 9, 10};0[array] 1;printf("%d\n", (-1)[array 5]);return 0; } 分析&#xff1a; C语…

SQLAlchemy Script

SQLAlchemy: 1.由于sqlalchemy中没有提供choice方法&#xff0c;所以借助SQLAlchemy-Utils组件提供的choice方法 from sqlalchemy_utils import ChoiceType Base declarative_base() class Xuan(Base): __tablename__ xuan types_choices ( (1,欧美), (2,日韩), (3,老男孩),…

内存文章汇总,并剖析mmap

在看这篇文章之前&#xff0c;可以先看看下面这几篇文章Linux内存&#xff0c;先看这篇文章Linux内存寻址方式Linux虚拟内存TLBLinux物理内存初始化Linux io内存存在的意义~修改cmdline 把内存改成512MB用mtrace定位内存泄漏什么是内存泄漏&#xff1f;Linux内存管理slub分配器…

[综述泛读] A survey on web services composition (IJWGS, 2005)

Time: 2.5 hours Dustdar S, Schreiner W. "A survey on web services composition." International Journal of Web and Grid Services: 1-30. 2005 (30 pages, 单栏) (gs:169) Schahram Dustdar (维也纳技术大学, full prof) Dusdar是Distributed Systems Group的老…

Spring 事务与脏读、不可重复读、幻读

索引&#xff1a; 目录索引 参看代码 GitHub&#xff1a; 1.Spring 事务 2.事务行为 一、Spring 事务: Spring 的事务机制是用统一的机制来处理不同数据访问技术的事务处理。 Spring 的事务机制提供了一个 PlatformTransactionManager 接口&#xff0c;不同的数据访问技术的事务…

韦老师的开发板和嵌入式书籍赠送

大家五一快乐&#xff01;我知道这个时候大家都没有什么心思学习&#xff0c;所以找了联合了几个朋友一起给大家送点东西。这几个技术号主都非常用心的给大家分享技术文章&#xff0c;我相信&#xff0c;跟他们一起&#xff0c;你们也能变得更加优秀。奖品包括&#xff1a;1. 韦…

每日一题(2)—— -2与2的比较

分析下面的代码&#xff0c;求运行结果。 #include <stdio.h>int main(void) {if(-2 > 2){printf("11111\r\n");}else{printf("22222\r\n");}return 0; }分析&#xff1a; -2和2都没有声明存储类型&#xff0c;编译器默认按int存储&#xff0c;所…