GoDm@'s Blog

嵌入式模块化设计中的数据共享优化方案

版权信息

:::warning

本文章为博主原创文章。遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

:::


问题的提出

在嵌入式项目中,模块化每个功能有利于管理和理清开发思路,但是,当我们需要将模块联动起来的时候,需要一些必要的变量以实现两个模块之间的互相配合,最常见的方法是使用全局变量,但这样做使模块间耦合性[1]大大提高了。

有什么更好的方案吗

有的兄弟有的。只不过要牺牲一些效率(需要通过接口访问)。我们可以为共享变量建立一个专门的.c/.h文件,例如SharedData.c/.h
这个文件集中管理模块间的共享变量。这样做结构清晰,每个模块只依赖 SharedData.h,而不是彼此依赖\
同时我们通过两种方法使需要访问变量的模块成功读取或修改变量:

结构体封装+指针传递

:::recommend

:::

.h文件

#ifndef SHARED_DATA_H
#define SHARED_DATA_H

typedef struct {
    int sensor_value;
    int motor_speed;
} SharedData;

// 只提供获取指针的接口,而不是直接暴露变量
SharedData* get_shared_data(void);

#endif

.c文件

#include "shared_data.h"

static SharedData system_data = {0, 0}; // 只在本文件可见

SharedData* get_shared_data() {
    return &system_data;
}

在其他模块中使用

#include "shared_data.h"

void moduleA_update() {
    SharedData *data = get_shared_data();
    data->sensor_value += 10;
}

:::warning

不推荐将接收共享变量的指针的变量定义为全局变量。尽管这样会方便一些。指针可能被多个模块修改,导致指向无效地址(增加 bug 风险)。推荐在每个函数内部通过接口访问变量。如果一定要这样做,请一定避免空指针(记住初始化指针)

:::

使用全局指针示例:

static SharedData *data;  // 仅限当前文件访问

void moduleA_init() {
    data = get_shared_data();//避免空指针
}

通过函数提供读取和修改的接口

:::recommend

:::

:::error

:::

.h文件

#ifndef SHARED_DATA_H
#define SHARED_DATA_H

void setSensorValue(int value);
int getSensorValue();

void setMotorSpeed(int speed);
int getMotorSpeed();

#endif

.c文件

#include "shared_data.h"

static int sensor_value = 0;
static int motor_speed = 0;

void setSensorValue(int value) {
    if (value >= 0) {  // 限制非法值
        sensor_value = value;
    }
}

int getSensorValue() {
    return sensor_value;
}

void setMotorSpeed(int speed) {
    if (speed >= 0) {
        motor_speed = speed;
    }
}

int getMotorSpeed() {
    return motor_speed;
}

在其他模块中使用

#include "shared_data.h"

void moduleA_update() {
    setSensorValue(getSensorValue() + 10);
}

联合起来

将两种方式联合起来使用——大部分变量,我们使用指针接口访问即可;如果有些变量需要一些个性化要求,我们为这些变量编写定制的接口就好。

挖坑

降低耦合性的方法还有使用单例模式,以及RTOS中的消息/事件机制。后续研究。


  1. 代码耦合性(Coupling)是指模块或组件之间的依赖程度。如果代码耦合性很高,模块之间会紧密依赖,导致代码难以维护、扩展和测试。 ↩︎


共计约970字。于2025/03/22首次发布,最后更新于2025/03/22。

本文章为博主原创文章。遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

#嵌入式 | #程序架构 | #降低耦合 |
  1. 问题的提出
  2. 有什么更好的方案吗
  3. 结构体封装+指针传递
    1. .h文件
    2. .c文件
    3. 在其他模块中使用
  4. 通过函数提供读取和修改的接口
    1. .h文件
    2. .c文件
    3. 在其他模块中使用
  5. 联合起来
  6. 挖坑