/* * 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 # include # include #include "uart_framework.h" #include "data_comm.h" #define LOG_TAG "uart.rx" #define LOG_LVL LOG_LVL_DBG #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); 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);