Files

7.8 KiB
Raw Permalink Blame History

tags, create time
tags create time
嵌入式系统
复习
RTOS
uC/OS-II
2026-06-10 11:11

嵌入式操作系统

概述

本文档讲解嵌入式操作系统的核心概念,重点覆盖RTOS调度策略、uC/OS-II的特性与API、任务管理机制,以及嵌入式Linux和WinCE的对比。RTOS是嵌入式系统考试中与ARM架构并列的重点。

正文

1. 嵌入式操作系统概述

嵌入式操作系统是运行在嵌入式硬件上的系统软件,负责管理硬件资源、提供任务调度和服务接口。与通用操作系统相比,它更注重实时性、可裁剪性和可靠性。

嵌入式操作系统的分类:

分类 特点 典型代表
嵌入式RTOS 严格实时,微内核,可裁剪 FreeRTOS, uC/OS-II, RT-Thread
嵌入式Linux 功能丰富,开源,非严格实时 Android, OpenWrt, Yocto
商用嵌入式OS 商业授权,完整生态 WinCE, VxWorks, QNX

2. 抢占式 vs 协作式调度

这是RTOS最核心的概念之一:

抢占式调度(Preemptive):

  • 高优先级任务立即获得CPU控制权
  • 无论当前任务在做什么,都会被中断
  • 实时性好,响应时间可预测
  • uC/OS-II、FreeRTOS均采用此方式

协作式调度(Cooperative):

  • 任务必须主动放弃CPU(调用yield或等待事件)
  • 实现简单,但一个任务卡死会影响整个系统
  • 早期Windows 3.1、部分简单RTOS使用
graph TD
    subgraph preemptive["Preemptive Scheduling"]
        direction TB
        PA1["Task A running"] --> |"Higher priority Task B becomes ready"| PB1["Task B preempts A"]
        PB1 --> |"Task B finishes"| PA2["Task A resumes"]
    end

    subgraph cooperative["Cooperative Scheduling"]
        direction TB
        CA1["Task A running"] --> |"Task A calls yield or blocks"| CB1["Task B runs"]
        CB1 --> |"Task B yields"| CA2["Task A resumes"]
    end

    style PA1 fill:#90caf9
    style PB1 fill:#ef9a9a
    style PA2 fill:#90caf9
    style CA1 fill:#a5d6a7
    style CB1 fill:#ffcc80
    style CA2 fill:#a5d6a7

[!question] 为什么嵌入式系统通常选择抢占式调度? 嵌入式系统经常需要处理紧急事件(如传感器报警、安全检测),如果采用协作式调度,低优先级任务长时间不让出CPU会导致高优先级任务无法及时响应,可能造成安全事故。

3. RTOS实时性指标

衡量一个RTOS的实时性,主要看两个指标:

  1. 调度器执行时间:调度算法本身运行所需的时间。越短越好。
  2. 任务切换时间:从一个任务切换到另一个任务所需的时间(保存上下文 + 恢复上下文 + 刷新流水线)。

[!tip] 最坏情况下的响应时间 对于硬实时系统,关注的是最坏情况下的响应时间,而不是平均响应时间。最坏响应时间 = 最长中断屏蔽时间 + 最高优先级任务执行时间。

4. uC/OS-II概述

uC/OS-II是一个经典的抢占式实时内核,主要特点:

  • 抢占式基于优先级的调度
  • 可裁剪:通过条件编译去掉不需要的功能
  • 可移植:支持多种处理器架构
  • 确定性:服务时间可预测
  • 商业软件:非开源,需要购买授权
  • 支持64个任务(优先级0-63,0最高,63最低)

[!warning] uC/OS-II不是免费的 uC/OS-II是商业软件,与FreeRTOS(免费开源)不同。学习和评估可以使用,但商业应用需要购买许可证。

5. 任务管理API

uC/OS-II提供了完善的任务管理接口:

创建与删除

// 创建任务
INT8U OSTaskCreate(
    void (*task)(void *),  // 任务函数指针
    void *pdata,           // 传递给任务的参数
    OS_STK *ptos,          // 任务栈顶指针
    INT8U prio             // 任务优先级
);

