嵌入式c开发的传感器驱动通用框架封装与实现(干货总结)

目录

一、框架设计思路

二、框架核心实现

1. 类型与接口定义(sensor_framework.h)

2. 框架实现(sensor_framework.c)

三、传感器驱动实现(以 DS18B20 温度传感器为例)

1. DS18B20 驱动(sensor_ds18b20.c)

四、使用示例(上层应用)

五、框架扩展与移植


前言:

做嵌入式开发,如果没有好的框架以及架构,写出来的程序实时性以及扩展性不满足可维护性以及可移植性,那么程序写的就是失败的,所以强烈建议做嵌入式开发的朋友学习好的框架,学习架构知识!如果觉得认同,可以关注我,可以带你实现高级框架,优美的嵌入式系统框架!

另外,我的资源中上传了一本书:《从入职到架构师,嵌入式软件成长之路》,强烈建议下载阅读,学习如何更好的做架构设计!

正文:

在嵌入式 C 开发中,传感器驱动框架的封装需要兼顾可扩展性移植性易用性。核心思想是通过抽象接口屏蔽硬件细节,让上层应用无需关心传感器的具体通信方式(I2C/SPI/UART)和寄存器操作,只需调用统一 API 即可完成数据交互。

一、框架设计思路

  1. 接口抽象:将传感器的通用操作(初始化、读取数据、配置参数、销毁)抽象为函数指针,定义统一接口。
  2. 设备管理:通过注册 / 注销机制管理所有传感器,支持动态添加新传感器。
  3. 数据标准化:定义通用数据结构,统一不同传感器的输出格式(如温度、湿度、加速度等)。
  4. 硬件解耦:框架层不涉及具体硬件操作(如 I2C 时序),由传感器驱动实现细节。

二、框架核心实现

1. 类型与接口定义(sensor_framework.h)

首先定义传感器类型、状态码和核心接口,作为框架的 "协议"。

#ifndef SENSOR_FRAMEWORK_H
#define SENSOR_FRAMEWORK_H

#include <stdint.h>
#include <stdbool.h>

// 传感器类型枚举(可扩展)
typedef enum {
    SENSOR_TYPE_TEMP,    // 温度传感器
    SENSOR_TYPE_HUMI,    // 湿度传感器
    SENSOR_TYPE_ACCEL,   // 加速度传感器
    SENSOR_TYPE_MAX
} SensorType;

// 传感器数据结构(通用格式,按需扩展)
typedef struct {
    SensorType type;     // 数据类型
    union {
        float temp;      // 温度值 (℃)
        float humi;      // 湿度值 (%)
        struct {         // 加速度值 (g)
            float x;
            float y;
            float z;
        } accel;
    } data;
    uint32_t timestamp;  // 数据时间戳
} SensorData;

// 传感器状态码
typedef enum {
    SENSOR_OK = 0,       // 操作成功
    SENSOR_INIT_FAILED,  // 初始化失败
    SENSOR_READ_FAILED,  // 读取失败
    SENSOR_CFG_FAILED,   // 配置失败
    SENSOR_NOT_FOUND     // 传感器未找到
} SensorStatus;

// 前向声明传感器设备结构体
typedef struct SensorDevice SensorDevice;

// 传感器操作接口(函数指针)
typedef SensorStatus (*SensorInitFunc)(SensorDevice *dev);       // 初始化
typedef SensorStatus (*SensorReadFunc)(SensorDevice *dev, SensorData *data);  // 读取数据
typedef SensorStatus (*SensorConfigFunc)(SensorDevice *dev, void *cfg);  // 配置参数
typedef void (*SensorDestroyFunc)(SensorDevice *dev);            // 销毁资源

// 传感器设备结构体(核心)
struct SensorDevice {
    const char *name;       // 传感器名称(如"DS18B20")
    SensorType type;        // 传感器类型
    uint8_t id;             // 唯一ID(用于区分同类型多个传感器)
    void *private_data;     // 私有数据(如I2C地址、引脚等硬件信息)
    
    // 操作接口
    SensorInitFunc init;
    SensorReadFunc read;
    SensorConfigFunc config;
    SensorDestroyFunc destroy;
    
    struct SensorDevice *next;  // 链表节点(用于设备管理)
};

// 框架管理函数
SensorStatus sensor_register(SensorDevice *dev);  // 注册传感器
SensorStatus sensor_unregister(uint8_t id);       // 注销传感器
SensorDevice* sensor_find(uint8_t id);            // 查找传感器
SensorStatus sensor_init_all(void);               // 初始化所有传感器
SensorStatus sensor_read_data(uint8_t id, SensorData *data);  // 读取指定传感器数据

#endif // SENSOR_FRAMEWORK_H
2. 框架实现(sensor_framework.c)

实现设备管理(注册 / 注销 / 查找)和通用 API,本质是维护一个传感器链表。

#include "sensor_framework.h"
#include <string.h>

// 传感器链表头(全局唯一)
static SensorDevice *sensor_list = NULL;

// 注册传感器(添加到链表)
SensorStatus sensor_register(SensorDevice *dev) {
    if (dev == NULL || dev->name == NULL) {
        return SENSOR_CFG_FAILED;
    }
    
    // 检查ID是否重复
    SensorDevice *temp = sensor_list;
    while (temp) {
        if (temp->id == dev->id) {
            return SENSOR_CFG_FAILED;  // ID冲突
        }
        temp = temp->next;
    }
    
    // 添加到链表头部
    dev->next = sensor_list;
    sensor_list = dev;
    return SENSOR_OK;
}

