MyRTOS

HarderHeng Lv5

写在前面

目前个人的发展方向应该是RTOS。

想基于uCOS开始写一个属于自己的嵌入式操作系统,同时增加自己对嵌入式操作系统的理解和认识。

零、内存管理

为什么要把内存管理放在任务调度之前呢?明明说嵌入式操作系统的核心是任务调度,内存管理可以手动进行管理。

正是因为在设计任务调度的TCB时考虑到了这个事情。用户层面的动态内存管理是不必要的,但是系统资源的内存管理是需要考虑的。整个嵌入式系统运行期间,基本上就是任务栈和系统在占用内存,用户程序需要动态内存的情况很少,甚至说给用户一个很大的静态任务栈,也可以满足大内存的需求。

  • 不管使用多少个任务,uCOS默认都静态的申请20个TCB的内存,这对内存来说是浪费的,对用户来说是不需要关心的。
  • 任务栈需要用户手动创建,使用多少就分配多少,使用几个任务就分配几个内存栈,对内存来说是不浪费的,对用户来说是更加麻烦的。
  • 有没有一种能够同时利好用户内存浪费的方法?那就是动态内存管理。之前说的内存管理不重要,是指对用户的动态内存管理不重要。想象一下,对PC进行编程时,对一个简单程序来说,需要使用超越栈大小的内存,就应该是动态内存申请或者全局变量。一个简单的程序,在使用内存的地方进行一个简单的全局变量申请即可,完全不需要动态内存申请。对嵌入式系统来说也是一样的。同时考虑到动态内存申请的缺点,对嵌入式系统来说,时间和内存碎片都是不可接受的。

这里将去掉讨论用户级动态内存申请,即不会给用户实现malloc函数的功能,但是允许用户的Task_Stk足够大。

同时将用户的Task_Stk纳入系统级资源的讨论范围,用户在使用API创建任务时,自动调用API创建任务栈。虽然用户依然能够看到所有任务的栈,但是这样的设计依然符合操作系统的设计准则。MPU内存保护单元可以控制能够访问的内存区域,打算使用MPU来实现内存保护的功能,使得用户程序只能访问自己的栈内存。

挖坑

  • 操作系统内核态和用户态区分,触发svc中断进入特权模式。目前打算全部运行在内核态
  • MPU内存保护,使得任务只能够访问自己的任务栈。目前不打算实现MPU,MPU要结合特权模式来编程

1.系统资源内存申请

在操作系统初始化之前,所有任务开始运行起来之前,申请所有需要使用的内存,包括Task_Stk、Mutex、Mbox、TCB

内存申请包括两层

  • 第一层是大致的静态申请,通过链接脚本大致分配整体的内存空间,将这部分的内存空间加入到TLSF的内存管理器中,并且划分成指定大小的快。

  • 第二层就是针对需要申请内存的类型,比如Mbox,最佳匹配合适大小的内存块。

2.TLSF算法

一、任务调度

任务调度是嵌入式操作系统的核心部分。

一般来说,嵌入式系统中会有多个操作硬件的行为,封装在不同的函数中。在何时调用某一个函数实现一个任务,在没有操作系统的时候,是非常难以确定的,也使得实现任务的用户APP函数需要考虑更多。嵌入式操作系统可以不支持内存管理(手动进行管理),但是一定需要支持任务调度。

任务优先级

在嵌入式系统中,为了保证硬实时性,可以将每个任务分配一个固定的priority(优先级),每一个优先级就对应着一个任务,防止出现两个同样优先级的任务同时处在就绪状态。当然有一些嵌入式操作系统允许支持同样的优先级,为了保持简单性和简洁性,这里就暂时是只允许一个优先级对应一个任务

这里我的设计希望是一个优先级对应一个任务,暂时支持64个优先级,正好用一个字节表示任务就绪表的第一层索引,用8个字节表示任务就绪表的第二层索引。可扩展成16*16的256位优先级。

优先级从0到63,数字越大优先级越小,

二、临界区设计

按理说临界区设计也该在任务调度设计之前,因为任何改变系统资源配置的时候,都需要保证不被中断,防止出现在中断内改变系统资源的问题。

这里使用

  • Title: MyRTOS
  • Author: HarderHeng
  • Created at : 2025-03-06 22:44:52
  • Updated at : 2025-03-10 15:24:22
  • Link: https://harderheng.life/2025/03/06/MyRTOS/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments