时钟修改
This commit is contained in:
1 parent
f751863707
commit
c7cf944e61
12 files changed
+236
-135
No files matched your search
+79
-60
@@ -7,30 +7,40 @@
|
||||
* 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 <drivers/serial.h> // ← 显式包含,确保 RT_SERIAL_EVENT_RX_IDLE 可见
|
||||
#include "data_comm.h"
|
||||
|
||||
#define DBG_TAG "SCCM_link"
|
||||
#define DBG_LVL DBG_LOG
|
||||
#include <rtdbg.h>
|
||||
|
||||
#define SAMPLE_UART_NAME "uart1"
|
||||
#define RX_LINE_BUF_SIZE 1024 // 假设 MAX_INPUT_LEN 已定义,如 256
|
||||
#define RX_LINE_BUF_SIZE 1024
|
||||
|
||||
static rt_device_t serial;
|
||||
static struct rt_semaphore rx_sem;
|
||||
|
||||
// 接收回调:注意 size 实际是事件指针(RT-Thread 特性)
|
||||
// 接收回调
|
||||
static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size)
|
||||
{
|
||||
rt_uint32_t event = *(rt_uint32_t *)&size; // 强制解释为事件
|
||||
|
||||
// if (event & RT_SERIAL_EVENT_RX_IDLE)
|
||||
// 注意:在 RT-Thread 5.x,当使用 INT_RX 时,size 是接收到的字节数
|
||||
// 但若启用了 RX_IDLE 模式,底层驱动会在 IDLE 时回调,并传入事件
|
||||
// 安全做法:检查是否为事件(高位标志)
|
||||
// if (size & RT_SERIAL_EVENT_RX_IDLE)
|
||||
{
|
||||
LOG_D("RX IDLE event received");
|
||||
rt_sem_release(&rx_sem);
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
// 如果是普通数据(size > 0),也可处理,但本例依赖 IDLE 触发
|
||||
return RT_EOK;
|
||||
}
|
||||
|
||||
// 从串口设备读取一行(以 \n 结尾)
|
||||
static int read_line_from_uart(char *buf, int maxlen)
|
||||
{
|
||||
char ch;
|
||||
@@ -38,14 +48,14 @@ static int read_line_from_uart(char *buf, int maxlen)
|
||||
|
||||
while (len < maxlen - 1)
|
||||
{
|
||||
// 从串口缓冲区读一个字节(非阻塞,因为由 IDLE 触发说明有数据)
|
||||
if (rt_device_read(serial, 0, &ch, 1) <= 0)
|
||||
// 注意:在 INT_RX 模式下,rt_device_read 会从驱动内部 buffer 读取
|
||||
rt_size_t result = rt_device_read(serial, 0, &ch, 1);
|
||||
if (result <= 0)
|
||||
{
|
||||
break; // 无数据(理论上不应发生)
|
||||
break; // 无更多数据
|
||||
}
|
||||
|
||||
buf[len++] = ch;
|
||||
|
||||
if (ch == '\n')
|
||||
{
|
||||
buf[len] = '\0';
|
||||
@@ -53,7 +63,6 @@ static int read_line_from_uart(char *buf, int maxlen)
|
||||
}
|
||||
}
|
||||
|
||||
// 缓冲区满仍未遇到 \n,强制结束(可选策略)
|
||||
buf[len] = '\0';
|
||||
return len;
|
||||
}
|
||||
@@ -63,89 +72,99 @@ void uart_thread_entry(void *parameter)
|
||||
char input[RX_LINE_BUF_SIZE];
|
||||
int len;
|
||||
|
||||
// 初始化信号量
|
||||
rt_sem_init(&rx_sem, "rx_sem", 0, RT_IPC_FLAG_FIFO);
|
||||
|
||||
// 查找串口设备
|
||||
serial = rt_device_find(SAMPLE_UART_NAME);
|
||||
if (!serial)
|
||||
{
|
||||
rt_kprintf("Cannot find %s\n", SAMPLE_UART_NAME);
|
||||
LOG_E("Cannot find %s", SAMPLE_UART_NAME);
|
||||
return;
|
||||
}
|
||||
|
||||
// 配置串口:设置内部接收缓冲区大小(必须 >= 最大可能的一行)
|
||||
// Step 1: 设置串口基本参数(波特率等)
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
config.bufsz = RX_LINE_BUF_SIZE; // 关键:驱动内部 buffer 要够大
|
||||
config.baud_rate = BAUD_RATE_115200; // 根据需要调整
|
||||
config.data_bits = DATA_BITS_8;
|
||||
config.stop_bits = STOP_BITS_1;
|
||||
config.parity = PARITY_NONE;
|
||||
config.bufsz = RX_LINE_BUF_SIZE; // 驱动内部接收 buffer 大小
|
||||
rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config);
|
||||
|
||||
// 打开串口:使用中断接收(INT_RX),不使用 DMA
|
||||
// Step 2: 【关键】启用 RX IDLE 模式
|
||||
// rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, (void*)RT_SERIAL_RX_IDLE);
|
||||
|
||||
// Step 3: 打开串口(使用中断接收)
|
||||
rt_err_t result = rt_device_open(serial, RT_DEVICE_FLAG_INT_RX | RT_DEVICE_FLAG_INT_TX);
|
||||
if (result != RT_EOK)
|
||||
{
|
||||
rt_kprintf("Failed to open %s with INT, error=%d\n", SAMPLE_UART_NAME, result);
|
||||
LOG_E("Failed to open %s, error=%d", SAMPLE_UART_NAME, result);
|
||||
return;
|
||||
}
|
||||
|
||||
// 设置接收回调(用于接收 IDLE 事件)
|
||||
// Step 4: 设置回调
|
||||
rt_device_set_rx_indicate(serial, uart_rx_ind);
|
||||
|
||||
rt_kprintf("UART thread (IDLE mode) running on %s...\n", SAMPLE_UART_NAME);
|
||||
LOG_I("SCCM thread (IDLE mode) running on %s", SAMPLE_UART_NAME);
|
||||
|
||||
while (1)
|
||||
{
|
||||
// 等待空闲中断通知
|
||||
if (rt_sem_take(&rx_sem, RT_WAITING_FOREVER) == RT_EOK)
|
||||
{
|
||||
// 读取完整行
|
||||
len = read_line_from_uart(input, sizeof(input));
|
||||
if (len <= 0) continue;
|
||||
{
|
||||
// 等待数据就绪
|
||||
if (rt_sem_take(&rx_sem, RT_WAITING_FOREVER) == RT_EOK)
|
||||
{
|
||||
// 处理接收到的数据(提取完整行)
|
||||
while ((len = get_line(input, sizeof(input))) > 0)
|
||||
{
|
||||
// 动态分配请求结构体(见之前完整代码)
|
||||
struct proc_request *req = rt_malloc(sizeof(struct proc_request));
|
||||
if (!req) continue;
|
||||
|
||||
// 构造请求
|
||||
struct proc_request *req = rt_malloc(sizeof(struct proc_request));
|
||||
if (!req) continue;
|
||||
rt_strncpy(req->input, input, sizeof(req->input));
|
||||
req->input_len = len;
|
||||
//req->input[len]='\0';
|
||||
|
||||
rt_strncpy(req->input, input, sizeof(req->input) - 1);
|
||||
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);
|
||||
|
||||
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_WAITING_FOREVER) == RT_EOK)
|
||||
{
|
||||
rt_device_write(serial, 0, req->output, req->output_len);
|
||||
}
|
||||
}
|
||||
|
||||
// 发送至处理队列
|
||||
if (rt_mq_send(proc_mq, &req, sizeof(req)) == RT_EOK)
|
||||
{
|
||||
// 等待响应
|
||||
if (rt_sem_take(req->sem, RT_WAITING_FOREVER) == RT_EOK)
|
||||
{
|
||||
rt_device_write(serial, 0, req->output, req->output_len);
|
||||
}
|
||||
}
|
||||
|
||||
// 清理资源
|
||||
rt_sem_detach(req->sem);
|
||||
rt_free(req->sem);
|
||||
rt_free(req);
|
||||
}
|
||||
}
|
||||
// 清理
|
||||
rt_sem_detach(req->sem); // 或 rt_sem_delete
|
||||
rt_free(req->sem);
|
||||
rt_free(req);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 启动 UART 线程
|
||||
int start_uart_thread(void)
|
||||
{
|
||||
rt_thread_t tid = rt_thread_create("data_uart",
|
||||
uart_thread_entry,
|
||||
RT_NULL,
|
||||
2048, // 栈大小(2KB 足够)
|
||||
25, // 优先级
|
||||
10); // 时间片
|
||||
2048,
|
||||
25,
|
||||
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;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -438,7 +438,7 @@ rt_err_t db_send_command(enum db_cmd_type type, const char* sql, rt_int32_t time
|
||||
void thread_DB_SQLite(void)
|
||||
{
|
||||
rt_thread_t tid;
|
||||
tid = rt_thread_create("db_sql", db_sqlite, RT_NULL, 1024 *32, 3, 10);
|
||||
tid = rt_thread_create("db_sql", db_sqlite, RT_NULL, 1024 *32, 20, 10);
|
||||
|
||||
if (tid != RT_NULL)
|
||||
{
|
||||
|
||||
Reference in new issue
Block a user