// 注销传感器(从链表移除)
SensorStatus sensor_unregister(uint8_t id) {
    SensorDevice *prev = NULL;
    SensorDevice *curr = sensor_list;
    
    while (curr) {
        if (curr->id == id) {
            if (prev) {
                prev->next = curr->next;
            } else {
                sensor_list = curr->next;  // 移除头节点
            }
            if (curr->destroy) {
                curr->destroy(curr);  // 调用销毁函数释放资源
            }
            return SENSOR_OK;
        }
        prev = curr;
        curr = curr->next;
    }
    return SENSOR_NOT_FOUND;
}

// 查找传感器(通过ID)
SensorDevice* sensor_find(uint8_t id) {
    SensorDevice *temp = sensor_list;
    while (temp) {
        if (temp->id == id) {
            return temp;
        }
        temp = temp->next;
    }
    return NULL;
}

// 初始化所有注册的传感器
SensorStatus sensor_init_all(void) {
    SensorDevice *temp = sensor_list;
    SensorStatus ret = SENSOR_OK;
    
    while (temp) {
        if (temp->init) {
            if (temp->init(temp) != SENSOR_OK) {
                ret = SENSOR_INIT_FAILED;  // 只要有一个失败,整体返回失败
            }
        }
        temp = temp->next;
    }
    return ret;
}

// 读取指定传感器数据
SensorStatus sensor_read_data(uint8_t id, SensorData *data) {
    if (data == NULL) {
        return SENSOR_CFG_FAILED;
    }
    
    SensorDevice *dev = sensor_find(id);
    if (dev == NULL || dev->read == NULL) {
        return SENSOR_NOT_FOUND;
    }
    
    return dev->read(dev, data);
}

三、传感器驱动实现(以 DS18B20 温度传感器为例)

传感器驱动需实现框架定义的接口,封装硬件细节(如 GPIO/I2C 操作)。

1. DS18B20 驱动(sensor_ds18b20.c)
#include "sensor_framework.h"
#include "ds18b20_hw.h"  // 硬件层(如GPIO初始化、时序函数)

// DS18B20私有数据(硬件相关参数)
typedef struct {
    uint8_t gpio_pin;  // 连接的GPIO引脚
} DS18B20PrivateData;

// 初始化DS18B20
static SensorStatus ds18b20_init(SensorDevice *dev) {
    if (dev == NULL || dev->private_data == NULL) {
        return SENSOR_INIT_FAILED;
    }
    
    DS18B20PrivateData *priv = (DS18B20PrivateData*)dev->private_data;
    // 调用硬件层初始化函数(如配置GPIO为输出)
    if (ds18b20_hw_init(priv->gpio_pin) != 0) {
        return SENSOR_INIT_FAILED;
    }
    return SENSOR_OK;
}

// 读取DS18B20温度数据
static SensorStatus ds18b20_read(SensorDevice *dev, SensorData *data) {
    if (dev == NULL || data == NULL || dev->private_data == NULL) {
        return SENSOR_READ_FAILED;
    }
    
    DS18B20PrivateData *priv = (DS18B20PrivateData*)dev->private_data;
    float temp;
    
    // 调用硬件层读取函数(如发送读取命令、解析温度)
    if (ds18b20_hw_read(priv->gpio_pin, &temp) != 0) {
        return SENSOR_READ_FAILED;
    }
    
    // 填充通用数据结构
    data->type = SENSOR_TYPE_TEMP;
    data->data.temp = temp;
    data->timestamp = 0;  // 实际应用中可使用系统定时器
    return SENSOR_OK;
}

// 销毁DS18B20资源
static void ds18b20_destroy(SensorDevice *dev) {
    if (dev && dev->private_data) {
        // 释放私有数据(如果需要)
        // free(dev->private_data);  // 若使用动态内存
    }
}

// 定义DS18B20设备实例
static DS18B20PrivateData ds18b20_priv = {
    .gpio_pin = 5  // 假设连接到GPIO5
};

SensorDevice ds18b20_dev = {
    .name = "DS18B20",
    .type = SENSOR_TYPE_TEMP,
    .id = 1,  // 唯一ID
    .private_data = &ds18b20_priv,
    .init = ds18b20_init,
    .read = ds18b20_read,
    .config = NULL,  // DS18B20无需复杂配置,可设为NULL
    .destroy = ds18b20_destroy
};

四、使用示例(上层应用)

应用层通过框架 API 操作传感器,无需关心硬件细节。

#include "sensor_framework.h"
#include "sensor_ds18b20.h"  // 包含具体传感器驱动

int main(void) {
    SensorData data;
    
    // 1. 注册传感器
    sensor_register(&ds18b20_dev);
    
    // 2. 初始化所有传感器
    if (sensor_init_all() != SENSOR_OK) {
        // 处理初始化失败
        while (1);
    }
    
    // 3. 循环读取数据
    while (1) {
        // 读取ID=1的传感器(DS18B20)
        if (sensor_read_data(1, &data) == SENSOR_OK) {
            if (data.type == SENSOR_TYPE_TEMP) {
                // 打印温度数据(实际应用中可发送到上位机等)
                printf("Temp: %.2f℃\r\n", data.data.temp);
            }
        }
        
        // 延时(根据需求调整)
        delay_ms(1000);
    }
    
    return 0;
}

五、框架扩展与移植

  1. 添加新传感器:只需实现SensorDevice结构体和接口函数,调用sensor_register注册即可。
  2. 移植到不同平台:修改传感器驱动中的硬件层(如ds18b20_hw.c),适配新平台的 GPIO/I2C 驱动。
  3. 扩展功能:可添加传感器休眠 / 唤醒接口、数据滤波、校准等功能,只需在SensorDevice中扩展函数指针。

该框架通过 "接口抽象 + 设备管理" 实现了传感器驱动的模块化,适合在资源有限的嵌入式系统中使用,同时兼顾了灵活性和可维护性。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

start_up_go

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值