设计模式——EIT构型(三)

"多功能网关的通信模式切换"

在这个例子中,网关需要支持多种通信方式(如 Wi-Fi、LoRa、NB-IoT)。我们不希望在主任务里写一堆 if-elseswitch-case


场景设计:通用通信引擎 (Communication Engine)

1. I:Interface (接口协议层)

定义所有通信方式必须遵守的"合同"。在 C 语言中,这是一个结构体。

c 复制代码
// comm_interface.h
typedef struct {
    const char* type_name;
    int  (*connect)(void);                 // 连接
    int  (*send)(uint8_t *data, uint16_t len); // 发送
    void (*sleep)(void);                  // 休眠(低功耗处理)
} CommInterface;

2. T:Transformation (具体的零件/驱动层)

这里我们实现两个"零件":Wi-Fi 和 LoRa。

c 复制代码
// wifi_driver.c (零件 T1)
#include "comm_interface.h"

static int wifi_conn() { /* 执行 AT 指令连 Wi-Fi */ return 0; }
static int wifi_send(uint8_t *d, uint16_t l) { /* 通过 TCP 发送 */ return 0; }

CommInterface wifi_t = {
    .type_name = "ESP8266_WIFI",
    .connect = wifi_conn,
    .send = wifi_send
};

// lora_driver.c (零件 T2)
#include "comm_interface.h"

static int lora_conn() { /* 设置扩频因子和频率 */ return 0; }
static int lora_send(uint8_t *d, uint16_t l) { /* 通过射频芯片发送 */ return 0; }

CommInterface lora_t = {
    .type_name = "SX1278_LORA",
    .connect = lora_conn,
    .send = lora_send
};

3. E:Engine (FreeRTOS 任务引擎)

这是核心控制逻辑,它只管调用接口 I,不关心当前用的是哪个 T

c 复制代码
// comm_engine.c
#include "FreeRTOS.h"
#include "task.h"
#include "queue.h"

// 引擎持有的接口指针
static CommInterface *current_comm = NULL;
extern QueueHandle_t xDataQueue; // 假设数据来自其他任务

void vCommEngineTask(void *pvParameters) {
    // 动态选择一个 T (也可以通过宏定义或配置选择)
    current_comm = (CommInterface *)pvParameters; 

    printf("[Engine] 启动通信引擎,当前模式: %s\n", current_comm->type_name);
    
    // 1. 调用 I 层接口进行连接
    if (current_comm->connect() == 0) {
        uint8_t buffer[64];
        for (;;) {
            // 2. 等待队列数据(典型的 FreeRTOS 阻塞模式)
            if (xQueueReceive(xDataQueue, buffer, portMAX_DELAY) == pdPASS) {
                // 3. 调用 I 层接口发送,引擎不关心具体是发往 Wi-Fi 还是 LoRa
                current_comm->send(buffer, 64);
                printf("[Engine] 数据已通过 %s 成功发送\n", current_comm->type_name);
            }
        }
    }
}

4. 为什么这对 FreeRTOS 开发至关重要?

内存隔离与静态分配

在嵌入式中,你可以为不同的 T 零件分配不同的静态配置。通过将 CommInterface 指针作为 xTaskCreate 的参数传入,你可以用同一个 Engine 函数创建出两个功能不同的 Task。

易于测试 (Mocking)

如果你现在手头没有 LoRa 硬件,你可以快速写一个 sim_lora_t (模拟零件),只做 printf 输出。Engine 代码不需要任何改动就能跑通业务逻辑测试。

处理中断 (ISR) 的解耦

你可以把 I 接口扩展,加入回调函数。当硬件中断触发时,底层驱动 (T) 调用 I 中的回调,由 E 来决定是否唤醒某个 FreeRTOS 任务。


相关推荐
lee_curry4 小时前
第四章 jvm中的垃圾回收器
java·jvm·垃圾收集器
易连EDI—EasyLink5 小时前
易连EDI–EasyLink实现OCR智能数据采集
网络·人工智能·安全·汽车·ocr·edi
@insist1235 小时前
信息安全工程师考点精讲:身份认证核心原理与分类体系(上篇)
大数据·网络·分类·信息安全工程师·软件水平考试
九转成圣5 小时前
Java 性能优化实战:如何将海量扁平数据高效转化为类目字典树?
java·开发语言·json
SmartRadio5 小时前
ESP32-S3 双模式切换实现:兼顾手机_路由器连接与WiFi长距离通信
开发语言·网络·智能手机·esp32·长距离wifi
_.Switch6 小时前
东方财富股票数据JS逆向:secids字段和AES加密实战
开发语言·前端·javascript·网络·爬虫·python·ecmascript
直奔標竿6 小时前
Java开发者AI转型第二十七课!Spring AI 个人知识库实战(六)——全栈闭环收官,解锁前端流式渲染终极技巧
java·开发语言·前端·人工智能·后端·spring
金銀銅鐵6 小时前
[java] 编译之后的记录类(Record Classes)长什么样子(上)
java·jvm·后端
金色光环7 小时前
FreeModbus释放底层的 TCP 监听端口
服务器·网络·tcp/ip
数智化精益手记局7 小时前
拆解物料管理erp系统的核心功能,看物料管理erp系统如何解决库存积压与缺料难题
大数据·网络·人工智能·安全·信息可视化·精益工程