文章目录
-
- 每日一句正能量
- 一、引言:架构选型是嵌入式开发的第一性原理
- 二、固件架构演进史
-
- [2.1 从单片到系统的四十年](#2.1 从单片到系统的四十年)
- [2.2 演进的根本驱动力](#2.2 演进的根本驱动力)
- 三、三维决策矩阵
-
- [3.1 雷达图总览](#3.1 雷达图总览)
- [3.2 详细决策矩阵](#3.2 详细决策矩阵)
- 四、裸机架构深度解析
-
- [4.1 适用场景](#4.1 适用场景)
- [4.2 核心设计模式](#4.2 核心设计模式)
- [4.3 裸机的高级技巧](#4.3 裸机的高级技巧)
- [五、RTOS 架构深度解析](#五、RTOS 架构深度解析)
-
- [5.1 RTOS 选型对比](#5.1 RTOS 选型对比)
- [5.2 任务设计与调度](#5.2 任务设计与调度)
- [5.3 实时性保障技巧](#5.3 实时性保障技巧)
- [六、嵌入式 Linux 架构深度解析](#六、嵌入式 Linux 架构深度解析)
-
- [6.1 系统组成与启动流程](#6.1 系统组成与启动流程)
- [6.2 实时性增强:PREEMPT_RT](#6.2 实时性增强:PREEMPT_RT)
- 七、选型决策树
-
- [7.1 决策流程](#7.1 决策流程)
- [7.2 典型场景速查表](#7.2 典型场景速查表)
- 八、成本与复杂度量化分析
-
- [8.1 全生命周期成本](#8.1 全生命周期成本)
- [8.2 复杂度拐点理论](#8.2 复杂度拐点理论)
- 九、混合架构:异构多核方案
-
- [9.1 为何需要混合架构?](#9.1 为何需要混合架构?)
- [9.2 核间通信实现](#9.2 核间通信实现)
- [9.3 混合架构最佳实践](#9.3 混合架构最佳实践)
- 十、决策框架总结
-
- [10.1 选型检查清单](#10.1 选型检查清单)
- [10.2 最终建议](#10.2 最终建议)

每日一句正能量
热爱是明知普通仍不肯将就。
很多人因为觉得自己"普通"就放弃追求热爱的事物------比如普通人不配学画画、普通人不配写诗。但真正的热爱恰恰相反:我知道自己可能不会成名成家,甚至画得笨拙,但我依然愿意认真地做这件事,不糊弄、不妥协。这种"不肯将就"是对自己生命的尊重,也是抵抗虚无的方式。
一、引言:架构选型是嵌入式开发的第一性原理
在嵌入式项目启动时,团队面临的第一个重大决策往往不是"用什么芯片",而是"用什么架构"。这个选择将深刻影响后续的开发效率、系统性能、维护成本和商业成败。
一个典型的场景:某智能门锁项目,团队最初选择了嵌入式 Linux(因为"生态好"),结果启动时间 8 秒,功耗 2W,BOM 成本 ¥180------而竞品使用裸机方案,启动时间 200ms,功耗 0.1W,BOM 成本 ¥35。最终产品因续航和成本问题被迫回炉重造。
本文将从复杂度、实时性、成本三个核心维度,系统分析裸机(Bare Metal)、RTOS、嵌入式 Linux 三种架构的适用场景,并提供可落地的决策方法论。
二、固件架构演进史
2.1 从单片到系统的四十年

裸机时代(1980s-2000s):8051、AVR、PIC 等 8/16 位 MCU 主导市场。程序以轮询或中断方式运行,开发者直接操作寄存器,代码量通常小于 10KB。这一时期的嵌入式系统功能单一,一个芯片只做一件事。
RTOS 时代(2000s-2010s):ARM Cortex-M 系列崛起,FreeRTOS、RT-Thread、μC/OS 等实时操作系统普及。多任务调度、信号量、互斥锁等机制使复杂应用开发成为可能,代码量增长到 20-200KB。
Linux 时代(2010s-至今):物联网和边缘计算推动需求爆发。ARM Cortex-A 系列 + 嵌入式 Linux(Yocto、Buildroot)成为网关、智能终端的标准配置,支持完整的网络协议栈、文件系统和图形界面,代码量达到 2-50MB。
2.2 演进的根本驱动力
| 驱动力 | 裸机→RTOS | RTOS→Linux |
|---|---|---|
| 硬件性能 | MCU 主频从 8MHz 到 400MHz | 应用处理器从 200MHz 到 2GHz |
| 软件复杂度 | 功能点从 5 个到 50 个 | 功能点从 50 个到 500+ 个 |
| 网络需求 | 从串口到以太网/WiFi | 从 TCP/IP 到 5G/边缘 AI |
| 安全要求 | 从功能正确到功能安全(ISO 26262) | 从设备安全到系统安全(等保 2.0) |
| 开发效率 | 从汇编到 C 再到 C++ | 从手写代码到包管理 + 容器化 |
三、三维决策矩阵
3.1 雷达图总览

三种架构在六个维度的评分(0-10,10 为最佳):
| 维度 | 裸机 | RTOS | Linux | 说明 |
|---|---|---|---|---|
| 实时性 | 10 | 8 | 3 | 中断响应与调度确定性 |
| 资源占用 | 10 | 7 | 2 | Flash/RAM/CPU 开销 |
| 开发效率 | 3 | 6 | 9 | 代码复用与工具链完善度 |
| 功能丰富度 | 2 | 6 | 10 | 协议栈、文件系统、GUI |
| 硬件成本 | 10 | 7 | 3 | MCU/MPU 价格 |
| 维护难度 | 3 | 5 | 8 | 代码可读性与升级便利性 |
关键洞察:
- 裸机在实时性和资源占用上无可匹敌,但功能扩展能力极弱
- Linux 在开发效率和功能丰富度上碾压,但实时性和成本是硬伤
- RTOS 是"中间路线",在多数维度达到 6-8 分,适合平衡型项目
3.2 详细决策矩阵

四、裸机架构深度解析
4.1 适用场景
裸机架构适用于以下场景:
- 硬实时系统:响应时间要求 < 10μs(如电机控制、飞行控制)
- 极简资源:Flash < 32KB,RAM < 4KB(如遥控器、传感器节点)
- 安全关键:需要通过功能安全认证(ISO 26262 ASIL-D、IEC 61508 SIL 3)
- 超低功耗:纽扣电池供电,要求待机电流 < 1μA
4.2 核心设计模式
c
/* 模式1: 超级循环 (Super Loop) */
int main(void) {
HAL_Init();
system_init();
while (1) {
sensor_read(); /* 读取传感器 */
data_process(); /* 数据处理 */
control_output(); /* 控制输出 */
communication(); /* 通信处理 */
/* 简单的延时或睡眠 */
__WFI();
}
}
/* 模式2: 前后台系统 (中断 + 主循环) */
volatile uint8_t g_sensor_ready = 0;
volatile uint8_t g_uart_rx_flag = 0;
/* 中断服务程序 (前台) */
void TIM2_IRQHandler(void) {
if (TIM2->SR & TIM_SR_UIF) {
TIM2->SR &= ~TIM_SR_UIF;
g_sensor_ready = 1; /* 标记传感器数据就绪 */
}
}
void USART1_IRQHandler(void) {
if (USART1->SR & USART_SR_RXNE) {
g_rx_buffer[g_rx_head++] = USART1->DR;
g_uart_rx_flag = 1;
}
}
/* 主循环 (后台) */
int main(void) {
system_init();
while (1) {
if (g_sensor_ready) {
g_sensor_ready = 0;
process_sensor_data();
}
if (g_uart_rx_flag) {
g_uart_rx_flag = 0;
handle_uart_command();
}
__WFI(); /* 等待中断 */
}
}
/* 模式3: 状态机驱动 */
typedef enum {
STATE_IDLE,
STATE_CONNECTING,
STATE_CONNECTED,
STATE_ERROR
} system_state_t;
system_state_t g_state = STATE_IDLE;
void state_machine_run(event_t event) {
switch (g_state) {
case STATE_IDLE:
if (event == EVT_BUTTON_PRESS) {
wifi_connect();
g_state = STATE_CONNECTING;
}
break;
case STATE_CONNECTING:
if (event == EVT_WIFI_CONNECTED) {
mqtt_subscribe();
g_state = STATE_CONNECTED;
} else if (event == EVT_TIMEOUT) {
g_state = STATE_ERROR;
}
break;
case STATE_CONNECTED:
if (event == EVT_BUTTON_PRESS) {
wifi_disconnect();
g_state = STATE_IDLE;
}
break;
case STATE_ERROR:
error_handler();
g_state = STATE_IDLE;
break;
}
}
4.3 裸机的高级技巧
c
/* 技巧1: 函数指针表实现伪多任务 */
typedef void (*task_fn_t)(void);
typedef struct {
task_fn_t fn;
uint32_t period_ms;
uint32_t last_run;
uint8_t enabled;
} task_t;
static task_t g_tasks[] = {
{task_sensor, 10, 0, 1}, /* 100Hz */
{task_control, 20, 0, 1}, /* 50Hz */
{task_display, 100, 0, 1}, /* 10Hz */
{task_comm, 200, 0, 1}, /* 5Hz */
};
void scheduler_run(void) {
uint32_t now = get_tick_ms();
for (int i = 0; i < ARRAY_SIZE(g_tasks); i++) {
if (g_tasks[i].enabled && (now - g_tasks[i].last_run) >= g_tasks[i].period_ms) {
g_tasks[i].last_run = now;
g_tasks[i].fn();
}
}
}
/* 技巧2: 编译期计算减少运行时开销 */
#define CRC32_POLY 0xEDB88320
/* 编译期生成 CRC 查找表 */
static const uint32_t s_crc32_table[256] = {
#include \"crc32_table.inc\" /* 由脚本预生成 */
};
static inline uint32_t crc32_byte(uint32_t crc, uint8_t data) {
return (crc >> 8) ^ s_crc32_table[(crc ^ data) & 0xFF];
}
/* 技巧3: 内存池替代动态分配 */
#define POOL_BLOCK_SIZE 64
#define POOL_BLOCK_COUNT 32
static uint8_t s_pool[POOL_BLOCK_COUNT][POOL_BLOCK_SIZE];
static uint8_t s_pool_used[POOL_BLOCK_COUNT] = {0};
void *pool_alloc(void) {
for (int i = 0; i < POOL_BLOCK_COUNT; i++) {
if (!s_pool_used[i]) {
s_pool_used[i] = 1;
return s_pool[i];
}
}
return NULL; /* 无可用块 */
}
void pool_free(void *ptr) {
int idx = ((uint8_t *)ptr - (uint8_t *)s_pool) / POOL_BLOCK_SIZE;
if (idx >= 0 && idx < POOL_BLOCK_COUNT) {
s_pool_used[idx] = 0;
}
}
五、RTOS 架构深度解析
5.1 RTOS 选型对比
| RTOS | 许可证 | 代码量 | 特性 | 适用场景 |
|---|---|---|---|---|
| FreeRTOS | MIT | 4-9KB | 轻量、生态广、AWS 支持 | 通用嵌入式 |
| RT-Thread | Apache 2.0 | 8-20KB | 国产、组件丰富、POSIX 兼容 | 物联网设备 |
| Zephyr | Apache 2.0 | 15-30KB | 现代架构、安全认证、多平台 | 安全关键/IoT |
| ThreadX | MIT | 2-15KB | 微软支持、医疗/航空认证 | 高可靠性 |
| NuttX | Apache 2.0 | 20-50KB | 类 Linux、POSIX 完整 | 需要 Linux 兼容 |
| HarmonyOS LiteOS-M | Apache 2.0 | 10-20KB | 华为生态、分布式能力 | 鸿蒙生态设备 |
5.2 任务设计与调度
c
/* FreeRTOS 任务创建示例 */
#include \"FreeRTOS.h\"
#include \"task.h\"
#include \"queue.h\"
#include \"semphr.h\"
/* 任务优先级定义 */
#define PRIORITY_SENSOR (configMAX_PRIORITIES - 1) /* 最高: 传感器采集 */
#define PRIORITY_CONTROL (configMAX_PRIORITIES - 2) /* 控制算法 */
#define PRIORITY_COMM (configMAX_PRIORITIES - 3) /* 通信处理 */
#define PRIORITY_DISPLAY (configMAX_PRIORITIES - 4) /* 界面显示 */
#define PRIORITY_LOG (configMAX_PRIORITIES - 5) /* 最低: 日志 */
/* 任务句柄 */
static TaskHandle_t xSensorTask;
static TaskHandle_t xControlTask;
static TaskHandle_t xCommTask;
/* 同步原语 */
static QueueHandle_t xSensorQueue; /* 传感器数据队列 */
static SemaphoreHandle_t xControlSem; /* 控制信号量 */
static EventGroupHandle_t xSystemEvents;/* 系统事件组 */\
/* 传感器采集任务 */
static void vSensorTask(void *pvParameters) {
sensor_data_t data;
TickType_t xLastWakeTime = xTaskGetTickCount();
while (1) {
/* 周期性执行: 100Hz */
vTaskDelayUntil(&xLastWakeTime, pdMS_TO_TICKS(10));
/* 读取传感器 */
data.timestamp = xTaskGetTickCount();
data.temperature = adc_read_channel(0);
data.pressure = adc_read_channel(1);
/* 发送到队列 (非阻塞) */
xQueueSend(xSensorQueue, &data, 0);
/* 通知控制任务 */
xSemaphoreGive(xControlSem);
}
}
/* 控制算法任务 */
static void vControlTask(void *pvParameters) {
sensor_data_t data;
control_output_t output;
while (1) {
/* 等待传感器数据就绪 */
if (xSemaphoreTake(xControlSem, pdMS_TO_TICKS(100)) == pdTRUE) {
/* 从队列读取数据 */
if (xQueueReceive(xSensorQueue, &data, 0) == pdTRUE) {
/* 执行 PID 控制 */
output = pid_calculate(&g_pid, data.temperature, SETPOINT);
/* 输出到执行器 */
pwm_set_duty(output.pwm_duty);
}
} else {
/* 超时处理: 传感器故障 */
system_enter_safe_mode();
}
}
}
/* 通信任务 */
static void vCommTask(void *pvParameters) {
uint8_t rx_buffer[256];
while (1) {
/* 等待串口数据 */
size_t len = uart_receive(rx_buffer, sizeof(rx_buffer), pdMS_TO_TICKS(100));
if (len > 0) {
protocol_parse(rx_buffer, len);
}
/* 周期性发送状态 */
static TickType_t last_tx = 0;
if (xTaskGetTickCount() - last_tx >= pdMS_TO_TICKS(1000)) {
last_tx = xTaskGetTickCount();
send_status_packet();
}
}
}
/* 系统初始化 */
void system_init(void) {
/* 创建同步原语 */
xSensorQueue = xQueueCreate(10, sizeof(sensor_data_t));
xControlSem = xSemaphoreCreateBinary();\n xSystemEvents = xEventGroupCreate();
/* 创建任务 */
xTaskCreate(vSensorTask, \"Sensor\", 512, NULL, PRIORITY_SENSOR, &xSensorTask);
xTaskCreate(vControlTask, \"Control\", 1024, NULL, PRIORITY_CONTROL, &xControlTask);
xTaskCreate(vCommTask, \"Comm\", 1024, NULL, PRIORITY_COMM, &xCommTask);
/* 启动调度器 */
vTaskStartScheduler();
}
5.3 实时性保障技巧
c
/* 技巧1: 中断延迟测量与优化 */
volatile uint32_t g_max_irq_latency = 0;
void TIM_IRQHandler(void) {
uint32_t enter = DWT->CYCCNT; /* 进入中断时的时钟 */
/* 中断处理 */
handle_irq();
uint32_t exit = DWT->CYCCNT;
uint32_t latency = exit - enter;
if (latency > g_max_irq_latency) {
g_max_irq_latency = latency;
}
}
/* 技巧2: 优先级继承防止优先级反转 */
/* FreeRTOS 中互斥锁自动启用优先级继承 */
SemaphoreHandle_t xMutex = xSemaphoreCreateMutex();
void high_priority_task(void) {
if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
/* 访问共享资源 */
access_shared_resource();
xSemaphoreGive(xMutex);
}
}
/* 技巧3: 零拷贝队列减少内存复制 */
typedef struct {
uint8_t *data; /* 指向静态缓冲区的指针 */
uint16_t len; /* 数据长度 */
uint16_t buffer_id; /* 缓冲区ID,用于回收 */
} zero_copy_item_t;
static uint8_t s_buffer_pool[4][1024]; /* 4个缓冲区 */
static volatile uint8_t s_buffer_used[4] = {0};
QueueHandle_t xZeroCopyQueue;
/* 生产者 */
void producer(void) {
for (int i = 0; i < 4; i++) {
if (!s_buffer_used[i]) {
s_buffer_used[i] = 1;
uint16_t len = read_data(s_buffer_pool[i]);
zero_copy_item_t item = {
.data = s_buffer_pool[i],
.len = len,
.buffer_id = i
};
xQueueSend(xZeroCopyQueue, &item, portMAX_DELAY);
break;
}
}
}
/* 消费者 */
void consumer(void) {
zero_copy_item_t item;
if (xQueueReceive(xZeroCopyQueue, &item, portMAX_DELAY) == pdTRUE) {
process_data(item.data, item.len);
s_buffer_used[item.buffer_id] = 0; /* 释放缓冲区 */
}
}
六、嵌入式 Linux 架构深度解析
6.1 系统组成与启动流程
c
/* 嵌入式 Linux 系统层次 */
/*
* ┌─────────────────────────────────────┐
* │ 应用层: 业务应用 / 中间件 / 容器 │
* ├─────────────────────────────────────┤
* │ 库层: glibc / musl / 第三方库 │
* ├─────────────────────────────────────┤
* │ 系统调用接口 (System Call) │
* ├─────────────────────────────────────┤
* │ 内核层: 进程调度 / 内存管理 / VFS │
* │ 网络栈 / 设备驱动 │
* ├─────────────────────────────────────┤
* │ 硬件抽象层: BSP / Bootloader │
* └─────────────────────────────────────┘
*/
/* 启动时间优化策略 */
/*
* 标准启动: U-Boot (2s) → Kernel (3s) → systemd (5s) = 10s
* 优化目标: < 1s\n *
* 优化手段:
* 1. 使用 U-Boot Falcon Mode 跳过第二阶段
* 2. 内核裁剪: 只编译必要驱动 (从 8MB 到 2MB)
* 3. 使用 initramfs 替代根文件系统挂载
* 4. 替换 systemd 为 busybox init 或 custom init\
* 5. 延迟加载非关键驱动 (modprobe)
* 6. 使用 readahead 预加载关键文件
*/
/* 快速启动 init 示例 */
#include <stdio.h>
#include <unistd.h>
#include <sys/wait.h>
int main(int argc, char *argv[]) {
/* 挂载基本文件系统 */
mount(\"proc\", \"/proc\", \"proc\", 0, NULL);
mount(\"sysfs\", \"/sys\", \"sysfs\", 0, NULL);
mount(\"devtmpfs\", \"/dev\", \"devtmpfs\", 0, NULL);
/* 设置主机名 */
sethostname(\"embedded\", 8);
/* 启动关键服务 */
if (fork() == 0) {
execl(\"/sbin/udhcpc\", \"udhcpc\", \"-i\", \"eth0\", NULL);
}
/* 启动主应用 */
if (fork() == 0) {
/* 设置实时优先级 */
struct sched_param param = {.sched_priority = 80};
sched_setscheduler(0, SCHED_FIFO, ¶m);
execl(\"/app/main\", \"main\", NULL);
}
/* 等待子进程 */
while (1) {
int status;
pid_t pid = wait(&status);
if (pid > 0) {
printf(\"Process %d exited, restarting...\\n\", pid);
/* 重启逻辑 */
}
}
return 0;
}
6.2 实时性增强:PREEMPT_RT
c
/* Linux PREEMPT_RT 补丁使能硬实时 */
/* 配置内核: CONFIG_PREEMPT_RT=y */
/* 实时线程创建 */
#include <pthread.h>
#include <sched.h>
int create_realtime_thread(void *(*start_routine)(void *), int priority) {
pthread_t thread;
pthread_attr_t attr;
struct sched_param param;
pthread_attr_init(&attr);
/* 设置调度策略为 SCHED_FIFO */
pthread_attr_setschedpolicy(&attr, SCHED_FIFO);
/* 设置优先级 (1-99, 99 最高) */
param.sched_priority = priority;
pthread_attr_setschedparam(&attr, ¶m);
/* 继承父线程的调度属性 */
pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED);
/* 绑定到特定 CPU 核心 */
cpu_set_t cpuset;
CPU_ZERO(&cpuset);
CPU_SET(0, &cpuset); /* 绑定到 CPU0 */
pthread_attr_setaffinity_np(&attr, sizeof(cpuset), &cpuset);
int ret = pthread_create(&thread, &attr, start_routine, NULL);
pthread_attr_destroy(&attr);
return ret;
}
/* 实时性能测试 */
void *rt_task(void *arg) {
struct timespec ts;
uint64_t max_latency = 0;
uint64_t total_latency = 0;
int count = 0;
clock_gettime(CLOCK_MONOTONIC, &ts);
while (count < 100000) {
/* 等待下一个周期 */
ts.tv_nsec += 1000000; /* 1ms 周期 */
if (ts.tv_nsec >= 1000000000) {
ts.tv_sec++;
ts.tv_nsec -= 1000000000;
}
uint64_t before = get_time_ns();
clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL);
uint64_t after = get_time_ns();
uint64_t latency = after - (before + 1000000);
if (latency > max_latency) max_latency = latency;
total_latency += latency;
count++;
}
printf(\"RT Thread: avg=%lu ns, max=%lu ns\\n\",
total_latency / count, max_latency);
return NULL;
}
七、选型决策树
7.1 决策流程

7.2 典型场景速查表
| 场景 | 推荐架构 | 代表平台 | 关键理由 |
|---|---|---|---|
| 汽车 ECU (发动机/ABS) | 裸机/AutoSAR | Infineon TC3xx | 功能安全 ASIL-D |
| 工业伺服驱动 | 裸机 | STM32H7/G4 | 抖动 < 100ns |
| 智能手环 | 裸机/轻量RTOS | NRF52832 | 功耗 < 100μA |
| 智能家居网关 | RTOS/Linux | ESP32/RTL8720 | 多协议+成本平衡 |
| 安防摄像头 | Linux | Hi3516/RV1126 | AI推理+编码 |
| 车载信息娱乐 | Linux/QNX | i.MX8/RK3588 | 多媒体+功能安全 |
| 无人机飞控 | 裸机+RTOS双核 | STM32H7+Linux | 实时+视觉 |
八、成本与复杂度量化分析
8.1 全生命周期成本

成本构成分析:
| 成本项 | 裸机 | RTOS | Linux | 说明 |
|---|---|---|---|---|
| BOM 成本 | ¥0.5-5 | ¥5-30 | ¥30-200 | MCU vs MPU 价差 |
| 开发成本 | 中 | 中 | 高 | 学习曲线与调试时间 |
| 维护成本 | 高 | 中 | 低 | 代码可读性与社区支持 |
| 认证成本 | 低 | 中 | 高 | 安全认证复杂度 |
关键发现:
- 裸机 BOM 成本最低,但维护成本随功能增长指数上升
- Linux 初期投入高,但功能扩展的边际成本极低
- RTOS 在 15-30 个功能点的"甜蜜区"性价比最高
8.2 复杂度拐点理论
功能点 < 10: 裸机优势明显,复杂度可控
功能点 10-15: 裸机复杂度急剧上升,考虑 RTOS
功能点 15-30: RTOS 最佳区间,线性复杂度增长
功能点 30-50: RTOS 仍可行,但需精心设计
功能点 > 50: Linux 成为必然选择
九、混合架构:异构多核方案
9.1 为何需要混合架构?
单一架构往往无法同时满足实时性和功能丰富度的双重要求。异构多核处理器(如 i.MX RT1176、STM32MP1、RK3566)提供了"实时核 + 应用核"的解决方案。

9.2 核间通信实现
c
/* RPMsg 核间通信示例 (基于共享内存) */
#include \"rpmsg_lite.h\"
#define RPMSG_LITE_LINK_ID 0
#define EP_ADDR 1
struct rpmsg_lite_instance *rpmsg;
struct rpmsg_lite_endpoint *ep;
/* 初始化 RPMsg */
void ipc_init(void) {
rpmsg = rpmsg_lite_master_init(
(void *)RPMSG_LITE_SRTM_SHMEM_BASE, /* 共享内存基址 */
RPMSG_LITE_SRTM_SHMEM_SIZE, /* 共享内存大小 */
RPMSG_LITE_LINK_ID,
RL_NO_FLAGS
);
ep = rpmsg_lite_create_ept(rpmsg, EP_ADDR, ipc_endpoint_cb, NULL);
}
/* 端点回调 */
int32_t ipc_endpoint_cb(void *payload, uint32_t payload_len,
uint32_t src, void *priv) {
ipc_message_t *msg = (ipc_message_t *)payload;\
switch (msg->type) {
case IPC_SENSOR_DATA:
/* 实时核发送的传感器数据 */
process_sensor_data(&msg->data.sensor);
break;
case IPC_CONTROL_CMD:
/* 应用核发送的控制命令 */
send_to_realtime_core(msg);
break;
case IPC_LOG_MSG:
/* 实时核的日志 */
write_to_log_file(msg->data.log.text);
break;
}
return RL_SUCCESS;
}
/* 发送消息到对端 */
void ipc_send_sensor_data(sensor_data_t *data) {
ipc_message_t msg = {
.type = IPC_SENSOR_DATA,
.seq = g_seq++,
.timestamp = get_us_tick(),
};
memcpy(&msg.data.sensor, data, sizeof(sensor_data_t));
rpmsg_lite_send(rpmsg, ep, EP_ADDR, &msg, sizeof(msg), RL_DONT_BLOCK);
}
/* 共享内存数据结构 */
typedef struct {
uint32_t type; /* 消息类型 */
uint32_t seq; /* 序列号 */
uint64_t timestamp; /* 时间戳 */
union {
sensor_data_t sensor;
control_cmd_t control;
log_msg_t log;
} data;
} __attribute__((packed)) ipc_message_t;
9.3 混合架构最佳实践
c
/* 实时核 (Cortex-M): 硬实时任务 */
void realtime_core_main(void) {
/* 初始化电机控制 */
motor_init();
/* 初始化 RPMsg */
ipc_init();
/* 1000Hz 控制循环 */
while (1) {
uint32_t start = DWT->CYCCNT;
/* 读取编码器 */
int32_t position = encoder_read();
/* PID 计算 */
int32_t error = g_target - position;
int32_t output = pid_update(&g_pid, error);
/* 输出 PWM */
pwm_set(output);
/* 发送状态到应用核 (每 100 周期一次) */
static int count = 0;
if (++count >= 100) {
count = 0;
sensor_data_t data = {.position = position, .output = output};
ipc_send_sensor_data(&data);
}
/* 精确延时到下一个周期 */
uint32_t elapsed = (DWT->CYCCNT - start) / (SystemCoreClock / 1000000);
if (elapsed < 1000) { /* 1ms = 1000us */
delay_us(1000 - elapsed);
}
}
}
/* 应用核 (Cortex-A): 复杂业务处理 */
int app_core_main(int argc, char *argv[]) {
/* 初始化 Linux 系统 */
system_init();
/* 初始化 RPMsg */
ipc_init();
/* 启动 Web 服务器 */
start_web_server();
/* 启动 AI 推理引擎 */
ai_engine_init(\"model.tflite\");
/* 主循环: 处理业务逻辑 */
while (1) {
/* 检查来自实时核的数据 */
ipc_message_t msg;
if (ipc_recv(&msg, 100) == 0) {
if (msg.type == IPC_SENSOR_DATA) {
/* 存储到数据库 */
db_insert(&msg.data.sensor);
/* AI 异常检测 */
if (ai_detect_anomaly(&msg.data.sensor)) {
send_alert(\"异常 detected!\");
}
}
}
/* 处理 Web 请求 */
web_server_poll();
}
return 0;
}
十、决策框架总结
10.1 选型检查清单
□ 实时性要求
□ 硬实时 (< 10μs) → 裸机
□ 软实时 (< 1ms) → RTOS
□ 非实时 → Linux
□ 资源约束
□ Flash < 64KB / RAM < 8KB → 裸机
□ Flash < 1MB / RAM < 256KB → RTOS
□ Flash > 4MB / RAM > 64MB → Linux
□ 功能复杂度
□ 功能点 < 10 → 裸机
□ 功能点 10-30 → RTOS
□ 功能点 > 30 → Linux
□ 网络需求
□ 仅串口/简单协议 → 裸机/RTOS
□ TCP/IP + HTTP → RTOS/Linux
□ 多协议 + 加密 → Linux
□ 安全认证
□ ISO 26262 ASIL-D → 裸机 + 认证工具链
□ IEC 61508 SIL 3 → RTOS (ThreadX/Zephyr)
□ 一般安全要求 → Linux (SELinux/AppArmor)
□ 团队能力
□ 嵌入式资深团队 → 裸机/RTOS
□ Linux 应用团队 → Linux
□ 混合团队 → 异构多核
□ 成本约束
□ BOM < ¥50 → 裸机/RTOS
□ BOM ¥50-200 → RTOS/轻量 Linux
□ BOM > ¥200 → Linux
10.2 最终建议
没有最好的架构,只有最合适的架构。
- 选择裸机:当实时性和资源效率是首要目标,且功能简单明确时
- 选择 RTOS:当需要多任务协作,但资源仍受限,且实时性要求中等时
- 选择 Linux:当功能复杂、需要丰富软件生态,且硬件资源充足时
- 选择混合架构:当需要同时满足硬实时和复杂业务,且使用异构多核平台时
记住:架构选型不是一成不变的。随着产品迭代,从裸机迁移到 RTOS,或从 RTOS 引入 Linux 协处理器,都是正常的演进路径。关键是建立清晰的决策依据,避免过度工程化。
转载自:https://blog.csdn.net/u014727709/article/details/162632755
欢迎 👍点赞✍评论⭐收藏,欢迎指正