/* * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes * 2023-06-01 murmur the first version * 处理TT相关的初始化、状态切换等逻辑 */ #include #define LOG_TAG "main_scha" #define LOG_LVL LOG_LVL_DBG #include #include #include //#include #include #include static struct rt_event sw_check; //软件条件 static struct rt_event hw_check; //硬件条件 #define ALL_READY 1 static int maxTTWaitTime = 4; static int maxTTRetryCnt = 3; rt_sem_t TTReady= RT_NULL;//天通具备发送状态后 rt_sem_release(TTReady); rt_sem_t cfgUpdate = RT_NULL; rt_sem_t shuntDownTT = RT_NULL; void TTisReady(void) { rt_sem_release(TTReady); } SYS_CFG scfg={ .sendInterval =60, .maxTTWaitTime = 4, .maxTTRetryCnt = 3, .minTTPeriCnt=5, .minTTsinal=5, .timeout=5, .maxSizePerFile=1024 }; /** * 更新全局参数 */ static void updatecfg(void) { //因为不知原因,采用事件集独立更新配置出错,无精力深查 //独立响应单个参数更新事件,程序上更复杂也没特别必要 //现采用事件通知、统一全部重新加载 while(1) { if(rt_sem_take(cfgUpdate, RT_WAITING_FOREVER) == RT_EOK) { scfg.maxTTWaitTime = get_cfg("maxTTWaitTime"); scfg.maxTTRetryCnt = get_cfg("maxTTRetryCnt"); scfg.minTTPeriCnt = get_cfg("minTTPeriCnt"); scfg.minTTsinal = get_cfg("minTTsinal"); scfg.timeout = get_cfg("timeout"); scfg.maxSizePerFile = get_cfg("maxSizePerFile"); } LOG_D("cfg updated."); } } void sysSemInit() { TTReady = rt_sem_create("TTisReady", 0, RT_IPC_FLAG_PRIO); cfgUpdate = rt_sem_create("cfgUpdate", 0, RT_IPC_FLAG_PRIO); shuntDownTT = rt_sem_create("shuntDNTT", 0, RT_IPC_FLAG_PRIO); rt_sem_release(cfgUpdate); //上电更新值 updatecfg(); // LOG_D("sysSemInit DONE."); } static void initEvent(void) { /* 事 件 控 制 块 */ rt_err_t result = rt_event_init(&sw_check, "SHcheck", RT_IPC_FLAG_PRIO); result = rt_event_init(&hw_check, "HWcheck", RT_IPC_FLAG_PRIO) | result; if (result != RT_EOK) { LOG_E("init event failed.\n"); } } INIT_COMPONENT_EXPORT(initEvent); void upSWflag(void) { rt_event_send(&sw_check, FILE_IS_OK); } void upTTflag(void) { rt_event_send(&sw_check, TT_IS_OK); } void d_upSWflag() { // extern struct rt_event sw_check;//软件条件 // rt_event_send(&sw_check, FILE_IS_OK); // void upSWflag(void); upSWflag(); } //extern void ttinfoInit(void); //extern void startTTinfo(void); /** * 监控TT状态。需求条件1:TT连续5个周期为激活状态且信号强度不低于5。 */ void checkTT() { repGetTT(); //持续更新 } static void upSendFile_thread_entry(void) { //等待事件 extern struct rt_event hw_check; //硬件条件 static rt_uint8_t d[10][200] = { }; static rt_uint8_t s[10] = { }; while (1) { if (rt_event_recv(&hw_check, ALL_READY, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, RT_NULL) == RT_EOK) { //get file to be send char *f = "2023_06_16_10_28_00_123.bin"; // char *f="1023_05_19_15_29_59_254.txt"; // pack file rt_uint8_t len = 0; len = pack_File(f, 0, d, s); rt_kprintf("len is %d\n", len); if (len) { for (size_t var = 0; var < len; var++) { sendMsg(d[var], s[var]); } tcpClose(); LOG_I("Done."); } } } } //MSH_CMD_EXPORT(getFileData_thread_entry,tet); static void upSendFile(void) { /* 创建 serial 线程 */ rt_thread_t thread = rt_thread_create("upSendFile", upSendFile_thread_entry, RT_NULL, 1024 * 12, 27, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { LOG_E("thread 'upSendFile' create failure."); return; } } static void chkAndSendFile_thread_entry() { static rt_err_t rst = RT_ERROR; updatecfg(); static rt_uint8_t d[10][200] = { }; static rt_uint8_t s[10] = { }; while (1) { // int e; LOG_I("等待软件就绪"); rst = rt_event_recv(&sw_check, FILE_IS_OK | TIMER_IS_OUT, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, RT_WAITING_FOREVER, RT_NULL); if (rst == RT_EOK) //软件条件满足 { //检查硬件条件 LOG_I("软件就绪,开始等待TT"); // continue; checkTT(); //打包数据 } for (size_t var = 0; var < maxTTRetryCnt; var++) //轮询尝试 { LOG_I("第%d次尝试。", var + 1); // rst = rt_event_recv(&sw_check, TT_IS_OK, RT_EVENT_FLAG_OR | RT_EVENT_FLAG_CLEAR, maxTTWaitTime*60*1000, // RT_NULL); rst = rt_sem_take(TTReady, rt_tick_from_millisecond(maxTTWaitTime * 60 * 1000)); if (rst == RT_EOK) //硬件条件满足 { LOG_I("TT准备就绪"); rt_event_send(&hw_check, ALL_READY); break; } else if (rst == -RT_ETIMEOUT) ; //超时则重试 { LOG_W("第%d次尝试中TT准备失败。", var + 1); // pwTT_thread_entry("0"); rt_thread_mdelay(1000); checkTT(); // continue; } } //continue; //发送数据 //可能有多个待发文件,每个文件打包后为一个二维数组 //如果先打包后发送,需要三维数组,和大内存占用 //故改为“打包-发送”轮询操作 // upSendFile(); LOG_I("----------------------------"); } } void chkAndSendFile() { /* 创建 serial 线程 */ rt_thread_t thread = rt_thread_create("chk&send", chkAndSendFile_thread_entry, RT_NULL, 1024 * 5, 24, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { LOG_E("thread 'chk&send' create failure."); return; } } //INIT_COMPONENT_EXPORT(smsg); static rt_timer_t tmrToPNTT=RT_NULL; static int isInWindow=0;//winow 关闭时复位 /** * 关闭超时定时器,定时时间到后关闭TT */ void stopTM() { if (!tmrToPNTT) { return; } rt_timer_stop(tmrToPNTT); rt_timer_stop(tmrToPNTT); } /** * 重启超时定时器,定时时间到后关闭TT */ void resetTM() { // LOG_D("try to reset"); if (tmrToPNTT == RT_NULL) { return; } if (isInWindow) { stopTM(); return; } rt_tick_t t= rt_tick_from_millisecond(scfg.timeout*60*1000); rt_timer_control(tmrToPNTT, RT_TIMER_CTRL_SET_TIME,(void*) &t); rt_timer_stop(tmrToPNTT); rt_timer_start(tmrToPNTT); // LOG_D("timer reseted."); } void d_getRemain() { LOG_D("=%d=",rt_tick_from_millisecond(10*60*1000)); rt_tick_t *arg1,*arg2; arg1=rt_timer_control(tmrToPNTT, RT_TIMER_CTRL_GET_TIME, (void*)arg1); arg2=rt_timer_control(tmrToPNTT, RT_TIMER_CTRL_GET_REMAIN_TIME, (void*)arg2); LOG_D("tm=%d-%d",&arg1,&arg2); } static int toPN=0; /* 定时器超时函数 */ static void timeoutFunc(void *parameter) { // rt_kprintf("periodic timer is timeout %d\n", cnt); // rt_timer_stop(timer1); LOG_W("3s to shunt down TT"); rt_thread_mdelay(1000); LOG_W("2s to shunt down TT"); rt_thread_mdelay(1000); LOG_W("1s to shunt down TT"); rt_thread_mdelay(1000); deInitTT();//Function[rt_mutex_take] shall not be used in ISR // rt_sem_release(shuntDownTT); // toPN =1; } //RT_TICK_PER_SECOND //tcp连接保活 //实际场景不存在中间断掉的可能 void initTT_thread_entry() { pwTT_thread_entry("1"); while (1) { if (!tmrToPNTT) { tmrToPNTT = rt_timer_create("TTtimeout", timeoutFunc, RT_NULL, rt_tick_from_millisecond(scfg.timeout*60*1000), RT_TIMER_FLAG_ONE_SHOT);//RT_TIMER_FLAG_SOFT_TIMER // rt_timer_start(tmrToPNTT); } if (!isTTon()) { break; } if (!isEthUP()) { //只初始化一次 LOG_D("init eth..."); if (rt_hw_stm32_eth_init() == RT_EOK) { LOG_D("eth inited DONE."); }; //激活网口 } else if (!isTCPok()) //判断TCP连接是否正常,异常自动重连 { // LOG_W("TT server is not ready,--%d",isTCPok()); tcpInit(); // rt_thread_mdelay(1000); if (isTCPok()) { LOG_D("TCP is ready."); tcpRecMQ(); //开启tcp接收线程 recTT(); } } rt_thread_mdelay(3000); //chk with 3 second interval } } void deInitTT_thread_entry() { if (rt_sem_take(shuntDownTT, RT_WAITING_FOREVER) == RT_EOK) // if (toPN) { pwTT_thread_entry("0"); rt_hw_stm32_eth_deinit(); //qu激活网口 if (tmrToPNTT) { rt_timer_delete(tmrToPNTT); //关闭倒计时 tmrToPNTT = RT_NULL; } tcpClose(); LOG_W("shunt down TT DONE"); // break; } // rt_thread_mdelay(1000); // } } //INIT_APP_EXPORT(deInitTT_thread_entry); /** * TT上电,初始化TT相关的网络、TCP等,并保活 */ void initTT() { /* 创建 serial 线程 */ rt_thread_t thread = rt_thread_create("initTT", initTT_thread_entry, RT_NULL, 1024 * 1.5, 20, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { LOG_E("thread 'initTT' create failure."); return; } /* 创建 serial 线程 */ thread = rt_thread_create("deInitTT", deInitTT_thread_entry, RT_NULL, 1024 * 2, 19, 10); /* 创建成功则启动线程 */ if (thread != RT_NULL) { rt_thread_startup(thread); } else { LOG_E("thread 'deInitTT' create failure."); return; } } /** * TT上电,初始化TT相关的网络、TCP等,并保活 */ void deInitTT() { // /* 创建 serial 线程 */ // rt_thread_t thread = rt_thread_create("deInitTT", deInitTT_thread_entry, RT_NULL, 1024 * 2, 30, 10); // /* 创建成功则启动线程 */ // if (thread != RT_NULL) // { // rt_thread_startup(thread); // } // else // { // LOG_E("thread 'initTT' create failure."); // return; // } rt_sem_release(shuntDownTT); } //INIT_APP_EXPORT(deInitTT); #define FUNC_DEMO #ifdef FUNC_DEMO //测试时导出命令到控制台 MSH_CMD_EXPORT(d_upSWflag,FILE_IS_OK); MSH_CMD_EXPORT(chkAndSendFile, chkAndSendFile); MSH_CMD_EXPORT(upSendFile, upSendFile); MSH_CMD_EXPORT(initTT,初始化TT); MSH_CMD_EXPORT(deInitTT,初始化TT); MSH_CMD_EXPORT(d_getRemain,d_getRemain); #endif