17 changed files with 1267 additions and 646 deletions
			
			
		
								
									Binary file not shown.
								
							
						
					| @ -0,0 +1,152 @@ | |||||
|  | /*
 | ||||
|  |  * Copyright (c) 2006-2021, RT-Thread Development Team | ||||
|  |  * | ||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||
|  |  * | ||||
|  |  * Change Logs: | ||||
|  |  * Date           Author       Notes | ||||
|  |  * 2025-10-25     Administrator       the first version | ||||
|  |  */ | ||||
|  | # include <rtthread.h> | ||||
|  | # include <rtdevice.h> | ||||
|  | # include <board.h> | ||||
|  | # include <stdio.h> | ||||
|  | #include "uart_framework.h" | ||||
|  | #include "data_comm.h" | ||||
|  | 
 | ||||
|  | #define LOG_TAG              "uart.rx" | ||||
|  | #define LOG_LVL              LOG_LVL_DBG | ||||
|  | //#include <ulog.h>
 | ||||
|  | 
 | ||||
|  | #define UART_NAME           "uart2" | ||||
|  | #define UART_BAUD_RATE      BAUD_RATE_115200 | ||||
|  | 
 | ||||
|  | #define RS485RD             GET_PIN(A,10) | ||||
|  | #define RS485_RX()          rt_pin_write(RS485RD, 0) | ||||
|  | #define RS485_TX()          rt_pin_write(RS485RD, 1) | ||||
|  | 
 | ||||
|  | #define RECV_BUF_SIZE       (512) | ||||
|  | #define FRAME_TIMEOUT_MS    20 | ||||
|  | #define SEND_INTERVAL_MS    0 | ||||
|  | #define REQUEST_TIMEOUT_MS  250 | ||||
|  | 
 | ||||
|  | static uart_framework_t uf = RT_NULL; | ||||
|  | 
 | ||||
|  | static void rs485_set_tx(void) | ||||
|  | { | ||||
|  |     RS485_TX(); | ||||
|  |     rt_thread_mdelay(1); | ||||
|  | } | ||||
|  | 
 | ||||
|  | static void rs485_set_rx(void) | ||||
|  | { | ||||
|  |     rt_thread_mdelay(1); | ||||
|  |     RS485_RX(); | ||||
|  | } | ||||
|  | 
 | ||||
|  | static void rs485_gpio_init(void) | ||||
|  | { | ||||
|  |     rt_pin_mode(RS485RD, PIN_MODE_OUTPUT); | ||||
|  |     rs485_set_rx(); | ||||
|  | } | ||||
|  | 
 | ||||
