c语言面向对象的led

参考

基于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
相关推荐
奇妙之二进制2 小时前
fastdds源码分析之WriterListener
linux·开发语言·dds
小园子的小菜2 小时前
生产实战|冷热数据转换:从识别、触发到落地全流程解析
java·开发语言·spring
zhangzeyuaaa2 小时前
Python协程
开发语言·python
zhangzeyuaaa2 小时前
Python多进程同步与共享内存完全指南:从Lock到分布式共享
开发语言·分布式·python
钰珠AIOT2 小时前
什么是句柄,有什么用?适用于什么场景?
c语言·c++
꧁细听勿语情꧂2 小时前
用队列实现栈、用栈实现队列,树、二叉树、满二叉树、完全二叉树,堆、向下向上调整算法、出堆入堆、堆排序
c语言·开发语言·数据结构·算法
香山上的麻雀10082 小时前
由 Rust 开发的能大幅降低LLM token消耗的高性能 CLI 代理工具 rtk
开发语言·后端·rust
Fleshy数模2 小时前
玩转 Python:多线程、装饰器、视觉检测与正则匹配实战
开发语言·python·视觉检测
薛定猫AI2 小时前
【深度解析】Qwen 3.6 Max Preview:面向智能体编码、视觉推理与 Three.js 前端生成的能力拆解
开发语言·前端·javascript