MyRTOS
写在前面
目前个人的发展方向应该是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.