AP05/heartbeat_test.c

188 lines
7.0 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <time.h>
#include <fcntl.h>
#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;
}