35747|175

130

帖子

1

TA的资源

一粒金砂(高级)

楼主
 

一个极易使用的RTOS [复制链接]

 
       原创文章,转载请注明出处!
  致RTOS新手:预练RTOS,必先学习CPU体系结构,否则看代码只会增加您的烦恼!但如果只是想快速使用,那么这个RTOS就是您的最佳选择.
  致高手:祝贺您,OS已经没什么好研究的了,应该研究在嵌入式开发中如何应用面向对象,设计模式等上流设计,
如:面向对象的3个基本要素与5个基本原则,可使代码优雅灵活,易于复用,易于扩展
粗略介绍一下3要素与5原则:
    3个基本要素:封装、继承、多态
    5个基本原则:
    单一职责原则(Single-Resposibility Principle)
      其核心思想为:一个类(或模块),最好只做一件事,只有一个引起它的变化
    开放封闭原则(Open-Closed principle)
      其核心思想为:软件实体应该是可扩展的,而不可修改的
    Liskov替换原则(Liskov-Substituion Principle)
      其核心思想为:子类必须能够替换其基类
    依赖倒置原则(Dependecy-Inversion Principle)
      其核心思想为:高层模块不依赖于底层模块,二者都同依赖于抽象;抽象不依赖于具体,具体依赖于抽象。
    接口隔离原则(Interface-Segregation Principle)
      其核心思想为:使用多个小的专门的接口,而不要使用一个大的总接口。
    以上不同的设计模式对应不同的需求,而设计原则则代表永恒的灵魂,需要在实践中时时刻刻地遵守,但不一定要完全遵守.

    那么如何设计RTOS呢?先看一段Keil工程结构截图与一段main.cpp代码:

main.cpp代码
  1. #include "os.h"                // 包含OS
  2. osThread Task1;                // 定义一个任务
  3. TACK_DEF(Task1Stk,256);        // 为任务1定义一个栈空间
  4. osMutex m1;                    // 定义一个互斥量

  5. void Fun1(void){
  6.     m1.Wait();
  7.     // 其它代码
  8.     m1.Release();
  9. }
  10. void Task1Fun(void){
  11.     int id = Task1.Id;         // 获取任务ID
  12.     Fun1();
  13.     os::Pass();                // 释放CPU,切换任务
  14.     os::Delete();              // 删除该任务,即使没有这句,也会自动删除
  15. }
  16. void TaskMain(void){
  17.     // 创建任务1,正常优先级
  18.     Task1.Create(Task1Fun,osPriorityNormal, Task1Stk,sizeof(Task1Stk));
  19. }
  20. int main(void){            
  21.     // 其它外设初始化      
  22.     os::Start(TaskMain);        // 启动OS
  23. }
复制代码

      不错,这样就可以了,OS按CPU体系结构已被编译成OS_[CM0/CM3/CM4F/ARM/ARMF/AVR].lib,并提供与CPU无关的头文件(仅此一个)以及一个配置文件(OS_Conf_CM.c),该配置文件每个工程一个副本,
配置文件中的CM对应系结构为cortex-M系列,另外还有ARM系列,AVR系列等配置模板,全图形化操作,CM系列如图:

      可见,这个OS使用起来非常简单,是其它OS不能比的.比如C++特性,细心的您可能已经发现了,任务的定义,互斥量的定义和其他OS明显不同,
另外还有osEvnet类,osSemaphore类,osMailBox类,全都在os.h文件中定义,但凡了解C++与OS概念的人都能轻易使用.如互斥量的定义:

  1. class osMutex{
  2. private:
  3.   U32 mut[4];     // 隐藏细节
  4. public:
  5.   osMutex();     // 构造函数,自动调用的互斥量初始化
  6.   void Wait(void);   // 等待
  7.   void Release(void);   // 释放
  8. };
