diff --git a/.config b/.config index e45f21e..4241799 100644 --- a/.config +++ b/.config @@ -536,6 +536,7 @@ CONFIG_PKG_CJSON_VER="v1.7.17" # CONFIG_PKG_USING_RVBACKTRACE is not set # CONFIG_PKG_USING_HPATCHLITE is not set # CONFIG_PKG_USING_THREAD_METRIC is not set +# CONFIG_PKG_USING_UORB is not set # end of tools packages # @@ -630,7 +631,13 @@ CONFIG_PKG_USING_SQLITE_V3193=y # CONFIG_PKG_USING_FLASH_BLOB is not set # CONFIG_PKG_USING_MLIBC is not set # CONFIG_PKG_USING_TASK_MSG_BUS is not set -# CONFIG_PKG_USING_UART_FRAMEWORK is not set +CONFIG_PKG_USING_UART_FRAMEWORK=y +CONFIG_PKG_UART_FRAMEWORK_PATH="/packages/system/UartFramework" +# CONFIG_PKG_USING_UART_FRAMEWORK_V001 is not set +# CONFIG_PKG_USING_UART_FRAMEWORK_V004 is not set +# CONFIG_PKG_USING_UART_FRAMEWORK_V100 is not set +CONFIG_PKG_USING_UART_FRAMEWORK_LATEST_VERSION=y +CONFIG_PKG_UART_FRAMEWORK_VER="latest" # CONFIG_PKG_USING_SFDB is not set # CONFIG_PKG_USING_RTP is not set # CONFIG_PKG_USING_REB is not set diff --git a/.cproject b/.cproject index fb30876..a80b123 100644 --- a/.cproject +++ b/.cproject @@ -1,529 +1,534 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.settings/.rtmenus b/.settings/.rtmenus index 740e67b..c35ae97 100644 Binary files a/.settings/.rtmenus and b/.settings/.rtmenus differ diff --git a/.settings/language.settings.xml b/.settings/language.settings.xml index 0febdaf..ec88f73 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 index e9f6f20..a79984f 100644 --- a/applications/DATA/DATA_comm.c +++ b/applications/DATA/DATA_comm.c @@ -101,42 +101,44 @@ void pasre_DAT(const char *api, const char *json_str) cJSON_AddItemToObject(dat,"Groups",cJSON_CreateString(machine_ID)); } else if (strcmp(api, "SC810") == 0) - {//工单明细 - // === 解析整数变量 StepN === - GET_INT_VAR(StepN, root, "StepN", 0); - // 字符串赋值 - GET_STRING(Work, root, "Work", sizeof(Work)); - GET_STRING(Dye, root, "Dye", sizeof(Dye)); - GET_STRING(StepID, root, "StepID", sizeof(StepID)); - GET_STRING(SIDS1, root, "SIDS1", sizeof(SIDS1)); - GET_STRING(SIDS2, root, "SIDS2", sizeof(SIDS2)); - GET_STRING(SIDS3, root, "SIDS3", sizeof(SIDS3)); - // 浮点数赋值 - GET_FLOAT_VAR(P1, root, "P1", 0.0f); - GET_FLOAT_VAR(P2, root, "P2", 0.0f); - GET_FLOAT_VAR(P3, root, "P3", 0.0f); - GET_FLOAT_VAR(P4, root, "P4", 0.0f); - GET_FLOAT_VAR(P5, root, "P5", 0.0f); - GET_FLOAT_VAR(P1S1, root, "P1S1", 0.0f); - GET_FLOAT_VAR(P2S1, root, "P2S1", 0.0f); - GET_FLOAT_VAR(P3S1, root, "P3S1", 0.0f); - GET_FLOAT_VAR(P4S1, root, "P4S1", 0.0f); - GET_FLOAT_VAR(P5S1, root, "P5S1", 0.0f); - GET_FLOAT_VAR(P1S2, root, "P1S2", 0.0f); - GET_FLOAT_VAR(P2S2, root, "P2S2", 0.0f); - GET_FLOAT_VAR(P3S2, root, "P3S2", 0.0f); - GET_FLOAT_VAR(P4S2, root, "P4S2", 0.0f); - GET_FLOAT_VAR(P5S2, root, "P5S2", 0.0f); - GET_FLOAT_VAR(P1S3, root, "P1S3", 0.0f); - GET_FLOAT_VAR(P2S3, root, "P2S3", 0.0f); - GET_FLOAT_VAR(P3S3, root, "P3S3", 0.0f); - GET_FLOAT_VAR(P4S3, root, "P4S3", 0.0f); - GET_FLOAT_VAR(P5S3, root, "P5S3", 0.0f); - cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work)); - cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(Redye)); + { } - else if (strcmp(api, "SC811") == 0) { - printf("Processing:SC811\n"); + else if (strcmp(api, "SC811") == 0) + {//工单明细 + // === 解析整数变量 StepN === + GET_INT_VAR(StepN, root, "StepN", 0); + // 字符串赋值 + GET_STRING(Work, root, "Work", sizeof(Work)); + GET_STRING(Dye, root, "Dye", sizeof(Dye)); + GET_STRING(StepID, root, "StepID", sizeof(StepID)); + GET_STRING(SIDS1, root, "SIDS1", sizeof(SIDS1)); + GET_STRING(SIDS2, root, "SIDS2", sizeof(SIDS2)); + GET_STRING(SIDS3, root, "SIDS3", sizeof(SIDS3)); + // 浮点数赋值 + GET_FLOAT_VAR(P1, root, "P1", 0.0f); + GET_FLOAT_VAR(P2, root, "P2", 0.0f); + GET_FLOAT_VAR(P3, root, "P3", 0.0f); + GET_FLOAT_VAR(P4, root, "P4", 0.0f); + GET_FLOAT_VAR(P5, root, "P5", 0.0f); + GET_FLOAT_VAR(P1S1, root, "P1S1", 0.0f); + GET_FLOAT_VAR(P2S1, root, "P2S1", 0.0f); + GET_FLOAT_VAR(P3S1, root, "P3S1", 0.0f); + GET_FLOAT_VAR(P4S1, root, "P4S1", 0.0f); + GET_FLOAT_VAR(P5S1, root, "P5S1", 0.0f); + GET_FLOAT_VAR(P1S2, root, "P1S2", 0.0f); + GET_FLOAT_VAR(P2S2, root, "P2S2", 0.0f); + GET_FLOAT_VAR(P3S2, root, "P3S2", 0.0f); + GET_FLOAT_VAR(P4S2, root, "P4S2", 0.0f); + GET_FLOAT_VAR(P5S2, root, "P5S2", 0.0f); + GET_FLOAT_VAR(P1S3, root, "P1S3", 0.0f); + GET_FLOAT_VAR(P2S3, root, "P2S3", 0.0f); + GET_FLOAT_VAR(P3S3, root, "P3S3", 0.0f); + GET_FLOAT_VAR(P4S3, root, "P4S3", 0.0f); + GET_FLOAT_VAR(P5S3, root, "P5S3", 0.0f); + + cJSON_AddItemToObject(dat,"Work",cJSON_CreateString(Work)); + cJSON_AddItemToObject(dat,"ReDye",cJSON_CreateNumber(Redye)); + cJSON_AddItemToObject(dat,"StepN",cJSON_CreateNumber(StepN)); } else if (strcmp(api, "SC812") == 0) { printf("Processing:SC812\n"); @@ -295,18 +297,22 @@ void proc_thread_entry(void *parameter) if (!req) continue; memcpy(DATA_api,req->input,5); extract_between(req->input, "[", "]", machine_ID, sizeof(machine_ID)); + + char *p=strstr(req->input,"]"); if(!p){cjson_falg=0;} else { p += strlen("]"); } + //处理指令分析 pasre_DAT(DATA_api,p); // 回复 int16_t total_len = strlen(machine_ID) + strlen(json_buffer) + 8; char t_buffer[total_len]; - snprintf(t_buffer,total_len,"%s[%s]%s",DATA_api,machine_ID,json_buffer); + snprintf(t_buffer,total_len,"%s[%s]%s\n",DATA_api,machine_ID,json_buffer); req->output_len = rt_snprintf(req->output, sizeof(req->output),t_buffer); + // 通知 UART 线程可以发送了 if (req->sem) { diff --git a/applications/DATA/DATA_comm.h b/applications/DATA/DATA_comm.h index 5a3636b..41edfe6 100644 --- a/applications/DATA/DATA_comm.h +++ b/applications/DATA/DATA_comm.h @@ -11,7 +11,7 @@ #define APPLICATIONS_DATA_COMM_H_ // 最大输入/输出长度 -#define MAX_INPUT_LEN 1024 +#define MAX_INPUT_LEN 512 #define MAX_OUTPUT_LEN 1024*3 // 请求结构体 diff --git a/applications/DATA/DATA_uart.c b/applications/DATA/DATA_uart.c index ac4cf63..47d5566 100644 --- a/applications/DATA/DATA_uart.c +++ b/applications/DATA/DATA_uart.c @@ -14,7 +14,7 @@ #define SAMPLE_UART_NAME "uart2" #define DMA_RX_BUF_SIZE 512 -#define RINGBUF_SIZE 4096 +#define RINGBUF_SIZE 1024 static rt_device_t serial; @@ -74,21 +74,14 @@ void uart_thread_entry(void *parameter) { // 处理接收到的数据(提取完整行) while ((len = get_line(input, sizeof(input))) > 0) - { // 调试:打印每个字节 - /* rt_kprintf("Len=%d, Data: ", len); - for (int i = 0; i < len; i++) { - rt_kprintf("[%02X '%c'] ", input[i], - (input[i] >= 32 && input[i] < 127) ? input[i] : '.'); - } - rt_kprintf("\n"); - - 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->input[len]='\0'; req->sem = rt_malloc(sizeof(struct rt_semaphore)); if (!req->sem) { diff --git a/applications/DATA/uart_rs485.c b/applications/DATA/uart_rs485.c new file mode 100644 index 0000000..fb3fff7 --- /dev/null +++ b/applications/DATA/uart_rs485.c @@ -0,0 +1,152 @@ +/* + * 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 +#include "uart_framework.h" +#include "data_comm.h" + +#define LOG_TAG "uart.rx" +#define LOG_LVL LOG_LVL_DBG +//#include + +#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); + + //这里直接返回接收到的数据 + // rt_uint8_t *frame_data = data; + // rt_uint16_t frame_len = size; + // rt_kprintf("rx_buf", 16, frame_data, frame_len); + // rt_err_t res = uart_framework_send(uf, frame_data, frame_len); + + 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); diff --git a/applications/DATA/uart_rs485.h b/applications/DATA/uart_rs485.h new file mode 100644 index 0000000..43d41df --- /dev/null +++ b/applications/DATA/uart_rs485.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-25 Administrator the first version + */ +#ifndef APPLICATIONS_DATA_UART_RS485_H_ +#define APPLICATIONS_DATA_UART_RS485_H_ + +int app_uart_rs485_startup(void); + +#endif /* APPLICATIONS_DATA_UART_RS485_H_ */ diff --git a/applications/DBSQL/DB_SQLite.c b/applications/DBSQL/DB_SQLite.c index 0548067..ddda5c8 100644 --- a/applications/DBSQL/DB_SQLite.c +++ b/applications/DBSQL/DB_SQLite.c @@ -10,25 +10,262 @@ #include #include #include +#include #include "DB_SQLite.h" - +#include "sqlite3.h" #include -#define DB_NAME "/rt.db" +#define DB_NAME "/SC828.db" +int db_HelperInit; +sqlite3 **db; + +static const char *sql_upgrade_workorder_steps = + "CREATE TABLE WorkorderSteps (" + "WorkOrder VARCHAR," + "DYELOT VARCHAR," + "ProgramID VARCHAR," + "Program VARCHAR," + "ReDye INT DEFAULT (0)," + "Mode VARCHAR," + "Step INT," + "StepID VARCHAR," + "StepName VARCHAR," + "ParameterName VARCHAR," + "Parameter1 DOUBLE," + "Parameter2 DOUBLE," + "Parameter3 DOUBLE," + "Parameter4 DOUBLE," + "Parameter5 DOUBLE," + "Parameter6 INT," + "Parameter7 INT," + "Parameter8 INT," + "Parameter9 INT," + "Parameter10 INT," + "Remark VARCHAR," + "StepTime INT," + "StepID_S1 VARCHAR," + "StepID_S2 VARCHAR," + "StepID_S3 VARCHAR," + "StepName_S1 VARCHAR," + "StepName_S2 VARCHAR," + "StepName_S3 VARCHAR," + "Parameter1_S1 DOUBLE," + "Parameter1_S2 DOUBLE," + "Parameter1_S3 DOUBLE," + "Parameter2_S1 DOUBLE," + "Parameter2_S2 DOUBLE," + "Parameter2_S3 DOUBLE," + "Parameter3_S1 DOUBLE," + "Parameter3_S2 DOUBLE," + "Parameter3_S3 DOUBLE," + "Parameter4_S1 DOUBLE," + "Parameter4_S2 DOUBLE," + "Parameter4_S3 DOUBLE," + "Parameter5_S1 DOUBLE," + "Parameter5_S2 DOUBLE," + "Parameter5_S3 DOUBLE" + "); "; + +static const char *sql_upgrade_workorder_set = + "CREATE TABLE WorkOrderSet (" + "WorkOrder VARCHAR," + "ReDye INT DEFAULT (0)," + "PumpSpeed INT," + "Blower INT," + "Swing INT," + "ClothWheel INT," + "Nozzle INT" + "); "; + +static const char *sql_upgrade_workorder = + "CREATE TABLE WorkOrder (" + "WorkOrder VARCHAR," + "Dyelot VARCHAR," + "ReDye INT DEFAULT (0)," + "ProgramName VARCHAR," + "StartTime DATETIME," + "EndTime DATETIME," + "Time TEXT," + "lock INT," + "State INT," + "ProgramID VARCHAR," + "Machines VARCHAR," + "color VARCHAR," + "ColorNumber VARCHAR," + "Client VARCHAR," + "ClothWeight VARCHAR," + "ClothSpecies VARCHAR," + "BathRatio VARCHAR," + "Total VARCHAR," + "USER VARCHAR," + "ColorName VARCHAR," + "Remark TEXT" + "); "; + +static const char *sql_upgrade_run_table = + // "PRAGMA foreign_keys = OFF; " + // "BEGIN TRANSACTION; " + // "CREATE TABLE sqlitestudio_temp_table AS SELECT * FROM RUN; " + // "DROP TABLE RUN; " + "CREATE TABLE RUN (" + "WorkOrder VARCHAR," + "DYELOT VARCHAR," + "ReDye INT DEFAULT (0)," + "RUN INT," + "Mode VARCHAR," + "ProgramID VARCHAR," + "Program VARCHAR," + "StepID VARCHAR," + "Step INT," + "StepName VARCHAR," + "ParameterName VARCHAR," + "Parameter1 DOUBLE," + "Parameter2 DOUBLE," + "Parameter3 DOUBLE," + "Parameter4 DOUBLE," + "Parameter5 DOUBLE," + "Parameter6 INT," + "Parameter7 INT," + "Parameter8 INT," + "Parameter9 INT," + "Parameter10 INT," + "Remark VARCHAR," + "StepTime INT," + "StepID_S1 VARCHAR," + "StepID_S2 VARCHAR," + "StepID_S3 VARCHAR," + "StepName_S1 VARCHAR," + "StepName_S2 VARCHAR," + "StepName_S3 VARCHAR," + "Parameter1_S1 DOUBLE," + "Parameter1_S2 DOUBLE," + "Parameter1_S3 DOUBLE," + "Parameter2_S1 DOUBLE," + "Parameter2_S2 DOUBLE," + "Parameter2_S3 DOUBLE," + "Parameter3_S1 DOUBLE," + "Parameter3_S2 DOUBLE," + "Parameter3_S3 DOUBLE," + "Parameter4_S1 DOUBLE," + "Parameter4_S2 DOUBLE," + "Parameter4_S3 DOUBLE," + "Parameter5_S1 DOUBLE," + "Parameter5_S2 DOUBLE," + "Parameter5_S3 DOUBLE" + ");"; + +static const char *sql_upgrade_dyelot_table = + "CREATE TABLE Dyelot (" + "WorkOrder VARCHAR," + "Dyelot VARCHAR," + "ReDye INT," + "Machine VARCHAR," + "Step INT," + "Tank INT," + "State INT," + "ProductCode VARCHAR," + "ProductName VARCHAR," + "ProductType INT," + "Grams FLOAT," + "Amount FLOAT," + "CALL_TIME VARCHAR," + "DispenseEndTime VARCHAR," + "Type INT" + "); "; + +static const char *sql_upgrade_iolog_table = + // "CREATE TABLE sqlitestudio_temp_table AS SELECT * FROM IOLog; " + // "DROP TABLE IOLog; " + "CREATE TABLE IOLog (" + "ID varchar(32)," + "IOName varchar(32)," + "type varchar(32)," + "Value DOUBLE DEFAULT (0)," + "DIO BOOLEAN," + "AIO INTEGER DEFAULT (0)," + "PLC varchar(32)" + "); "; + +static const char *sql_upgrade_chart_table = + "CREATE TABLE Chart (" + "WorkOrder varchar(32)," + "DYELOT varchar(32)," + "ReDye INTEGER ," + "Name varchar(32)," + "Time varchar(32)," + "MTT DOUBLE DEFAULT (0)," + "MTL DOUBLE DEFAULT (0)," + "STTA DOUBLE DEFAULT (0)," + "STLA DOUBLE DEFAULT (0)," + "STTB DOUBLE DEFAULT (0)," + "STLB DOUBLE DEFAULT (0)," + "STTC DOUBLE DEFAULT (0)," + "STLC DOUBLE DEFAULT (0)," + "MTH DOUBLE DEFAULT (0)," + "MST DOUBLE DEFAULT (0)," + "MSL DOUBLE DEFAULT (0)," + "MUT DOUBLE DEFAULT (0)" + "); "; void db_sqlite(void *parameter) { - int db_HelperInit; - int db_; + if (access(DB_NAME, F_OK) == 0) + { + rt_kprintf("DB open\n"); + if (db_connect(DB_NAME) == RT_EOK){ + if(db_table_is_exist("WorkorderSteps")<=0){ + if(db_create_database(sql_upgrade_workorder_steps)==0) + {rt_kprintf("WorkorderSteps Created successfully \n");}else{rt_kprintf("WorkorderSteps Creation failed \n");} + } + if(db_table_is_exist("WorkOrderSet")<=0){ + if(db_create_database(sql_upgrade_workorder_set)==0) + {rt_kprintf("WorkOrderSet Created successfully \n");}else{rt_kprintf("WorkOrderSet Creation failed \n");} + } + if(db_table_is_exist("WorkOrder")<=0){ + if(db_create_database(sql_upgrade_workorder)==0) + {rt_kprintf("WorkOrder Created successfully \n");}else{rt_kprintf("WorkOrder Creation failed \n");} + } + if(db_table_is_exist("RUN")<=0){ + if(db_create_database(sql_upgrade_run_table)==0) + {rt_kprintf("RUN Created successfully \n");}else{rt_kprintf("RUN Creation failed \n");} + } + if(db_table_is_exist("Dyelot")<=0){ + if(db_create_database(sql_upgrade_dyelot_table)==0) + {rt_kprintf("Dyelot Created successfully \n");}else{rt_kprintf("Dyelot Creation failed \n");} + } + if(db_table_is_exist("IOLog")<=0){ + if(db_create_database(sql_upgrade_iolog_table)==0) + {rt_kprintf("IOLog Created successfully \n");}else{rt_kprintf("IOLog Creation failed \n");} + } + if(db_table_is_exist("Chart")<=0){ + if(db_create_database(sql_upgrade_chart_table)==0) + {rt_kprintf("Chart Created successfully \n");}else{rt_kprintf("Chart Creation failed \n");} + } + }else{ + rt_kprintf("DB open failed \n"); + } + + }else{ + rt_kprintf("DB open failed \n"); + sqlite3_open(DB_NAME, db); + //创建表 + db_create_database(sql_upgrade_workorder_steps); + db_create_database(sql_upgrade_workorder_set); + db_create_database(sql_upgrade_workorder); + db_create_database(sql_upgrade_run_table); + db_create_database(sql_upgrade_dyelot_table); + db_create_database(sql_upgrade_iolog_table); + db_create_database(sql_upgrade_chart_table); + } - db_HelperInit = db_helper_init(); - if(db_HelperInit =RT_EOK){ - rt_kprintf("HelperInit database\n"); - }else { + // db_HelperInit = db_helper_init(); + // if(db_HelperInit =RT_EOK){ + // rt_kprintf("HelperInit database\n"); + // }else { + // sqlite3_open(DB_NAME, db); // 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); @@ -36,15 +273,12 @@ void db_sqlite(void *parameter) 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);"; @@ -57,7 +291,7 @@ 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); + tid = rt_thread_create("db_sqlite", db_sqlite, RT_NULL, 1024*64, 3, 15); if (tid != RT_NULL) { diff --git a/applications/main.c b/applications/main.c index a8a5478..dce0269 100644 --- a/applications/main.c +++ b/applications/main.c @@ -16,7 +16,7 @@ #include "RUN_LED.h" #include "DB_SQLite.h" #include "DATA_comm.h" -#include "DATA_uart.h" +#include "uart_rs485.h" #define DBG_TAG "main" #define DBG_LVL DBG_LOG @@ -28,10 +28,8 @@ int main(void) rt_sem_take(mount_sem, rt_tick_from_millisecond(5000)); // 等待挂载完成,最多等待 5 秒 thread_RUN_LED();//运行指示灯线程 thread_DB_SQLite(); - - start_uart_thread(); data_comm_init(); - + app_uart_rs485_startup(); return RT_EOK; diff --git a/applications/mount_sdio_elmfatfs_pin.c b/applications/mount_sdio_elmfatfs_pin.c new file mode 100644 index 0000000..6a3291f --- /dev/null +++ b/applications/mount_sdio_elmfatfs_pin.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2025-10-22 Administrator the first version + */ +#include "dfs_fs.h" +#include +#include +#include"drv_common.h" + +#define DBG_TAG "sd_cd" +#define DBG_LVL DBG_LOG +#include + +// ==================== 配置参数 ==================== +#define SD_DEVICE_NAME "sd0" +#define MOUNT_POINT "/" + +// CD 引脚配置(根据你的 BSP 修改) +#define CD_PIN GET_PIN(A, 0) // 示例:PA0,根据实际修改! + +// 消息类型 +#define SD_EVENT_INSERTED 1 +#define SD_EVENT_REMOVED 2 + +// =============================================== +static rt_mq_t sd_event_mq = RT_NULL; +static rt_sem_t mount_sync_sem = RT_NULL; + +/** + * @brief CD 引脚中断回调 + */ +void cd_pin_irq(void *param) +{ + rt_uint8_t event; + rt_base_t level = rt_hw_interrupt_disable(); + + // 读取当前电平 + int pin_level = rt_pin_read(CD_PIN); + + if (pin_level == PIN_HIGH) + { + rt_kprintf("SD Card removed (CD high)\n"); + event = SD_EVENT_REMOVED; + } + else // PIN_LOW + { + rt_kprintf("SD Card inserted (CD low)\n"); + event = SD_EVENT_INSERTED; + } + + // 发送事件到消息队列 + if (sd_event_mq != RT_NULL) + { + rt_mq_send(sd_event_mq, &event, 1); + } + + rt_hw_interrupt_enable(level); +} + +/** + * @brief 初始化 CD 引脚为外部中断模式 + */ +int cd_pin_init(void) +{ + rt_pin_mode(CD_PIN, PIN_MODE_INPUT_PULLUP); // 内部上拉 + rt_pin_attach_irq(CD_PIN, PIN_IRQ_MODE_FALLING | PIN_IRQ_MODE_RISING, cd_pin_irq, RT_NULL); + rt_pin_irq_enable(CD_PIN, ENABLE); // 使能中断 + return 0; +} + +/** + * @brief 处理 SD 卡插拔事件的主线程 + */ +void sd_card_event_thread(void *parameter) +{ + uint8_t event; + rt_bool_t mounted = RT_FALSE; + + rt_kprintf("SD card event thread started...\n"); + + while (1) + { + // 等待事件 + if (rt_mq_recv(sd_event_mq, &event, 1, RT_WAITING_FOREVER) != RT_EOK) + continue; + + switch (event) + { + case SD_EVENT_INSERTED: + if (!mounted) + { + rt_kprintf("Initializing and mounting SD card...\n"); + + // 等待设备 ready(可选) + rt_thread_mdelay(100); + + // 尝试挂载 + if (dfs_mount(SD_DEVICE_NAME, MOUNT_POINT, "elm", 0, 0) == RT_EOK) + { + rt_kprintf("SD card mounted to %s\n", MOUNT_POINT); + mounted = RT_TRUE; + + // 通知其他模块可以使用 SD 卡 + if (mount_sync_sem) + rt_sem_release(mount_sync_sem); + } + else + { + rt_kprintf("Failed to mount SD card\n"); + } + } + break; + + case SD_EVENT_REMOVED: + if (mounted) + { + if (dfs_unmount(MOUNT_POINT) == 0) + { + rt_kprintf("SD card unmounted\n"); + mounted = RT_FALSE; + } + else + { + rt_kprintf("Unmount failed or not mounted\n"); + } + } + break; + + default: + break; + } + } +} + +/** + * @brief 启动 SD 卡热插拔检测 + */ +int stm32_sdcard_hotplug_init(void) +{ + rt_thread_t tid; + + // 创建事件消息队列 + sd_event_mq = rt_mq_create("sd_event", 1, 10, RT_IPC_FLAG_FIFO); + if (sd_event_mq == RT_NULL) + { + rt_kprintf("Failed to create message queue for SD event!\n"); + return -RT_ENOMEM; + } + + // 创建同步信号量(可选,用于通知挂载完成) + mount_sync_sem = rt_sem_create("sd_mount", 0, RT_IPC_FLAG_FIFO); + + // 创建事件处理线程 + tid = rt_thread_create("sd_event", + sd_card_event_thread, + RT_NULL, + 2048, + RT_THREAD_PRIORITY_MAX - 2, + 10); + if (tid != RT_NULL) + { + rt_thread_startup(tid); + LOG_I("SD event thread created\n"); + } + else + { + rt_kprintf("Failed to create SD event thread!\n"); + return -RT_ERROR; + } + + return RT_EOK; +} +//INIT_COMPONENT_EXPORT(cd_pin_init); +//INIT_APP_EXPORT(stm32_sdcard_hotplug_init); diff --git a/packages/UartFramework-latest b/packages/UartFramework-latest new file mode 160000 index 0000000..679392a --- /dev/null +++ b/packages/UartFramework-latest @@ -0,0 +1 @@ +Subproject commit 679392a4b6beb09dd3e2febe03c2aabc3f298412 diff --git a/packages/pkgs.json b/packages/pkgs.json index d0e9680..9abb50a 100644 --- a/packages/pkgs.json +++ b/packages/pkgs.json @@ -8,5 +8,10 @@ "path": "/packages/system/sqlite", "ver": "v3.19.3", "name": "SQLITE" + }, + { + "path": "/packages/system/UartFramework", + "ver": "latest", + "name": "UART_FRAMEWORK" } ] \ No newline at end of file diff --git a/rt-thread/components/dfs/filesystems/elmfat/dfs_elm.c b/rt-thread/components/dfs/filesystems/elmfat/dfs_elm.c index eb57034..b31626a 100644 --- a/rt-thread/components/dfs/filesystems/elmfat/dfs_elm.c +++ b/rt-thread/components/dfs/filesystems/elmfat/dfs_elm.c @@ -863,7 +863,7 @@ DSTATUS disk_status(BYTE drv) } /* Read Sector(s) */ -DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count) +/*DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count) { rt_size_t result; rt_device_t device = disk[drv]; @@ -875,10 +875,22 @@ DRESULT disk_read(BYTE drv, BYTE *buff, DWORD sector, UINT count) } return RES_ERROR; -} +}*/ +DRESULT disk_read(BYTE drv, BYTE *buff, LBA_t sector, UINT count) +{ + rt_size_t result; + rt_device_t device = disk[drv]; + result = rt_device_read(device, sector, buff, count); + if (result == count) + { + return RES_OK; + } + + return RES_ERROR; +} /* Write Sector(s) */ -DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count) +/*DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count) { rt_size_t result; rt_device_t device = disk[drv]; @@ -890,6 +902,19 @@ DRESULT disk_write(BYTE drv, const BYTE *buff, DWORD sector, UINT count) } return RES_ERROR; +}*/ +DRESULT disk_write(BYTE drv, const BYTE *buff, LBA_t sector, UINT count) +{ + rt_size_t result; + rt_device_t device = disk[drv]; + + result = rt_device_write(device, sector, buff, count); + if (result == count) + { + return RES_OK; + } + + return RES_ERROR; } /* Miscellaneous Functions */ @@ -1025,4 +1050,3 @@ void ff_memfree(void *mem) rt_free(mem); } #endif /* FF_USE_LFN == 3 */ - diff --git a/rt-thread/components/dfs/filesystems/elmfat/ffconf.h b/rt-thread/components/dfs/filesystems/elmfat/ffconf.h index d028648..e9ad2e5 100644 --- a/rt-thread/components/dfs/filesystems/elmfat/ffconf.h +++ b/rt-thread/components/dfs/filesystems/elmfat/ffconf.h @@ -2,20 +2,20 @@ / FatFs Functional Configurations /---------------------------------------------------------------------------*/ -#define FFCONF_DEF 86631 /* Revision ID */ +#define FFCONF_DEF 86631 /* Revision ID */ /*---------------------------------------------------------------------------/ / Function Configurations /---------------------------------------------------------------------------*/ -#define FF_FS_READONLY 0 +#define FF_FS_READONLY 0 /* This option switches read-only configuration. (0:Read/Write or 1:Read-only) / Read-only configuration removes writing API functions, f_write(), f_sync(), / f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree() / and optional writing functions as well. */ -#define FF_FS_MINIMIZE 0 +#define FF_FS_MINIMIZE 0 /* This option defines minimization level to remove some basic API functions. / / 0: Basic functions are fully enabled. @@ -25,41 +25,41 @@ / 3: f_lseek() function is removed in addition to 2. */ -#define FF_USE_FIND 0 +#define FF_USE_FIND 0 /* This option switches filtered directory read functions, f_findfirst() and / f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */ -#define FF_USE_MKFS 1 +#define FF_USE_MKFS 1 /* This option switches f_mkfs() function. (0:Disable or 1:Enable) */ -#define FF_USE_FASTSEEK 1 +#define FF_USE_FASTSEEK 1 /* This option switches fast seek function. (0:Disable or 1:Enable) */ -#define FF_USE_EXPAND 0 +#define FF_USE_EXPAND 0 /* This option switches f_expand function. (0:Disable or 1:Enable) */ -#define FF_USE_CHMOD 0 +#define FF_USE_CHMOD 0 /* This option switches attribute manipulation functions, f_chmod() and f_utime(). / (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */ -#define FF_USE_LABEL 0 +#define FF_USE_LABEL 0 /* This option switches volume label functions, f_getlabel() and f_setlabel(). / (0:Disable or 1:Enable) */ -#define FF_USE_FORWARD 0 +#define FF_USE_FORWARD 0 /* This option switches f_forward() function. (0:Disable or 1:Enable) */ -#define FF_USE_STRFUNC 0 -#define FF_PRINT_LLI 0 -#define FF_PRINT_FLOAT 0 -#define FF_STRF_ENCODE 3 +#define FF_USE_STRFUNC 0 +#define FF_PRINT_LLI 0 +#define FF_PRINT_FLOAT 0 +#define FF_STRF_ENCODE 3 /* FF_USE_STRFUNC switches string functions, f_gets(), f_putc(), f_puts() and / f_printf(). / @@ -85,9 +85,9 @@ /---------------------------------------------------------------------------*/ #ifdef RT_DFS_ELM_CODE_PAGE -# define FF_CODE_PAGE RT_DFS_ELM_CODE_PAGE +# define FF_CODE_PAGE RT_DFS_ELM_CODE_PAGE #else -# define FF_CODE_PAGE 936 +# define FF_CODE_PAGE 936 #endif /* This option specifies the OEM code page to be used on the target system. / Incorrect code page setting can cause a file open failure. @@ -118,11 +118,11 @@ #if RT_DFS_ELM_USE_LFN -#define FF_USE_LFN RT_DFS_ELM_USE_LFN -#define FF_MAX_LFN RT_DFS_ELM_MAX_LFN +#define FF_USE_LFN RT_DFS_ELM_USE_LFN +#define FF_MAX_LFN RT_DFS_ELM_MAX_LFN #else -#define FF_USE_LFN 0 /* 0 to 3 */ -#define FF_MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ +#define FF_USE_LFN 0 /* 0 to 3 */ +#define FF_MAX_LFN 255 /* Maximum LFN length to handle (12 to 255) */ #endif /* The FF_USE_LFN switches the support for LFN (long file name). / @@ -152,9 +152,9 @@ / / Also behavior of string I/O functions will be affected by this option. / When LFN is not enabled, this option has no effect. */ -#define FF_LFN_UNICODE RT_DFS_ELM_LFN_UNICODE /* 0:ANSI/OEM or 1:Unicode */ +#define FF_LFN_UNICODE RT_DFS_ELM_LFN_UNICODE /* 0:ANSI/OEM or 1:Unicode */ #else -#define FF_LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ +#define FF_LFN_UNICODE 0 /* 0:ANSI/OEM or 1:Unicode */ #endif /* This option switches the character encoding on the API when LFN is enabled. / @@ -167,15 +167,15 @@ / When LFN is not enabled, this option has no effect. */ -#define FF_LFN_BUF 255 -#define FF_SFN_BUF 12 +#define FF_LFN_BUF 255 +#define FF_SFN_BUF 12 /* This set of options defines size of file name members in the FILINFO structure / which is used to read out directory items. These values should be suffcient for / the file names to read. The maximum possible length of the read file name depends / on character encoding. When LFN is not enabled, these options have no effect. */ -#define FF_FS_RPATH 0 +#define FF_FS_RPATH 0 /* This option configures support for relative path. / / 0: Disable relative path and remove related functions. @@ -191,13 +191,13 @@ #ifdef RT_DFS_ELM_DRIVES #define FF_VOLUMES RT_DFS_ELM_DRIVES #else -#define FF_VOLUMES 1 +#define FF_VOLUMES 1 #endif /* Number of volumes (logical drives) to be used. (1-10) */ -#define FF_STR_VOLUME_ID 0 -#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" +#define FF_STR_VOLUME_ID 0 +#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3" /* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings. / When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive / number in the path name. FF_VOLUME_STRS defines the volume ID strings for each @@ -210,7 +210,7 @@ */ -#define FF_MULTI_PARTITION 0 +#define FF_MULTI_PARTITION 0 /* This option switches support for multiple volumes on the physical drive. / By default (0), each logical drive number is bound to the same physical drive / number and only an FAT volume found on the physical drive will be mounted. @@ -219,11 +219,11 @@ / funciton will be available. */ -#define FF_MIN_SS 512 +#define FF_MIN_SS 512 #ifdef RT_DFS_ELM_MAX_SECTOR_SIZE #define FF_MAX_SS RT_DFS_ELM_MAX_SECTOR_SIZE #else -#define FF_MAX_SS 512 /* 512, 1024, 2048 or 4096 */ +#define FF_MAX_SS 512 /* 512, 1024, 2048 or 4096 */ #endif /* This set of options configures the range of sector size to be supported. (512, / 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and @@ -233,17 +233,17 @@ / GET_SECTOR_SIZE command. */ -#define FF_LBA64 0 +#define FF_LBA64 1 /* This option switches support for 64-bit LBA. (0:Disable or 1:Enable) / To enable the 64-bit LBA, also exFAT needs to be enabled. (FF_FS_EXFAT == 1) */ -#define FF_MIN_GPT 0x10000000 +#define FF_MIN_GPT 0x10000000 /* Minimum number of sectors to switch GPT as partitioning format in f_mkfs and / f_fdisk function. 0x100000000 max. This option has no effect when FF_LBA64 == 0. */ -#define FF_USE_TRIM 0 +#define FF_USE_TRIM 0 /* This option switches support for ATA-TRIM. (0:Disable or 1:Enable) / To enable Trim function, also CTRL_TRIM command should be implemented to the / disk_ioctl() function. */ @@ -254,26 +254,26 @@ / System Configurations /---------------------------------------------------------------------------*/ -#define FF_FS_TINY 0 +#define FF_FS_TINY 0 /* This option switches tiny buffer configuration. (0:Normal or 1:Tiny) / At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes. / Instead of private sector buffer eliminated from the file object, common sector / buffer in the filesystem object (FATFS) is used for the file data transfer. */ - +#define RT_DFS_ELM_USE_EXFAT//exfat支持 #ifdef RT_DFS_ELM_USE_EXFAT -#define FF_FS_EXFAT 1 +#define FF_FS_EXFAT 1 #else -#define FF_FS_EXFAT 0 +#define FF_FS_EXFAT 0 #endif /* This option switches support for exFAT filesystem. (0:Disable or 1:Enable) / To enable exFAT, also LFN needs to be enabled. (FF_USE_LFN >= 1) / Note that enabling exFAT discards ANSI C (C89) compatibility. */ -#define FF_FS_NORTC 0 -#define FF_NORTC_MON 1 -#define FF_NORTC_MDAY 1 -#define FF_NORTC_YEAR 2020 +#define FF_FS_NORTC 0 +#define FF_NORTC_MON 1 +#define FF_NORTC_MDAY 1 +#define FF_NORTC_YEAR 2020 /* The option FF_FS_NORTC switches timestamp functiton. If the system does not have / any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable / the timestamp function. Every object modified by FatFs will have a fixed timestamp @@ -284,7 +284,7 @@ / These options have no effect in read-only configuration (FF_FS_READONLY = 1). */ -#define FF_FS_NOFSINFO 0 +#define FF_FS_NOFSINFO 0 /* If you need to know correct free space on the FAT32 volume, set bit 0 of this / option, and f_getfree() function at first time after volume mount will force / a full FAT scan. Bit 1 controls the use of last allocated cluster number. @@ -296,7 +296,7 @@ */ -#define FF_FS_LOCK 0 +#define FF_FS_LOCK 0 /* The option FF_FS_LOCK switches file lock function to control duplicated file open / and illegal operation to open objects. This option must be 0 when FF_FS_READONLY / is 1. @@ -308,18 +308,18 @@ / lock control is independent of re-entrancy. */ -/* #include // O/S definitions */ +/* #include // O/S definitions */ #include #ifdef RT_DFS_ELM_REENTRANT -#define FF_FS_REENTRANT 1 /* 0 or 1 */ +#define FF_FS_REENTRANT 1 /* 0 or 1 */ #else -#define FF_FS_REENTRANT 0 /* 0:Disable or 1:Enable */ +#define FF_FS_REENTRANT 0 /* 0:Disable or 1:Enable */ #endif #ifndef RT_DFS_ELM_MUTEX_TIMEOUT #define RT_DFS_ELM_MUTEX_TIMEOUT 3000 #endif -#define FF_FS_TIMEOUT RT_DFS_ELM_MUTEX_TIMEOUT -#define FF_SYNC_t rt_mutex_t +#define FF_FS_TIMEOUT RT_DFS_ELM_MUTEX_TIMEOUT +#define FF_SYNC_t rt_mutex_t /* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs / module itself. Note that regardless of this option, file access to different / volume is always re-entrant and volume control functions, f_mount(), f_mkfs() diff --git a/rtconfig.h b/rtconfig.h index d7332ff..aa3d070 100644 --- a/rtconfig.h +++ b/rtconfig.h @@ -234,6 +234,8 @@ #define PKG_SQLITE_SQL_MAX_LEN 1024 #define PKG_SQLITE_DB_NAME_MAX_LEN 64 #define PKG_USING_SQLITE_V3193 +#define PKG_USING_UART_FRAMEWORK +#define PKG_USING_UART_FRAMEWORK_LATEST_VERSION /* end of system packages */ /* peripheral libraries and drivers */