《嵌入式 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前(笔者是实习打工的牛马,时间比较稀缺,读者大佬们海涵)

相关推荐
量子炒饭大师1 小时前
【Linux系统编程】Cyberpunk在霓虹丛林中构建堡垒 ——【关于shell命令及其运行原理】
linux·运维·服务器·shell
IT大白鼠1 小时前
主流Linux文件系统稳定性及性能分析
linux·运维·服务器·文件系统
南境十里·墨染春水1 小时前
linux学习进展 I/O复用函数初步
linux·运维·学习
LinuxGeek10241 小时前
Linux内核“Dirty Frag”漏洞(CVE-2026-43284)修复方案
linux·运维·服务器
曦夜日长1 小时前
Linux系统篇,权限(一):用户创建与切换、权限及角色定义与修改、文件权限二进制表示
linux·运维·服务器
原来是猿1 小时前
应用层【协议再识/序列化与反序列化】
linux·运维·服务器·网络·网络协议·tcp/ip
北风toto2 小时前
log4j中文日志乱码问号-Linux启动jar包,输出中文日志变成问号?
linux·log4j·jar
实心儿儿2 小时前
Linux —— 库的制作和原理(3)
linux·运维·服务器
十子木2 小时前
linux 安装claude code
linux