/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2025-10-20 Administrator the first version * 2025-11-12 Modified Switch to IDLE interrupt mode (no DMA, no ringbuffer) * 2025-11-21 Fixed Enable RX_IDLE mode correctly for RT-Thread 5.1 */ #include #include #include "data_comm.h" #include #define DBG_TAG "SCCM_link" #define DBG_LVL DBG_LOG #include static struct rt_semaphore rx_sem; #define RX_LINE_BUF_SIZE 1024 #define RS485_SAMPLE_SLAVE_SERIAL "uart4" #define RS485_SAMPLE_SLAVE_BAUDRATE 57600 #define RS485_SAMPLE_MASTER_PARITY 0 //0 -- none parity #define RS485_SAMPLE_SLAVE_PIN -1 //-1 -- nonuse rs485 mode control #define RS485_SAMPLE_SLAVE_LVL 1 #define RS485_TOM_MS 50 void uart_thread_entry(void *parameter) { rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO); static rt_uint8_t input[RX_LINE_BUF_SIZE]; rs485_inst_t *hinst = rs485_create(RS485_SAMPLE_SLAVE_SERIAL, RS485_SAMPLE_SLAVE_BAUDRATE, RS485_SAMPLE_MASTER_PARITY, RS485_SAMPLE_SLAVE_PIN, RS485_SAMPLE_SLAVE_LVL); if (hinst == RT_NULL) { LOG_E("create LINK instance fail."); return; } rs485_set_recv_tmo(hinst, RS485_TOM_MS); if (rs485_connect(hinst) != RT_EOK) { rs485_destory(hinst); LOG_E("LINK connect fail."); return; } LOG_I("SCCM thread running on %s", RS485_SAMPLE_SLAVE_SERIAL); while (1) { int len = rs485_recv(hinst, input, sizeof(input)); if (len > 0) { // 动态分配请求结构体(见之前完整代码) struct proc_request *req = rt_malloc(sizeof(struct proc_request)); if (!req) continue; rt_strncpy(req->input, (const char *)input, sizeof(req->input)); req->input_len = len; req->sem = rt_malloc(sizeof(struct rt_semaphore)); if (!req->sem) { rt_free(req); continue; } 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_tick_from_millisecond(100)) >= RT_EOK) { if(req->output_len>0) rs485_send(hinst, req->output, req->output_len); } } // 清理 rt_sem_detach(req->sem); // 或 rt_sem_delete rt_free(req->sem); rt_free(req); } } } int start_uart_thread(void) { rt_thread_t tid = rt_thread_create("sccm",uart_thread_entry,RT_NULL,2048,11,10); if (tid != RT_NULL) { rt_thread_startup(tid); LOG_I("Create SCCM_uart thread"); return 0; } else { LOG_E("Failed to create SCCM_uart thread!"); return -1; } } INIT_COMPONENT_EXPORT(start_uart_thread);