添加兔喜生产版本新核心板代码

This commit is contained in:
zzh 2025-12-22 12:04:07 +08:00
parent 54e049c555
commit 2c943baeaf
7 changed files with 628 additions and 195 deletions

View File

@ -104,4 +104,15 @@ LINK_DIRECTORIES(
ADD_EXECUTABLE(tx_server ${SRC_TX_SERVER}) ADD_EXECUTABLE(tx_server ${SRC_TX_SERVER})
TARGET_LINK_LIBRARIES(tx_server pthread dl curl ${CMAKE_CURRENT_LIST_DIR}/hiredis/libhiredis.a) 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)

188
heartbeat_test.c Normal file
View File

@ -0,0 +1,188 @@
#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;
}

385
main.c
View File

@ -33,6 +33,7 @@ pthread_t pt_reboot;
pthread_t pt_watchdog; pthread_t pt_watchdog;
pthread_t pt_tagsearch; pthread_t pt_tagsearch;
pthread_t pt_removeduplicatetag; pthread_t pt_removeduplicatetag;
pthread_t pt_simulate_3027; // 模拟3027任务线程
uart_utils_t uartSend = {0}; uart_utils_t uartSend = {0};
uart_utils_t uartRecvData = {0}; uart_utils_t uartRecvData = {0};
uart_utils_t uartRecvBack = {0}; uart_utils_t uartRecvBack = {0};
@ -64,7 +65,7 @@ int fd;
int UPCASE=0; int UPCASE=0;
int count_value=0; int count_value=0;
int getPayloadTime=120*1000;//usecond int getPayloadTime=120*1000;//usecond
char softwareVersion[16]="1.1.41"; char softwareVersion[16]="1.1.40";
char stationsn[16]="TJ251372224247";//TJ250995217957 char stationsn[16]="TJ251372224247";//TJ250995217957
char productid[8]="10045"; char productid[8]="10045";
char appKey[32]="fdhQmhqhvbL1cf1K9mUqt"; char appKey[32]="fdhQmhqhvbL1cf1K9mUqt";
@ -145,6 +146,7 @@ static time_t label_buf_first_time = 0;
void *thread_timeout_check(void *arg); void *thread_timeout_check(void *arg);
void *thread_3015_lighton_merge(void *arg); void *thread_3015_lighton_merge(void *arg);
void *thread_label_batch_send(void *arg); void *thread_label_batch_send(void *arg);
void *thread_simulate_3027_task(void *arg);
int getLedOtaVersion(char *filename); int getLedOtaVersion(char *filename);
int getApOtaVersion(char *filename,char *modename); int getApOtaVersion(char *filename,char *modename);
@ -597,84 +599,157 @@ void otaAp(){
} }
void enableWatchDog() { void enableWatchDog() {
int fd; // 使用 /dev/watchdog 设备,第一次喂狗自动开启看门狗
char path[64]; // 超时时间固定为5s不喂狗时默认关闭
char value[2]; LOG_I("watchdog will be enabled on first feed\n");
// 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);
} }
void feedWatchDog() { void feedWatchDog() {
int fd = open("/sys/class/gpio/gpio112/value", O_WRONLY); // 使用 /dev/watchdog 设备喂狗
if (fd < 0) { // 超时时间固定为5s喂狗命令: echo "" > /dev/watchdog
LOG_I("can not open watchdog gpio112\n"); int fd;
return; int gpio_fd = open("/sys/class/gpio/gpio112/value", O_WRONLY);
} int led_state = 0;
while(1) { 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("Failed to open gpio118 value: %s\n", strerror(errno));
return;
}
write(fd, "0", 1);
usleep(100*1000);
write(fd, "0", 1);
close(fd);
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); write(fd, "0", 1);
usleep(100*1000); usleep(100*1000);
write(fd, "1", 1); write(fd, "1", 1);
sleep(1); close(fd);
LOG_I("GPIO118 set to HIGH\n");
} }
close(fd); // 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; 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){ void rebootSystem(void){
while(!isTimeToReboot){ while(!isTimeToReboot){
@ -1540,7 +1615,7 @@ void getDevRawPassword(char *devsn){
// 首次获取密码成功后启动搜索标签功能(只运行一次) // 首次获取密码成功后启动搜索标签功能(只运行一次)
LOG_I("Starting tag search after first registration...\n"); LOG_I("Starting tag search after first registration...\n");
isSearchLabelOntest = true; isSearchLabelOntest = true;
searchTimeOut=20; searchTimeOut=5;
searchTimeOld=getCurrentTime(); searchTimeOld=getCurrentTime();
while(isSearchLabelOntest) { while(isSearchLabelOntest) {
@ -1706,7 +1781,7 @@ error:
/*================================================================================*/ /*================================================================================*/
void *thread_ota(void *arg){ void *thread_ota(void *arg){
prctl(PR_SET_NAME, "ota"); prctl(PR_SET_NAME, "ota");
checkOtaKey(); //checkOtaKey();
} }
void *thread_mqtt(void *arg){ void *thread_mqtt(void *arg){
@ -1727,6 +1802,7 @@ void *thread_reboot(void *arg){
void *thread_feed_watchdog(void *arg){ void *thread_feed_watchdog(void *arg){
prctl(PR_SET_NAME, "watchdog"); prctl(PR_SET_NAME, "watchdog");
feedWatchDog(); feedWatchDog();
return NULL;
} }
#if 1 #if 1
@ -1777,7 +1853,7 @@ void *thread_tag_search_send(void *arg){
if(isSearchLabelOn){ if(isSearchLabelOn){
sleep(10); sleep(10);
searchTimeNew=getCurrentTime(); searchTimeNew=getCurrentTime();
if((searchTimeNew-searchTimeOld)>=(searchTimeOut-20)){ if((searchTimeNew-searchTimeOld)>=(searchTimeOut)){
isSearchReport=true; isSearchReport=true;
search_tag_report(); search_tag_report();
isSearchReport=false; isSearchReport=false;
@ -1812,8 +1888,9 @@ void *thread_uart_recv_ack(void *arg){
int ret=0; int ret=0;
while(1){ while(1){
// 仅在成功收到ACK时打印日志并处理减少超时噪声
ret=uart_data_receive_ack(&uartSend,&parm_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); LOG_I("ack:%x\n",parm_ack);
if(parm_ack==0x2323){ if(parm_ack==0x2323){
// 记录收到0x2323的时间并设置等待0x4646标志 // 记录收到0x2323的时间并设置等待0x4646标志
@ -1900,7 +1977,10 @@ void *thread_uart_recv_ack(void *arg){
} }
#endif #endif
#if 1 #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); uart_data_send_search(&uartSend,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF);
isSearchLabel=false; isSearchLabel=false;
} }
@ -2021,14 +2101,23 @@ void *thread_uart_recv_data(void *arg){
uint8_t lable1; uint8_t lable1;
uint16_t lable2; uint16_t lable2;
uint32_t lable3; uint32_t lable3;
#if 1
while(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); &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, //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); //sleep(2);
if(ret <= 0) {
usleep(1000); // 1ms延时避免空转
} else {
usleep(100); // 0.1ms延时,保证处理效率
} }
} }
#endif
}
void *thread_uart_recv_back(void *arg){ void *thread_uart_recv_back(void *arg){
prctl(PR_SET_NAME, "uart_back"); prctl(PR_SET_NAME, "uart_back");
@ -2054,7 +2143,7 @@ void *thread_uart_recv_back(void *arg){
//} //}
PutDataIntoQueue(tagCode,batteryV); PutDataIntoQueue(tagCode,batteryV);
if(tagFeature==0x83){ 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){ }else if(tagFeature==0x82){
//LOG_I("light down tag:%08x,battery:%04x\n",tagCode,batteryV); //LOG_I("light down tag:%08x,battery:%04x\n",tagCode,batteryV);
light_off_tag_report(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); LOG_I("key down tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version);
}else if(tagFeature==0xff){ }else if(tagFeature==0xff){
//LOG_I("heart tag:%08x,battery:%04x,version:%4x\n",tagCode,batteryV,version); //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); LOG_I("searchTimeOut:%d\n",searchTimeOut);
searchTimeOld=getCurrentTime(); searchTimeOld=getCurrentTime();
LOG_I("searchTimeOld:%d\n",searchTimeOld); LOG_I("searchTimeOld:%d\n",searchTimeOld);
uart_data_send_head_search(&uartSend, 120);
isSearchLabelOn=true; isSearchLabelOn=true;
}else if(strcmp(mqtt_parm.msg_type,"3015")==0){ }else if(strcmp(mqtt_parm.msg_type,"3015")==0){
LOG_I("3015 light on (merge mode)\n"); 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)); 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); LOG_I("lightDuration:%s\n",mqtt_parm.msg_lightDuration);
isLightEnable=true;
if(isLightEnable){ 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污染 // 设置规则并广播点亮重置变量防止被3015污染
isSendComEnd=false; isSendComEnd=false;
@ -2580,6 +2676,7 @@ void *thread_mqtt_recv(void *arg){
//LOG_I("Sending second broadcast\n"); //LOG_I("Sending second broadcast\n");
//uart_data_send_head_lightonrule(&uartSend, 5); //uart_data_send_head_lightonrule(&uartSend, 5);
}else{ }else{
LOG_I("isLightEnable2:%d\n",isLightEnable);
mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"light disabled",0,productid); mqtt_service_reply(stationsn,mqtt_parm.msg_messageId,"light disabled",0,productid);
} }
} else if(strcmp(mqtt_parm.msg_type,"2333")==0){ } else if(strcmp(mqtt_parm.msg_type,"2333")==0){
@ -2832,7 +2929,7 @@ int main(int argc, char *argv[])
} }
#if 1 #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"); snprintf(syscmd, sizeof(syscmd), "ls Log.*|xargs rm -fr");
system(syscmd); system(syscmd);
@ -2860,7 +2957,18 @@ int main(int argc, char *argv[])
{ {
int fd = open("/sys/class/gpio/export", O_WRONLY); int fd = open("/sys/class/gpio/export", O_WRONLY);
if (fd >= 0) { if (fd >= 0) {
write(fd, "112", 3);
write(fd, "113", 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); close(fd);
} }
} }
@ -2872,7 +2980,65 @@ int main(int argc, char *argv[])
close(fd); 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 #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 #if 0
system("insmod /system/lib/modules/wk2xxx_spi.ko"); system("insmod /system/lib/modules/wk2xxx_spi.ko");
system("busybox udhcpc -i eth0"); 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 113 > /sys/class/gpio/export");//pin 113 yellow
system("echo out > /sys/class/gpio/gpio113/direction"); system("echo out > /sys/class/gpio/gpio113/direction");
#endif #endif
uart_open(&uartSend,"/dev/ttyS0");//GT U12 ttyS0,U14 ttyS4,U21 ttysWK0 U13 ttysWK1 U15 ttysWK2 U22 ttysWK3 U20 ttyS1 uart_open(&uartRecvData,"/dev/ttyS0");//DT
uart_init(&uartSend,115200,8,1,'N',0);
uart_open(&uartRecvData,"/dev/ttyS4");//DT
uart_init(&uartRecvData,115200,8,1,'N',0); 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_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 #if 0
struct dma_config cfg = { struct dma_config cfg = {
.buf = malloc(256), .buf = malloc(256),
@ -3016,6 +3190,17 @@ int main(int argc, char *argv[])
LOG_I("pthread_create label_batch_send success\n"); 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); ret = pthread_create(&pt_ota,NULL,thread_ota,NULL);
if(ret!=0){ if(ret!=0){
LOG_I("pthread_create ota fail\n"); LOG_I("pthread_create ota fail\n");
@ -3213,7 +3398,7 @@ void *thread_3015_lighton_merge(void *arg) {
int total_all = 0; int total_all = 0;
while (1) { while (1) {
pthread_mutex_lock(&lightsn_buffer_mutex); //pthread_mutex_lock(&lightsn_buffer_mutex);
if (is_3015_collecting) { if (is_3015_collecting) {
time_t now = time(NULL); time_t now = time(NULL);
if ((now - first_3015_time >= 3) || (lightsn_buffer_count >= MAX_LIGHTSN_BUFFER)) { 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.sound=atoi(mqtt_parm.msg_sound),
.s.flash=atoi(mqtt_parm.msg_flash), .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); 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); 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; isLightOn = false;
} }
} }
pthread_mutex_unlock(&lightsn_buffer_mutex); //pthread_mutex_unlock(&lightsn_buffer_mutex);
usleep(100*1000); usleep(100*1000);
} }
return NULL; return NULL;
@ -3354,3 +3543,33 @@ void light_battery_report(uint32_t tagCode, uint16_t batteryV) {
} }
curl_easy_cleanup(curl); 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;
}

View File

@ -483,7 +483,7 @@ static pthread_t led_thread;
void* led_blink_thread(void* arg) { void* led_blink_thread(void* arg) {
prctl(PR_SET_NAME, "led_blink"); 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) { if (fd < 0) {
LOG_I("Failed to open GPIO\n"); LOG_I("Failed to open GPIO\n");
return NULL; return NULL;

View File

@ -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))){ if(sizeof(jt_head_package) == write(uart->uart_fd, &jt_head_package, sizeof(jt_head_package))){
ret = 0; ret = 0;
//LOG_I("%s success\n",__func__); LOG_I("%s success\n",__func__);
}else{ }else{
//LOG_I("%s fail\n", __func__); LOG_I("%s fail\n", __func__);
ret = -2; ret = -2;
goto error; 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)){ 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, 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); jt_receive_package.pre3,jt_receive_package.ack);
// 设备可能在pre3发送不同标识0x2424、0x4343(CC)、0x4444(DD)
if((jt_receive_package.pre1 == 0x2424) if((jt_receive_package.pre1 == 0x2424)
&&(jt_receive_package.pre2 == 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; *parm_ack=jt_receive_package.ack;
}else{ }else{
LOG_I("%s failed\n", __func__); LOG_I("%s failed\n", __func__);
ret = -2; ret = -2;
} }
}else{ }else{
LOG_I("%s, failed, time out\n", __func__); //LOG_I("%s, failed, time out\n", __func__);
ret = -1; ret = -1;
} }

View File

@ -25,8 +25,8 @@ int read_data_until_time(int fd, char *buffer, int len, int timeout_first, int t
for(i=0; i<len; i++){ for(i=0; i<len; i++){
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
//ret = select(FD_SETSIZE, &fds, NULL, NULL, &tv); // 使用超时等待避免永久阻塞nfds 传入 fd+1
ret = select(FD_SETSIZE, &fds, NULL, NULL, 0); ret = select(fd + 1, &fds, NULL, NULL, &tv);
if(ret < 0){ if(ret < 0){
LOG_I("%s:seclect error\n",__func__); LOG_I("%s:seclect error\n",__func__);
i = -1; i = -1;
@ -72,8 +72,8 @@ int read_data_until_char(int fd, char *buffer, int len, char until, int timeout_
tv.tv_usec = timeout_first*1000; tv.tv_usec = timeout_first*1000;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
//ret = select(FD_SETSIZE, &fds, NULL, NULL, &tv); // 使用超时等待避免永久阻塞nfds 传入 fd+1
ret = select(FD_SETSIZE, &fds, NULL, NULL, 0); ret = select(fd + 1, &fds, NULL, NULL, &tv);
if(ret < 0){ if(ret < 0){
LOG_I("%s:seclect error\n",__func__); LOG_I("%s:seclect error\n",__func__);
i = -1; i = -1;
@ -125,8 +125,8 @@ int read_data_until_str(int fd, char *buffer, int len, char *until, int until_le
tv.tv_usec = timeout_first*1000; tv.tv_usec = timeout_first*1000;
FD_ZERO(&fds); FD_ZERO(&fds);
FD_SET(fd, &fds); FD_SET(fd, &fds);
//ret = select(FD_SETSIZE, &fds, NULL, NULL, &tv); // 使用超时等待避免永久阻塞nfds 传入 fd+1
ret = select(FD_SETSIZE, &fds, NULL, NULL, 0); ret = select(fd + 1, &fds, NULL, NULL, &tv);
if(ret < 0){ if(ret < 0){
LOG_I("%s:seclect error\n",__func__); LOG_I("%s:seclect error\n",__func__);
i = -1; i = -1;

View File

@ -7,6 +7,7 @@
#include <termios.h> #include <termios.h>
#include <string.h> #include <string.h>
#include <sys/select.h> #include <sys/select.h>
#include <sys/ioctl.h>
#include "read_utils.h" #include "read_utils.h"
#include "uart_utils.h" #include "uart_utils.h"
@ -331,6 +332,19 @@ int uart_init(uart_utils_t *uart,
if(options != &uart->option_back){ if(options != &uart->option_back){
free(options); 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, &current_options);
current_options.c_cc[VMIN] = 0; // 非阻塞读取
current_options.c_cc[VTIME] = 5; // 100ms超时
tcsetattr(uart->uart_fd, TCSANOW, &current_options);
return uart->uart_fd; return uart->uart_fd;
exit: exit:
return -1; return -1;