复制代码
  • 再说说这个OS的一些其它主要特性,
        1.Cortex-M系列内核不会关中断
        2.基于优先级的时间片轮转调度算法,共7个优先级(实时, 高, 高于正常, 正常, 低于正常, 低, 空闲)
        3.互斥量与信号量支持优先级抢占与优先级变更,(不支持优先级继承)
        4.互斥量支持嵌套与递归(递归函数使用互斥量)
        5.支持任务在任何情况下删除时同时清除相关的互斥量与信号量状态,不论递归或嵌套,不会影响其它任务(类二叉树列表而已)
        6.每个任务共16个事件,可以等待多个事件都发生或任意一个发生
        7.源代码仅一个C文件与一个cpp文件以及一个汇编文件,共不足1500行代码(不算其它体系结构的汇编文件)
        8.性能: (在 STM32F103 24MHz 情况下测试得出, 单位us)
初始化系统,启动任务
30.3
创建任务(无任务切换)15.7
创建任务(任务切换)16.3
删除任务(含切换)13.2
任务切换(正常7.9) (高于正常7.4) (高7.0) (实时6.5)
设置事件(含切换)8.3

    不仅如此,该OS还有非常好的C++支持,因为作者修改了编译器的默认启动顺序(见samsis\inc\os\samos_rt.c文件),
在清零存储器,全局变量赋初值后,运行main之前插入了两件事,初始化OS与初始化C++,这样你可以任意使用c++的构造函数,虚函数.
即使你使勾选了.这些事情是在OS配置文件中完成的(包括定时器),所以上面的main.cpp代码没有OS初始化部分,也没有互斥量初始化部分


该demo创建了3个任务,分别控制3个LED以不同的频率翻转并print一个字符串,欢迎下载评估交流

高手:这只是一个微控制器OS,如果您有更好的建议或者更易于使用的OS,请炫出来,让我开开眼,RTX除外,您也可以检验(Keil软件仿真看汇编SVC部分),看是不是符合Cortex-M的特性,也可以检验raw-os的CM版,不过您可能会晕!

我当然知道,OS不算什么,对使用者仅仅改变编程习惯而已,只有完整的中间件(符合设计模式的中间件,OS只是其中一个小模块)配合使用,才能使开发人员快速开发产品,只关注应用相关,中间件以后发帖介绍,或移驾至http://www.cnblogs.com/samos2011/预览一下

原创文章,转载请注明出处!

OS下载地址:


查看精华帖全部内容,请登录或者注册

SamFramework.rar

37.99 KB, 下载次数: 146

RTOS

最新回复

吃瓜。。 = =、  详情 回复 发表于 2018-11-23 17:12

赞赏

1

查看全部赞赏

点赞 关注(9)

回复
举报

130

帖子

1

TA的资源

一粒金砂(高级)

推荐
 
