|
|
|
|
/*
|
|
|
|
|
* 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 <rtthread.h>
|
|
|
|
|
#include <rtdevice.h>
|
|
|
|
|
#include "data_comm.h"
|
|
|
|
|
#include <rs485.h>
|
|
|
|
|
|
|
|
|
|
#define DBG_TAG "SCCM_link"
|
|
|
|
|
#define DBG_LVL DBG_LOG
|
|
|
|
|
#include <rtdbg.h>
|
|
|
|
|
|
|
|
|
|
static struct rt_semaphore rx_sem;
|
|
|
|
|
|
|
|
|
|
#define RX_LINE_BUF_SIZE 1024
|
|
|
|
|
#define RS485_SAMPLE_SLAVE_SERIAL "uart1"
|
|
|
|
|
#define RS485_SAMPLE_SLAVE_BAUDRATE 115200
|
|
|
|
|
#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)
|
|
|
|
|
{
|
|
|
|
|
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("uart1",uart_thread_entry,RT_NULL,2048,20,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;
|
|
|
|
|
}
|
|
|
|
|
}
|