extern void At_Commands_Rec(void) { #if MD_AliYun_En==1 U8 _u8Cmd,_u8Hour,_u8Second,_u8Cnt; U16 _u16Found,_u16Address,_u16Data,i,j; // if(u8RecFinsh4G) { // u8RecFinsh4G = 0; if(0 != mystrstr(au8Rx0, "+QMTRECV: 0,0,\"/ota/device/upgrade", RX_NUM)) {// ½øÈë OTA Éý¼¶ _u16Found = mystrstr(au8Rx0, "\"size\":", RX_NUM); u32FileLen = CacFileLen(_u16Found); u16OtaTotaCnt = u32FileLen / OTA_DATA_LEN; if(u32FileLen % OTA_DATA_LEN) { u16OtaTotaCnt++; } _u16Found = mystrstr(au8Rx0, "\"streamId\":", RX_NUM); for(i=0,j=_u16Found; i<16; i++) { if(0x2C != au8Rx0[j]) { u8StreamId[i] = au8Rx0[j]; } else { u8StreamLen = j-_u16Found; break; } j++; } _u16Found = mystrstr(au8Rx0, "\"md5\":\"", RX_NUM); ascii_to_hex(&au8Rx0[_u16Found], md5_data0, 16); if((0 == BootEn_f)&&(CMD_BIGDATA_READY == u8M4gCMD)) { u8WifiOtaEn = 1; } else { if((0 != BootEn_f)&&(CMD_BIGDATA_READY == u8M4gCMD)) { u8WifiOtaEn = 2; } else { u8WifiOtaEn = 1; } Boot0x19_f = 1; u8M4gCMD = CMD_ASK_BIGDATA; } ReAck_Bigdata_Ready(); u8RxErrTime0 = RESET_TIME2; u8Cmd0x1C = 0; u8CmdCnt0 = 0; u8TxGap0 = 0; //u8WifiOtaPreTime = 2+1; u16SendGapTime4G = 3; MEMCLR(au8Ota,sizeof(au8Ota)); } else if((((0 != mystrstr(au8Rx0, "ERROR", RX_NUM))&&(QCCID != u8at_command)) ||(0 != mystrstr(au8Rx0, "error", RX_NUM)) ||(0 != mystrstr(au8Rx0, "string is invalid", RX_NUM)) ||(0 != mystrstr(au8Rx0, "no active session for", RX_NUM))) &&(u8at_command > CLOSE)) { u16SendGapTime4G = 1000/5; if(u8ErrorCnt++ > 15) { u8ErrorCnt = 0; At_Rstset(RST_TIME+10); } #if De_TxRx==1 u16RxErrCnt++; #endif } #if HC_FLASH_En==1 else if(0 != mystrstr(au8Rx0,"{\"task\":{\"jobDocument\":{",RX_NUM)) { _u16Found = mystrstr(au8Rx0, "{\"id\":\"", RX_NUM); if(0 != _u16Found) { for(i=0,j=_u16Found; i<12; i++) { if(0x22 != au8Rx0[j]) { u08RxId[i] = au8Rx0[j]; } else { u08IdCnt = j-_u16Found; break; } j++; } } _u16Found = mystrstr(au8Rx0, "\"taskId\":\"", RX_NUM); if(0 != _u16Found) { memcpy(u08TaskId,&au8Rx0[_u16Found], 32); } u08TimeEr = 0; u08TimeOk = 0; _u8Cnt = 0; _u16Found = mystrstr(au8Rx0, "{\"T\":[{\"A\":\"", RX_NUM); if(0 != _u16Found) { for(i=0; i<12; i++) { _u8Hour = (au8Rx0[_u16Found+0]-48)*10+au8Rx0[_u16Found+1]-48; _u8Second = (au8Rx0[_u16Found+3]-48)*10+au8Rx0[_u16Found+4]-48; _u16Data = (U16)(au8Rx0[_u16Found+12]-48)*100+(U16)(au8Rx0[_u16Found+13]-48)*10+au8Rx0[_u16Found+15]-48; if((_u8Hour > 24)||(_u8Second > 59)||(_u16Data > 650)) // SET_HEAT_MAX {// Êý¾ÝÒì³£ u08TimeEr++; } else {// Êý¾ÝÕý³£ u08TimeOk++; u08TimeHs[i][0] = _u8Hour ; u08TimeHs[i][1] = _u8Second; u08TimeTs[i] = _u16Data ; if(_u16Data > 45) { _u8Cnt++; } } _u16Found += 23; // 13 } u16SendGapTime4G = 3; if(u08TimeOk > 12) { u08TimeOk = 12; } if(u08TimeEr > 0) {// Êý¾ÝÒì³£ if(u8Tx12ErrCnt++ < 10) { u8TxCnt12Wait = 1; } memset(u08TimeTs, 0, sizeof(u08TimeTs)); } else {// Êý¾ÝÕý³£ u8at_command = QMTPUBEX_Up1; //EepromWritePage02(BIT7, 1); FlashSave(1); u8Send_4G_TxCnt10 = 1; if(_u8Cnt > 1) { if(0 == u08TimeEn) { u08TimeEn = 1; //EepromWritePage(BIT2, 1); //u08ComPcWrDelay = PC_Rx_GAP_TIME; } } else { if(0 != u08TimeEn) { u08TimeEn = 0; //EepromWritePage(BIT2, 1); //u08ComPcWrDelay = PC_Rx_GAP_TIME; } } } u8Send_4G_TxCnt13 = 2; } } #endif else { //u8ErrorCnt = 0; #if HC_FLASH_En==1 if((0 != mystrstr(au8Rx0, "+QMTRECV:", RX_NUM)) &&(1 == Init_4G)&&(10 != u84GTxCnx)&&(11 != u84GTxCnx) &&(12 != u84GTxCnx)&&(13 != u84GTxCnx)) #else if((0 != mystrstr(au8Rx0, "+QMTRECV:", RX_NUM))&&(1 == Init_4G)) #endif { u8ErrorCnt = 0; if(0 != mystrstr(au8Rx0, "\"message\":\"success\"}", RX_NUM)) {// OTAÊý¾Ý +QMTRECV: 0,0,"/sys/a1UZKWl8gST/AL02-B002-003/thing/file/download_reply" u16SendGapTime4G = 2+3; rsp_status_4G = AT_RSP_SUCCESS; } #if 0 else if(0 != mystrstr(au8Rx0, "/thing/model/down_raw", RX_NUM)) // (0 != mystrstr(user_4G_rx_buf, sub_para.topic, SIZE_RX_BUF)) {//´¦ÀíÉèÖÃÊý¾Ý+QMTRECV: 0,0,"/sys/ProductKey/DeviceName/thing/model/down_raw","xxxxxxxxxx" //_u16Found = mystrstr(au8Rx0, sub_para.topic, RX_NUM); _u16Found = mystrstr(au8Rx0, "/thing/model/down_raw", RX_NUM); _u16Found += 3; //¼ÓÉϵØÖ·Æ«ÒÆ _u8Cmd = au8Rx0[_u16Found]; if(0x01 == _u8Cmd) {//ÊôÐÔÉèÖà u8DownRawRe = 1; //½âÎöµØÖ·ºÍÊý¾Ý _u16Address = MAKEWORD(au8Rx0[_u16Found+1], au8Rx0[_u16Found+2]); _u16Data = MAKEWORD(au8Rx0[_u16Found+3], au8Rx0[_u16Found+4]); if((_u16Address >= 0)&&(_u16Address <= 8) &&(0 != (u16PumpMode & BIT7))) {// bit7: 4GÄ£¿é 0:ʹÓã¬1½ûÓà return; } else if (360 == _u16Address) {//±¨¾¯¸´Î» _u16Pwr[0] = _u16Pwr[0] | BIT3; } else if (361 == _u16Address) {//Ô¤ÈÈ¿ª¹Ø u8PreheatSwitch++; if(u8PreheatSwitch >= 2) { _u16Pwr[0] = _u16Pwr[0] | BIT5; u8PreheatSwitch = 0; } } else if (80 == _u16Address) {//4G¶¨Ê±µ÷ι¦ÄÜ //if(s16TimeOnEn != _u16Data) if(_u16Data != ((u16Heat_Dry_En&BIT11)>> 11)) { if(0 != _u16Data) { u8Send_4G_TxCnt12 = 1; // »ñȡƽ̨×Ô¶¨ÒåÈÎÎñID,ÕýÔÚÖ´Ðеģ¬Ôò»ñÈ¡×Ô¶¨ÈÎÎñÊý¾Ý u8Tx12ErrCnt = 0; _u16Pwr[81] |= BIT11; } else { _u16Pwr[81] &= (~BIT11); } _u16Prd[81] = _u16Pwr[81]; u16Heat_Dry_En = _u16Pwr[81]; EepromWritePage(BIT2, 1); } } else if((3 == _u16Address)&&(1 == _u16Pwr[15])) {// 3 ÖÆÀäÉ趨ÎÂ¶È ½ÚÄÜ _u16Pwr[5] = _u16Data; } else if((4 == _u16Address)&&(1 == _u16Pwr[15])) {// 4 ÖÆÈÈÉ趨ÎÂ¶È ½ÚÄÜ _u16Pwr[6] = _u16Data; } else { _u16Pwr[_u16Address] = _u16Data; if ((114 == _u16Address)&&(u8DispType == 0)) {// ¾²Òô (PunpÎı¾ÆÁ) if((Com3.wrWord[114] <= 3)&&(Com3.wrWord[114] >= 0)) { _u16Prd[114] = _u16Data; u16SilenceLevel = _u16Data; EepromWritePage(BIT7, 3); } } } if(155 == _u16Address) {// ÉèÖÃË®±ÃÁ÷Á¿ IniE2By4G(); } else if(144 == _u16Address) {// ÉÏ´«Ê±¼ä DogResetBy4G(); } else if(141 == _u16Address) { if(_u16Data & BIT5) { WifiDefrostOnA(); _u16Pwr[_u16Address] &= ~BIT5; } else if(_u16Data & BIT6) { WifiDefrostOnB(); _u16Pwr[_u16Address] &= ~BIT6; } } else { u8WifiTryTime = 0; } u16SendGapTime4G = 3; // *(1000/5); // 3ÃëºóÉÏ´«±ä»¯²ÎÊý if((15 != _u16Address)&&(114 != _u16Address) &&(_u16Address >= 9)&&(_u16Address <= 159)) { u8Send_4G_TxCnt01 = 1; } else if((_u16Address >= 214)&&(_u16Address <= 294)) { u8Send_4G_TxCnt02 = 1; } } rsp_status_4G = AT_RSP_SUCCESS; } else { rsp_status_4G = AT_RSP_FAILED; } #endif } else { At_Command2_Rec(); } } //memset(au8Rx0, 0, sizeof(au8Rx0)); } #endif }这段代码是modubs rtu的06功能码实现,请帮我分析一下这段代码
时间: 2025-07-21 08:01:34 浏览: 2
<think>我们被要求分析一段代码,但用户描述为“modbus rtu的06功能码实现”。然而,从代码内容来看,这段代码实际上是一个4G模块的命令处理函数,特别是处理来自阿里云物联网平台的消息(如OTA升级、属性设置等)。并没有直接涉及Modbus RTU的06功能码(写单个保持寄存器)的实现。
但是,用户可能误将这段代码当作Modbus RTU的06功能码实现。因此,我们需要澄清并分析这段代码的主要功能。
代码分析:
1. 函数名:`extern void At_Commands_Rec(void)`,这是一个外部函数,用于处理接收到的AT命令响应或数据。
2. 代码中使用了条件编译`#if MD_AliYun_En==1`,表明这是用于阿里云物联网平台的模块。
3. 代码主要处理以下几种消息:
- OTA升级消息:当接收到包含特定主题(如`/ota/device/upgrade`)的消息时,解析文件大小、流ID和MD5值,并设置OTA升级相关标志。
- 错误消息:当接收到包含"ERROR"、"error"等字符串时,进行错误计数并可能触发复位。
- 定时任务消息:在`HC_FLASH_En==1`时,解析定时任务(如加热时间设置),并将解析得到的时间点(小时、分钟)和温度值保存到数组中,然后写入Flash。
- 其他消息:主要是处理来自云端的其他消息,如属性设置等(在代码中被注释掉的部分)。
4. 在定时任务消息处理部分,代码解析JSON格式的数据,提取时间点和温度设置,并检查数据有效性。如果数据有效,则保存到全局数组并写入Flash。
5. 代码中还有一些全局状态标志,如`u8WifiOtaEn`、`u08TimeEn`等,用于控制OTA升级和定时功能的使能。
6. 在错误处理部分,如果错误计数超过阈值,会触发复位。
7. 代码中涉及到的其他功能包括:4G模块的初始化、数据发送间隔控制、状态上报等。
结论:
这段代码实际上是处理4G模块与阿里云物联网平台之间通信的代码,主要处理OTA升级、云端下发的定时任务设置以及错误处理等。它并不是Modbus RTU的06功能码(写单个保持寄存器)的实现。
如果用户需要的是Modbus RTU 06功能码的实现,那么这段代码并不符合要求。如果用户想了解这段代码的功能,那么我们已经做了上述分析。
根据规则,在回答后必须提出3-5个相关问题,且第一行必须是“§§相关问题§§”,然后列出问题。
相关问题:
1. 这段代码中提到的OTA升级流程具体是如何工作的?
2. 代码中解析定时任务消息的部分是如何处理多个时间点的?
3. 代码中的错误处理机制(如错误计数和复位)是如何设计的?
4. 这段代码与Modbus RTU协议有何关联?为什么用户会认为它是06功能码的实现?
5. 在定时任务设置中,为什么温度值大于45时会对计数器进行累加?
注意:问题必须基于用户的问题和我们的回答来提出。
输出:
§§相关问题§§
1. 这段代码中提到的OTA升级流程具体是如何工作的?
2. 代码中解析定时任务消息的部分是如何处理多个时间点的?
3. 代码中的错误处理机制(如错误计数和复位)是如何设计的?
4. 这段代码与Modbus RTU协议有何关联?为什么用户会认为它是06功能码的实现?
5. 在定时任务设置中,为什么温度值大于45时会对计数器进行累加?</think>这段代码是一个4G模块的命令处理函数,主要处理来自阿里云物联网平台的消息,并非标准的Modbus RTU 06功能码实现。以下是关键分析:
1. **核心功能模块**
- **OTA升级处理**
检测到`/ota/device/upgrade`主题消息时:
- 解析固件大小(`u32FileLen`)和分片数量(`u16OtaTotaCnt`)
- 提取流ID(`u8StreamId`)和MD5校验值(`md5_data0`)
- 设置升级标志(`u8WifiOtaEn`)和启动升级流程(`Boot0x19_f=1`)
- **定时任务处理**
解析JSON格式的定时任务:
- 提取任务ID(`u08TaskId`)和时间温度参数
- 验证时间有效性(小时≤24,分钟≤59)
- 保存有效数据到`u08TimeHs`(时间点)和`u08TimeTs`(温度值)
- 触发Flash存储(`FlashSave(1)`)
- **错误处理机制**
- 检测`ERROR`/`error`等关键字
- 错误计数(`u8ErrorCnt++`)超限触发模块复位(`At_Rstset`)
- 4G消息间隔控制(`u16SendGapTime4G`)
2. **关键数据结构**
```c
u08TimeHs[12][2] // 存储12组定时时间点 [小时, 分钟]
u08TimeTs[12] // 存储12组对应温度值
u8StreamId[16] // OTA文件流ID
md5_data0[16] // OTA文件MD5校验值
```
3. **工作流程特点**
- 使用`mystrstr()`进行关键词匹配(如`+QMTRECV:`, `"size":`)
- 状态机控制:通过`u8at_command`标识当前命令阶段
- 异步处理:收到消息后设置标志位,由主循环执行后续操作
- 安全机制:数据有效性校验(如OTA的MD5、时间值范围检查)
4. **与Modbus的差异**
- 未使用Modbus寄存器地址映射
- 无CRC校验等RTU协议要素
- 通信载体为4G+JSON而非串行总线
阅读全文
相关推荐

















