参考
基于rtdef.h的轻量级设备管理、终端、协程与应用管理框架设计
base.h
公共头文件
c
#ifndef __BASE_H__
#define __BASE_H__
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
/* =========================================================
* container_of
* 从成员指针反推父结构体指针
* ========================================================= */
#define container_of(ptr, type, member) \
((type *)((char *)(ptr) - offsetof(type, member)))
/* =========================================================
* 通用错误码
* ========================================================= */
#define RET_OK (0)
#define RET_ERROR (-1)
#define RET_NULL (-2)
#define RET_UNSUP (-3)
#ifdef __cplusplus
}
#endif
#endif
DeviceCore.h
GPIO / I2C 统一抽象接口
c
#ifndef __DEVICE_CORE_H__
#define __DEVICE_CORE_H__
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
/* ================= GPIO ================= */
struct gpio_desc;
struct gpio_ops {
void (*set)(struct gpio_desc *gpio, int value);
void (*toggle)(struct gpio_desc *gpio);
};
struct gpio_desc {
const struct gpio_ops *ops;
void *chip_ctx;
uint32_t pin; /* 抽象pin */
};
/* ================= I2C ================= */
struct i2c_desc;
struct i2c_ops {
int (*write)(struct i2c_desc *i2c, uint8_t reg, uint8_t val);
int (*read)(struct i2c_desc *i2c, uint8_t reg, uint8_t *val);
};
struct i2c_desc {
const struct i2c_ops *ops;
void *bus_ctx;
uint8_t addr;
};
/* API */
void gpio_set(struct gpio_desc *gpio, int value);
void gpio_toggle(struct gpio_desc *gpio);
int i2c_write(struct i2c_desc *i2c, uint8_t reg, uint8_t val);
int i2c_read(struct i2c_desc *i2c, uint8_t reg, uint8_t *val);
#ifdef __cplusplus
}
#endif
#endif
DeviceCore.c
c
#include "DeviceCore.h"
void gpio_set(struct gpio_desc *gpio, int value)
{
if (gpio == NULL) return;
if (gpio->ops == NULL) return;
if (gpio->ops->set == NULL) return;
gpio->ops->set(gpio, value);
}
void gpio_toggle(struct gpio_desc *gpio)
{
if (gpio == NULL) return;
if (gpio->ops == NULL) return;
if (gpio->ops->toggle == NULL) return;
gpio->ops->toggle(gpio);
}
int i2c_write(struct i2c_desc *i2c, uint8_t reg, uint8_t val)
{
if (i2c == NULL) return -1;
if (i2c->ops == NULL) return -2;
if (i2c->ops->write == NULL) return -3;
return i2c->ops->write(i2c, reg, val);
}
int i2c_read(struct i2c_desc *i2c, uint8_t reg, uint8_t *val)
{
if (i2c == NULL) return -1;
if (i2c->ops == NULL) return -2;
if (i2c->ops->read == NULL) return -3;
return i2c->ops->read(i2c, reg, val);
}
LedBase.h
led设备基类
c
#ifndef __LED_BASE_H__
#define __LED_BASE_H__
#include "stdint.h"
#ifdef __cplusplus
extern "C" {
#endif
struct led_dev;
/* ================= LED 生命周期 + 行为 ================= */
struct led_ops {
int (*init)(struct led_dev *dev);
int (*deinit)(struct led_dev *dev);
int (*on)(struct led_dev *dev);
int (*off)(struct led_dev *dev);
int (*toggle)(struct led_dev *dev);
};
/* LED 设备基类 */
struct led_dev {
const struct led_ops *ops;
};
/* API */
int led_init(struct led_dev *dev);
int led_deinit(struct led_dev *dev);
int led_on(struct led_dev *dev);
int led_off(struct led_dev *dev);
int led_toggle(struct led_dev *dev);
#ifdef __cplusplus
}
#endif
#endif
LedBase.c
c
#include "LedBase.h"
int led_init(struct led_dev *dev)
{
if (dev == NULL) return -1;
if (dev->ops == NULL) return -2;
if (dev->ops->init == NULL) return -3;
return dev->ops->init(dev);
}
int led_deinit(struct led_dev *dev)
{
if (dev == NULL) return -1;
if (dev->ops == NULL) return -2;
if (dev->ops->deinit == NULL) return -3;
return dev->ops->deinit(dev);
}
int led_on(struct led_dev *dev)
{
if (dev == NULL) return -1;
if (dev->ops == NULL) return -2;
if (dev->ops->on == NULL) return -3;
return dev->ops->on(dev);
}
int led_off(struct led_dev *dev)
{
if (dev == NULL) return -1;
if (dev->ops == NULL) return -2;
if (dev->ops->off == NULL) return -3;
return dev->ops->off(dev);
}
int led_toggle(struct led_dev *dev)
{
if (dev == NULL) return -1;
if (dev->ops == NULL) return -2;
if (dev->ops->toggle == NULL) return -3;
return dev->ops->toggle(dev);
}
GpioLed.h
GPIO LED设备实现
c
#ifndef __GPIO_LED_H__
#define __GPIO_LED_H__
#include "LedBase.h"
#include "DeviceCore.h"
#ifdef __cplusplus
extern "C" {
#endif
struct gpio_led {
struct led_dev base;
struct gpio_desc *gpio;
};
/**
* 创建并初始化 gpio_led 对象
* @param led
* @param gpio
*/
void gpio_led_create(struct gpio_led *led,
struct gpio_desc *gpio);
#ifdef __cplusplus
}
#endif
#endif
GpioLed.c
c
#include "base.h"
#include "GpioLed.h"
#include <stddef.h>
/* ===== lifecycle ===== */
static int gpio_led_init(struct led_dev *dev)
{
struct gpio_led *led =container_of(dev, struct gpio_led, base);
//gpio_set(led->gpio, 0);
return 0;
}
static int gpio_led_deinit(struct led_dev *dev)
{
struct gpio_led *led =container_of(dev, struct gpio_led, base);
//gpio_set(led->gpio, 0);
return 0;
}
/* ===== behavior ===== */
static int gpio_led_on(struct led_dev *dev)
{
struct gpio_led *led =container_of(dev, struct gpio_led, base);
gpio_set(led->gpio, 1);
return 0;
}
static int gpio_led_off(struct led_dev *dev)
{
struct gpio_led *led =container_of(dev, struct gpio_led, base);
gpio_set(led->gpio, 0);
return 0;
}
static int gpio_led_toggle(struct led_dev *dev)
{
struct gpio_led *led =container_of(dev, struct gpio_led, base);
gpio_toggle(led->gpio);
return 0;
}
/* ===== ops ===== */
static const struct led_ops gpio_led_ops = {
.init = gpio_led_init,
.deinit = gpio_led_deinit,
.on = gpio_led_on,
.off = gpio_led_off,
.toggle = gpio_led_toggle,
};
void gpio_led_create(struct gpio_led *led,
struct gpio_desc *gpio)
{
led->base.ops = &gpio_led_ops;
led->gpio = gpio;
}
I2cLed.h
IIC LED设备实现
c
#ifndef __I2C_LED_H__
#define __I2C_LED_H__
#include "LedBase.h"
#include "DeviceCore.h"
#ifdef __cplusplus
extern "C" {
#endif
struct i2c_led {
struct led_dev base;
struct i2c_desc *i2c;
/**
* 决定是哪个灯的寄存器
*/
uint8_t reg;
};
/**
* 创建并初始化 i2c_led 对象
* @param led
* @param i2c
* @param reg
*/
void i2c_led_create(struct i2c_led *led,
struct i2c_desc *i2c,
uint8_t reg);
#ifdef __cplusplus
}
#endif
#endif
I2cLed.c
c
#include "base.h"
#include "I2cLed.h"
#include <stddef.h>
static int i2c_led_init(struct led_dev *dev)
{
struct i2c_led *led =container_of(dev, struct i2c_led, base);
i2c_write(led->i2c, led->reg, 0);
return 0;
}
static int i2c_led_deinit(struct led_dev *dev)
{
struct i2c_led *led =container_of(dev, struct i2c_led, base);
i2c_write(led->i2c, led->reg, 0);
return 0;
}
static int i2c_led_on(struct led_dev *dev)
{
struct i2c_led *led =container_of(dev, struct i2c_led, base);
return i2c_write(led->i2c, led->reg, 1);
}
static int i2c_led_off(struct led_dev *dev)
{
struct i2c_led *led =container_of(dev, struct i2c_led, base);
return i2c_write(led->i2c, led->reg, 0);
}
static const struct led_ops i2c_led_ops = {
.init = i2c_led_init,
.deinit = i2c_led_deinit,
.on = i2c_led_on,
.off = i2c_led_off,
.toggle = NULL,
};
void i2c_led_create(struct i2c_led *led,
struct i2c_desc *i2c,
uint8_t reg)
{
led->base.ops = &i2c_led_ops;
led->i2c = i2c;
led->reg = reg;
}
stm32_gpio.h
差异集中
stm32 gpio实现
c
#ifndef __STM32_GPIO_H__
#define __STM32_GPIO_H__
#include <stdint.h>
#include "DeviceCore.h"
#ifdef __cplusplus
extern "C" {
#endif
/* ================= GPIO寄存器模型(简化版) ================= */
typedef struct
{
uint32_t CRL;
uint32_t CRH;
uint32_t IDR;
uint32_t ODR;
uint32_t BSRR;
uint32_t BRR;
uint32_t LCKR;
} GPIO_TypeDef;
/* ================= GPIO状态 ================= */
typedef enum
{
GPIO_PIN_RESET = 0,
GPIO_PIN_SET
} GPIO_PinState;
/* ================= STM32 GPIO上下文 ================= */
typedef struct
{
GPIO_TypeDef *port;
uint16_t pin;
} stm32_gpio_ctx_t;
/* ================= API ================= */
void stm32_gpio_probe(struct gpio_desc *gpio,
stm32_gpio_ctx_t *ctx);
int stm32_gpio_remove(struct gpio_desc *gpio);
#ifdef __cplusplus
}
#endif
#endif
stm32_gpio.c
c
#include "stm32_gpio.h"
/* ================= 内部实现 ================= */
static void stm32_gpio_set(struct gpio_desc *gpio, int value)
{
stm32_gpio_ctx_t *ctx = (stm32_gpio_ctx_t *)gpio->chip_ctx;
if (ctx == NULL || ctx->port == NULL)
return;
if (value)
{
/* 置位 */
ctx->port->BSRR = (1U << ctx->pin);
}
else
{
/* 复位 */
ctx->port->BRR = (1U << ctx->pin);
}
printf("%s\n", __FUNCTION__);
}
static void stm32_gpio_toggle(struct gpio_desc *gpio)
{
stm32_gpio_ctx_t *ctx = (stm32_gpio_ctx_t *)gpio->chip_ctx;
if (ctx == NULL || ctx->port == NULL)
return;
/* 读取输出寄存器 */
if (ctx->port->ODR & (1U << ctx->pin))
{
ctx->port->BRR = (1U << ctx->pin);
}
else
{
ctx->port->BSRR = (1U << ctx->pin);
}
printf("%s\n", __FUNCTION__);
}
/* ================= ops表 ================= */
static const struct gpio_ops stm32_gpio_ops =
{
.set = stm32_gpio_set,
.toggle = stm32_gpio_toggle,
};
int stm32_gpio_remove(struct gpio_desc *gpio){
printf("%s\n", __FUNCTION__);
return 0;
}
/* ================= 对外初始化 ================= */
void stm32_gpio_probe(struct gpio_desc *gpio,
stm32_gpio_ctx_t *ctx)
{
gpio->ops = &stm32_gpio_ops;
gpio->chip_ctx = ctx;
gpio->pin = ctx->pin;
printf("%s\n", __FUNCTION__);
}
main.cpp
c
#include "GpioLed.h"
#include "stm32_gpio.h"
/* =========================================================
* 模拟硬件层(MCU真实GPIO外设寄存器)
* =========================================================
* GPIO_TypeDef 在 STM32 中代表:
* - GPIOA / GPIOB / GPIOC 这些硬件外设寄存器
*
* 这里用 GPIOA_sim 模拟真实硬件
* ========================================================= */
static GPIO_TypeDef GPIOA_sim;
/* =========================================================
* STM32 GPIO上下文(硬件绑定信息)
* =========================================================
* 这个结构体的作用:
* 描述"这个GPIO用的是哪个端口 + 哪个引脚"
*
* 类似 Linux 的:
* gpio_chip + pin number
*
* 字段说明:
* port → 指向 GPIOA_sim(模拟GPIOA寄存器)
* pin → 第5号引脚(PA5)
* ========================================================= */
static stm32_gpio_ctx_t stm32_gpio_ctx =
{
.port = &GPIOA_sim, /* GPIO外设地址(模拟GPIOA) */
.pin = 5 /* 第5号引脚 */
};
/* =========================================================
* GPIO抽象对象(通用GPIO描述符)
* =========================================================
* gpio_desc 是"中间层抽象"
*
* 它的作用:
* 不关心 STM32 / ESP32 / Linux
* 只提供统一接口给上层使用
*
* 内部包含:
* - ops → GPIO操作函数表(set/toggle)
* - chip_ctx → 平台相关数据(stm32_gpio_ctx)
* ========================================================= */
static struct gpio_desc gpio;
/* =========================================================
* LED设备对象(真正业务对象)
* =========================================================
* gpio_led 是 LED 设备实例
*
* 它的作用:
* 表示一个"真实LED设备"
*
* 内部包含:
* - base → led_dev(统一LED接口)
* - gpio → 绑定的GPIO资源
*
* 注意:
* LED 不知道 GPIOA / STM32
* 只知道 "我绑定了一个 gpio_desc"
* ========================================================= */
static struct gpio_led led;
/* =========================================================
* 主函数入口
* ========================================================= */
int main(void)
{
setvbuf(stdout, NULL, _IONBF, 0);
/* =====================================================
* 1️⃣ GPIO初始化(平台层绑定,将平台差异集中到这里)
* =====================================================
*
* 做了什么:
* 把 stm32_gpio_ctx 绑定到 gpio_desc
* 注册 stm32 的 gpio_ops
*
* 结果:
* gpio.desc → 变成"可操作GPIO对象"
*
* ===================================================== */
stm32_gpio_probe(&gpio, &stm32_gpio_ctx);
/* =====================================================
* 2️⃣ LED绑定GPIO(设备层绑定资源)
* =====================================================
*
* 做了什么:
* LED设备绑定 gpio_desc
* LED建立"控制关系"
*
* 结果:
* LED → GPIO → STM32硬件
*
* 注意:
* LED 仍然不知道 STM32
* ===================================================== */
gpio_led_create(&led, &gpio);
/* =====================================================
* 3️⃣ LED初始化(生命周期 init)
* =====================================================
*
* 做了什么:
* 调用 led_ops->init()
* 初始化LED状态(比如默认灭灯)
*
* 类似 Linux:
* probe() / init()
* ===================================================== */
led_init(&led.base);
/* =====================================================
* 4️⃣ 主循环(业务行为)
* =====================================================
*
* 这里是"用户行为层"
* 不再关心 GPIO / STM32
* ===================================================== */
while (1)
{
/* 点亮LED */
led_on(&led.base);
/* 关闭LED */
led_off(&led.base);
/* 翻转LED */
led_toggle(&led.base);
break;
}
/* =====================================================
* 5️⃣ 释放资源(嵌入式通常不会执行)
* ===================================================== */
led_deinit(&led.base);
stm32_gpio_remove(&gpio);
return 0;
}
测试
bash
C:\Users\PC\CLionProjects\untitled14\cmake-build-debug\untitled14.exe
stm32_gpio_probe
stm32_gpio_set
stm32_gpio_set
stm32_gpio_toggle
stm32_gpio_remove