本帖最后由 samos2011 于 2015-8-12 11:48 编辑

  应各位朋友的疑问,看来光说这个OS易于使用而不说点别的是不对的,估计也有持怀疑态度的,一个才2832字节的OS就号称有这么多功能,还号称最好用,既然如此, 那就说说与CPU体系结构相关的设计,至于任务管理等等只不过是几个链表而已,不值一提!(新手莫怪)

  首先,这是一个针对Cortex-M设计的OS,是一个不关中断的OS,如果用过uC/OS或者类似uC/OS的系统的朋友来说恐怕是难以理解的,就连隔壁的Raw-OS大师也提出,不关中断如何避免重入与保护临界资源?我想说的是,这是在对Cortex-M编写OS,而不是ARM7/9之类的CPU.

  如果熟悉 CM的朋友应该知道,CM具有很多先进的特性,如双堆栈,双模式(特权模式,用户模式),硬件支持中断优先级与中断嵌套,为了得到最佳中断响应时间,还支持晚到中断与咬尾中断,还有最最精妙的是异常发生时自动保存R0-R3,R12,PCSR等寄存器(为什么是这几个请自行查阅AAPCS),SVC(系统调用),SysTick(系统定时器),PendSV(可悬挂中断请求),这为OS的编写提供极大的硬件支持,完美解决现有OS关中断的不足移植繁琐的不足.

  关于CM的更多信息,中断的发生与返回,中断发生时的具体行为有兴趣者建议还是参考

  那么如何实现:
  已知高优先级中断在执行过程中不会被低优先级所中断,处理完高优先级,在未自动出栈时又立即处理挂起的低优先级中断(咬尾中断特性)那么我们把PendSV设为最低优先级,其次是SysTick,然后是SVC,其它的任何中断都要高于这三个.这样就决定了应用程序在SVC调用时即使发生时间片中断,时间片中断也不会立即执行,由于SVC调用只有一条指令,也就不存在多个任务同时SVC调用的可能,这样就保证了内核函数不会被重入而不需要关中断了,只要避免了重入,就保证了OS算法的可靠性,各种临界资源管理算法自然也就安全了

  由于是双堆栈,异常处理时都是使用MSP,而任务使用的是PSP,所依中断可以嵌套多少级与任务堆栈定义没有关系,定义任务堆栈时只需要考虑任务本身的需求,不然则不行,你得为每个任务加大堆栈已应对任何情况下发生的中断所消耗的任务堆栈空间.
  OS代码都是需要经SVC调用才会得到运行,所以OS是运行在特权模式下的,使用的MSP,所以OS是可以被其它中断所中断的.这绝对安全

  关于实时性:通常高优先级任务都是在等待事件,在用户的外部中断中当然可以设置事件,设置事件时仅仅将PendSV悬起,但没有马上执行,在用户中断返回的瞬间,PendSV立即执行(如果没有更高级别的中断的话,别忘了,还有晚到中断),任务也就切换了,没有比这更快的了

  在这些特性下,用户编写的任何中断都能得到最快的响应速度,延迟与否与OS无关,用户拥有最高控制权,

  虽然没有一句代码,但我认为精要的东西已经都讲了
  有疑问或更专业的信息还是参考

  uC/OS虽然很优秀,但为了兼容所有CPU,选择了牺牲CM的先进特性,隔壁的大师也说是为了通用而做成一样关中断,或者修改关中断为屏蔽低优先级中断即可,对此我表示无语, 殊不知,真正的通用是在使用上体现的,而具体实现则要针对具体!







 
 

回复

1026

帖子

0

TA的资源

五彩晶圆(中级)

沙发
 
有源码就好啦。。。
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

板凳
 
sblpp 发表于 2015-8-6 17:56
有源码就好啦。。。

那要看有多少人觉得用的爽咯!谢谢您测试评估!
 
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

4
 
,支持,期待源码来学习
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

5
 
247153481 发表于 2015-8-7 12:25
,支持,期待源码来学习

感谢,其实源码不是关键,这里展示的主要是设计思想,RTOS应该做成什么样!
 
 
 

回复

954

帖子

0

TA的资源

纯净的硅(初级)

6
 
samos2011 发表于 2015-8-7 12:33
感谢,其实源码不是关键,这里展示的主要是设计思想,RTOS应该做成什么样!

恩,对,思想才是最重要的,不过自己去实现的时候总是出问题了。先祝楼主的rtos能流行起来
 
 
 

回复

1026

帖子

0

TA的资源

五彩晶圆(中级)

7
 
samos2011 发表于 2015-8-6 18:01
那要看有多少人觉得用的爽咯!谢谢您测试评估!

期待开源啊!大侠。
希望能移植到Kinetis平台上,支持M0+和M4.
谢谢!
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

8
 
Mutex , Semaphore , Evnet 使用范例:
(仅介绍如何简洁明了的使用,不涉及原理)
Mutex :
互斥量在头文件中被定义成:
  1. class osMutex{
  2.         private:
  3.                 uint32 mut[4];
  4.         public:
  5.                 osMutex();                                // 构造函数,初始化
  6.                 OS_RESULT        Wait(void);      // 等待
  7.                 OS_RESULT        Release(void); // 释放
  8. };
复制代码


