《嵌入式 Linux 控制服务从零搭建(一):项目立意与架构总览》

一、概要

1.专栏定位

这是一个指导Linux入门的同学从零搭建一个嵌入式Linux控制服务平台的专栏,为大家提供一个可参考的Linux实战项目。笔者也是从0学到现在的,体会过"死活找不到合适项目用来仿写"的尴尬期,所以现在想和大家分享的,不仅是从技术角度的死板教程,更是从工程角度总揽全局,教会你如何从0开始搭建一个属于自己的项目

2.目标读者

  • ✅ 有 C++ 基础(语法 + STL 能用),想理解嵌入式 Linux 应用层服务设计的同学

  • ✅ 学过 socket 编程、写过简单 IPC,写起代码来"头重脚轻",大型项目从零上手没思路的同学

  • ❌ 不适合:刚开始学 C 的纯小白;想看一个 ROS2 / D-Bus 替代品的资深 SDE

3.仓库地址

项目仓库:<仓库将在RERADME与基础示例补齐后开放>

笔者是一个大三的手残党,结合自己的日常积累,参考了一些优秀的模块设计思路,完成了这样一个Linux控制服务平台,总的来说还是资历浅浅,发出来也希望能和大家多多交流,大家如果有更好的建议或者改进方法,也可以评论或者私聊笔者,欢迎大家多多锐评(手动狗头)

二、设计目的

1.嵌入式 Linux 设备端缺一个什么样的东西?

想象一个场景:如果要从0开始设计一款扫地机器人(或者是相机、音响,随你想),这些消费设备通常包含多个复杂的进程和资源,比如可能包含外部信息采集模块(视觉、激光等)、UI/客户端进程、底层的Hald进程等等。这些复杂的进程需要一个常驻服务进程做"对外接入+内部协调资源"的工作,如果每次都从0搭建,非常繁琐且冗余。

如果我们把这个"常驻服务进程"抽象成一个包含基础设施、协议、服务层、ctl客户端于一体的控制服务系统,使用时只需要接入外部模块,是否就会变得非常方便呢?这就是我们即将搭建的------MiniDeviceProxy控制服务平台。

MiniDeviceProxy 的目标是面向嵌入式 Linux 单设备场景,提供一个轻量、可裁剪、易二次开发的本地控制服务骨架。相比脚本式控制方式,它具备常驻服务、统一 IPC、配置中心、状态裁决和后台任务管理能力。

因此,本项目更适合作为学习嵌入式 Linux 应用层服务设计的实战项目,也可以作为小型设备控制服务的基础骨架。

2.为什么不使用优秀的开源框架?

|---------|---------------------------------------------------------------------------------------|
| 方案 | 不适用的原因 |
| ROS/DDS | 面向多机分布式机器人节点通信,QoS、节点发现、序列化都很重;本地单设备控制场景属于"杀鸡用牛刀",且嵌入式裁剪成本高 |
| D-Bus | D-Bus 是成熟的通用本地服务总线,在桌面和嵌入式系统中都有大量应用;但其对象模型、接口描述和依赖体系对学习型小项目而言偏重,本项目更关注可控、可裁剪的设备控制面骨架。 |
| 自行搭建 | 每个项目从零写一套 IPC + 状态管理 + 配置中心,模块边界、命名、错误处理风格各异,无法跨项目沉淀 |

3.项目定位

▎ "面向嵌入式 Linux 单设备场景的轻量级控制与任务编排平台。"

五个特征:轻量、本地优先、控制平面导向、易部署易裁剪、对二次开发友好

三、主体设计思路

1.进程模型

cpp 复制代码
mini_proxyd(服务端) + mini_ctl(CLI 客户端)

2.架构图

层级职责:

  • app:进程入口,初始化与退出

  • service:平台内核管理器(路由、状态、任务、配置、事件)

  • base:执行与并发基础设施

  • common:日志、错误码、协议结构、JSON 工具

3.模块核心职责

