diff --git a/.config b/.config index 280b4c1..e45f21e 100644 --- a/.config +++ b/.config @@ -160,7 +160,7 @@ CONFIG_RT_USING_DEVICE_IPC=y CONFIG_RT_USING_SERIAL=y CONFIG_RT_USING_SERIAL_V1=y # CONFIG_RT_USING_SERIAL_V2 is not set -# CONFIG_RT_SERIAL_USING_DMA is not set +CONFIG_RT_SERIAL_USING_DMA=y CONFIG_RT_SERIAL_RB_BUFSZ=64 # CONFIG_RT_USING_CAN is not set # CONFIG_RT_USING_HWTIMER is not set diff --git a/.cproject b/.cproject index d284003..84e6af8 100644 --- a/.cproject +++ b/.cproject @@ -1,339 +1,435 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index e18944c..0febdaf 100644 --- a/.settings/language.settings.xml +++ b/.settings/language.settings.xml @@ -5,7 +5,7 @@ - + diff --git a/applications/DATA/DATA_comm.c b/applications/DATA/DATA_comm.c new file mode 100644 index 0000000..ed0abdc --- /dev/null +++ b/applications/DATA/DATA_comm.c @@ -0,0 +1,60 @@ +/* + * 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 + */ +/* DATA_comm.c */ +#include +#include "data_comm.h" + +rt_mq_t proc_mq; + +void proc_thread_entry(void *parameter) +{ + struct proc_request *req; + + while (1) + { + // 接收请求指针 + if (rt_mq_recv(proc_mq, &req, sizeof(req), RT_WAITING_FOREVER) == RT_EOK) + { + if (!req) continue; + + rt_kprintf("Processing: %.*s\n", req->input_len, req->input); + + // 示例处理:回显 + req->output_len = rt_snprintf(req->output, sizeof(req->output), + "Echo: %.*s", req->input_len, req->input); + + // 通知 UART 线程可以发送了 + if (req->sem) + { + rt_sem_release(req->sem); + } + } + } +} + +int data_comm_init(void) +{ + proc_mq = rt_mq_create("proc_mq", sizeof(struct proc_request*), 5, RT_IPC_FLAG_FIFO); + if (proc_mq == RT_NULL) + { + rt_kprintf("Failed to create message queue!\n"); + return -1; + } + + rt_thread_t tid = rt_thread_create("proc", proc_thread_entry, RT_NULL, + 2048, 20, 10); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + + return 0; +} +//INIT_COMPONENT_EXPORT(data_comm_init); diff --git a/applications/DATA/DATA_comm.h b/applications/DATA/DATA_comm.h new file mode 100644 index 0000000..e35b528 --- /dev/null +++ b/applications/DATA/DATA_comm.h @@ -0,0 +1,31 @@ +/* + * 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 + */ +#ifndef APPLICATIONS_DATA_COMM_H_ +#define APPLICATIONS_DATA_COMM_H_ + +// 最大输入/输出长度 +#define MAX_INPUT_LEN 512 +#define MAX_OUTPUT_LEN 1024 + +// 请求结构体 +struct proc_request { + char input[MAX_INPUT_LEN]; + int input_len; + char output[MAX_OUTPUT_LEN]; + int output_len; + struct rt_semaphore *sem; // 指向动态分配的信号量 +}; + +// 消息队列(供外部使用) +extern rt_mq_t proc_mq; + +int data_comm_init(void); + +#endif /* APPLICATIONS_DATA_COMM_H_ */ diff --git a/applications/DATA/DATA_uart.c b/applications/DATA/DATA_uart.c new file mode 100644 index 0000000..ca3cfe2 --- /dev/null +++ b/applications/DATA/DATA_uart.c @@ -0,0 +1,151 @@ +/* + * 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 + */ +/* DATA_uart.c */ +#include +#include +#include "data_comm.h" + +#define SAMPLE_UART_NAME "uart2" +#define DMA_RX_BUF_SIZE 512 +#define RINGBUF_SIZE 4096 + +static rt_device_t serial; + +// DMA 接收缓冲区 +static rt_uint8_t dma_rx_buffer[DMA_RX_BUF_SIZE]; + +// 环形缓冲区(暂存未完整报文) +static struct rt_ringbuffer rx_rb; +static rt_uint8_t rb_pool[RINGBUF_SIZE]; + +// 接收回调信号量 +static struct rt_semaphore rx_sem; + +// 函数声明 +static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size); +static int get_line(char *buf, int maxlen); + +void uart_thread_entry(void *parameter) +{ + char input[MAX_INPUT_LEN]; + int len; + + // 初始化环形缓冲区和信号量 + rt_ringbuffer_init(&rx_rb, rb_pool, sizeof(rb_pool)); + 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); + return; + } + + // 配置串口参数(只设置 bufsz,去掉 dma_rx) + struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; + config.bufsz = DMA_RX_BUF_SIZE; // 设置接收缓冲区大小 + + rt_device_control(serial, RT_DEVICE_CTRL_CONFIG, &config); + + // 打开设备:关键!使用 RT_DEVICE_FLAG_DMA_RX 启用 DMA 接收 + rt_err_t result = rt_device_open(serial, RT_DEVICE_FLAG_DMA_RX | RT_DEVICE_FLAG_DMA_TX); + if (result != RT_EOK) + { + rt_kprintf("Failed to open %s with DMA, error=%d\n", SAMPLE_UART_NAME, result); + return; + } + + // 设置接收指示回调(DMA 完成或中断后调用) + rt_device_set_rx_indicate(serial, uart_rx_ind); + + rt_kprintf("UART DMA thread running...\n"); + + while (1) + { + // 等待数据就绪 + if (rt_sem_take(&rx_sem, RT_WAITING_FOREVER) == RT_EOK) + { + // 处理接收到的数据(提取完整行) + while ((len = get_line(input, sizeof(input))) > 0) + { + rt_kprintf("Received: %.*s\n", len, input); + + // 动态分配请求结构体(见之前完整代码) + 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->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); + } + } + + // 清理 + rt_sem_detach(req->sem); // 或 rt_sem_delete + rt_free(req->sem); + rt_free(req); + } + } + } +} +// DMA 接收回调 +static rt_err_t uart_rx_ind(rt_device_t dev, rt_size_t size) +{ + rt_ringbuffer_put(&rx_rb, (const rt_uint8_t*)dma_rx_buffer, size); + rt_sem_release(&rx_sem); // 通知线程处理 + return RT_EOK; +} + +// 从环形缓冲区提取一行 +static int get_line(char *buf, int maxlen) +{ + int i = 0; + char ch; + + while (rt_ringbuffer_getchar(&rx_rb, &ch) == 1) + { + if (ch == '\n' || ch == '\r') { + if (i > 0) break; + continue; + } + if (i < maxlen - 1) buf[i++] = ch; + } + buf[i] = '\0'; + return i > 0 ? i : 0; +} + +// 启动 UART 线程 +int start_uart_thread(void) +{ + rt_thread_t tid = rt_thread_create("uart_rx", uart_thread_entry, RT_NULL, + 4096, // 栈大小:4KB + 25, // 优先级 + 10); // 时间片 + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + return 0; +} +//INIT_COMPONENT_EXPORT(start_uart_thread); diff --git a/applications/DATA/DATA_uart.h b/applications/DATA/DATA_uart.h new file mode 100644 index 0000000..12e7c93 --- /dev/null +++ b/applications/DATA/DATA_uart.h @@ -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-20 Administrator the first version + */ +#ifndef APPLICATIONS_DATA_UART_H_ +#define APPLICATIONS_DATA_UART_H_ + +int start_uart_thread(void); + +#endif /* APPLICATIONS_DATA_UART_H_ */ diff --git a/applications/DBSQL/DB_SQLite.c b/applications/DBSQL/DB_SQLite.c new file mode 100644 index 0000000..0548067 --- /dev/null +++ b/applications/DBSQL/DB_SQLite.c @@ -0,0 +1,71 @@ +/* + * 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 + */ +#include +#include +#include +#include "DB_SQLite.h" + +#include +#define DB_NAME "/rt.db" + +void db_sqlite(void *parameter) +{ + int db_HelperInit; + int db_; + + db_HelperInit = db_helper_init(); + + if(db_HelperInit =RT_EOK){ + rt_kprintf("HelperInit database\n"); + }else { + // db_ = db_create_database("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);"); + // if(db_=0){rt_kprintf("database ok\n");}else{rt_kprintf("database no\n");} + } + + /* int fd = 0; + const char *dbname = db_get_name(); + fd = open(dbname, O_RDONLY); + if (fd > 0) + rt_kprintf("%s exist\r\n", dbname); + else + rt_kprintf("%s not exist\r\n"); + + + const char *sql = "CREATE TABLE IF NOT EXISTS student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);"; + rt_kprintf("sql cmd: %s\r\n\r\n", sql); + int ret = db_create_database(sql); + rt_kprintf("sql ret: %d\r\n", ret);*/ + + // sqlite3_os_init(); + + /* int rc = db_connect("/rt.db"); + if (rc <0) { + const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);"; + int db_create_database(sql); + }*/ +} + +/* 线程 */ +void thread_DB_SQLite(void) +{ + /* 初始化线程 1,名称是 thread1,入口是 thread1_entry*/ + rt_thread_t tid; + tid = rt_thread_create("db_sqlite", db_sqlite, RT_NULL, 1024*32, 3, 10); + + if (tid != RT_NULL) + { + rt_thread_startup(tid); + } + else + { + rt_kprintf("Failed to create sqlite_sys thread!\n"); + } + // return 0; +} diff --git a/applications/DBSQL/DB_SQLite.h b/applications/DBSQL/DB_SQLite.h new file mode 100644 index 0000000..34de0eb --- /dev/null +++ b/applications/DBSQL/DB_SQLite.h @@ -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-20 Administrator the first version + */ +#ifndef APPLICATIONS_DB_DB_SQLITE_H_ +#define APPLICATIONS_DB_SQLITE_SYS_H_ + +void thread_DB_SQLite(void); + +#endif /* APPLICATIONS_DB_DB_SQLITE_H_ */ diff --git a/applications/RUN_LED/RUN_LED.c b/applications/RUN_LED/RUN_LED.c index 2eaef53..53fbab4 100644 --- a/applications/RUN_LED/RUN_LED.c +++ b/applications/RUN_LED/RUN_LED.c @@ -2,6 +2,7 @@ #include #include #include"drv_common.h" +#include "RUN_LED.h" #define LED_PIN GET_PIN(C,13) @@ -18,12 +19,12 @@ void RUN_LED(void *parameter) } } -/* 线程示例 */ +/* 线程 */ void thread_RUN_LED(void) { /* 初始化线程 1,名称是 thread1,入口是 thread1_entry*/ rt_thread_t tid; - tid = rt_thread_create("run_led", RUN_LED, RT_NULL, 512, 3, 10); + tid = rt_thread_create("run_led", RUN_LED, RT_NULL, 256, 3, 10); if (tid != RT_NULL) { diff --git a/applications/main.c b/applications/main.c index 46d49c2..aab594f 100644 --- a/applications/main.c +++ b/applications/main.c @@ -1,4 +1,6 @@ /* +#include +#include * Copyright (c) 2006-2025, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 @@ -12,61 +14,23 @@ #include "dfs_fs.h" #include #include "RUN_LED.h" - -#include -#define DB_NAME "/rt.db" +#include "DB_SQLite.h" #define DBG_TAG "main" #define DBG_LVL DBG_LOG -#include - +extern rt_sem_t mount_sem; // 引用上面SD挂载线程定义的信号量 int main(void) { - rt_thread_mdelay(100); //等待sd_mount线程挂载文件系统,可使用IPC信号量完成同步,提高实时性 - - thread_RUN_LED(); - - //int db_HelperInit; - // db_HelperInit = db_helper_init(); - - // if(db_HelperInit =RT_EOK){ - // rt_kprintf("HelperInit database\n"); - // } - - - - - - - - - // int db_helper_init(); - - // sqlite3 *db; - // int8_t rc; - - // rc = sqlite3_open("rt.db", &db); - // if (rc != SQLITE_OK) - // { - //rt_kprintf("Cannot open database: %s\n", sqlite3_errmsg(db)); - //return -1; - // }else{ - // rt_kprintf("Database opened successfully\n"); - // sqlite3_close(db); - // } - // sqlite3_os_init(); - //if(int sqlite3_os_init()==RT_EOK){LOG_D("Sqlite int RT_EOK!");} + rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒 + thread_RUN_LED();//运行指示灯线程 + thread_DB_SQLite(); + start_uart_thread(); + data_comm_init(); - // sqlite3_os_init(); - /* int rc = db_connect("/rt.db"); - if (rc <0) { - const char *sql = "CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT,name varchar(32) NOT NULL,score INT NOT NULL);"; - int db_create_database(sql); - }*/ return RT_EOK; } diff --git a/applications/mount_sdio_elmfatfs.c b/applications/mount_sdio_elmfatfs.c index a6ce020..e107588 100644 --- a/applications/mount_sdio_elmfatfs.c +++ b/applications/mount_sdio_elmfatfs.c @@ -15,42 +15,81 @@ #define DBG_LVL DBG_LOG #include - +rt_sem_t mount_sem = RT_NULL; void sd_mount(void *parameter) { - while (1) - { - - if(rt_device_find("sd0") != RT_NULL) - { - if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK) - { - LOG_I("sd card mount to '/fatfs'"); - break; - } - else - { - LOG_W("sd card mount to '/fatfs' failed!"); - } - } - } + LOG_I("SD mount thread started, waiting for SD card..."); + int retry = 0; + while (retry<10) + { + if (rt_device_find("sd0") != RT_NULL) + { + if (dfs_mount("sd0", "/", "elm", 0, 0) == RT_EOK) + { + LOG_I("SD card mounted to '/' successfully"); + // 挂载成功,释放信号量 + if (mount_sem != RT_NULL) + { + rt_sem_release(mount_sem); + } + break; // 退出线程循环 + } + else + { + LOG_W("SD card mount failed, retrying..."); + } + } + else + { + LOG_D("SD device 'sd0' not found, retrying..."); + } + + // 避免空转,延时 100ms 再试 + rt_thread_mdelay(500); + retry++; + } } int stm32_sdcard_mount(void) { rt_thread_t tid; - tid = rt_thread_create("sd_mount", sd_mount, RT_NULL, - 1024*4, RT_THREAD_PRIORITY_MAX - 2, 20); - if (tid != RT_NULL) - { - rt_thread_startup(tid); - } - else - { - LOG_E("create sd_mount thread err!"); - } - return RT_EOK; + // 删除旧的信号量(如果存在) + if (mount_sem != RT_NULL) + { + rt_sem_delete(mount_sem); + } + + // 创建计数信号量,初始值为 0 + mount_sem = rt_sem_create("sd_mount", 0, RT_IPC_FLAG_FIFO); + if (mount_sem == RT_NULL) + { + LOG_E("Failed to create semaphore for SD mount!"); + return -RT_ENOMEM; + } + + tid = rt_thread_create("sd_mount", + sd_mount, + RT_NULL, + 4096, // 建议增大栈,避免溢出 + RT_THREAD_PRIORITY_MAX - 2, + 20); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + LOG_I("SD mount thread created and started"); + } + else + { + LOG_E("Failed to create SD mount thread!"); + rt_sem_delete(mount_sem); + mount_sem = RT_NULL; + return -RT_ERROR; + } + + return RT_EOK; } +// 使用 INIT_COMPONENTS_INIT 或 INIT_APP_EXPORT 自动启动 +//INIT_COMPONENTS_INIT(stm32_sdcard_mount); // 在组件初始化阶段运行 INIT_APP_EXPORT(stm32_sdcard_mount); diff --git a/drivers/board.h b/drivers/board.h index 338cb13..a56460c 100644 --- a/drivers/board.h +++ b/drivers/board.h @@ -71,6 +71,11 @@ extern "C" #define BSP_UART1_TX_PIN "PA9" #define BSP_UART1_RX_PIN "PA10" +#define BSP_USING_UART2 +#define BSP_UART2_TX_PIN "PA2" +#define BSP_UART2_RX_PIN "PA3" +#define BSP_UART2_TX_USING_DMA +#define BSP_UART2_RX_USING_DMA /*-------------------------- UART CONFIG END --------------------------*/ /*-------------------------- I2C CONFIG BEGIN --------------------------*/ diff --git a/rtconfig.h b/rtconfig.h index 873a24a..d7332ff 100644 --- a/rtconfig.h +++ b/rtconfig.h @@ -106,6 +106,7 @@ #define RT_USING_DEVICE_IPC #define RT_USING_SERIAL #define RT_USING_SERIAL_V1 +#define RT_SERIAL_USING_DMA #define RT_SERIAL_RB_BUFSZ 64 #define RT_USING_PIN #define RT_USING_SDIO