当需要使用互斥量时,您只要像定义变量一样定义一个互斥量即可,不需要初始化它:
  1. osMutex m1;
  2. int osPrintf(const char *format,...){
  3.        int len;
  4.        m1.Wait();
  5.        // 在printf函数执行过程中,其它任务不能再执行打印,需用到互斥量
  6.        len = printf(format);
  7.        m1.Release();
  8.        return len;
  9. }
复制代码


Semaphore :
信号量有两个构造函数,请看类定义
  1. class osSemaphore{
  2.         private:
  3.                 uint32 sem[2];
  4.         public:
  5.                 // 默认构造函数,token_count=1,同osMutex一样
  6.                 osSemaphore();
  7.                 // 可指定token_count的构造函数,表示最多能进入的任务数
  8.                 osSemaphore(uint16 token_count);
  9.                 OS_RESULT         Wait(void);        // 等待
  10.                 OS_RESULT         Release(void);   // 释放
  11. };
  12. // 使用同Mutex一样,定义变量就可以了
  13. // osSemaphore s1;       // 单值型
  14. // osSemaphore s1(10); // 表示可同时进入10个任务

复制代码


把临界资源比喻成房间,则:
Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。   
Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为单值型 semaphore,同mutex差不多。Semaphore一般的用法是,用于限制对于某一资源的同时访问,例如交通流量控制,停车场车位管理等
mutex与semaphore的主要的差异是mutex一定要由获得锁的进程来释放。而semaphore可以由其它进程释放

Evnet :
  1. class osEvnet{
  2.         public:      
  3.                 static OS_RESULT         Wait_And(uint16 wait_flags, uint16 timeoutMs); // 使任务等待多个事件都发生,具有超时控制
  4.                 static OS_RESULT         Wait_Or(uint16 wait_flags, uint16 timeoutMs);   // 使任务等待多个事件的任意一个发生,具有超时控制
  5.                 static OS_RESULT         Wait_And(uint16 wait_flags);
  6.                 static OS_RESULT         Wait_Or(uint16 wait_flags);
  7.                 static void                Set(uint16 event_flags, int task_id);
  8.                 static void                IsrSet(uint16 event_flags, int task_id);
  9. };
复制代码

使用范例:

  1. // 假设Task1受 X,Y 事件控制

  2. // 定义任务
  3. osThread Task1;

  4. // 定义两个事件
  5. #define EVNET_X (0x0001)   // 每个位表示一个事件
  6. #define EVNET_Y (0x0800)

  7. // Task1处理函数,等待X,Y都发生
  8. void Task1Fun(void){
  9.         osEvnet::Wait_And(EVNET_X | EVNET_Y);
  10.         // 事件发生后才执行的代码......
  11. }

  12. void Task2(void){
  13.         osEvnet::Set(EVNET_X,Task1.GetId());// 设置Task1的X事件
  14. }

  15. void 某中断服务函数(void){
  16.         osEvnet::IsrSet(EVNET_Y,Task1.GetId());// 设置Task1的Y事件
  17. }

  18. // 或者Task1等待X,Y任意一个发生都执行代码,并超时3秒钟
  19. void Task1Fun(void){
  20.         osEvnet::Wait_Or(EVNET_X | EVNET_Y,3000);
  21.         // 任意一个事件发生后才执行的代码......
  22. }
复制代码














 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

9
 
本帖最后由 samos2011 于 2015-8-11 10:15 编辑
sblpp 发表于 2015-8-11 09:45
期待开源啊!大侠。
希望能移植到Kinetis平台上,支持M0+和M4.
谢谢!

呵呵,M0/M4没放出来而已,先给个M3给大家玩玩!,M4可以直接使用M3,只是没有浮点支持
另:只要是基于Cortex-M3内核的处理器都能用,不分厂家型号外设资源多少!不需要任何移植!再次强调(不需要任何移植)
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

10
 
在我这个框架下,所谓的OS移植仅仅是点击->[加载文件到工程],然后选择对应体系结构的OS_XXX.Lib而已
 
 
 

回复

7815

帖子

55

TA的资源

裸片初长成(中级)

11
 
说说开销呗~
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

12
 
本帖最后由 samos2011 于 2015-8-11 12:43 编辑