|-----------|------------------|--------------------------|
| 模块 | 职责 | 关键约束 |
| ProxyMgr | 统一调度入口,路由请求到内部模块 | 不直接做业务裁决 |
| StateMgr | 系统状态唯一裁决者 | 模块只能 publish 事件,不可更改系统状态 |
| TaskMgr | 后台长任务唯一管理者 | 任务状态与系统状态有明确边界 |
| ConfigMgr | 配置文件唯一真源 | 写盘走临时文件 + rename |
| EventBus | 进程内事件发布 / 订阅 | 不持有线程,按订阅方提供的looper 异步分发 |
| MsgLooper | 控制面线程顺序的承载者 | 所有系统状态变更必须在它的线程上执行 |

四、项目学习价值

4.1 跟着这个专栏能学到什么?

C++ 工程能力

  • 现代 C++17:RAII、tl::expected / std::variant、模板状态类、std::function 包装

  • CMake 多 target 工程组织(app / lib / test 边界)

  • 单元测试组织(CTest + 自定义最小断言宏)

系统编程

  • Unix Domain Socket:监听、接受、收发、长度前缀分帧、EINTR 处理

  • 信号处理与优雅退出(SIGINT / SIGTERM 接管)

  • POSIX 文件系统:原子写盘(temp file + rename)

  • 多线程:mutex、condition_variable、线程不变量约定

架构设计

  • 模块边界划分(service / base / common 分层)

  • 事件驱动状态机的运行时模型(事件 → looper → 状态机裁决)

  • IPC 协议设计(长度前缀 + JSON payload + 请求 / 响应模型)

  • 配置中心设计
    项目落地(展示项目的真实落地能立,但不是核心):

  • 交叉编译 toolchain

  • systemd 服务部署

  • 板端 GPIO 控制

  • LVGL 板端 UI

五、系统主要功能

1.已实现的能力

✅ mini_proxyd 服务端常驻进程

✅ mini_ctl 命令行客户端

✅ Unix Domain Socket IPC(长度前缀分帧 + EINTR 处理)

✅ JSON 请求 / 响应协议(含版本字段、request_id、错误码)

✅ ProxyMgr 统一命令路由

✅ ConfigMgr 配置加载 / 读取 / 修改 / 持久化

✅ MsgLooper 控制面消息循环

✅ AsyncTaskExecutor 后台任务执行

✅ EventBus 进程内事件总线(订阅 RAII / 异步分发)

✅ StateMgr 事件驱动状态机(已接入主线)

✅ Logger 彩色日志 / 多级别 / 线程标识

✅ Signal 优雅退出

2.当前支持的命令

|--------|-------------|-----------|---------------|
| 模块 | 命令 | 参数 | 说明 |
| system | status | 无 | 查询服务运行状态 |
| system | help | 无 | 帮助信息 |
| state | get | 无 | 查询当前系统状态 |
| state | reset | 无 | 触发状态机回到 Ready |
| config | get_config | key | 读取配置项 |
| config | set_config | key value | 修改配置 |
| config | save_config | 无 | 保存配置到文件 |

下面是一个简单的demo演示系统的基本工作流程:

bash 复制代码
  # 启动服务端                                                                                                                                                              
  $ ./mini_proxyd                                                                                                                                                           
  [INFO] mini_proxyd starting...
  [INFO] EventBus initialized                                                                                                                                               
  [INFO] StateMgr entered state: Ready
  [INFO] Listening on /tmp/mini_proxyd.sock                                                                                                                                 
                                                                                                                                                                            
  # 另起一个终端
  $ ./mini_ctl state get                                                                                                                                                    
  {"code":0,"data":{"state":"Ready"}}                                                                                                                                       
   
  $ ./mini_ctl state reset                                                                                                                                                  
  {"code":0,"message":"reset event published"}
                                                                                                                                                                            
  $ ./mini_ctl config set_config ipc.backlog 8                                                                                                                              
  $ ./mini_ctl config save_config                                                                                                                                           
                                                      

六、尾声

本篇介绍了项目定位和项目能力,不知道有没有吸引到大家。评论区:你最关心专栏写哪一块?欢迎留言,下一篇会优先回应高赞问题

下一篇更新时间:2026.5.15前(笔者是实习打工的牛马,时间比较稀缺,读者大佬们海涵)

相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒2 天前
TShark:基础知识
linux
AlfredZhao2 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪3 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言