电子产业一站式赋能平台

PCB联盟网

搜索
查看: 55|回复: 0
收起左侧

分享一种应用于裸机上的单例模式

[复制链接]

585

主题

585

帖子

7218

积分

高级会员

Rank: 5Rank: 5

积分
7218
发表于 3 天前 | 显示全部楼层 |阅读模式
关注+星标公众,不错过精彩内容
作者 |嵌入式情报局
今天跟大家分享的设计模式中最简单且非常有效的设计模式,单例模式。一、什么是单例模式?1. 定义与核心思想单例模式(Singleton Pattern) 是一种创建型设计模式,其核心目标是 确保一个类在系统中仅有一个实例,并提供全局访问点。在嵌入式开发中,这一模式常用于管理硬件资源或全局状态,避免因多次初始化或并发操作导致的资源冲突。
2. 嵌入式中的典型特征? 唯一性:如UART串口控制器,多任务同时操作会引发数据混乱。
? 资源节约:避免重复初始化占用额外内存(尤其在RAM稀缺的MCU中)。
? 线程安全:需通过锁或关中断保护临界区(例如RTOS中的任务竞争)。
二、单例模式的作用与应用场景1. 四大核心作用? 统一管理硬件外设:如SPI Flash、ADC模块的全局访问。
? 减少内存开销:避免重复创建对象(适合资源有限的MCU)。
? 防止状态不一致:确保配置参数(如校准值)全局唯一。
? 简化跨模块调用:日志系统、任务调度器等无需传递实例。
2. 六大嵌入式应用场景场景示例风险规避硬件控制器I2C总线驱动、PWM发生器避免多任务操作时序冲突系统配置管理设备序列号、网络参数防止配置被意外覆盖日志记录器通过UART或Flash写入日志确保日志文件原子写入中断服务管理器统一管理外部中断优先级防止中断嵌套导致死锁电源管理模块休眠唤醒策略、低功耗模式统一控制电源状态数据缓存池传感器数据环形缓冲区避免多任务读写越界三、手把手用C语言实现单例模式1. 裸机环境实现(关中断保护)#include
#include "stm32g0xx_hal.h"  // 以STM32G0系列为例
// 单例对象:模拟SPI控制器
typedefstruct {
    uint32_t spi_speed;     // SPI时钟频率
    uint8_t  tx_buffer[64]; // 发送缓冲区
} SPIController;
static SPIController instance;     // 静态实例(编译期分配内存)
staticvolatileuint8_t initialized = 0;  // volatile防止编译器优化
// 获取SPI控制器实例(关中断保护原子操作)
SPIController* get_spi_controller(void) {
    if (!initialized) {
        __disable_irq();            // 关中断
        if (!initialized) {         // 双重检查锁定
            instance.spi_speed = 1000000;  // 默认1MHz
            HAL_SPI_Init(&hspi1);   // 初始化硬件SPI(需提前配置hspi1)
            initialized = 1;
        }
        __enable_irq();
    }
    return &instance;
}
// 示例:多任务调用SPI发送数据
void task_send_data(void) {
    SPIController* spi = get_spi_controller();
    HAL_SPI_Transmit(&hspi1, spi->tx_buffer, 64, 100); // 发送数据
}
代码解析? 静态内存分配:SPIController instance直接分配在全局区,避免动态内存风险。
? 关中断保护:裸机环境下通过__disable_irq()确保初始化原子性。
------------ END ------------

nimqu5f1ets6409853939.gif

nimqu5f1ets6409853939.gif

●专栏《嵌入式工具
●专栏《嵌入式开发》
●专栏《Keil教程》
●嵌入式专栏精选教程

关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。点击“阅读原文”查看更多分享。
回复

使用道具 举报

发表回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


联系客服 关注微信 下载APP 返回顶部 返回列表