#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; }