|  | static rt_err_t uart_rs485_init(void) | ||||
|  | { | ||||
|  |     rt_device_t serial_device = rt_device_find(UART_NAME); | ||||
|  |     if (serial_device == RT_NULL) | ||||
|  |     { | ||||
|  |         rt_kprintf("not find the serial device:%s!", UART_NAME); | ||||
|  |         return -RT_ERROR; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     /* 修改串口配置 */ | ||||
|  |     struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; | ||||
|  |     config.baud_rate = UART_BAUD_RATE; | ||||
|  |     config.bufsz = RECV_BUF_SIZE;   // 接收缓冲区大小
 | ||||
|  |     rt_device_control(serial_device, RT_DEVICE_CTRL_CONFIG, &config); | ||||
|  | 
 | ||||
|  |     rs485_gpio_init(); | ||||
|  |     struct uart_framework_cfg cfg = { .uart_name = UART_NAME, .max_frame_size = RECV_BUF_SIZE, .frame_interval_ms = | ||||
|  |     FRAME_TIMEOUT_MS, .send_interval_ms = SEND_INTERVAL_MS, .rs485_txd = rs485_set_tx, .rs485_rxd = rs485_set_rx }; | ||||
|  |     //如果不是485,则配置rs485_txd和rs485_rxd为RT_NULL
 | ||||
|  | 
 | ||||
|  |     uf = uart_framework_create(&cfg); | ||||
|  |     if (uf == RT_NULL) | ||||
|  |     { | ||||
|  |         rt_kprintf("SCCM link create failed on %s\n", UART_NAME); | ||||
|  |         return -RT_ERROR; | ||||
|  |     } | ||||
|  |     else | ||||
|  |     { | ||||
|  |         rt_kprintf("SCCM link create success on %s!\n", UART_NAME); | ||||
|  |         return RT_EOK; | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | static rt_err_t frame_handler(rt_uint8_t *data, rt_size_t size) | ||||
|  | { | ||||
|  |     //解析数据
 | ||||
|  |     rt_err_t res; | ||||
|  |     struct proc_request *req = rt_malloc(sizeof(struct proc_request)); | ||||
|  |     if (!req){ return RT_ERROR;} | ||||
|  |     rt_strncpy(req->input, (const char *)data, sizeof(req->input)); | ||||
|  |     req->input_len = size; | ||||
|  |     req->sem = rt_malloc(sizeof(struct rt_semaphore)); | ||||
|  | 
 | ||||
|  |     if (!req->sem) { | ||||
|  |         rt_free(req); | ||||
|  |         return RT_ERROR; | ||||
|  |     } | ||||
|  | 
 | ||||
|  |     rt_sem_init(req->sem, "uart_resp", 0, RT_IPC_FLAG_FIFO); | ||||
|  | 
 | ||||
|  |     // 发送到处理线程
 | ||||
|  |     if (rt_mq_send(proc_mq, &req, sizeof(req)) == RT_EOK) | ||||
|  |     { | ||||
|  |         // 等待处理完成
 | ||||
|  |         if (rt_sem_take(req->sem, RT_WAITING_FOREVER) == RT_EOK) | ||||
|  |         { | ||||
|  |             res=  uart_framework_send(uf, (rt_uint8_t *)req->output, req->output_len); | ||||
|  |         } | ||||
|  |     } | ||||
|  |     // 清理
 | ||||
|  |     rt_sem_detach(req->sem);  // 或 rt_sem_delete
 | ||||
|  |     rt_free(req->sem); | ||||
|  |     rt_free(req); | ||||
|  | 
 | ||||
|  |     //这里直接返回接收到的数据
 | ||||
|  |     // rt_uint8_t *frame_data = data;
 | ||||
|  |     // rt_uint16_t frame_len = size;
 | ||||
|  |    // rt_kprintf("rx_buf", 16, frame_data, frame_len);
 | ||||
|  |    // rt_err_t res = uart_framework_send(uf, frame_data, frame_len);
 | ||||
|  | 
 | ||||
|  |     return res; | ||||
|  | } | ||||
|  | 
 | ||||
|  | static void rs485_rx_handler(void *params) | ||||
|  | { | ||||
|  |     while (1) | ||||
|  |     { | ||||
|  |         if(uart_framework_receive(uf, RT_WAITING_FOREVER, RT_NULL, RT_NULL, 0) == RT_EOK) | ||||
|  |         { | ||||
|  |             frame_handler(uf->rx_buf, uf->rx_size); | ||||
|  |         } | ||||
|  |     } | ||||
|  | } | ||||
|  | 
 | ||||
|  | int app_uart_rs485_startup(void) | ||||
|  | { | ||||
|  |     rt_err_t rst; | ||||
|  |     rst = uart_rs485_init(); | ||||
|  |     if (rst != RT_EOK) | ||||
|  |         return rst; | ||||
|  | 
 | ||||
|  |     rt_thread_t t = rt_thread_create("rs485rx", rs485_rx_handler, RT_NULL, 1024 * 4, 12, 20); | ||||
|  |     if (t == RT_NULL) | ||||
|  |         return -RT_ENOMEM; | ||||
|  | 
 | ||||
|  |     rst = rt_thread_startup(t); | ||||
|  | 
 | ||||
|  |     return rst; | ||||
|  | } | ||||
|  | //INIT_APP_EXPORT(app_uart_rs485_startup);
 | ||||
| @ -0,0 +1,15 @@ | |||||
|  | /*
 | ||||
|  |  * Copyright (c) 2006-2021, RT-Thread Development Team | ||||
|  |  * | ||||
|  |  * SPDX-License-Identifier: Apache-2.0 | ||||
|  |  * | ||||
|  |  * Change Logs: | ||||
|  |  * Date           Author       Notes | ||||
|  |  * 2025-10-25     Administrator       the first version | ||||
|  |  */ | ||||
|  | #ifndef APPLICATIONS_DATA_UART_RS485_H_ | ||||
|  | #define APPLICATIONS_DATA_UART_RS485_H_ | ||||
|  | 
 | ||||
|  | int app_uart_rs485_startup(void); | ||||
|  | 
 | ||||
|  | #endif /* APPLICATIONS_DATA_UART_RS485_H_ */ | ||||
| @ -0,0 +1,179 @@ | |||||
|  | /*
 | ||||
|  |  * 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 <rtdbg.h> | ||||
|  | #include <board.h> | ||||
|  | #include"drv_common.h" | ||||
|  | 
 | ||||
|  | #define DBG_TAG "sd_cd" | ||||
|  | #define DBG_LVL DBG_LOG | ||||
|  | #include <rtdbg.h> | ||||
|  | 
 | ||||
|  | // ==================== 配置参数 ====================
 | ||||
|  | #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);
 | ||||
| @ -0,0 +1 @@ | |||||
|  | Subproject commit 679392a4b6beb09dd3e2febe03c2aabc3f298412 | ||||
					Loading…
					
					
				
		Reference in new issue