From 2c943baeafce6a09d806d7c27fb6b098bc9655be Mon Sep 17 00:00:00 2001 From: zzh <838331105@qq.com> Date: Mon, 22 Dec 2025 12:04:07 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E5=85=94=E5=96=9C=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E7=89=88=E6=9C=AC=E6=96=B0=E6=A0=B8=E5=BF=83=E6=9D=BF?= =?UTF-8?q?=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 11 ++ heartbeat_test.c | 188 +++++++++++++++++++ main.c | 395 +++++++++++++++++++++++++++++++--------- mqtt_utils/mqtt_utils.c | 2 +- uart_can/uart_can.c | 9 +- uart_utils/read_utils.c | 204 ++++++++++----------- uart_utils/uart_utils.c | 14 ++ 7 files changed, 628 insertions(+), 195 deletions(-) create mode 100644 heartbeat_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4b5ae59..5444301 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,4 +104,15 @@ LINK_DIRECTORIES( ADD_EXECUTABLE(tx_server ${SRC_TX_SERVER}) TARGET_LINK_LIBRARIES(tx_server pthread dl curl ${CMAKE_CURRENT_LIST_DIR}/hiredis/libhiredis.a) +# --- Heartbeat test target --- +AUX_SOURCE_DIRECTORY(uart_utils DIR_HT_UART_UTILS) +AUX_SOURCE_DIRECTORY(uart_can DIR_HT_UART_CAN) +AUX_SOURCE_DIRECTORY(debug_print DIR_HT_DEBUG_PRINT) +ADD_EXECUTABLE(heartbeat_test + ${DIR_HT_UART_UTILS} + ${DIR_HT_UART_CAN} + ${DIR_HT_DEBUG_PRINT} + ${CMAKE_CURRENT_LIST_DIR}/heartbeat_test.c) +TARGET_LINK_LIBRARIES(heartbeat_test pthread) + diff --git a/heartbeat_test.c b/heartbeat_test.c new file mode 100644 index 0000000..b88c37c --- /dev/null +++ b/heartbeat_test.c @@ -0,0 +1,188 @@ +#include +#include +#include +#include +#include +#include +#include + +#define DBG_TAG "heartbeat_test" +#define DBG_LVL DBG_INFO +#include "debug_print.h" + +#include "uart_utils.h" +#include "uart_can.h" + +static void gpio_init_113_117(void) { + int fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd >= 0) { + write(fd, "113", 3); + write(fd, "117", 3); + close(fd); + } + fd = open("/sys/class/gpio/gpio113/direction", O_WRONLY); + if (fd >= 0) { write(fd, "out", 3); close(fd); } + fd = open("/sys/class/gpio/gpio117/direction", O_WRONLY); + if (fd >= 0) { write(fd, "out", 3); close(fd); } +} + +static void setGpio113High(void) { + int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY); + if (fd < 0) { LOG_I("Failed to open gpio113 value: %s\n", strerror(errno)); return; } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); +} + +static void setGpio117High(void) { + int fd = open("/sys/class/gpio/gpio117/value", O_WRONLY); + if (fd < 0) { LOG_I("Failed to open gpio117 value: %s\n", strerror(errno)); return; } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); +} + +static void print_usage(const char* prog) { + printf("用法: %s [-d 接收设备] [-D 发送设备] [-b 波特率] [-t 超时秒]\n", prog); + printf("示例: %s -d /dev/ttyS5 -D /dev/ttyS0 -b 115200 -t 120\n", prog); +} + +int main(int argc, char** argv) { + const char* recv_dev = "/dev/ttyS5"; // 接收使用 ttyS5(与主程序一致) + const char* send_dev = "/dev/ttyS0"; // 发送使用 ttyS0(与主程序一致) + int baud = 115200; // 115200 8N1 + int timeout_sec = 120; // 默认两分钟搜索统计窗口 + + // 去重统计:两分钟内统计 tagFeature==0x83 的唯一 (tagCode, batteryV) + typedef struct { uint32_t tagCode; uint16_t batteryV; } search_entry_t; + search_entry_t found[1024]; + int found_count = 0; + + int opt; + while ((opt = getopt(argc, argv, "d:D:b:t:h")) != -1) { + switch (opt) { + case 'd': recv_dev = optarg; break; + case 'D': send_dev = optarg; break; + case 'b': baud = atoi(optarg); break; + case 't': timeout_sec = atoi(optarg); break; + case 'h': default: print_usage(argv[0]); return 0; + } + } + + // 初始化并拉高GPIO,确保发收链路打开 + //gpio_init_113_117(); + //setGpio113High(); + //setGpio117High(); + + uart_utils_t uartSend = {0}; + uart_utils_t uartRecv = {0}; + if (uart_open(&uartSend, (char*)send_dev) < 0) { + printf("❌ 无法打开发送设备 %s: %s\n", send_dev, strerror(errno)); + return 1; + } + if (uart_init(&uartSend, baud, 8, 1, 'N', 0) < 0) { + printf("❌ 初始化发送串口失败: %s\n", strerror(errno)); + return 1; + } + if (uart_open(&uartRecv, (char*)recv_dev) < 0) { + printf("❌ 无法打开接收设备 %s: %s\n", recv_dev, strerror(errno)); + return 1; + } + if (uart_init(&uartRecv, baud, 8, 1, 'N', 0) < 0) { + printf("❌ 初始化接收串口失败: %s\n", strerror(errno)); + return 1; + } + + printf("=== 心跳接收测试 ===\n"); + printf("接收设备: %s, 发送设备: %s, 波特率: %d, 统计时长: %d秒\n", recv_dev, send_dev, baud, timeout_sec); + + // 发送前再次确保发送链路 + //setGpio113High(); + uart_data_send_head_search(&uartSend, 110); + usleep(50000); + uint16_t ack = 0; + int ack_ret = uart_data_receive_ack(&uartSend, &ack); + if (ack_ret == sizeof(jt_receive_package_t)) { + LOG_I("head_search ACK: %04x\n", ack); + } else if (ack_ret == -1) { + LOG_I("head_search ACK 超时未收\n"); + } else { + LOG_I("head_search ACK 非法帧\n"); + } + // 无论ACK是否返回,仍发送一次搜索包以触发广播反馈 + uart_data_send_search(&uartSend,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF); + + time_t start = time(NULL); + int total = 0; + int timeout_count = 0; + int invalid_count = 0; + while (time(NULL) - start < timeout_sec) { + // 接收前确保接收链路 + //setGpio117High(); + + uint16_t parmAck = 0; + uint32_t tagCode = 0; + uint8_t tagSignal = 0; + uint8_t totalLen = 0; + uint8_t tagFeature = 0; + uint8_t count = 0; + uint16_t batteryV = 0; + uint16_t version = 0; + uint8_t ledCtrl = 0; + uint8_t lable1 = 0; + uint16_t lable2 = 0; + uint32_t lable3 = 0; + + int ret = uart_data_receive_data_back(&uartRecv, &parmAck, &tagCode, &tagSignal, &totalLen, &tagFeature, + &count, &batteryV, &version, &ledCtrl, &lable1, &lable2, &lable3); + if (ret == sizeof(jt_data_back_package_t)) { + total++; + LOG_I("recv_heartbeat:%04x,%08x,%02x,%02x,%02x,%02x,%04x,%04x,%02x,%02x,%04x,%08x\n", + parmAck, tagCode, tagSignal, totalLen, tagFeature, count, batteryV, version, + ledCtrl, lable1, lable2, lable3); + + if (tagFeature == 0xFF) { + printf("❤ 心跳: tag=%08X battery=%d version=%04X signal=%u\n", + tagCode, batteryV, version, tagSignal); + } else if (tagFeature == 0x81) { + printf("🔘 按键: tag=%08X battery=%d version=%04X\n", tagCode, batteryV, version); + } else if (tagFeature == 0x82) { + printf("💡 灭灯反馈: tag=%08X battery=%d\n", tagCode, batteryV); + } else if (tagFeature == 0x83) { + printf("🔎 搜索反馈: tag=%08X battery=%d\n", tagCode, batteryV); + int dup = 0; + for (int i = 0; i < found_count; ++i) { + if (found[i].tagCode == tagCode && found[i].batteryV == batteryV) { dup = 1; break; } + } + if (!dup) { + if (found_count < (int)(sizeof(found)/sizeof(found[0]))) { + found[found_count].tagCode = tagCode; + found[found_count].batteryV = batteryV; + found_count++; + printf("📌 记录灯条(去重): tag=%08X battery=%d (当前总计=%d)\n", tagCode, batteryV, found_count); + } + } + } else { + printf("📨 其他特征(0x%02X): tag=%08X battery=%d\n", tagFeature, tagCode, batteryV); + } + } else if (ret == -1) { + timeout_count++; + usleep(50 * 1000); + } else { + invalid_count++; + usleep(10 * 1000); + } + } + + printf("=== 统计结果(两分钟内, 去重) 搜索反馈灯条: %d 条 ===\n", found_count); + for (int i = 0; i < found_count; ++i) { + printf("- tag=%08X battery=%d\n", found[i].tagCode, found[i].batteryV); + } + + printf("=== 结束: 共接收有效帧 %d 条, 超时 %d 次, 非法帧 %d 次 ===\n", total, timeout_count, invalid_count); + uart_uninit(&uartRecv); + uart_uninit(&uartSend); + return total > 0 ? 0 : 1; +} \ No newline at end of file diff --git a/main.c b/main.c index 6d13be4..d722b17 100644 --- a/main.c +++ b/main.c @@ -33,6 +33,7 @@ pthread_t pt_reboot; pthread_t pt_watchdog; pthread_t pt_tagsearch; pthread_t pt_removeduplicatetag; +pthread_t pt_simulate_3027; // 模拟3027任务线程 uart_utils_t uartSend = {0}; uart_utils_t uartRecvData = {0}; uart_utils_t uartRecvBack = {0}; @@ -64,7 +65,7 @@ int fd; int UPCASE=0; int count_value=0; int getPayloadTime=120*1000;//usecond -char softwareVersion[16]="1.1.41"; +char softwareVersion[16]="1.1.40"; char stationsn[16]="TJ251372224247";//TJ250995217957 char productid[8]="10045"; char appKey[32]="fdhQmhqhvbL1cf1K9mUqt"; @@ -145,6 +146,7 @@ static time_t label_buf_first_time = 0; void *thread_timeout_check(void *arg); void *thread_3015_lighton_merge(void *arg); void *thread_label_batch_send(void *arg); +void *thread_simulate_3027_task(void *arg); int getLedOtaVersion(char *filename); int getApOtaVersion(char *filename,char *modename); @@ -597,83 +599,156 @@ void otaAp(){ } void enableWatchDog() { - int fd; - char path[64]; - char value[2]; - - // Enable watchdog pin SGM820 - fd = open("/sys/class/gpio/export", O_WRONLY); - if (fd < 0) { - LOG_I("Failed to open gpio export: %s\n", strerror(errno)); - return; - } - write(fd, "1", 1); - close(fd); - - // Enable feed watchdog pin - fd = open("/sys/class/gpio/export", O_WRONLY); - if (fd < 0) { - LOG_I("Failed to open gpio export: %s\n", strerror(errno)); - return; - } - write(fd, "112", 3); - close(fd); - - // Set gpio1 direction - fd = open("/sys/class/gpio/gpio1/direction", O_WRONLY); - if (fd < 0) { - LOG_I("Failed to open gpio1 direction: %s\n", strerror(errno)); - return; - } - write(fd, "out", 3); - close(fd); - - // Set gpio112 direction - fd = open("/sys/class/gpio/gpio112/direction", O_WRONLY); - if (fd < 0) { - LOG_I("Failed to open gpio112 direction: %s\n", strerror(errno)); - return; - } - write(fd, "out", 3); - close(fd); - - // Set gpio1 value - fd = open("/sys/class/gpio/gpio1/value", O_WRONLY); - if (fd < 0) { - LOG_I("Failed to open gpio1 value: %s\n", strerror(errno)); - return; - } - write(fd, "1", 1); - close(fd); - - LOG_I("enable watchdog\n"); - - // Set gpio112 value - fd = open("/sys/class/gpio/gpio112/value", O_WRONLY); - if (fd < 0) { - LOG_I("Failed to open gpio112 value: %s\n", strerror(errno)); - return; - } - write(fd, "1", 1); - close(fd); + // 使用 /dev/watchdog 设备,第一次喂狗自动开启看门狗 + // 超时时间固定为5s,不喂狗时默认关闭 + LOG_I("watchdog will be enabled on first feed\n"); } void feedWatchDog() { - int fd = open("/sys/class/gpio/gpio112/value", O_WRONLY); + // 使用 /dev/watchdog 设备喂狗 + // 超时时间固定为5s,喂狗命令: echo "" > /dev/watchdog + int fd; + int gpio_fd = open("/sys/class/gpio/gpio112/value", O_WRONLY); + int led_state = 0; + + while(1) { + fd = open("/dev/watchdog", O_WRONLY); + if (fd < 0) { + LOG_I("can not open /dev/watchdog: %s\n", strerror(errno)); + sleep(1); + continue; + } + write(fd, "", 1); + close(fd); + + // 喂狗时翻转 gpio112 灯状态 + if (gpio_fd >= 0) { + led_state = !led_state; + write(gpio_fd, led_state ? "1" : "0", 1); + } + + sleep(1); // 每2秒喂一次狗,超时时间为5s + } + + if (gpio_fd >= 0) { + close(gpio_fd); + } +} + +// GPIO118控制函数 +void setGpio118Low() { + int fd = open("/sys/class/gpio/gpio118/value", O_WRONLY); if (fd < 0) { - LOG_I("can not open watchdog gpio112\n"); + LOG_I("Failed to open gpio118 value: %s\n", strerror(errno)); return; } - - while(1) { - write(fd, "0", 1); - usleep(100*1000); - write(fd, "1", 1); - sleep(1); - } - + write(fd, "0", 1); + usleep(100*1000); + write(fd, "0", 1); close(fd); - return; + LOG_I("GPIO118 set to LOW\n"); +} + +void setGpio118High() { + int fd = open("/sys/class/gpio/gpio118/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio118 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); + LOG_I("GPIO118 set to HIGH\n"); +} + +// GPIO113控制函数 +void setGpio113High() { + int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio113 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); + LOG_I("GPIO113 set to HIGH\n"); +} + +// GPIO114控制函数 +void setGpio114High() { + int fd = open("/sys/class/gpio/gpio114/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio114 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); + LOG_I("GPIO114 set to HIGH\n"); +} + +void setGpio113Low() { + int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio113 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + close(fd); + LOG_I("GPIO113 set to LOW\n"); +} + +// GPIO115控制函数 +void setGpio115High() { + int fd = open("/sys/class/gpio/gpio115/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio115 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); + LOG_I("GPIO115 set to HIGH\n"); +} + +void setGpio115Low() { + int fd = open("/sys/class/gpio/gpio115/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio115 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + close(fd); + LOG_I("GPIO115 set to LOW\n"); +} + +// GPIO117控制函数 +void setGpio117High() { + int fd = open("/sys/class/gpio/gpio117/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio117 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + usleep(100*1000); + write(fd, "1", 1); + close(fd); + LOG_I("GPIO117 set to HIGH\n"); +} + +void setGpio117Low() { + int fd = open("/sys/class/gpio/gpio117/value", O_WRONLY); + if (fd < 0) { + LOG_I("Failed to open gpio117 value: %s\n", strerror(errno)); + return; + } + write(fd, "0", 1); + close(fd); + LOG_I("GPIO117 set to LOW\n"); } void rebootSystem(void){ @@ -1540,7 +1615,7 @@ void getDevRawPassword(char *devsn){ // 首次获取密码成功后启动搜索标签功能(只运行一次) LOG_I("Starting tag search after first registration...\n"); isSearchLabelOntest = true; - searchTimeOut=20; + searchTimeOut=5; searchTimeOld=getCurrentTime(); while(isSearchLabelOntest) { @@ -1706,7 +1781,7 @@ error: /*================================================================================*/ void *thread_ota(void *arg){ prctl(PR_SET_NAME, "ota"); - checkOtaKey(); + //checkOtaKey(); } void *thread_mqtt(void *arg){ @@ -1727,6 +1802,7 @@ void *thread_reboot(void *arg){ void *thread_feed_watchdog(void *arg){ prctl(PR_SET_NAME, "watchdog"); feedWatchDog(); + return NULL; } #if 1 @@ -1777,7 +1853,7 @@ void *thread_tag_search_send(void *arg){ if(isSearchLabelOn){ sleep(10); searchTimeNew=getCurrentTime(); - if((searchTimeNew-searchTimeOld)>=(searchTimeOut-20)){ + if((searchTimeNew-searchTimeOld)>=(searchTimeOut)){ isSearchReport=true; search_tag_report(); isSearchReport=false; @@ -1812,8 +1888,9 @@ void *thread_uart_recv_ack(void *arg){ int ret=0; while(1){ + // 仅在成功收到ACK时打印日志并处理,减少超时噪声 ret=uart_data_receive_ack(&uartSend,&parm_ack); - if(ret>0){ + if(ret == sizeof(jt_receive_package_t)){ LOG_I("ack:%x\n",parm_ack); if(parm_ack==0x2323){ // 记录收到0x2323的时间,并设置等待0x4646标志 @@ -1900,7 +1977,10 @@ void *thread_uart_recv_ack(void *arg){ } #endif #if 1 - if(isSearchLabel){ + if(isSearchLabelOn || isSearchLabelOntest){ + //LOG_I("isSearchLabel!!!!!!!!!\n"); + //uart_data_send_head_search(&uartSend, 110); + //usleep(50000); uart_data_send_search(&uartSend,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF); isSearchLabel=false; } @@ -2021,13 +2101,22 @@ void *thread_uart_recv_data(void *arg){ uint8_t lable1; uint16_t lable2; uint32_t lable3; + + #if 1 while(1){ - uart_data_receive_data_back(&uartRecvData,&parmAck,&tagCode,&tagSignal,&totalLen,&tagFeature, + int ret = uart_data_receive_data_back(&uartRecvData,&parmAck,&tagCode,&tagSignal,&totalLen,&tagFeature, &count,&batteryV,&version,&ledCtrl,&lable1,&lable2,&lable3); //LOG_I("recv_data:%04x,%08x,%02x,%02x,%02x,%02x,%04x,%04x,%02x,%02x,%04x,%08x\n",parmAck,tagCode,tagSignal,totalLen, - // tagFeature,count,batteryV,version,ledCtrl,lable1,lable2,lable3); + //tagFeature,count,batteryV,version,ledCtrl,lable1,lable2,lable3); //sleep(2); + + if(ret <= 0) { + usleep(1000); // 1ms延时,避免空转 + } else { + usleep(100); // 0.1ms延时,保证处理效率 + } } + #endif } void *thread_uart_recv_back(void *arg){ @@ -2054,7 +2143,7 @@ void *thread_uart_recv_back(void *arg){ //} PutDataIntoQueue(tagCode,batteryV); if(tagFeature==0x83){ - //LOG_I("search tag:%08x,battery:%04x\n",tagCode,batteryV); + LOG_I("search tag:%08x,battery:%04x\n",tagCode,batteryV); }else if(tagFeature==0x82){ //LOG_I("light down tag:%08x,battery:%04x\n",tagCode,batteryV); light_off_tag_report(tagCode,batteryV); @@ -2063,6 +2152,8 @@ void *thread_uart_recv_back(void *arg){ LOG_I("key down tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version); }else if(tagFeature==0xff){ //LOG_I("heart tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version); + }else if(tagFeature==0x84) { + LOG_I("light on tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version); } } } @@ -2380,6 +2471,7 @@ void *thread_mqtt_recv(void *arg){ LOG_I("searchTimeOut:%d\n",searchTimeOut); searchTimeOld=getCurrentTime(); LOG_I("searchTimeOld:%d\n",searchTimeOld); + uart_data_send_head_search(&uartSend, 120); isSearchLabelOn=true; }else if(strcmp(mqtt_parm.msg_type,"3015")==0){ LOG_I("3015 light on (merge mode)\n"); @@ -2524,8 +2616,12 @@ void *thread_mqtt_recv(void *arg){ get_string_from_json_string_by_key_unescape(msg_data, "lightDuration", mqtt_parm.msg_lightDuration, sizeof(mqtt_parm.msg_lightDuration)); LOG_I("lightDuration:%s\n",mqtt_parm.msg_lightDuration); + isLightEnable=true; + if(isLightEnable){ - mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); + LOG_I("isLightEnable1:%d\n",isLightEnable); + //mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"ok",1,productid); + LOG_I("isLightEnable_off:%d\n",isLightEnable); // 设置规则并广播点亮,重置变量,防止被3015污染 isSendComEnd=false; @@ -2580,6 +2676,7 @@ void *thread_mqtt_recv(void *arg){ //LOG_I("Sending second broadcast\n"); //uart_data_send_head_lightonrule(&uartSend, 5); }else{ + LOG_I("isLightEnable2:%d\n",isLightEnable); mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"light disabled",0,productid); } } else if(strcmp(mqtt_parm.msg_type,"2333")==0){ @@ -2832,7 +2929,7 @@ int main(int argc, char *argv[]) } #if 1 - system("insmod /system/lib/modules/wk2xxx_spi.ko"); + //system("insmod /system/lib/modules/wk2xxx_spi.ko"); //改版后没有此模块 snprintf(syscmd, sizeof(syscmd), "ls Log.*|xargs rm -fr"); system(syscmd); @@ -2860,7 +2957,18 @@ int main(int argc, char *argv[]) { int fd = open("/sys/class/gpio/export", O_WRONLY); if (fd >= 0) { + write(fd, "112", 3); write(fd, "113", 3); + write(fd, "114", 3); + write(fd, "115", 3); + write(fd, "117", 3); + close(fd); + } + } + { + int fd = open("/sys/class/gpio/gpio112/direction", O_WRONLY); + if (fd >= 0) { + write(fd, "out", 3); close(fd); } } @@ -2872,7 +2980,65 @@ int main(int argc, char *argv[]) close(fd); } } + #if 0 + // 导出 GPIO 118 + { + int fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd >= 0) { + write(fd, "118", 3); + close(fd); + } + } + // 设置 GPIO 118 方向为 out + { + int fd = open("/sys/class/gpio/gpio118/direction", O_WRONLY); + if (fd >= 0) { + write(fd, "out", 3); + close(fd); + } + } #endif + // 导出 GPIO 115 + { + int fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd >= 0) { + write(fd, "115", 3); + close(fd); + } + } + // 设置 GPIO 115 方向为 out + { + int fd = open("/sys/class/gpio/gpio115/direction", O_WRONLY); + if (fd >= 0) { + write(fd, "out", 3); + close(fd); + } + } + // 导出 GPIO 117 + { + int fd = open("/sys/class/gpio/export", O_WRONLY); + if (fd >= 0) { + write(fd, "117", 3); + close(fd); + } + } + // 设置 GPIO 117 方向为 out + { + int fd = open("/sys/class/gpio/gpio117/direction", O_WRONLY); + if (fd >= 0) { + write(fd, "out", 3); + close(fd); + } + } + #endif + + //setGpio118Low(); + + setGpio113High(); + setGpio114High(); + setGpio115High(); + setGpio117High(); + #if 0 system("insmod /system/lib/modules/wk2xxx_spi.ko"); system("busybox udhcpc -i eth0"); @@ -2882,13 +3048,21 @@ int main(int argc, char *argv[]) system("echo 113 > /sys/class/gpio/export");//pin 113 yellow system("echo out > /sys/class/gpio/gpio113/direction"); #endif - uart_open(&uartSend,"/dev/ttyS0");//GT U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1 - uart_init(&uartSend,115200,8,1,'N',0); - uart_open(&uartRecvData,"/dev/ttyS4");//DT + uart_open(&uartRecvData,"/dev/ttyS0");//DT uart_init(&uartRecvData,115200,8,1,'N',0); - uart_open(&uartRecvBack,"/dev/ttysWK0");//HT + uart_open(&uartRecvBack,"/dev/ttyS1");//HT uart_init(&uartRecvBack,115200,8,1,'N',0); + uart_open(&uartSend,"/dev/ttyS5");//GT U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1 + uart_init(&uartSend,115200,8,1,'N',0); +#if 0 + uart_open(&uartSend,"/dev/ttyS0");//DT + uart_init(&uartSend,115200,8,1,'N',0); + uart_open(&uartRecvData,"/dev/ttyS1");//HT + uart_init(&uartRecvData,115200,8,1,'N',0); + uart_open(&uartRecvBack,"/dev/ttyS5");//GT U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1 + uart_init(&uartRecvBack,115200,8,1,'N',0); +#endif #if 0 struct dma_config cfg = { .buf = malloc(256), @@ -3016,6 +3190,17 @@ int main(int argc, char *argv[]) LOG_I("pthread_create label_batch_send success\n"); } + #if 0 + // 新增:模拟3027任务线程 + ret = pthread_create(&pt_simulate_3027, NULL, thread_simulate_3027_task, NULL); + if (ret != 0) { + LOG_I("pthread_create simulate_3027 fail\n"); + } else { + pthread_detach(pt_simulate_3027); + LOG_I("pthread_create simulate_3027 success\n"); + } + #endif + ret = pthread_create(&pt_ota,NULL,thread_ota,NULL); if(ret!=0){ LOG_I("pthread_create ota fail\n"); @@ -3213,7 +3398,7 @@ void *thread_3015_lighton_merge(void *arg) { int total_all = 0; while (1) { - pthread_mutex_lock(&lightsn_buffer_mutex); + //pthread_mutex_lock(&lightsn_buffer_mutex); if (is_3015_collecting) { time_t now = time(NULL); if ((now - first_3015_time >= 3) || (lightsn_buffer_count >= MAX_LIGHTSN_BUFFER)) { @@ -3289,7 +3474,11 @@ void *thread_3015_lighton_merge(void *arg) { .s.sound=atoi(mqtt_parm.msg_sound), .s.flash=atoi(mqtt_parm.msg_flash), }; - uart_data_send_head_lightband(&uartSend, 2, this_batch); + uart_data_send_head_lightband(&uartSend, 5, this_batch); + usleep(50000); + uart_data_send_lightband(&uartSend, led_ctrl.ch, atoi(mqtt_parm.msg_flash), atoi(mqtt_parm.msg_lightDuration), tags, tag_leds, this_batch); + usleep(150000); + uart_data_send_head_lightband(&uartSend, 5, this_batch); usleep(50000); uart_data_send_lightband(&uartSend, led_ctrl.ch, atoi(mqtt_parm.msg_flash), atoi(mqtt_parm.msg_lightDuration), tags, tag_leds, this_batch); } @@ -3307,7 +3496,7 @@ void *thread_3015_lighton_merge(void *arg) { isLightOn = false; } } - pthread_mutex_unlock(&lightsn_buffer_mutex); + //pthread_mutex_unlock(&lightsn_buffer_mutex); usleep(100*1000); } return NULL; @@ -3354,3 +3543,33 @@ void light_battery_report(uint32_t tagCode, uint16_t batteryV) { } curl_easy_cleanup(curl); } + +// 模拟3027任务发送线程 +void *thread_simulate_3027_task(void *arg) { + prctl(PR_SET_NAME, "sim_3027"); + + // 等待系统初始化完成 + sleep(10); + + while (1) { + // 构造3027任务的JSON消息 + char simulate_payload[1024]; + snprintf(simulate_payload, sizeof(simulate_payload), + "{" + "\"deviceId\": \"TJ251679787196\"," + "\"messageId\": \"1933039995430551552\"," + "\"msg\": \"{\\\"data\\\":{\\\"color\\\":\\\"7\\\",\\\"flash\\\":\\\"0\\\",\\\"flashInterval\\\":\\\"4\\\",\\\"lightDuration\\\":\\\"30\\\",\\\"sound\\\":\\\"0\\\"},\\\"msgType\\\":\\\"3027\\\"}\"," + "\"timestamp\": 2147483647" + "}"); + + // 将模拟的3027任务放入消息队列 + PutDataIntoMQueue(simulate_payload); + + LOG_I("Simulated 3027 task sent: %s\n", simulate_payload); + + // 等待2分钟 (120秒) + sleep(120); + } + + return NULL; +} diff --git a/mqtt_utils/mqtt_utils.c b/mqtt_utils/mqtt_utils.c index ffdb9fd..ecac7cb 100644 --- a/mqtt_utils/mqtt_utils.c +++ b/mqtt_utils/mqtt_utils.c @@ -483,7 +483,7 @@ static pthread_t led_thread; void* led_blink_thread(void* arg) { prctl(PR_SET_NAME, "led_blink"); - int fd = open("/sys/class/gpio/gpio113/value", O_WRONLY); + int fd = open("/sys/class/gpio/gpio114/value", O_WRONLY); if (fd < 0) { LOG_I("Failed to open GPIO\n"); return NULL; diff --git a/uart_can/uart_can.c b/uart_can/uart_can.c index ad6a7ac..4573ec4 100644 --- a/uart_can/uart_can.c +++ b/uart_can/uart_can.c @@ -304,9 +304,9 @@ int uart_data_send_head_search(uart_utils_t *uart,uint8_t wakeup_time){ if(sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))){ ret = 0; - //LOG_I("%s success\n",__func__); + LOG_I("%s success\n",__func__); }else{ - //LOG_I("%s fail\n", __func__); + LOG_I("%s fail\n", __func__); ret = -2; goto error; } @@ -783,16 +783,17 @@ int uart_data_receive_ack(uart_utils_t *uart,uint16_t *parm_ack){ if(ret == sizeof(jt_receive_package_t)){ LOG_I("%s success:%04x,%04x,%04x,%04x\n", __func__,jt_receive_package.pre1,jt_receive_package.pre2, jt_receive_package.pre3,jt_receive_package.ack); + // 设备可能在pre3发送不同标识:0x2424、0x4343(CC)、0x4444(DD) if((jt_receive_package.pre1 == 0x2424) &&(jt_receive_package.pre2 == 0x2424) - &&(jt_receive_package.pre3 == 0x2424)){ + &&(jt_receive_package.pre3 == 0x2424 || jt_receive_package.pre3 == 0x4343 || jt_receive_package.pre3 == 0x4444)){ *parm_ack=jt_receive_package.ack; }else{ LOG_I("%s failed\n", __func__); ret = -2; } }else{ - LOG_I("%s, failed, time out\n", __func__); + //LOG_I("%s, failed, time out\n", __func__); ret = -1; } diff --git a/uart_utils/read_utils.c b/uart_utils/read_utils.c index a803764..244a8d1 100644 --- a/uart_utils/read_utils.c +++ b/uart_utils/read_utils.c @@ -20,39 +20,39 @@ int read_data_until_time(int fd, char *buffer, int len, int timeout_first, int t int i; memset(buffer, 0, len); - tv.tv_sec = 0; - tv.tv_usec = timeout_first*1000; - for(i=0; i 0){ - if(FD_ISSET(fd, &fds)){ - ret = read(fd, &c, 1); - if(ret < 0){ - LOG_I("read error\n"); - i = -1; - break; - }else if(ret == 0){ - //LOG_I("end of file\n"); - break; - }else{ - buffer[i] = c; - } - } - tv.tv_sec = 0; - tv.tv_usec = timeout_interval*1000; - }else{ - //LOG_I("read time out\n"); - break; - } - } - return i; + tv.tv_sec = 0; + tv.tv_usec = timeout_first*1000; + for(i=0; i 0){ + if(FD_ISSET(fd, &fds)){ + ret = read(fd, &c, 1); + if(ret < 0){ + LOG_I("read error\n"); + i = -1; + break; + }else if(ret == 0){ + //LOG_I("end of file\n"); + break; + }else{ + buffer[i] = c; + } + } + tv.tv_sec = 0; + tv.tv_usec = timeout_interval*1000; + }else{ + //LOG_I("read time out\n"); + break; + } + } + return i; } /************************************************************* @@ -67,45 +67,45 @@ int read_data_until_char(int fd, char *buffer, int len, char until, int timeout_ int i; memset(buffer, 0, len); - for(i=0; i 0){ - if(FD_ISSET(fd, &fds)){ - ret = read(fd, &c, 1); - if(ret < 0){ - LOG_I("read error\n"); - i = -1; - break; - }else if(ret == 0){ - LOG_I("end of file\n"); - }else{ - buffer[i] = c; -#if 0 - LOG_D("i= %d\n", i); - LOG_D("\t,[%#x], <%c>\n", c, c); -#endif + for(i=0; i 0){ + if(FD_ISSET(fd, &fds)){ + ret = read(fd, &c, 1); + if(ret < 0){ + LOG_I("read error\n"); + i = -1; + break; + }else if(ret == 0){ + LOG_I("end of file\n"); + }else{ + buffer[i] = c; +#if 0 + LOG_D("i= %d\n", i); + LOG_D("\t,[%#x], <%c>\n", c, c); +#endif tv.tv_sec = 0; tv.tv_usec = timeout_interval*1000; - if(c == until){ - i++; - break; - } - } - } - }else{ - //LOG_I("read time out\n"); - } - } - return i; + if(c == until){ + i++; + break; + } + } + } + }else{ + //LOG_I("read time out\n"); + } + } + return i; } /************************************************************* @@ -120,32 +120,32 @@ int read_data_until_str(int fd, char *buffer, int len, char *until, int until_le int i; memset(buffer, 0, len); - for(i=0; i 0){ - if(FD_ISSET(fd, &fds)){ - ret = read(fd, &c, 1); - if(ret < 0){ - LOG_I("read error\n"); - i = -1; - break; - }else if(ret == 0){ - LOG_I("end of file\n"); - }else{ - buffer[i] = c; + for(i=0; i 0){ + if(FD_ISSET(fd, &fds)){ + ret = read(fd, &c, 1); + if(ret < 0){ + LOG_I("read error\n"); + i = -1; + break; + }else if(ret == 0){ + LOG_I("end of file\n"); + }else{ + buffer[i] = c; #if 0 - LOG_I("i= %d\n", i); - LOG_I("\t,[%#x], <%c>\n", c, c); -#endif + LOG_I("i= %d\n", i); + LOG_I("\t,[%#x], <%c>\n", c, c); +#endif tv.tv_sec = 0; tv.tv_usec = timeout_interval*1000; if((i+1) >= until_len) { @@ -154,11 +154,11 @@ int read_data_until_str(int fd, char *buffer, int len, char *until, int until_le break; } } - } - } - }else{ - //LOG_I("read time out\n"); - } - } - return i; + } + } + }else{ + //LOG_I("read time out\n"); + } + } + return i; } diff --git a/uart_utils/uart_utils.c b/uart_utils/uart_utils.c index f9590ee..21925c6 100644 --- a/uart_utils/uart_utils.c +++ b/uart_utils/uart_utils.c @@ -7,6 +7,7 @@ #include #include #include +#include #include "read_utils.h" #include "uart_utils.h" @@ -331,6 +332,19 @@ int uart_init(uart_utils_t *uart, if(options != &uart->option_back){ free(options); } + + // 尝试设置更大的接收缓冲区(仅在支持的系统上) + int rx_buffer_size = 8192; // 8KB接收缓冲区 + // 注意:对于串口,缓冲区大小通常由系统驱动程序控制 + // 这里的设置可能不会生效,但不会导致错误 + ioctl(uart->uart_fd, FIONREAD, &rx_buffer_size); // 尝试读取当前缓冲区状态 + + // 重新获取当前属性以设置VMIN和VTIME + struct termios current_options; + tcgetattr(uart->uart_fd, ¤t_options); + current_options.c_cc[VMIN] = 0; // 非阻塞读取 + current_options.c_cc[VTIME] = 5; // 100ms超时 + tcsetattr(uart->uart_fd, TCSANOW, ¤t_options); return uart->uart_fd; exit: return -1;