// 删除任务
INT8U OSTaskDel(INT8U prio);     // 删除指定优先级的任务
INT8U OSTaskDelReq(INT8U prio);  // 请求其他任务删除自己

挂起与恢复

// 挂起任务(暂停执行)
INT8U OSTaskSuspend(INT8U prio);

// 恢复被挂起的任务
INT8U OSTaskResume(INT8U prio);

延时

// 延时指定时钟节拍数
void OSTimeDly(INT32U ticks);

// 精确延时(时、分、秒)
void OSTimeDlyHMSM(INT8U hours, INT8U minutes, 
                   INT8U seconds, INT16U ms);

优先级修改

// 动态修改任务优先级
INT8U OSTaskChangePrio(INT8U oldprio, INT8U newprio);

6. 任务状态

uC/OS-II中任务有5种状态:

stateDiagram-v2
    [*] --> Dormant: Task Created
    Dormant --> Ready: OSTaskCreate
    Ready --> Running: Scheduler Dispatch
    Running --> Ready: Preempted by higher priority
    Running --> Waiting: OSTimeDly or Event Wait
    Waiting --> Ready: Delay expires or Event occurs
    Running --> Suspended: OSTaskSuspend
    Suspended --> Ready: OSTaskResume
    Running --> Dormant: OSTaskDel

    Dormant --> [*]: Deleted
状态 说明 进入条件
Dormant(休眠) 任务代码存在内存中但未被调度器管理 OSTaskDel后
Ready(就绪) 任务准备好运行,等待CPU 创建后、事件到达后
Running(运行) 任务正在使用CPU执行 被调度器选中
Waiting(等待) 任务等待某个事件(延时、信号量等) 调用延时或等待函数
Suspended(挂起) 任务被显式挂起,不再参与调度 调用OSTaskSuspend

[!question] Ready和Waiting有什么区别? Ready状态的任务随时可以运行,只等调度器分配CPU;Waiting状态的任务即使给它CPU也无法运行,因为它在等待某个外部事件(如延时到期、信号量释放等)。

7. 任务优先级分配原则

  • 每个任务必须有唯一的优先级(uC/OS-II中不允许同优先级任务)
  • 数值越小,优先级越高(0最高,63最低)
  • 关键任务分配高优先级:如安全检测、紧急控制
  • 不同优先级之间可以抢占
  • 相同优先级的处理:在uC/OS-II中不支持,但在FreeRTOS中支持时间片轮转

分配策略示例:

任务 优先级 理由
安全监控 0-2 最高优先级,必须立即响应
电机控制 3-5 实时性要求高
传感器采集 6-10 周期性任务
通信处理 11-15 重要但允许一定延迟
UI显示 20-30 实时性要求低

8. 嵌入式Linux

嵌入式Linux基于标准Linux内核进行裁剪和定制:

  • 开源免费:遵循GPL协议
  • 功能丰富:网络协议栈、文件系统、设备驱动完善
  • 非严格意义上的RTOS:Linux本身不是实时内核,但通过PREEMPT_RT补丁可以实现软实时
  • 适合场景:需要复杂网络功能、多媒体处理的嵌入式设备

与RTOS的对比:

比较维度 嵌入式Linux RTOS (uC/OS-II)
实时性 软实时(非严格) 硬实时
内核大小 MB级 KB级
开源 是 否(商业)
功能 丰富 精简
适用场景 复杂嵌入式设备 资源受限的实时系统

9. WinCE

Windows CE(简称WinCE)是微软推出的嵌入式操作系统:

  • 非开源,商业授权
  • 提供完整的GUI和开发工具(Visual Studio集成)
  • 适合需要Windows风格界面的手持设备
  • 已逐渐被Windows IoT Core取代

[!question] 在资源极度受限的MCU(如Cortex-M0, 2KB RAM)上,应该选择什么OS? 这种情况下应该选择轻量级RTOS如FreeRTOS或直接裸机编程。嵌入式Linux至少需要几MB内存,uC/OS-II虽然裁剪后很小但也需要几十KB,而FreeRTOS最小仅需几百字节RAM。

关联笔记