Cortex-M版OS开销如下:
代码
2832 字节
数据
1266 字节
(含空闲任务栈256字节)
(含第一个任务栈256字节)
(含8个TCB: 48*8=384字节)
OS算法仅占用 370字节
TCB
48 字节/个
Mutex
32字节/个
Semaphore
16字节/个
任务堆栈
使用者定义

 
 
 

回复

7815

帖子

55

TA的资源

裸片初长成(中级)

13
 
samos2011 发表于 2015-8-11 12:33
Cortex-M版OS开销如下:

时间方面的开销捏
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

14
 
辛昕 发表于 2015-8-11 13:54
时间方面的开销捏

性能开销: (在 STM32F103 24MHz 情况下测试得出, 单位us)

初始化系统,启动任务

30.3
创建任务(无任务切换)15.7
创建任务(任务切换)16.3
删除任务(含切换)13.2
任务切换(正常7.9) (高于正常7.4) (高7.0) (实时6.5)
设置事件(含切换)8.3

 
 
 

回复

7815

帖子

55

TA的资源

裸片初长成(中级)

15
 
samos2011 发表于 2015-8-11 14:00
性能开销: (在 STM32F103 24MHz 情况下测试得出, 单位us)

哟,还不错的说~~

楼主不打算放出源码,不知道打算怎么推广你的os捏?

比起常见的 ucos freertos等不知道又有啥优势捏?

有木有啥支持的工具推出捏,是不是要收钱呢?收多少钱捏?

你的源码商用个人用怎么收费捏?

这些都得说说,不然谁敢用呀~~
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复

1万

帖子

2852

TA的资源

管理员

16
 
本帖最后由 okhxyyo 于 2015-8-11 14:19 编辑

第一次听说呀~楼主能详细介绍下这个os的性能么?跟别的os比起来有什么特别或者优势么?能放源码咱们看看么?
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

17
 
辛昕 发表于 2015-8-11 14:08
哟,还不错的说~~

楼主不打算放出源码,不知道打算怎么推广你的os捏?

比起常见的 ucos freertos ...

别的优点不敢说,但有一个优点是显而易见的,那就是易于使用
至于推广,太难了,09年就开始玩OS,偶尔萌生过推广的念头
随着技术的不断进步,项目经验的积累,才发现,仅仅一个OS就想让别人记住你太难了
本文主要还是想展示一些设计经验与思想,如您以前的博文<关于架构等>
在嵌入式开发中,使用C++的少,灵活应用设计模式的更少!
我更希望能在这方面引起共鸣!探讨嵌入式开发中的面向对象与设计模式!
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

18
 
这个OS的精髓不在OS的功能实现上,而是在它呈现给你的样子上!
如果都是按照CPU体系结构编写,OS的基本算法都是差不多的!
 
 
 

回复

130

帖子

1

TA的资源

一粒金砂(高级)

19
 
okhxyyo 发表于 2015-8-11 14:16
第一次听说呀~楼主能详细介绍下这个os的性能么?跟别的os比起来有什么特别或者优势么?能放源码咱们看看么 ...

关于性能以及开销与特性都在几张表里面(1楼12楼14楼)
论起优势那最直观的就是易于使用!呵呵
 
 
 

回复

7815

帖子

55

TA的资源

裸片初长成(中级)

20
 
samos2011 发表于 2015-8-11 14:21
别的优点不敢说,但有一个优点是显而易见的,那就是易于使用
至于推广,太难了,09年就开始玩OS,偶尔萌生过 ...

哦,你CSDN的博客我跑过去看了看。
不过内容还不是太多就是,我不知道你玩这么久了。

要不转来这里贴贴呗~~
 
个人签名

强者为尊,弱者,死无葬身之地

 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条
有奖直播 | AI之眼——安森美图像传感器 报名中
直播时间:2025年4月25日(周五)上午10:00-11:30
直播主题:AI之眼——安森美图像传感器
报名观看直播、直播间提问、填写问卷均有机会获得精美礼品!

查看 »

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网 9

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表