/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2025-10-22 Administrator the first version */ #include "dfs_fs.h" #include #include #include"drv_common.h" #define DBG_TAG "sd_cd" #define DBG_LVL DBG_LOG #include // ==================== 配置参数 ==================== #define SD_DEVICE_NAME "sd0" #define MOUNT_POINT "/" // CD 引脚配置(根据你的 BSP 修改) #define CD_PIN GET_PIN(A, 0) // 示例:PA0,根据实际修改! // 消息类型 #define SD_EVENT_INSERTED 1 #define SD_EVENT_REMOVED 2 // =============================================== static rt_mq_t sd_event_mq = RT_NULL; static rt_sem_t mount_sync_sem = RT_NULL; /** * @brief CD 引脚中断回调 */ void cd_pin_irq(void *param) { rt_uint8_t event; rt_base_t level = rt_hw_interrupt_disable(); // 读取当前电平 int pin_level = rt_pin_read(CD_PIN); if (pin_level == PIN_HIGH) { rt_kprintf("SD Card removed (CD high)\n"); event = SD_EVENT_REMOVED; } else // PIN_LOW { rt_kprintf("SD Card inserted (CD low)\n"); event = SD_EVENT_INSERTED; } // 发送事件到消息队列 if (sd_event_mq != RT_NULL) { rt_mq_send(sd_event_mq, &event, 1); } rt_hw_interrupt_enable(level); } /** * @brief 初始化 CD 引脚为外部中断模式 */ int cd_pin_init(void) { rt_pin_mode(CD_PIN, PIN_MODE_INPUT_PULLUP); // 内部上拉 rt_pin_attach_irq(CD_PIN, PIN_IRQ_MODE_FALLING | PIN_IRQ_MODE_RISING, cd_pin_irq, RT_NULL); rt_pin_irq_enable(CD_PIN, ENABLE); // 使能中断 return 0; } /** * @brief 处理 SD 卡插拔事件的主线程 */ void sd_card_event_thread(void *parameter) { uint8_t event; rt_bool_t mounted = RT_FALSE; rt_kprintf("SD card event thread started...\n"); while (1) { // 等待事件 if (rt_mq_recv(sd_event_mq, &event, 1, RT_WAITING_FOREVER) != RT_EOK) continue; switch (event) { case SD_EVENT_INSERTED: if (!mounted) { rt_kprintf("Initializing and mounting SD card...\n"); // 等待设备 ready(可选) rt_thread_mdelay(100); // 尝试挂载 if (dfs_mount(SD_DEVICE_NAME, MOUNT_POINT, "elm", 0, 0) == RT_EOK) { rt_kprintf("SD card mounted to %s\n", MOUNT_POINT); mounted = RT_TRUE; // 通知其他模块可以使用 SD 卡 if (mount_sync_sem) rt_sem_release(mount_sync_sem); } else { rt_kprintf("Failed to mount SD card\n"); } } break; case SD_EVENT_REMOVED: if (mounted) { if (dfs_unmount(MOUNT_POINT) == 0) { rt_kprintf("SD card unmounted\n"); mounted = RT_FALSE; } else { rt_kprintf("Unmount failed or not mounted\n"); } } break; default: break; } } } /** * @brief 启动 SD 卡热插拔检测 */ int stm32_sdcard_hotplug_init(void) { rt_thread_t tid; // 创建事件消息队列 sd_event_mq = rt_mq_create("sd_event", 1, 10, RT_IPC_FLAG_FIFO); if (sd_event_mq == RT_NULL) { rt_kprintf("Failed to create message queue for SD event!\n"); return -RT_ENOMEM; } // 创建同步信号量(可选,用于通知挂载完成) mount_sync_sem = rt_sem_create("sd_mount", 0, RT_IPC_FLAG_FIFO); // 创建事件处理线程 tid = rt_thread_create("sd_event", sd_card_event_thread, RT_NULL, 2048, RT_THREAD_PRIORITY_MAX - 2, 10); if (tid != RT_NULL) { rt_thread_startup(tid); LOG_I("SD event thread created\n"); } else { rt_kprintf("Failed to create SD event thread!\n"); return -RT_ERROR; } return RT_EOK; } //INIT_COMPONENT_EXPORT(cd_pin_init); //INIT_APP_EXPORT(stm32_sdcard_hotplug_init);