一、LiteOS概述与定位
华为LiteOS是华为面向物联网(IoT)领域构建的轻量级实时操作系统(RTOS),于2015年5月在华为网络大会上正式发布并开源。作为华为"1+8+N"全场景智慧生活战略中覆盖轻量设备的核心基础设施,LiteOS致力于为资源受限的IoT设备提供"小体积、低功耗、高实时性"的操作系统解决方案。
LiteOS的核心设计理念可以概括为四个关键词:
- 轻量:基础内核体积可裁剪至不到10KB,RAM占用最低仅需几KB,适配极度资源受限的MCU设备;
- 实时:采用优先级抢占式调度,微秒级中断响应,满足硬实时应用需求;
- 低功耗:支持Tickless机制和多种休眠唤醒模式,配合芯片整体功耗可低至μA级;
- 可裁剪:模块化设计,支持功能静态裁剪,开发者可按需组合组件。
LiteOS广泛应用于智能家居、个人穿戴、车联网、城市公共服务、制造业等领域,已聚合50+MCU和解决方案合作伙伴,涵盖抄表、停车、路灯、环保、共享单车、物流等众多行业场景。
目前LiteOS演进为两个子内核:LiteOS-M(面向MCU资源受限设备,如Cortex-M系列,内核最小可至6KB)和LiteOS-A(面向资源较丰富设备,如Cortex-A系列,支持MMU和进程隔离)。两者均已融入OpenHarmony生态体系。
二、核心架构解析
2.1 分层架构总览
LiteOS采用经典的分层架构设计,自底向上分为硬件抽象层、内核层、组件层和应用接口层:
硬件抽象层(HAL):屏蔽底层硬件差异,适配ARM Cortex-M0/M3/M4/M7、Cortex-A7/A9/A53、ARM64及RISC-V等多种CPU架构,提供统一的硬件访问接口,包括中断控制器(如GIC)、时钟管理、MMU/MPU等。
内核层:LiteOS的核心,提供操作系统最基本的服务:
- 基础内核(不可裁剪):任务管理、内存管理、中断管理、异常管理、系统时钟;
- 可裁剪模块:信号量、互斥锁、消息队列、事件标志、软件定时器等IPC与同步机制。
组件层:在内核基础上构建的扩展能力,包括:
- 扩展内核:C++支持、调测组件(Shell命令、Trace事件跟踪、CPU占用率统计、LMS内存检测等);
- 文件系统:VFS虚拟文件系统、ramfs、fatfs、littlefs等;
- 网络协议栈:LwIP、CoAP/LwM2M、MQTT、DTLS等物联网通信协议;
- 业务组件:OTA升级、GUI框架、AI推理、传感框架等。
应用接口层:提供标准C库、POSIX接口和CMSIS适配层,确保良好的可移植性和兼容性。
2.2 代码入口与启动流程
LiteOS的启动流程简洁高效,入口在工程的main.c中:
INT32 main(VOID)
{
// 1. 硬件初始化
HardwareInit();
// 2. 打印版本信息
PRINT_RELEASE("\n********Hello Huawei LiteOS********\n"
"\nLiteOS Kernel Version : %s\n"
"build data : %s %s\n\n"
"**********************************\n",
HW_LITEOS_KERNEL_VERSION_STRING, __DATE__, __TIME__);
// 3. 内核初始化(含创建用户任务)
UINT32 ret = OsMain();
if (ret != LOS_OK) {
return LOS_NOK;
}
// 4. 启动任务调度
OsStart();
return 0;
}
启动顺序为:硬件初始化 → 内核初始化 → 创建用户任务(app_init)→ 启动调度器,系统进入正常运行。
三、关键技术特性深度剖析
3.1 轻量级内核
LiteOS最引人注目的特性是其极致的轻量化。基础内核体积可裁剪至不到10KB,RAM占用最低仅需2KB。这一成就得益于以下设计:
- 模块化裁剪:所有可选功能(信号量、互斥锁、队列、事件、定时器等)均可通过宏配置裁剪,只保留系统运行所必需的最小内核;
- 精简数据结构:任务控制块(TCB)、内存池控制块等核心数据结构经过精心优化,减少内存占用;
- 零拷贝设计:消息队列等IPC机制采用零拷贝传输,减少内存拷贝开销。
3.2 任务调度机制
LiteOS采用优先级抢占式调度算法,支持0~31共32个优先级(数值越小优先级越高),同时支持相同优先级任务的时间片轮转(RR)调度。
任务调度的核心数据结构是任务控制块(TCB):
typedef struct {
UINT16 taskStatus; // 任务状态
UINT16 priority; // 任务优先级
UINT32 stackSize; // 栈大小
UINTPTR topOfStack; // 栈顶指针
UINTPTR taskEntry; // 任务入口函数
VOID *taskSem; // 任务持有的信号量
VOID *taskMux; // 任务持有的互斥锁
UINT32 taskID; // 任务ID
CHAR taskName[OS_TCB_NAME_LEN]; // 任务名称
TSK_ENTRY_FUNC pfnTaskEntry; // 任务入口函数指针
UINT32 uwArg; // 任务参数
} LosTaskCB;
任务在三种核心状态间切换:就绪(Ready)、运行(Running)、阻塞(Blocked)。调度器始终选择就绪队列中优先级最高的任务投入运行;当高优先级任务就绪时,当前低优先级任务会被立即抢占。
3.3 内存管理
LiteOS提供两种内存管理方式,适配不同应用场景:
动态内存管理:采用TLSF(Two-Level Segregate Fit)算法,专为实时系统设计,分配时间复杂度为O(1),碎片少。内存池控制块结构:
struct OsMemPoolHead {
struct OsMemPoolInfo info;
UINT32 freeListBitmap[OS_MEM_BITMAP_WORDS]; // 空闲链表位图
struct OsMemFreeNodeHead *freeList[OS_MEM_FREE_LIST_COUNT]; // 空闲链表数组
SPIN_LOCK_S spinlock; // 自旋锁
};
静态内存管理:初始化时预设固定大小的内存块,分配和释放效率极高,无内存碎片,适合对实时性和确定性要求极高的场景。
核心API:
| API | 功能 |
|---|---|
LOS_MemInit | 初始化内存池 |
LOS_MemAlloc | 分配动态内存 |
LOS_MemFree | 释放内存 |
LOS_MemRealloc | 重新分配内存 |
LOS_MemAllocAlign | 按对齐边界分配内存 |
3.4 任务间通信(IPC)
LiteOS提供丰富的IPC机制,满足不同同步与通信需求:
信号量(Semaphore):用于任务间同步和资源计数,支持二值信号量和计数信号量。
互斥锁(Mutex):用于保护共享资源的互斥访问,支持优先级继承协议以防止优先级反转。
消息队列(Queue):支持任务间异步消息传递,可配置队列长度和消息大小,采用FIFO顺序。
事件标志(Event):提供位级同步能力,一个任务可同时等待多个事件,支持"与"和"或"两种触发模式。
3.5 定时器与中断管理
软件定时器:支持单次触发(LOS_SWTMR_MODE_ONCE)和周期触发(LOS_SWTMR_MODE_PERIOD)两种模式,基于系统Tick驱动,通过排序链表管理所有定时任务。
中断管理:LiteOS将中断分为硬件中断和软件中断,硬件中断直接由CPU响应,软件中断通过系统Tick触发。中断处理采用"中断上半部+下半部"机制,上半部快速响应硬件事件,下半部延迟处理耗时操作,确保系统的实时性。
Tickless机制:系统空闲时停止周期性时钟中断,动态计算下一个最近到期时间,减少CPU唤醒次数,显著降低功耗。
3.6 电源管理
LiteOS的电源管理框架提供多级电源状态支持:
- 运行态:CPU全速运行;
- 空闲态:CPU进入WFI(Wait For Interrupt)低功耗模式;
- 深度睡眠:关闭CPU主时钟,保持RAM数据,通过外部中断唤醒;
- Tickless模式:动态调整系统Tick,空闲时关闭周期性中断,最大程度降低功耗。
四、LiteOS与鸿蒙生态的关系
LiteOS是鸿蒙(HarmonyOS/OpenHarmony)生态不可或缺的基石。在OpenHarmony的多内核架构中,LiteOS扮演轻量系统和小型系统的核心内核角色:
| 设备类别 | 内核 | RAM范围 | 代表设备 |
|---|---|---|---|
| 轻量系统 | LiteOS-M | 128KB+ | 传感器、智能穿戴 |
| 小型系统 | LiteOS-A | 1MB+ | 智能摄像头、家居中控 |
| 标准系统 | Linux | 128MB+ | 手机、平板、智慧屏 |
关键联系:
- 统一技术体系:LiteOS-M与LiteOS-A共享设计理念(低功耗框架),在API层通过CMSIS标准接口(如
osThreadNew)保持兼容性; - 生态整合:统一使用DevEco Studio开发工具链,支持ArkTS/JS语言开发;
- 端云协同:深度集成华为云IoT服务,支持设备接入、数据上报、远程控制;
- 分布式能力:作为鸿蒙分布式软总线的轻量端节点,支持设备发现与协同。
五、实战代码示例
以下示例基于LiteOS官方API,展示核心功能的完整使用方法。
5.1 任务创建与调度示例
#include "los_task.h"
#include "los_typedef.h"
#include <stdio.h>
// 任务1入口函数:高优先级任务
VOID Task1Entry(VOID)
{
while (1) {
printf("[Task1] 高优先级任务运行中, 采集传感器数据...\n");
LOS_TaskDelay(100); // 延时100个Tick,让出CPU
}
}
// 任务2入口函数:低优先级任务
VOID Task2Entry(VOID)
{
while (1) {
printf("[Task2] 低优先级任务运行中, 上报数据至云端...\n");
LOS_TaskDelay(200); // 延时200个Tick
}
}
UINT32 CreateTasks(VOID)
{
UINT32 ret;
UINT32 task1Id, task2Id;
TSK_INIT_PARAM_S task1Param = {0};
TSK_INIT_PARAM_S task2Param = {0};
// 配置任务1:优先级5(数值越小优先级越高)
task1Param.pfnTaskEntry = (TSK_ENTRY_FUNC)Task1Entry;
task1Param.pcName = "Task1_Sensor";
task1Param.uwStackSize = 1024;
task1Param.usTaskPrio = 5;
ret = LOS_TaskCreate(&task1Id, &task1Param);
if (ret != LOS_OK) {
printf("Task1创建失败! 错误码: 0x%x\n", ret);
return ret;
}
// 配置任务2:优先级10
task2Param.pfnTaskEntry = (TSK_ENTRY_FUNC)Task2Entry;
task2Param.pcName = "Task2_Report";
task2Param.uwStackSize = 1024;
task2Param.usTaskPrio = 10;
ret = LOS_TaskCreate(&task2Id, &task2Param);
if (ret != LOS_OK) {
printf("Task2创建失败! 错误码: 0x%x\n", ret);
return ret;
}
printf("任务创建成功! Task1 ID=%u, Task2 ID=%u\n", task1Id, task2Id);
return LOS_OK;
}
5.2 信号量与互斥锁同步示例
#include "los_sem.h"
#include "los_mux.h"
#include "los_task.h"
#include <stdio.h>
// 全局信号量和互斥锁ID
UINT32 g_semId;
UINT32 g_muxId;
// 共享资源
UINT32 g_sharedData = 0;
// 生产者任务:使用信号量通知,互斥锁保护共享资源
VOID ProducerTask(VOID)
{
while (1) {
// 获取互斥锁,保护共享资源
LOS_MuxLock(g_muxId, LOS_WAIT_FOREVER);
g_sharedData++;
printf("[Producer] 生产数据: %u\n", g_sharedData);
LOS_MuxUnlock(g_muxId);
// 释放信号量,通知消费者
LOS_SemPost(g_semId);
LOS_TaskDelay(100);
}
}
// 消费者任务:等待信号量后读取数据
VOID ConsumerTask(VOID)
{
while (1) {
// 等待信号量(阻塞直到生产者通知)
LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
// 获取互斥锁,安全读取共享资源
LOS_MuxLock(g_muxId, LOS_WAIT_FOREVER);
printf("[Consumer] 消费数据: %u\n", g_sharedData);
LOS_MuxUnlock(g_muxId);
}
}
UINT32 CreateSyncDemo(VOID)
{
UINT32 ret;
// 创建二值信号量(初始计数为0)
ret = LOS_SemCreate(0, &g_semId);
if (ret != LOS_OK) {
printf("信号量创建失败! 错误码: 0x%x\n", ret);
return ret;
}
// 创建互斥锁
ret = LOS_MuxCreate(&g_muxId);
if (ret != LOS_OK) {
printf("互斥锁创建失败! 错误码: 0x%x\n", ret);
return ret;
}
// 创建生产者任务
TSK_INIT_PARAM_S prodParam = {0};
prodParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ProducerTask;
prodParam.pcName = "Producer";
prodParam.uwStackSize = 1024;
prodParam.usTaskPrio = 5;
UINT32 prodTaskId;
ret = LOS_TaskCreate(&prodTaskId, &prodParam);
// 创建消费者任务
TSK_INIT_PARAM_S consParam = {0};
consParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ConsumerTask;
consParam.pcName = "Consumer";
consParam.uwStackSize = 1024;
consParam.usTaskPrio = 6;
UINT32 consTaskId;
ret = LOS_TaskCreate(&consTaskId, &consParam);
return LOS_OK;
}
5.3 消息队列通信示例
#include "los_queue.h"
#include "los_task.h"
#include <stdio.h>
#include <string.h>
#define QUEUE_LEN 5 // 队列长度:最多5条消息
#define QUEUE_MSG_SIZE 64 // 每条消息最大64字节
UINT32 g_queueId;
// 发送任务:向队列写入消息
VOID SenderTask(VOID)
{
UINT32 ret;
CHAR msgBuf[QUEUE_MSG_SIZE];
UINT32 msgCount = 0;
while (1) {
// 构造消息
snprintf(msgBuf, QUEUE_MSG_SIZE, "消息#%u: 传感器温度=%.1f°C",
msgCount++, 25.0 + (msgCount % 10) * 0.5);
// 向队列写入消息(阻塞式写入,队列满时等待)
ret = LOS_QueueWrite(g_queueId, msgBuf, QUEUE_MSG_SIZE, LOS_WAIT_FOREVER);
if (ret != LOS_OK) {
printf("[Sender] 消息写入失败! 错误码: 0x%x\n", ret);
} else {
printf("[Sender] 已发送: %s\n", msgBuf);
}
LOS_TaskDelay(200);
}
}
// 接收任务:从队列读取消息
VOID ReceiverTask(VOID)
{
UINT32 ret;
CHAR msgBuf[QUEUE_MSG_SIZE];
UINT32 readLen;
while (1) {
readLen = QUEUE_MSG_SIZE;
// 从队列读取消息(阻塞式读取,队列空时等待)
ret = LOS_QueueRead(g_queueId, msgBuf, readLen, LOS_WAIT_FOREVER);
if (ret != LOS_OK) {
printf("[Receiver] 消息读取失败! 错误码: 0x%x\n", ret);
} else {
printf("[Receiver] 已收到: %s\n", msgBuf);
}
}
}
UINT32 CreateQueueDemo(VOID)
{
UINT32 ret;
// 创建消息队列
ret = LOS_QueueCreate("MsgQueue", QUEUE_LEN, &g_queueId, 0, QUEUE_MSG_SIZE);
if (ret != LOS_OK) {
printf("消息队列创建失败! 错误码: 0x%x\n", ret);
return ret;
}
// 创建发送任务
TSK_INIT_PARAM_S sendParam = {0};
sendParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SenderTask;
sendParam.pcName = "Sender";
sendParam.uwStackSize = 1024;
sendParam.usTaskPrio = 5;
UINT32 sendTaskId;
LOS_TaskCreate(&sendTaskId, &sendParam);
// 创建接收任务
TSK_INIT_PARAM_S recvParam = {0};
recvParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ReceiverTask;
recvParam.pcName = "Receiver";
recvParam.uwStackSize = 1024;
recvParam.usTaskPrio = 6;
UINT32 recvTaskId;
LOS_TaskCreate(&recvTaskId, &recvParam);
return LOS_OK;
}
5.4 定时器与事件标志综合示例
#include "los_swtmr.h"
#include "los_event.h"
#include "los_task.h"
#include <stdio.h>
#define EVENT_SENSOR_READY 0x01 // 事件位0:传感器就绪
#define EVENT_DATA_VALID 0x02 // 事件位1:数据有效
#define EVENT_TIMEOUT 0x04 // 事件位2:超时
UINT32 g_swtmrId; // 软件定时器ID
EVENT_CB_S g_eventCb; // 事件控制块
// 定时器回调函数(周期触发)
VOID TimerCallback(UINT32 arg)
{
printf("[Timer] 周期定时器触发, arg=%u\n", arg);
// 写入事件标志,通知等待任务
LOS_EventWrite(&g_eventCb, EVENT_TIMEOUT);
}
// 等待任务:监听多个事件
VOID EventWaitTask(VOID)
{
UINT32 ret;
UINT32 event;
while (1) {
// 等待任意一个事件发生(LOS_EVTWAIT_OR模式)
ret = LOS_EventRead(&g_eventCb,
EVENT_SENSOR_READY | EVENT_DATA_VALID | EVENT_TIMEOUT,
LOS_WAITMODE_OR | LOS_WAITMODE_CLR,
LOS_WAIT_FOREVER);
if (ret & EVENT_TIMEOUT) {
printf("[EventWaitTask] 收到超时事件, 执行定时采集...\n");
}
if (ret & EVENT_SENSOR_READY) {
printf("[EventWaitTask] 传感器就绪, 开始读取数据...\n");
}
if (ret & EVENT_DATA_VALID) {
printf("[EventWaitTask] 数据有效, 执行业务处理...\n");
}
}
}
UINT32 CreateTimerEventDemo(VOID)
{
UINT32 ret;
// 初始化事件控制块
ret = LOS_EventInit(&g_eventCb);
if (ret != LOS_OK) {
printf("事件初始化失败! 错误码: 0x%x\n", ret);
return ret;
}
// 创建周期软件定时器(每500个Tick触发一次)
ret = LOS_SwtmrCreate(500, LOS_SWTMR_MODE_PERIOD,
(SWTMR_PROC_FUNC)TimerCallback,
&g_swtmrId, 0);
if (ret != LOS_OK) {
printf("定时器创建失败! 错误码: 0x%x\n", ret);
return ret;
}
// 启动定时器
ret = LOS_SwtmrStart(g_swtmrId);
if (ret != LOS_OK) {
printf("定时器启动失败! 错误码: 0x%x\n", ret);
return ret;
}
// 创建事件等待任务
TSK_INIT_PARAM_S taskParam = {0};
taskParam.pfnTaskEntry = (TSK_ENTRY_FUNC)EventWaitTask;
taskParam.pcName = "EventWaitTask";
taskParam.uwStackSize = 1024;
taskParam.usTaskPrio = 5;
UINT32 taskId;
ret = LOS_TaskCreate(&taskId, &taskParam);
// 模拟:3秒后触发传感器就绪事件
LOS_TaskDelay(300);
LOS_EventWrite(&g_eventCb, EVENT_SENSOR_READY);
return LOS_OK;
}
六、LiteOS-M与LiteOS-A对比
| 特性 | LiteOS-M | LiteOS-A |
|---|---|---|
| 目标平台 | MCU / 资源受限设备 | 应用处理器 / 资源丰富设备 |
| 内核大小 | 最小6KB | 几百KB |
| RAM需求 | 低至2KB | 1MB+ |
| 内存管理 | 静态内存池 | TLSF动态分配 + MMU虚拟内存 |
| 进程模型 | 单进程多任务 | 多进程多任务(进程隔离) |
| 任务调度 | 优先级抢占式 | 优先级抢占式 + 公平调度 + SMP |
| 文件系统 | 简化版 | 完整VFS(虚拟文件系统) |
| 网络协议栈 | 轻量级协议栈 | 完整TCP/IP协议栈 |
| 安全机制 | 基本安全(MPU保护) | 完整安全框架(权限控制、安全启动) |
七、总结与适用场景
华为LiteOS作为一款专为物联网设计的轻量级实时操作系统,在"小而精"的核心理念下实现了令人印象深刻的技术平衡:10KB级的内核体积、微秒级的实时响应、μA级的超低功耗,同时保留了完整的任务管理、内存管理、IPC通信、定时器等RTOS核心能力。
最佳适用场景:
- 智能传感器节点:温湿度传感器、光照传感器、气体检测器等资源极度受限的终端设备;
- 可穿戴设备:智能手环、健康监测贴片等电池供电、对功耗敏感的设备;
- 智慧城市基础设施:智能路灯、智能停车、环境监测等大规模部署的城域IoT终端;
- 工业物联网:工业传感器、远程RTU、设备状态监测等对实时性和可靠性有严格要求的场景;
- 智能家居单品:智能门锁、智能开关、烟雾报警器等需要快速响应的家居设备。
选型建议:当设备RAM在128KB~1MB范围、功能相对单一、对功耗和实时性有明确要求时,LiteOS-M是理想之选;当设备RAM在1MB以上、需要运行复杂应用或文件系统时,LiteOS-A更为合适;而对于鸿蒙生态开发者,LiteOS作为OpenHarmony轻量系统的内核,配合DevEco Studio可提供"一站式"开发体验。

8047

被折叠的 条评论
为什么被折叠?



