电子产业一站式赋能平台

PCB联盟网

搜索
查看: 24|回复: 0
收起左侧

设计嵌入式软件框架时,如何避免过度分层和过度封装?

[复制链接]

561

主题

561

帖子

3987

积分

四级会员

Rank: 4

积分
3987
发表于 昨天 09:16 | 显示全部楼层 |阅读模式
我是老温,一名热爱学习的嵌入式工程师8 u8 T9 o3 M4 ^: A* K* x
关注我,一起变得更加优秀!
1 Y: u: [, ?% \工程师在进行嵌入式软件架构设计的时候,很多时候需要在灵活性与资源约束之间进行权衡。% F; V3 N6 d% u! V$ h
分层与封装虽然能提升可维护性和移植性,但过度设计容易引发性能损耗与开发效率下降。
& N8 \; H" w: ?0 G8 G本文尝试讨论,在嵌入式软件框架设计时,应如何避免框架过度分层和封装设计,以便让开发者在资源、性能与维护成本之间找到最佳的平衡点。/ w3 u4 B' {7 I# |6 h

pxk1vzixkxt64016294011.jpg

pxk1vzixkxt64016294011.jpg

% x" S2 K) j* |& \一、嵌入式软件分层和封装接口的本质。, ?3 p5 X2 S5 b& }( @0 s
分层软件框架的工程学定义,单片机典型的四层框架设计示例。
  • Application Layer    // 业务逻辑实现//-------------------------------------Middleware Layer     // 协议栈/算法库//-------------------------------------Driver Layer         // 外设驱动封装//-------------------------------------Hardware Layer       // 寄存器级操作每个层级通过明确定义的接口进行通信,上层模块仅能调用下层提供的接口,禁止跨层访问。
    " L+ ]* e+ X8 A0 g这种设计将硬件操作与业务逻辑解耦,例如STM32的HAL库就将寄存器操作抽象为统一API。
    $ z. r4 F" B3 N! j; D函数接口封装的技术内涵是,接口封装通过信息隐藏(Information Hiding)实现模块隔离,其核心要素包括:接口的访问权限控制、参数校验机制、运行错误的处理策略、不同软件版本的兼容性设计。, {+ A0 C  _% w( y! \- _/ _5 ]! D
    标准的驱动接口封装示例如下:, t! S/ ^1 R8 l, \& E
  • // SPI控制器接口定义typedef struct {    int (*init)(uint32_t freq);    int (*transfer)(uint8_t *tx_buf, uint8_t *rx_buf, size_t len);    int (*deinit)(void);} spi_controller_t;二、软件分层和封装接口的设计必要性1 e4 C4 S+ z* j5 K6 W
    在大型的嵌入式软件系统开发中,分层软件框架带来的工程价值,主要体现在:提升可维护性、增强复用性、便于协作开发、降低移植成本。0 }0 g  @3 F7 `2 J8 B. @9 j- Y/ }
    举个例子,通过封装Modbus协议接口,可以实现协议栈和物理层(RS485/CAN总线)的解耦,在通信介质改变时,能节省了80%的接口调试时间。
  • // Modbus接口抽象typedef struct {    int (*read_holding_reg)(uint8_t addr, uint16_t reg, uint16_t *data);    int (*write_single_reg)(uint8_t addr, uint16_t reg, uint16_t value);} modbus_iface_t;三、经典分层架构的设计范式
    6 K" Q' z. c3 C1 t3 w硬件抽象层(HAL)模式,以ARM架构的 mbed OS 架构为例,其HAL设计规范可以使同一应用代码运行在不同厂商的Cortex-M芯片上,设计如下:
  • ┌─────────────┐│ Application │└──────┬──────┘       ▼┌─────────────┐│   mbed API  │└──────┬──────┘       ▼┌─────────────┐│ Chip Vendor ││   HAL Lib   │└──────┬──────┘       ▼┌─────────────┐│  寄存器操作   │└─────────────┘操作系统抽象层(OSAL)模式,采用适配器模式,可以使业务代码不依赖特定的RTOS内核,以便在不同的RTOS之间进行迁移。
  • // 线程接口抽象typedef struct {    void* (*create)(task_func_t func, const char *name, \                   uint32_t stack_size, void *param);    void (*delete)(void* handle);} os_thread_t;关于嵌入式软件的设计模式,可以回顾公众号以前的文章,点击->:嵌入式 C 语言设计模式
    9 B* @# S' d* g0 w/ k( \; a  o# b四、软件分层和接口封装的使用场景
    , F4 v2 i( O$ u& u一般情况下,必须采用软件分层设计的场景,有以下这些:需支持多硬件平台、复杂的协议栈集成、长期的维护工作、大型开发团队协作。
    5 m4 C0 a9 o& i* [! a而无需严格进行软件分层的场景,主要有:资源受限型的单片机、原型功能验证、高实时性的应用、短周期交付的项目。
    / G. H* d3 ]3 V$ X$ T8 z! C如果出现以下特征,则可能警示着接口过度设计,比如:内存占用超标、执行时间出现劣化、工程师开发效率下降,等等。" w0 g! z" W! q8 A! g8 V+ \
    需要警惕如下的接口嵌套陷阱。
  • // 过度封装示例result = hal_spi->controller->channel[0]->transfer(...);五、如何避免过度分层与封装设计
    4 y$ x( t: d, P. p! \: T采用分层粒度控制策略,使用环形依赖检测工具(比如Lattix DSM工具)分析模块的耦合度,让软件架构满足以下原则:--单向依赖原则:禁止出现循环依赖。--接口精简原则:每个模块暴露的API不超过7个。--层级深度约束原则:API封装调用不超过5层。
    6 @: g7 u6 Y4 w在实时数据采集系统里面,可以采用“条件编译分层”技术,利用编译器处理一些额外的工作,可以让嵌入式系统达到较优的实时性。
  • // 性能关键路径消除抽象#ifdef OPTIMIZE_PERFORMANCE    #define SPI_TRANSFER(data)     REG_SPI_DR = (data)#else    #define SPI_TRANSFER(data)     hal_spi_transfer(data)#endif良好的函数封装接口设计,应该满足以下原则:--参数正交:修改某一参数时,不影响其他功能。--耗时确定:接口调用的耗时可以基本确定。--异常隔离:分层间的异常不会导致其他层崩溃。, Y. w  f2 c' e5 N1 \. W# o9 x) i9 E1 w
    六、总结
    1 l! d4 }+ b8 c嵌入式软件虽然没有架构师相关的岗位,但优秀的嵌入式软件工程师,在规划和设计整个嵌入式系统的功能的时候,应当在可维护性和性能之间、在抽象成本和开发效率之间,寻找一个最佳的平衡点。9 C9 V/ o9 O7 Y
    结合以往的项目生命周期、团队经验规模、硬件平台约束等参数,通过建立一个量化的评估体系,以便可以动态调整嵌入式系统的分层与封装策略。6 t( E; X5 X8 @% N; B6 A, R/ M
    谨记一点:没有完美的分层架构,只有适合当前上下文的设计。0 k3 t% a+ N4 i: }9 ^
    -END-
    7 [( @9 m& R7 |往期推荐:点击图片即可跳转阅读
      ?4 }4 L- i8 v) c; O/ T# y

    hcooxdyk2s164016294111.jpg

    hcooxdyk2s164016294111.jpg
    ) B0 \( D) _& N- o
    掌握这5个代码小技巧,让嵌入式软件调试更加高效!
    8 Q  Z: e8 `% F

    ynye410voln64016294211.jpg

    ynye410voln64016294211.jpg

    6 [8 y0 d  M: G6 r* }5 D' A! |嵌入式Linux工业网关设计,离不开这个关键核心通信模块。
    2 ?3 x9 S3 i/ G& D

    froiyzgjnuf64016294311.jpg

    froiyzgjnuf64016294311.jpg

    9 h5 A: v" X, O7 Z嵌入式软硬件开发,工程师在预研阶段就要开始考虑如何降本增效!# a% K' N' d% c' e% n2 f& {( S% @
    我是老温,一名热爱学习的嵌入式工程师
    9 o  H9 c/ D; k6 A7 t# l关注我,一起变得更加优秀!
    , m4 k/ _! ~6 b! X7 _' i

    aibjmbwsgxu64016294411.jpg

    aibjmbwsgxu64016294411.jpg
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表