实时操作系统与 POSIX 层
本页介绍 AC79NN SDK 的运行时基础:底层 FreeRTOS 内核、杰理自研的 os_api 抽象接口层,以及 Amazon FreeRTOS-Plus-POSIX 兼容层(pthread / mqueue / semaphore 等),说明它们的分层关系、核心 API、配置开关与典型用法。
Purpose and Scope
本页覆盖 SDK 中与"实时操作系统(RTOS)与 POSIX 层"相关的全部基础设施:
- 底层 RTOS 内核(FreeRTOS)的定位与接入方式;
- 杰理
os_api抽象层(任务、信号量、互斥量、消息队列、消息邮箱等)的设计意图与核心接口; - FreeRTOS-Plus-POSIX 兼容层(
FreeRTOS_POSIX.h、pthread、mqueue)如何让标准 POSIX 程序直接运行; - 系统初始化与调度启动流程(
os_init/os_init_tick/os_start); - 相关配置开关(
os_cfg.h)与测试示例(os_api/pthreads_api用例)。
以下内容属于其他页面,不在本页展开:设备驱动与中断(见驱动相关页面)、内存管理/堆分配策略、具体的电源管理流程。本页聚焦于"任务/同步/通信原语"这一运行时的核心机制。
Overview
AC79NN SDK 是一个典型的嵌入式 AIoT 单芯片 SDK,片上同时运行音频、蓝牙、网络协议栈与应用逻辑,因此需要抢占式多任务实时操作系统来保证时延与确定性。整个运行时自底向上分为三层:
- 内核层:FreeRTOS 提供抢占式调度、tick 时钟、任务状态机与内核对象(信号量、队列、事件组)。SDK 中通过
FreeRTOS/FreeRTOS.h、event_groups.h、semphr.h等头文件接入。 - 抽象层:杰理自研的
os_api.h将内核能力包装成一套稳定、精简、与具体内核解耦的 C 接口(os_task_create、os_sem_*、os_mutex_*、os_q_*、os_taskq_*等)。SDK 内绝大多数业务模块(音频、蓝牙、网络)都通过这一层使用操作系统,而不是直接调用 FreeRTOS,从而保持可移植性。 - 兼容层:
include_lib/system/os/POSIX/FreeRTOS-Plus-POSIX/下的 Amazon FreeRTOS POSIX V1.1.0 移植,提供pthread_*、mq_*、POSIX semaphore、timer 等标准接口,使第三方/标准 POSIX 代码(如 lwIP、mDNS、benchmark)无需修改即可编译运行。
这种"内核 + 私有抽象 + POSIX 兼容"的三层结构是设计意图的核心:私有 os_api 保证杰理 SDK 内部代码的长期稳定与最小化开销;POSIX 层保证开源第三方代码的可移植性;两者共享同一个 FreeRTOS 内核调度器,互不冲突。
Architecture
flowchart TD
subgraph sg_App["应用层 Application"]
App["音频/蓝牙/网络/用户应用"]
Example["os_api 示例<br/>pthreads_api 示例"]
end
subgraph sg_API["系统调用层 API Layer"]
OSAPI["杰理 os_api 抽象层<br/>os_api.h / os_cfg.h"]
POSIX["FreeRTOS-Plus-POSIX<br/>FreeRTOS_POSIX.h"]
PThread["pthread / mqueue / sem / timer"]
end
subgraph sg_Kernel["内核层 FreeRTOS Kernel"]
Sched["任务调度器 Task Scheduler"]
Sync["信号量 semphr.h"]
Queue["队列 queue.h"]
Event["事件组 event_groups.h"]
Tick["Tick 时钟"]
end
subgraph sg_HW["硬件层 Hardware"]
CPU["AC79NN CPU 核"]
Timer["硬件定时器"]
end
App --> OSAPI
Example --> OSAPI
Example --> POSIX
POSIX --> PThread
App --> PThread
PThread --> Sched
OSAPI --> Sched
OSAPI --> Sync
OSAPI --> Queue
OSAPI --> Event
Sched --> Tick
Sync --> Tick
Queue --> Tick
Tick --> Timer
Sched --> CPU
分层职责说明:
- 应用层通过两种入口访问操作系统:SDK 业务代码走
os_api(如os_task_create),第三方/标准代码走 POSIX(如pthread_create)。两者在示例工程中并存,例如apps/common/example/system/os/pthreads_api/main.c同时调用pthread_*与os_time_dly。 os_api层是杰理 SDK 事实上的"系统调用"边界,接口签名稳定、不随 FreeRTOS 版本变化,且大多可直接映射到内核对象(任务→TCB、信号量→semphr、队列→queue)。- POSIX 层(Amazon FreeRTOS POSIX V1.1.0)以
FreeRTOS_POSIX.h为统一入口头文件,必须先于其他 POSIX 头文件包含(见 FreeRTOS_POSIX.h),它依次引入 portable 配置、FreeRTOS 内核头文件与内部数据结构。 - 内核层提供真正的调度与同步原语,所有上层接口最终都落到 FreeRTOS 的
task、semphr、queue、event_groups上。
核心机制:os_api 抽象层
设计意图
os_api.h 位于 include_lib/system/os/,是杰理 SDK 对操作系统能力的统一封装边界。它只依赖三个基础头文件:generic/typedef.h(基本类型)、os/os_cpu.h(CPU/临界区)、os/os_error.h(错误码)、os/os_type.h(类型定义),并通过 extern "C" 保证 C/C++ 混编安全:
#include "generic/typedef.h"
#include "os/os_cpu.h"
#include "os/os_error.h"
#include "os/os_type.h"
来源:os_api.h
这种"只依赖自包含类型头、不暴露内核头文件"的设计,使得上层模块在编译期与 FreeRTOS 完全解耦——更换内核(例如替换为其他 RTOS)时,只需重写 os_api 的实现,业务代码零改动。
任务消息类型:消息队列的分类体系
os_api 将投递到任务消息队列的消息按语义划分为四类,高位作为类型标志:
#define Q_MSG 0x100000 /*!< 普通消息 */
#define Q_EVENT 0x200000 /*!< 事件消息 */
#define Q_CALLBACK 0x300000 /*!< 回调消息 */
#define Q_USER 0x400000 /*!< 用户消息 */
来源:os_api.h
设计意图:不同语义的消息用同一个队列承载,接收端可以按类型位(与 Q_MSG 等掩码相与)快速分流处理。Q_CALLBACK 常被用于把"函数指针 + 参数"打包投递到指定任务上下文执行,避免跨任务直接调用带来的竞态。
任务创建:动态与静态两种栈
os_api 提供两种任务创建接口,签名一致,区别在于任务控制块(TCB)+ 任务栈 + 消息队列内存的来源:
int os_task_create(void (*func)(void *parm),
void *parm,
u8 prio,
u32 stk_size,
int q_size,
const char *name);
int os_task_create_static(void (*func)(void *parm),
void *parm,
u8 prio,
u32 stk_size,
int q_size,
const char *name,
u8 *tcb_stk_q);
来源:os_api.h
要点解读:
prio为优先级,stk_size与q_size均以 4 字节(一个字)为单位——这是嵌入式场景常见的约定,需要换算成字节时必须乘 4。os_task_create由内核从堆中动态分配三块内存;os_task_create_static由调用者传入一块tcb_stk_q静态内存块(包含 TCB 空间 + 栈空间 + 队列空间),用于系统启动早期堆尚未就绪、或对确定性要求极高的关键任务。- 每个任务自带一个消息队列(
q_size),配合os_taskq_post/__os_taskq_post使用——这是杰理 SDK 任务间通信的主要范式(见下文"核心流程")。
任务归属与删除标志
#define OS_TASK_DEL_REQ 0x01u /*!< 删除请求 */
#define OS_TASK_DEL_RES 0x02u /*!< 删除响应 */
#define OS_TASK_DEL_OK 0x03u /*!< 删除完成 */
#define OS_TASK_SELF (const char *)0x1
#define OS_TASK_FATHER (const char *)0x2
来源:os_api.h
设计意图:嵌入式 RTOS 中"任务主动删除自己"或"父任务删除子任务"都存在资源释放时序问题(栈可能正在被使用)。OS_TASK_DEL_REQ/RES/OK 三态握手机制让删除变成请求-应答式协作流程:请求方发删除请求,目标任务在安全的调度点响应,确认 OS_TASK_DEL_OK 后才真正回收资源。OS_TASK_SELF / OS_TASK_FATHER 用于指定删除目标为"当前任务"或"父任务"。
初始化与启动流程
os_api 暴露三个启动阶段接口:
void os_init(void); // 初始化操作系统
void os_init_tick(int); // 初始化时钟节拍
void os_start(void); // 开始调度
来源:os_api.h
典型启动序列为:os_init() 建立内核对象 → os_init_tick(tick_rate) 配置 tick 周期 → 创建首个应用任务(通常用 os_task_create 静态/动态创建)→ os_start() 交出控制权,由 FreeRTOS 调度器接管,此后系统完全由 tick 驱动。
sequenceDiagram
participant B as Boot/启动代码
participant A as os_api 层
participant K as FreeRTOS 内核
participant T as 应用任务
B->>A: os_init()
A->>K: 初始化内核数据结构
B->>A: os_init_tick(rate)
A->>K: 配置 SysTick/硬件定时器
B->>A: os_task_create(func, parm, prio, stk, q, name)
A->>K: 分配 TCB+栈+队列,挂入就绪链表
B->>A: os_start()
A->>K: 启动调度器 (vTaskStartScheduler)
K-->>T: 首次上下文切换,进入 func(parm)
T->>T: 运行业务逻辑
POSIX 兼容层:FreeRTOS-Plus-POSIX
统一入口头文件
POSIX 层的总入口是 FreeRTOS_POSIX.h(Amazon FreeRTOS POSIX V1.1.0 移植)。它按固定顺序引入平台配置、FreeRTOS 内核头与内部类型,因此所有 POSIX 源文件必须最先包含它:
#include "FreeRTOS_POSIX_portable.h"
#include "FreeRTOS_POSIX_portable_default.h"
#include "FreeRTOS/FreeRTOS.h"
#include "FreeRTOS/event_groups.h"
#include "FreeRTOS/semphr.h"
#include "FreeRTOS_POSIX/sys/types.h"
#include "FreeRTOS_POSIX_internal.h"
该层位于 include_lib/system/os/POSIX/FreeRTOS-Plus-POSIX/include/,配套 portable/ 下的 FreeRTOS_POSIX_portable.h / FreeRTOS_POSIX_portable_default.h 负责平台相关配置(如 pthread_t 与 FreeRTOS TaskHandle_t 的映射、超时转换宏),这是把标准 POSIX 语义(阻塞、超时、优先级)翻译到 FreeRTOS 原语的关键适配点。
提供的 POSIX 能力
- pthread:
pthread_create/pthread_mutex_*/pthread_exit/pthread_join等线程与互斥量接口,线程由 FreeRTOS 任务承载,pthread_t内部映射到TaskHandle_t。 - POSIX 消息队列:
mqd_t、mq_open/mq_send/mq_receive,底层映射到 FreeRTOS 队列。 - POSIX 信号量与定时器:semaphore 与 timer 接口。
SDK 中该层的主要消费者包括:apps/common/example/third_party/ 下的 coremark(core_portme_posix_overrides.h)、mDNS(lib/net/mdns/code/mDNSPosix.c)、lvgl 文件系统驱动(lv_fs_posix.c)等——它们以标准 POSIX 代码形式引入,通过兼容层直接运行在 FreeRTOS 之上。
核心流程:任务间消息通信
杰理 SDK 中任务间通信的典型范式是 os_taskq_post 消息投递:任意上下文(中断、其他任务、回调)向目标任务的消息队列投递消息,目标任务在自身的消息循环中取出并分发处理。__os_taskq_post 是底层实现入口,按任务名定位目标队列:
int __os_taskq_post(const char *name, int type, int argc, int *argv);
来源:os_api.h
flowchart TD
Sender["发送方<br/>中断/任务/回调"] -->|"os_taskq_post(name, type, argc, argv)"| Q{"目标任务<br/>队列是否已满?"}
Q -->|"否"| Enqueue["消息写入目标任务队列<br/>(Q_MSG/Q_EVENT/Q_CALLBACK/Q_USER)"]
Q -->|"是"| Ret["返回错误/阻塞等待"]
Enqueue --> Wake["唤醒目标任务 (调度器)"]
Wake --> Loop["目标任务消息循环<br/>os_taskq_accept 取出消息"]
Loop --> Type{"按 type 高位分流"}
Type -->|"Q_MSG"| HandleMsg["处理普通消息"]
Type -->|"Q_CALLBACK"| HandleCb["在任务上下文执行回调"]
Type -->|"Q_EVENT"| HandleEvt["处理事件"]
Type -->|"Q_USER"| HandleUser["处理用户自定义消息"]
设计意图:所有跨任务交互都收敛到"队列 + 消息循环",避免多任务直接共享变量带来的竞态;消息类型位让一个队列承载多种语义,接收端分流逻辑统一、扩展新消息类型只需新增一个类型位与分支。
核心流程:POSIX 线程互斥示例
SDK 自带 pthreads_api 示例工程(apps/common/example/system/os/pthreads_api/main.c),演示标准 POSIX 线程在 RTOS 上运行。其互斥锁测试的流程为:初始化 pthread_mutex_t → 创建两个线程 func1/func2 → 每个线程 pthread_mutex_lock 后逐字符打印字符串 → pthread_mutex_unlock 释放。两个线程竞争同一把锁,保证打印互不交错;线程创建后主流程即返回(pthread_join 被注释掉),体现嵌入式场景"创建后由调度器管理、不阻塞等待回收"的用法。
sequenceDiagram
participant M as main (posix_mutex_test)
participant P as POSIX 兼容层
participant K as FreeRTOS 内核
participant T1 as 线程 func1 (pthread_t p1)
participant T2 as 线程 func2 (pthread_t p2)
M->>P: pthread_mutex_init(&mutex, NULL)
M->>P: pthread_create(&p1, NULL, func1, str1)
P->>K: 创建任务,绑定函数指针
M->>P: pthread_create(&p2, NULL, func2, str2)
P->>K: 创建任务,绑定函数指针
K-->>T1: 调度 func1 运行
T1->>P: pthread_mutex_lock(&mutex)
P->>K: 获取内核互斥量
T1->>T1: 逐字符打印 (临界区)
K-->>T2: 调度 func2,尝试 lock 被阻塞
T1->>P: pthread_mutex_unlock(&mutex)
P->>K: 释放互斥量,唤醒 T2
K-->>T2: T2 获得锁,继续打印
Usage Examples
示例 1:创建动态任务(os_api 层)
从 os_api.h 的接口契约可直接看到任务的创建方式——指定入口函数、参数、优先级、栈大小(字为单位)、队列大小与任务名:
int os_task_create(void (*func)(void *parm),
void *parm,
u8 prio,
u32 stk_size,
int q_size,
const char *name);
来源:os_api.h
示例 2:POSIX 互斥锁测试(pthreads_api 示例)
static void posix_mutex_test(void)
{
char *str1 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *str2 = "abcdefghijklmnopqrstuvwxyz";
int err;
pthread_mutex_init(&mutex, NULL);
if ((err = pthread_create(&p1, NULL, func1, str1)) != 0) {
printf("[0]pthread_create fail\n");
}
if ((err = pthread_create(&p2, NULL, func2, str2)) != 0) {
printf("[1]pthread_create fail\n");
}
/* pthread_join(p1, NULL); */
/* pthread_join(p2, NULL); */
}
该示例同时印证了两个事实:POSIX pthread_* 接口在此 SDK 中真实可用;os_time_dly 等杰理 os_api 接口可与 POSIX 接口混用(示例文件第 16 行声明 extern void os_time_dly(int tick);)。
示例 3:POSIX 消息队列发送线程(pthreads_api 示例)
static mqd_t mqID;
//发送线程
static void *thread_send(void *args)
{
char msg[] = "This is a message for test!";
mqd_t *sendID = (mqd_t *)args;
while (1) {
if (mq_send(*sendID, msg, sizeof(msg), 0) < 0) {
printf("send msg err!\n");
//终止当前线程
pthread_exit(NULL);
}
os_time_dly(100);
}
return (void *)0;
}
要点:mq_send 失败(如队列满)时调用 pthread_exit(NULL) 终止自身线程,这是 POSIX 线程在出错路径上的标准退出方式;循环内用 os_time_dly(100) 节流,避免忙等耗尽 CPU——os_time_dly 的参数以 tick 为单位。
Configuration Options
RTOS 组件的裁剪配置集中在 include_lib/system/os/os_cfg.h。该头文件以宏开关控制各内核对象是否编译生成代码,关闭不需要的功能可减小 ROM/RAM 占用——这是嵌入式 SDK 典型的"按需裁剪"配置策略。
| 宏定义 | 类型 | 默认值 | 说明 |
|---|---|---|---|
OS_TASKQ_EN | int | 1 | 使能/关闭任务消息队列(QUEUES)代码生成 |
OS_TASKQ_ACCEPT_EN | int | 1 | 包含 OSTaskQAccept()(非阻塞取消息) |
OS_TASKQ_PEND_EN | int | 1 | 包含 OSTaskQPend()(阻塞取消息) |
OS_TASKQ_FLUSH_EN | int | 1 | 包含 OSTaskQFlush()(清空队列) |
OS_TASKQ_POST_EN | int | 1 | 包含 OSTaskQPost()(投递消息) |
OS_TASKQ_POST_FRONT_EN | int | 1 | 包含 OSTaskQPostFront()(队首投递,高优先级消息) |
OS_TASKQ_QUERY_EN | int | 1 | 包含 OSTaskQQuery()(查询队列状态) |
OS_SEM_EN | int | 1 | 使能/关闭信号量(SEMAPHORES)代码生成 |
OS_SEM_ACCEPT_EN | int | 1 | 包含 OSSemAccept()(非阻塞获取信号量) |
OS_SEM_DEL_EN | int | 1 | 包含 OSSemDel()(删除信号量) |
OS_SEM_QUERY_EN | int | 1 | 包含 OSSemQuery()(查询信号量计数) |
OS_SEM_SET_EN | int | 1 | 包含 OSSemSet()(重置信号量计数) |
来源:os_cfg.h
裁剪原则:产品固件若未用到任务队列或信号量,可将对应 *_EN 置 0 减小代码体积;示例/调试固件保持全部使能。注意 OS_TASKQ_* 与 OS_SEM_* 是两组独立开关,且每个能力还有子开关(*_ACCEPT_EN、*_POST_EN 等),可做到细粒度裁剪。
API Reference
以下列出 os_api 层最核心的接口(完整列表见 os_api.h)。
void os_init(void)
初始化操作系统。必须在任何其他 OS 调用之前、os_start() 之前调用一次。
void os_init_tick(int tick_rate)
初始化 OS 时钟节拍(tick)。tick_rate 决定调度时基粒度;配置错误会导致 os_time_dly、超时等待的实际时长与预期不符。
void os_start(void)
启动调度器。调用后控制权移交 RTOS,此函数不返回;所有应用任务应在调用前创建完毕。
int os_task_create(void (*func)(void *parm), void *parm, u8 prio, u32 stk_size, int q_size, const char *name)
创建动态任务(TCB + 栈 + 消息队列从堆分配)。
参数:
func:任务入口函数指针parm:传给入口函数的私有指针prio:任务优先级(数值约定见内核文档)stk_size:栈大小,以 4 字节为单位q_size:消息队列大小,以 4 字节为单位name:任务名字符串,用于调试与os_current_task()/os_taskq_post定位
返回: 0 成功;-1 失败(如内存不足)。
int os_task_create_static(void (*func)(void *parm), void *parm, u8 prio, u32 stk_size, int q_size, const char *name, u8 *tcb_stk_q)
创建静态任务。与 os_task_create 差异仅在最后一个参数:调用者必须提供一块足够容纳 TCB + 栈 + 队列的静态内存 tcb_stk_q。用于启动早期或确定性关键任务。
const char *os_current_task(void)
返回当前运行任务的名称。用于日志定位与断言,典型用法是打印"当前在哪个任务里"。
int __os_taskq_post(const char *name, int type, int argc, int *argv)
向名为 name 的任务消息队列投递一条消息。type 使用 Q_MSG/Q_EVENT/Q_CALLBACK/Q_USER 类型位(可叠加用户位),argc/argv 携带消息参数。上层通常封装为 os_taskq_post 宏/包装函数使用。
返回: 投递结果(0 成功;非 0 失败,如目标任务不存在或队列满)。
同步原语族(按 os_cfg.h 裁剪)
- 信号量:
os_sem_create/os_sem_post/os_sem_pend/os_sem_accept/os_sem_del/os_sem_set/os_sem_query(对应OSSem*,由OS_SEM_EN系列开关控制); - 互斥量:
os_mutex_create/os_mutex_pend/os_mutex_post等; - 队列:
os_q_create/os_q_send/os_q_post/os_q_pend等; - 删除标志:
OS_DEL_NO_PEND/OS_DEL_ALWAYS控制删除时是否强制等待(见 os_api.h 第 31-32 行)。
说明:由于
os_api为预编译库(include_lib),信号量/互斥量/队列的完整函数签名在头文件中的声明与上述任务接口同风格;具体实现在库中,本页以头文件声明的契约为准。
失败模式、边界情况与并发
任务删除的时序问题(thread_can_not_kill_test)
SDK 专门提供 apps/common/example/system/os/os_api/thread_can_not_kill_test.c 用例,验证"某些任务不可被杀"的场景。要点:任务正在持有锁、处于临界区或内核资源中时,强制删除会造成资源泄漏或死锁。os_api 的 OS_TASK_DEL_REQ/RES/OK 三态协议正是为了把删除变为协作式:任务必须在安全点确认响应,才能完成回收。业务代码应避免跨任务 free 对方栈/TCB 的行为,优先使用消息通知任务自行退出。
栈大小与队列大小不足
stk_size过小 → 栈溢出(FreeRTOS 支持栈高水位检查,但过浅会先踩坏相邻内存)。调试期应通过任务名(os_current_task)定位溢出任务。q_size过小 →os_taskq_post/mq_send返回失败。POSIX 示例中对mq_send失败调用pthread_exit退出线程(见上文示例 3),说明队列满在嵌入式场景是可预期的运行时错误,必须显式处理而非忽略。
优先级反转与互斥量
使用 pthread_mutex_* / os_mutex_* 时,若低优先级任务持有锁、高优先级任务等待,会出现优先级反转。FreeRTOS 的互斥量默认带优先级继承,但 POSIX 兼容层对 pthread_mutex 的映射行为取决于 FreeRTOS_POSIX_portable.h 的配置,需在移植配置中确认。高实时性路径建议直接使用 os_api 原语并遵循 SDK 既有优先级约定。
中断上下文约束
os_taskq_post 支持从中断上下文投递(队列机制天然支持),但所有阻塞型 pend 接口(os_sem_pend、os_q_pend、pthread_mutex_lock)禁止在中断上下文调用。os_api 提供 os_sem_accept / os_taskq_accept 等非阻塞变体(由 OS_SEM_ACCEPT_EN、OS_TASKQ_ACCEPT_EN 开关控制)供中断/高实时上下文使用。
并发一致性
- 多任务共享变量必须通过互斥量/临界区保护;消息队列是推荐的跨任务通信方式。
- 静态任务内存块(
tcb_stk_q)由调用者管理生命周期,任务未退出前不得释放或复用该内存。
性能与运维考量
- 裁剪开关:发布固件前按需关闭
os_cfg.h中未用到的功能(如OS_TASKQ_*、OS_SEM_*子开关),直接减少代码体积。 - 栈尺寸优化:
stk_size/q_size以 4 字节为单位,配置过大会浪费 SRAM;建议用内核栈水位统计校准到"峰值 + 安全余量"。 - tick 粒度:
os_init_tick的节拍直接决定os_time_dly的精度与调度开销,功耗敏感场景可降低 tick 频率,实时性敏感场景则需提高。 - 任务命名规范:
name参数贯穿调试(os_current_task)、消息投递(os_taskq_post)与日志,统一命名规范可显著降低多任务系统排障成本。
扩展点
- 更换/升级内核:业务代码只依赖
os_api.h,替换内核只需重新实现os_api库,接口契约(os_cfg.h宏、任务/信号量/队列语义)保持即可。 - POSIX 平台适配:
FreeRTOS_POSIX_portable.h/FreeRTOS_POSIX_portable_default.h是 FreeRTOS-Plus-POSIX 的平台适配点,涉及类型映射与超时换算,接入新芯片/新工具链时改这里。 - 新增消息类型:
Q_MSG/Q_EVENT/Q_CALLBACK/Q_USER的高位类型体系可扩展用户自定义位,在消息循环中新增分支即可。 - 静态内存策略:对确定性要求高的任务(音频、协议栈关键路径)使用
os_task_create_static,避免运行时堆分配失败。
测试
SDK 提供两类现成测试入口:
apps/common/example/system/os/os_api/:main.c(总入口)、mutex_test.c、sem_test.c、queue_test.c、static_task_test.c、thread_can_not_kill_test.c,覆盖任务创建(动态/静态)、互斥量、信号量、队列与任务删除边界;apps/common/example/system/os/pthreads_api/main.c:通过USE_PTHREAD_API_TEST宏使能,内含POSIX_MUTEX_TEST/POSIX_SEM_TEST/POSIX_QUEUE_TEST三种可切换用例,验证 POSIX 兼容层的互斥量、信号量与消息队列(mqd_t)。
这些用例同时充当"API 使用规范"的活文档:移植新平台后先跑通它们,可快速验证 RTOS 与 POSIX 层功能完整性。
Related Links
- os_api.h(核心接口声明)
- os_cfg.h(RTOS 裁剪配置)
- FreeRTOS_POSIX.h(POSIX 层统一入口)
- pthreads_api 示例
- os_api 测试示例目录
- 相关页面:系统初始化与启动流程、驱动与中断管理、内存管理(各页面按目录导航查看)