% Create input data and the corresponding ground truth numImages = 8; Igt = zeros([inputSize,numImages],'uint8'); Inorm = zeros([inputSize,numImages],'uint8'); for k = 1:numImages I = imread(imagesVal{k}); joint = gtruthJointsVal(:,:,k); bbox = gtruthBboxesVal(:,k); data = cell(3,1); data{1} = I; data{2} = joint; data{3} = bbox; augmentedData = augmentImageAndKeypoint(data,inputSize,symmPairs,false); Inorm(:,:,:,k) = augmentedData{1}; Igt(:,:,:,k) = visualizeKeyPoints(augmentedData{1},augmentedData{2},skeleton,[]); end if showDatasetImages figure, montage(Igt,"Size",[1 numImages]); %#ok<UNRCH> title('Each cropped image') end Estimate keypoints for each cropped image detector = posenet.PoseEstimator('MATFile',modelFile,... 'NetworkName','simplePoseNet','SkeletonConnectionMap','SkeletonConnectionMap'); heatmaps = predict(detector,Inorm); Iheatmaps = detector.visualizeHeatmaps(heatmaps, Inorm); if showDatasetImages montage(Iheatmaps,"Size",[1 numImages]); %#ok<UNRCH> title("Joint heatmaps") end Extract the miximum likely points. keypoints = detector.heatmaps2Keypoints(heatmaps); Ipred = detector.visualizeKeyPoints(Iheatmaps,keypoints); if showDatasetImages montage(cat(4,Igt,Ipred),"Size",[2 numImages]); %#ok<UNRCH> title('Joint extraction'); end解释这段代码
时间: 2024-04-27 08:24:21 浏览: 216
这段代码是用于实现基于 PoseNet 的人体姿态估计,主要分为以下步骤:
1. 创建输入数据和对应的 ground truth 数据:通过读取输入图片和 ground truth 数据集,对数据进行预处理和增强,生成 Inorm 和 Igt 两个矩阵,其中 Inorm 存储输入图片,Igt 存储 ground truth 数据的可视化结果。
2. 展示数据集图片:如果 showDatasetImages 变量为 true,则展示生成的 ground truth 数据的可视化结果。
3. 姿态估计:创建 PoseNet 的姿态估计器 detector,使用 predict 函数对 Inorm 进行姿态估计,生成 heatmaps 矩阵,其中包含了每个关键点的 heatmap。使用 visualizeHeatmaps 函数将 heatmaps 可视化为 Iheatmaps。
4. 关键点提取:使用 heatmaps2Keypoints 函数从 heatmaps 中提取关键点,生成 keypoints 矩阵。使用 visualizeKeyPoints 函数将 keypoints 可视化为 Ipred。
5. 展示结果:如果 showDatasetImages 变量为 true,则展示生成的 ground truth 数据可视化结果和姿态估计结果的可视化结果。
总的来说,这段代码实现了基于 PoseNet 的人体姿态估计,包括数据预处理、姿态估计、关键点提取和结果展示等步骤。
相关问题
62Warning:gizProtocolResendData 104160 103106 1Warning: timeout, resend data DHT11 OK: T=29, H=62DHT11 OK: T=29, H=62DHT11 OK: T=29, H=62DHT11 OK: T=29, H=62valuelight Changedchanged, report dataDHT11 OK: T=29, H=62Warning:gizProtocolResendData 109442 108389 0Warning: timeout, resend data DHT11 OK: T=29, H=63Warning:gizProtocolResendData 110504 109451 1Warning: timeout, resend data DHT11 OK: T=29, H=62DHT11 OK: T=29, H=62DHT11 OK: T=29, H=62DHT11 OK: T=29, H=62valuelight Changedchanged, report dataDHT11 OK: T=29, H=63Warning:gizProtocolResendData 115787 114733 0Warning: timeout, resend data DHT11 OK: T=29, H=63Warning:gizProtocolResendData 116849 115795 1Warnin配置入网有问题,/** ************************************************************ * @file gizwits_protocol.c * @brief Corresponding gizwits_product.c header file (including product hardware and software version definition) * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note 机智云.只为智能硬件而生 * Gizwits Smart Cloud for Smart Products * 链接|增值ֵ|开放|中立|安全|自有|自由|生态 * www.gizwits.com * ***********************************************************/ #include "ringBuffer.h" #include "gizwits_product.h" #include "dataPointTools.h" /** Protocol global variables **/ gizwitsProtocol_t gizwitsProtocol; /**@name The serial port receives the ring buffer implementation * @{ */ rb_t pRb; ///< Ring buffer structure variable static uint8_t rbBuf[RB_MAX_LEN]; ///< Ring buffer data cache buffer /**@} */ /** * @brief Write data to the ring buffer * @param [in] buf : buf adress * @param [in] len : byte length * @return correct : Returns the length of the written data failure : -1 */ int32_t gizPutData(uint8_t *buf, uint32_t len) { int32_t count = 0; if(NULL == buf) { GIZWITS_LOG("ERR: gizPutData buf is empty \n"); return -1; } count = rbWrite(&pRb, buf, len); if(count != len) { GIZWITS_LOG("ERR: Failed to rbWrite \n"); return -1; } return count; } /** * @brief Protocol header initialization * * @param [out] head : Protocol header pointer * * @return 0, success; other, failure */ static int8_t gizProtocolHeadInit(protocolHead_t *head) { if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolHeadInit head is empty \n"); return -1; } memset((uint8_t *)head, 0, sizeof(protocolHead_t)); head->head[0] = 0xFF; head->head[1] = 0xFF; return 0; } /** * @brief Protocol ACK check processing function * * @param [in] data : data adress * @param [in] len : data length * * @return 0, suceess; other, failure */ static int8_t gizProtocolWaitAck(uint8_t *gizdata, uint32_t len) { if(NULL == gizdata) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); memcpy((uint8_t *)gizwitsProtocol.waitAck.buf, gizdata, len); gizwitsProtocol.waitAck.dataLen = (uint16_t)len; gizwitsProtocol.waitAck.flag = 1; gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); return 0; } /** * @brief generates "controlled events" according to protocol * @param [in] issuedData: Controlled data * @param [out] info: event queue * @param [out] dataPoints: data point data * @return 0, the implementation of success, non-0, failed */ static int8_t ICACHE_FLASH_ATTR gizDataPoint2Event(gizwitsIssued_t *issuedData, eventInfo_t *info, dataPoint_t *dataPoints) { if((NULL == issuedData) || (NULL == info) ||(NULL == dataPoints)) { GIZWITS_LOG("gizDataPoint2Event Error , Illegal Param\n"); return -1; } /** Greater than 1 byte to do bit conversion **/ if(sizeof(issuedData->attrFlags) > 1) { if(-1 == gizByteOrderExchange((uint8_t *)&issuedData->attrFlags,sizeof(attrFlags_t))) { GIZWITS_LOG("gizByteOrderExchange Error\n"); return -1; } } if(0x01 == issuedData->attrFlags.flagFan_OnOff) { info->event[info->num] = EVENT_Fan_OnOff; info->num++; dataPoints->valueFan_OnOff = gizStandardDecompressionValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } if(0x01 == issuedData->attrFlags.flagLED_OnOff) { info->event[info->num] = EVENT_LED_OnOff; info->num++; dataPoints->valueLED_OnOff = gizStandardDecompressionValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } return 0; } /** * @brief contrasts the current data with the last data * * @param [in] cur: current data point data * @param [in] last: last data point data * * @return: 0, no change in data; 1, data changes */ static int8_t ICACHE_FLASH_ATTR gizCheckReport(dataPoint_t *cur, dataPoint_t *last) { int8_t ret = 0; static uint32_t lastReportTime = 0; uint32_t currentTime = 0; if((NULL == cur) || (NULL == last)) { GIZWITS_LOG("gizCheckReport Error , Illegal Param\n"); return -1; } currentTime = gizGetTimerCount(); if(last->valueFan_OnOff != cur->valueFan_OnOff) { GIZWITS_LOG("valueFan_OnOff Changed\n"); ret = 1; } if(last->valueLED_OnOff != cur->valueLED_OnOff) { GIZWITS_LOG("valueLED_OnOff Changed\n"); ret = 1; } if(last->valuetemp != cur->valuetemp) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuetemp Changed\n"); ret = 1; } } if(last->valuehumi != cur->valuehumi) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuehumi Changed\n"); ret = 1; } } if(last->valuelight != cur->valuelight) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuelight Changed\n"); ret = 1; } } if(1 == ret) { lastReportTime = gizGetTimerCount(); } return ret; } /** * @brief User data point data is converted to wit the cloud to report data point data * * @param [in] dataPoints: user data point data address * @param [out] devStatusPtr: wit the cloud data point data address * * @return 0, the correct return; -1, the error returned */ static int8_t ICACHE_FLASH_ATTR gizDataPoints2ReportData(dataPoint_t *dataPoints , devStatus_t *devStatusPtr) { if((NULL == dataPoints) || (NULL == devStatusPtr)) { GIZWITS_LOG("gizDataPoints2ReportData Error , Illegal Param\n"); return -1; } gizMemset((uint8_t *)devStatusPtr->wBitBuf,0,sizeof(devStatusPtr->wBitBuf)); gizStandardCompressValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueFan_OnOff); gizStandardCompressValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueLED_OnOff); gizByteOrderExchange((uint8_t *)devStatusPtr->wBitBuf,sizeof(devStatusPtr->wBitBuf)); devStatusPtr->valuetemp = gizY2X(temp_RATIO, temp_ADDITION, dataPoints->valuetemp); devStatusPtr->valuehumi = gizY2X(humi_RATIO, humi_ADDITION, dataPoints->valuehumi); devStatusPtr->valuelight = exchangeBytes(gizY2X(light_RATIO, light_ADDITION, dataPoints->valuelight)); return 0; } /** * @brief This function is called by the Gagent module to receive the relevant protocol data from the cloud or APP * @param [in] inData The protocol data entered * @param [in] inLen Enter the length of the data * @param [out] outData The output of the protocol data * @param [out] outLen The length of the output data * @return 0, the implementation of success, non-0, failed */ static int8_t gizProtocolIssuedProcess(char *did, uint8_t *inData, uint32_t inLen, uint8_t *outData, uint32_t *outLen) { uint8_t issuedAction = inData[0]; if((NULL == inData)||(NULL == outData)||(NULL == outLen)) { GIZWITS_LOG("gizProtocolIssuedProcess Error , Illegal Param\n"); return -1; } if(NULL == did) { memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent, 0, sizeof(eventInfo_t)); switch(issuedAction) { case ACTION_CONTROL_DEVICE: gizDataPoint2Event((gizwitsIssued_t *)&inData[1], &gizwitsProtocol.issuedProcessEvent,&gizwitsProtocol.gizCurrentDataPoint); gizwitsProtocol.issuedFlag = ACTION_CONTROL_TYPE; outData = NULL; *outLen = 0; break; case ACTION_READ_DEV_STATUS: if(0 == gizDataPoints2ReportData(&gizwitsProtocol.gizLastDataPoint,&gizwitsProtocol.reportData.devStatus)) { memcpy(outData+1, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(gizwitsReport_t)); outData[0] = ACTION_READ_DEV_STATUS_ACK; *outLen = sizeof(gizwitsReport_t)+1; } else { return -1; } break; case ACTION_W2D_TRANSPARENT_DATA: memcpy(gizwitsProtocol.transparentBuff, &inData[1], inLen-1); gizwitsProtocol.transparentLen = inLen - 1; gizwitsProtocol.issuedProcessEvent.event[gizwitsProtocol.issuedProcessEvent.num] = TRANSPARENT_DATA; gizwitsProtocol.issuedProcessEvent.num++; gizwitsProtocol.issuedFlag = ACTION_W2D_TRANSPARENT_TYPE; outData = NULL; *outLen = 0; break; default: break; } } return 0; } /** * @brief The protocol sends data back , P0 ACK * * @param [in] head : Protocol head pointer * @param [in] data : Payload data * @param [in] len : Payload data length * @param [in] proFlag : DID flag ,1 for Virtual sub device did ,0 for single product or gateway * * @return : 0,Ack success; * -1,Input Param Illegal * -2,Serial send faild */ static int32_t gizProtocolIssuedDataAck(protocolHead_t *head, uint8_t *gizdata, uint32_t len, uint8_t proFlag) { int32_t ret = 0; uint8_t tx_buf[RB_MAX_LEN]; uint32_t offset = 0; uint8_t sDidLen = 0; uint16_t data_len = 0; uint8_t *pTxBuf = tx_buf; if(NULL == gizdata) { GIZWITS_LOG("[ERR] data Is Null \n"); return -1; } if(0x1 == proFlag) { sDidLen = *((uint8_t *)head + sizeof(protocolHead_t)); data_len = 5 + 1 + sDidLen + len; } else { data_len = 5 + len; } GIZWITS_LOG("len = %d , sDidLen = %d ,data_len = %d\n", len,sDidLen,data_len); *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8); *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= head->cmd + 1; *pTxBuf ++= head->sn; *pTxBuf ++= 0x00; *pTxBuf ++= proFlag; offset = 8; if(0x1 == proFlag) { *pTxBuf ++= sDidLen; offset += 1; memcpy(&tx_buf[offset],(uint8_t *)head+sizeof(protocolHead_t)+1,sDidLen); offset += sDidLen; pTxBuf += sDidLen; } if(0 != len) { memcpy(&tx_buf[offset],gizdata,len); } tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("uart write error %d \n", ret); return -2; } return 0; } /** * @brief Report data interface * * @param [in] action : PO action * @param [in] data : Payload data * @param [in] len : Payload data length * * @return : 0,Ack success; * -1,Input Param Illegal * -2,Serial send faild */ static int32_t gizReportData(uint8_t action, uint8_t *gizdata, uint32_t len) { int32_t ret = 0; protocolReport_t protocolReport; if(NULL == gizdata) { GIZWITS_LOG("gizReportData Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&protocolReport); protocolReport.head.cmd = CMD_REPORT_P0; protocolReport.head.sn = gizwitsProtocol.sn++; protocolReport.action = action; protocolReport.head.len = exchangeBytes(sizeof(protocolReport_t)-4); memcpy((gizwitsReport_t *)&protocolReport.reportData, (gizwitsReport_t *)gizdata,len); protocolReport.sum = gizProtocolSum((uint8_t *)&protocolReport, sizeof(protocolReport_t)); ret = uartWrite((uint8_t *)&protocolReport, sizeof(protocolReport_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); return -2; } gizProtocolWaitAck((uint8_t *)&protocolReport, sizeof(protocolReport_t)); return ret; }/** * @brief Datapoints reporting mechanism * * 1. Changes are reported immediately * 2. Data timing report , 600000 Millisecond * *@param [in] currentData : Current datapoints value * @return : NULL */ static void gizDevReportPolicy(dataPoint_t *currentData) { static uint32_t lastRepTime = 0; uint32_t timeNow = gizGetTimerCount(); if((1 == gizCheckReport(currentData, (dataPoint_t *)&gizwitsProtocol.gizLastDataPoint))) { GIZWITS_LOG("changed, report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); } if((0 == (timeNow % (600000))) && (lastRepTime != timeNow)) { GIZWITS_LOG("Info: 600S report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); lastRepTime = timeNow; } } /** * @brief Get a packet of data from the ring buffer * * @param [in] rb : Input data address * @param [out] data : Output data address * @param [out] len : Output data length * * @return : 0,Return correct ;-1,Return failure;-2,Data check failure */ static int8_t gizProtocolGetOnePacket(rb_t *rb, uint8_t *gizdata, uint16_t *len) { int32_t ret = 0; uint8_t sum = 0; int32_t i = 0; uint8_t tmpData; uint16_t tmpLen = 0; uint16_t tmpCount = 0; static uint8_t protocolFlag = 0; static uint16_t protocolCount = 0; static uint8_t lastData = 0; static uint8_t debugCount = 0; uint8_t *protocolBuff = gizdata; protocolHead_t *head = NULL; if((NULL == rb) || (NULL == gizdata) ||(NULL == len)) { GIZWITS_LOG("gizProtocolGetOnePacket Error , Illegal Param\n"); return -1; } tmpLen = rbCanRead(rb); if(0 == tmpLen) { return -1; } for(i=0; i<tmpLen; i++) { ret = rbRead(rb, &tmpData, 1); if(0 != ret) { if((0xFF == lastData) && (0xFF == tmpData)) { if(0 == protocolFlag) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; protocolFlag = 1; } else { if((protocolCount > 4) && (protocolCount != tmpCount)) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; } } } else if((0xFF == lastData) && (0x55 == tmpData)) { } else { if(1 == protocolFlag) { protocolBuff[protocolCount] = tmpData; protocolCount++; if(protocolCount > 4) { head = (protocolHead_t *)protocolBuff; tmpCount = exchangeBytes(head->len)+4; if (tmpCount >= MAX_PACKAGE_LEN || tmpCount <= 4) { protocolFlag = 0; protocolCount = 0; GIZWITS_LOG("ERR:the data length is too long or too small, will abandon \n"); } if(protocolCount == tmpCount) { break; } } } } lastData = tmpData; debugCount++; } } if((protocolCount > 4) && (protocolCount == tmpCount)) { sum = gizProtocolSum(protocolBuff, protocolCount); if(protocolBuff[protocolCount-1] == sum) { *len = tmpCount; protocolFlag = 0; protocolCount = 0; debugCount = 0; lastData = 0; return 0; } else { protocolFlag = 0; protocolCount = 0; return -2; } } return 1; } /** * @brief Protocol data resend * The protocol data resend when check timeout and meet the resend limiting * @param none * * @return none */ static void gizProtocolResendData(void) { int32_t ret = 0; if(0 == gizwitsProtocol.waitAck.flag) { return; } GIZWITS_LOG("Warning: timeout, resend data \n"); ret = uartWrite(gizwitsProtocol.waitAck.buf, gizwitsProtocol.waitAck.dataLen); if(ret != gizwitsProtocol.waitAck.dataLen) { GIZWITS_LOG("ERR: resend data error\n"); } gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); } /** * @brief Clear the ACK protocol message * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolWaitAckCheck(protocolHead_t *head) { protocolHead_t *waitAckHead = (protocolHead_t *)gizwitsProtocol.waitAck.buf; if(NULL == head) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } if(waitAckHead->cmd+1 == head->cmd) { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } return 0; } /** * @brief Send general protocol message data * * @param [in] head : Protocol header address * * @return : Return effective data length;-1,return failure */ static int32_t gizProtocolCommonAck(protocolHead_t *head) { int32_t ret = 0; protocolCommon_t ack; if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolCommonAck data is empty \n"); return -1; } memcpy((uint8_t *)&ack, (uint8_t *)head, sizeof(protocolHead_t)); ack.head.cmd = ack.head.cmd+1; ack.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); ack.sum = gizProtocolSum((uint8_t *)&ack, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&ack, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief ACK processing function * Time-out 200ms no ACK resend,resend two times at most * @param none * * @return none */ static void gizProtocolAckHandle(void) { if(1 == gizwitsProtocol.waitAck.flag) { if(SEND_MAX_NUM > gizwitsProtocol.waitAck.num) { // Time-out no ACK resend if(SEND_MAX_TIME < (gizGetTimerCount() - gizwitsProtocol.waitAck.sendTime)) { GIZWITS_LOG("Warning:gizProtocolResendData %d %d %d\n", gizGetTimerCount(), gizwitsProtocol.waitAck.sendTime, gizwitsProtocol.waitAck.num); gizProtocolResendData(); gizwitsProtocol.waitAck.num++; } } else { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } } } /** * @brief Protocol 4.1 WiFi module requests device information * * @param[in] head : Protocol header address * * @return Return effective data length;-1,return failure */ static int32_t gizProtocolGetDeviceInfo(protocolHead_t * head) { int32_t ret = 0; protocolDeviceInfo_t deviceInfo; if(NULL == head) { GIZWITS_LOG("gizProtocolGetDeviceInfo Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&deviceInfo); deviceInfo.head.cmd = ACK_GET_DEVICE_INFO; deviceInfo.head.sn = head->sn; memcpy((uint8_t *)deviceInfo.protocolVer, protocol_VERSION, 8); memcpy((uint8_t *)deviceInfo.p0Ver, P0_VERSION, 8); memcpy((uint8_t *)deviceInfo.softVer, SOFTWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.hardVer, HARDWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.productKey, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy((uint8_t *)deviceInfo.productSecret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memset((uint8_t *)deviceInfo.devAttr, 0, 8); deviceInfo.devAttr[7] |= DEV_IS_GATEWAY<<0; deviceInfo.devAttr[7] |= (0x01<<1); deviceInfo.ninableTime = exchangeBytes(NINABLETIME); #ifdef DATA_CONFIG_ENABLE deviceInfo.DataLen = exchangeBytes(GIZ_DATA_LEN); sprintf(deviceInfo.Data,"apName=%s&apPwd=%s&cfgMode=%s",AP_NAME,AP_PWD,CFG_MODE); #endif deviceInfo.head.len = exchangeBytes(sizeof(protocolDeviceInfo_t)-4); deviceInfo.sum = gizProtocolSum((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); ret = uartWrite((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.7 Handling of illegal message notification * @param[in] head : Protocol header address * @param[in] errno : Illegal message notification type * @return 0, success; other, failure */ static int32_t gizProtocolErrorCmd(protocolHead_t *head,errorPacketsType_t errno) { int32_t ret = 0; protocolErrorType_t errorType; if(NULL == head) { GIZWITS_LOG("gizProtocolErrorCmd Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&errorType); errorType.head.cmd = ACK_ERROR_PACKAGE; errorType.head.sn = head->sn; errorType.head.len = exchangeBytes(sizeof(protocolErrorType_t)-4); errorType.error = errno; errorType.sum = gizProtocolSum((uint8_t *)&errorType, sizeof(protocolErrorType_t)); ret = uartWrite((uint8_t *)&errorType, sizeof(protocolErrorType_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.13 Get and process network time * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolNTP(protocolHead_t *head) { protocolUTT_t *UTTInfo = (protocolUTT_t *)head; if(NULL == head) { GIZWITS_LOG("ERR: NTP is empty \n"); return -1; } memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.year,(uint8_t *)UTTInfo->time, 7); memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.ntp,(uint8_t *)UTTInfo->ntp_time, 4); gizwitsProtocol.TimeNTP.year = exchangeBytes(gizwitsProtocol.TimeNTP.year); gizwitsProtocol.TimeNTP.ntp =exchangeWord(gizwitsProtocol.TimeNTP.ntp); gizwitsProtocol.NTPEvent.event[gizwitsProtocol.NTPEvent.num] = WIFI_NTP; gizwitsProtocol.NTPEvent.num++; gizwitsProtocol.issuedFlag = GET_NTP_TYPE; return 0; } /** * @brief Protocol 4.4 Device MCU restarts function * @param none * @return none */ static void gizProtocolReboot(void) { uint32_t timeDelay = gizGetTimerCount(); /*Wait 600ms*/ while((gizGetTimerCount() - timeDelay) <= 600); mcuRestart(); } /** * @brief Protocol 4.5 :The WiFi module informs the device MCU of working status about the WiFi module * @param[in] status WiFi module working status * @return none */ static int8_t gizProtocolModuleStatus(protocolWifiStatus_t *status) { static wifiStatus_t lastStatus; if(NULL == status) { GIZWITS_LOG("gizProtocolModuleStatus Error , Illegal Param\n"); return -1; } status->ststus.value = exchangeBytes(status->ststus.value); //OnBoarding mode status if(lastStatus.types.onboarding != status->ststus.types.onboarding) { if(1 == status->ststus.types.onboarding) { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_AIRLINK; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: AirLink mode\n"); } } else { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_STATION; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: Station mode\n"); } } } //binding mode status if(lastStatus.types.binding != status->ststus.types.binding) { lastStatus.types.binding = status->ststus.types.binding; if(1 == status->ststus.types.binding) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in binding mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out binding mode\n"); } } //router status if(lastStatus.types.con_route != status->ststus.types.con_route) { lastStatus.types.con_route = status->ststus.types.con_route; if(1 == status->ststus.types.con_route) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected router\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected router\n"); } } //M2M server status if(lastStatus.types.con_m2m != status->ststus.types.con_m2m) { lastStatus.types.con_m2m = status->ststus.types.con_m2m; if(1 == status->ststus.types.con_m2m) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected m2m\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected m2m\n"); } } //APP status if(lastStatus.types.app != status->ststus.types.app) { lastStatus.types.app = status->ststus.types.app; if(1 == status->ststus.types.app) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: app connect\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: no app connect\n"); } } //test mode status if(lastStatus.types.test != status->ststus.types.test) { lastStatus.types.test = status->ststus.types.test; if(1 == status->ststus.types.test) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in test mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out test mode\n"); } } gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_RSSI; gizwitsProtocol.wifiStatusEvent.num++; gizwitsProtocol.wifiStatusData.rssi = status->ststus.types.rssi; GIZWITS_LOG("RSSI is %d \n", gizwitsProtocol.wifiStatusData.rssi); gizwitsProtocol.issuedFlag = WIFI_STATUS_TYPE; return 0; } /**@name Gizwits User API interface * @{ */ /** * @brief gizwits Protocol initialization interface * Protocol-related timer, serial port initialization * Datapoint initialization * @param none * @return none */ void gizwitsInit(void) { pRb.rbCapacity = RB_MAX_LEN; pRb.rbBuff = rbBuf; if(0 == rbCreate(&pRb)) { GIZWITS_LOG("rbCreate Success \n"); } else { GIZWITS_LOG("rbCreate Faild \n"); } memset((uint8_t *)&gizwitsProtocol, 0, sizeof(gizwitsProtocol_t)); } /** * @brief WiFi configure interface * Set the WiFi module into the corresponding configuration mode or reset the module * @param[in] mode :0x0, reset the module ;0x01, SoftAp mode ;0x02, AirLink mode ;0x03, Production test mode; 0x04:allow users to bind devices * @return Error command code */ int32_t gizwitsSetMode(uint8_t mode) { int32_t ret = 0; protocolCfgMode_t cfgMode; protocolCommon_t setDefault; switch(mode) { case WIFI_RESET_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_SET_DEFAULT; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_SOFTAP_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_AIRLINK_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_PRODUCTION_TEST: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_PRODUCTION_TEST; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_NINABLE_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_NINABLE_MODE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_REBOOT_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_REBOOT_MODULE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; default: GIZWITS_LOG("ERR: CfgMode error!\n"); break; } return ret; } /** * @brief Get the the network time * Protocol 4.13:"Device MCU send" of "the MCU requests access to the network time" * @param[in] none * @return none */ void gizwitsGetNTP(void) { int32_t ret = 0; protocolCommon_t getNTP; gizProtocolHeadInit((protocolHead_t *)&getNTP); getNTP.head.cmd = CMD_GET_NTP; getNTP.head.sn = gizwitsProtocol.sn++; getNTP.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); getNTP.sum = gizProtocolSum((uint8_t *)&getNTP, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&getNTP, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getNTP, sizeof(protocolCommon_t)); } /** * @brief Get Module Info * * @param[in] none * @return none */ void gizwitsGetModuleInfo(void) { int32_t ret = 0; protocolGetModuleInfo_t getModuleInfo; gizProtocolHeadInit((protocolHead_t *)&getModuleInfo); getModuleInfo.head.cmd = CMD_ASK_MODULE_INFO; getModuleInfo.head.sn = gizwitsProtocol.sn++; getModuleInfo.type = 0x0; getModuleInfo.head.len = exchangeBytes(sizeof(protocolGetModuleInfo_t)-4); getModuleInfo.sum = gizProtocolSum((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); ret = uartWrite((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); } /** * @brief Module Info Analyse * * @param [in] head : * * @return 0, Success, , other,Faild */ static int8_t gizProtocolModuleInfoHandle(protocolHead_t *head) { protocolModuleInfo_t *moduleInfo = (protocolModuleInfo_t *)head; if(NULL == head) { GIZWITS_LOG("NTP is empty \n"); return -1; } #if MODULE_TYPE memcpy((uint8_t *)&gizwitsProtocol.gprsInfoNews,(uint8_t *)&moduleInfo->gprsModuleInfo, sizeof(gprsInfo_t)); #else memcpy((uint8_t *)&gizwitsProtocol.wifiModuleNews,(uint8_t *)&moduleInfo->wifiModuleInfo, sizeof(moduleInfo_t)); #endif gizwitsProtocol.moduleInfoEvent.event[gizwitsProtocol.moduleInfoEvent.num] = MODULE_INFO; gizwitsProtocol.moduleInfoEvent.num++; gizwitsProtocol.issuedFlag = GET_MODULEINFO_TYPE; return 0; } /** * @brief Protocol handling function * * @param [in] currentData :The protocol data pointer * @return none */ int32_t gizwitsHandle(dataPoint_t *currentData) { int8_t ret = 0; #ifdef PROTOCOL_DEBUG uint16_t i = 0; #endif uint8_t ackData[RB_MAX_LEN]; uint16_t protocolLen = 0; uint32_t ackLen = 0; protocolHead_t *recvHead = NULL; char *didPtr = NULL; uint16_t offset = 0; if(NULL == currentData) { GIZWITS_LOG("GizwitsHandle Error , Illegal Param\n"); return -1; } /*resend strategy*/ gizProtocolAckHandle(); ret = gizProtocolGetOnePacket(&pRb, gizwitsProtocol.protocolBuf, &protocolLen); if(0 == ret) { GIZWITS_LOG("Get One Packet!\n"); #ifdef PROTOCOL_DEBUG GIZWITS_LOG("WiFi2MCU[%4d:%4d]: ", gizGetTimerCount(), protocolLen); for(i=0; i<protocolLen;i++) { GIZWITS_LOG("%02x ", gizwitsProtocol.protocolBuf[i]); } GIZWITS_LOG("\n"); #endif recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; switch (recvHead->cmd) { case CMD_GET_DEVICE_INTO: gizProtocolGetDeviceInfo(recvHead); break; case CMD_ISSUED_P0: GIZWITS_LOG("flag %x %x \n", recvHead->flags[0], recvHead->flags[1]); //offset = 1; if(0 == gizProtocolIssuedProcess(didPtr, gizwitsProtocol.protocolBuf+sizeof(protocolHead_t)+offset, protocolLen-(sizeof(protocolHead_t)+offset+1), ackData, &ackLen)) { gizProtocolIssuedDataAck(recvHead, ackData, ackLen,recvHead->flags[1]); GIZWITS_LOG("AckData : \n"); } break; case CMD_HEARTBEAT: gizProtocolCommonAck(recvHead); break; case CMD_WIFISTATUS: gizProtocolCommonAck(recvHead); gizProtocolModuleStatus((protocolWifiStatus_t *)recvHead); break; case ACK_REPORT_P0: case ACK_WIFI_CONFIG: case ACK_SET_DEFAULT: case ACK_NINABLE_MODE: case ACK_REBOOT_MODULE: gizProtocolWaitAckCheck(recvHead); break; case CMD_MCU_REBOOT: gizProtocolCommonAck(recvHead); GIZWITS_LOG("report:MCU reboot!\n"); gizProtocolReboot(); break; case CMD_ERROR_PACKAGE: break; case ACK_PRODUCTION_TEST: gizProtocolWaitAckCheck(recvHead); GIZWITS_LOG("Ack PRODUCTION_MODE success \n"); break; case ACK_GET_NTP: gizProtocolWaitAckCheck(recvHead); gizProtocolNTP(recvHead); GIZWITS_LOG("Ack GET_UTT success \n"); break; case ACK_ASK_MODULE_INFO: gizProtocolWaitAckCheck(recvHead); gizProtocolModuleInfoHandle(recvHead); GIZWITS_LOG("Ack GET_Module success \n"); break; default: gizProtocolErrorCmd(recvHead,ERROR_CMD); GIZWITS_LOG("ERR: cmd code error!\n"); break; } } else if(-2 == ret) { //Check failed, report exception recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; gizProtocolErrorCmd(recvHead,ERROR_ACK_SUM); GIZWITS_LOG("ERR: check sum error!\n"); return -2; } switch(gizwitsProtocol.issuedFlag) { case ACTION_CONTROL_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)&gizwitsProtocol.gizCurrentDataPoint, sizeof(dataPoint_t)); memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent,0x0,sizeof(gizwitsProtocol.issuedProcessEvent)); break; case WIFI_STATUS_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.wifiStatusEvent, (uint8_t *)&gizwitsProtocol.wifiStatusData, sizeof(moduleStatusInfo_t)); memset((uint8_t *)&gizwitsProtocol.wifiStatusEvent,0x0,sizeof(gizwitsProtocol.wifiStatusEvent)); break; case ACTION_W2D_TRANSPARENT_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)gizwitsProtocol.transparentBuff, gizwitsProtocol.transparentLen); break; case GET_NTP_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.NTPEvent, (uint8_t *)&gizwitsProtocol.TimeNTP, sizeof(protocolTime_t)); memset((uint8_t *)&gizwitsProtocol.NTPEvent,0x0,sizeof(gizwitsProtocol.NTPEvent)); break; case GET_MODULEINFO_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.moduleInfoEvent, (uint8_t *)&gizwitsProtocol.wifiModuleNews, sizeof(moduleInfo_t)); memset((uint8_t *)&gizwitsProtocol.moduleInfoEvent,0x0,sizeof(moduleInfo_t)); break; default: break; } gizDevReportPolicy(currentData); return 0; } /** * @brief gizwits report transparent data interface * The user can call the interface to complete the reporting of private protocol data * @param [in] data :Private protocol data * @param [in] len :Private protocol data length * @return 0,success ;other,failure */ int32_t gizwitsPassthroughData(uint8_t * gizdata, uint32_t len) { int32_t ret = 0; uint8_t tx_buf[MAX_PACKAGE_LEN]; uint8_t *pTxBuf = tx_buf; uint16_t data_len = 6+len; if(NULL == gizdata) { GIZWITS_LOG("[ERR] gizwitsPassthroughData Error \n"); return (-1); } *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8);//len *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= CMD_REPORT_P0;//0x1b cmd *pTxBuf ++= gizwitsProtocol.sn++;//sn *pTxBuf ++= 0x00;//flag *pTxBuf ++= 0x00;//flag *pTxBuf ++= ACTION_D2W_TRANSPARENT_DATA;//P0_Cmd memcpy(&tx_buf[9],gizdata,len); tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck(tx_buf, data_len+4); return 0; } /**@} */#include "sys.h" #include "usart.h" #include "gizwits_product.h" #if 1 #pragma import(__use_no_semihosting) //ҪࠢѨҪք֧Ԗگ˽ struct __FILE { int handle; }; FILE __stdout; //֨ӥ_sys_exit()ӔҜĢʹԃѫܺģʽ void _sys_exit(int x) { x = x; } //ט֨ӥfputcگ˽ int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0);//ѭ۷ע̍,ֱսע̍Ϊҏ USART1->DR = (u8) ch; return ch; } #endif #if EN_USART1_RX //ɧڻʹŜޓ˕ //Ԯࠚ1אؾϱԌѲ //עӢ,ׁȡUSARTx->SRŜҜĢĪĻǤĮքխϳ u8 USART_RX_BUF[USART_REC_LEN]; //ޓ˕ۺԥ,خճUSART_REC_LENٶؖޚ. //ޓ˕״̬ //bit15ì ޓ˕ΪԉҪ־ //bit14ì ޓ˕ս0x0d //bit13~0ì ޓ˕սքԐЧؖޚ˽Ŀ u16 USART_RX_STA=0; //ޓ˕״̬Ҫ݇ void uart1_init(u32 bound){ //GPIOࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹŜUSART1ìGPIOAʱד //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART1, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א USART_Cmd(USART1, ENABLE); //ʹŜԮࠚ1 } void uart2_init(u32 bound){ //GPIOࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //ʹŜUSART2ìGPIOAʱד RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART2, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א USART_Cmd(USART2, ENABLE); //ʹŜԮࠚ1 } void USART1_IRQHandler(void) //Ԯࠚ1אؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //ޓ˕א(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE); Res =USART_ReceiveData(USART1); //ׁȡޓ˕սք˽ߝ } } void USART2_IRQHandler(void) //Ԯࠚ2אؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) //ޓ˕א(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART2,USART_IT_RXNE); Res =USART_ReceiveData(USART2); //ׁȡޓ˕սք˽ߝ gizPutData(&Res,1); } } #endif
<think>我们正在处理一段嵌入式设备的代码,主要涉及机智云(Gizwits)协议的实现。代码中包含了与WiFi模块通信、数据点处理、事件处理等功能。用户提供的日志显示了一些警告和超时重发数据的信息,以及温湿度传感器(DHT11)的数据读取。
根据用户的问题,我们需要分析代码并解决可能的问题。用户提到“配置入网有问题”,并且日志中有“Warning: timeout, resend data”的提示,这表明设备在通信过程中出现了超时,可能是WiFi模块没有正确响应。
首先,我们注意到代码中处理协议的部分,特别是超时重发机制。在`gizProtocolResendData`函数中,如果等待ACK超时,会重新发送数据。但日志显示多次重发后仍然失败。
可能的原因:
1. 硬件连接问题:检查USART串口连接是否正确,波特率是否匹配。
2. WiFi模块工作状态:模块可能未正确启动或配置。
3. 协议处理错误:代码中处理协议的部分可能有逻辑错误。
我们重点检查串口初始化和数据发送接收部分。
在提供的代码中,我们看到了两个串口的初始化:USART1和USART2。其中,USART2用于与WiFi模块通信(因为USART2的中断服务程序调用了`gizPutData`,这是将数据放入环形缓冲区的函数)。
在`uart2_init`函数中,初始化了USART2,并设置了相应的GPIO和中断。但是,我们注意到在初始化USART2时,时钟配置如下:
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
这是正确的,因为USART2挂在APB1上,而GPIOA挂在APB2上。
但是,我们还需要检查波特率是否与WiFi模块要求的波特率一致。通常,WiFi模块(如ESP8266)默认波特率为115200,但代码中用户初始化串口2时传入的波特率参数是多少?在main函数中应该可以看到。由于用户没有提供main函数,我们假设波特率设置正确。
另外,在中断服务程序USART2_IRQHandler中,每次接收到一个字节就调用`gizPutData`放入环形缓冲区。然后,主循环中会调用`gizwitsHandle`来处理协议。
问题可能出现在协议处理过程中,比如等待ACK超时。我们检查一下等待ACK的时间设置:
在`gizProtocolAckHandle`函数中,超时时间定义为SEND_MAX_TIME(200ms),最多重发SEND_MAX_NUM(2次)。如果超过2次,就清除等待标志。
日志中出现了多次重发,说明第一次发送后没有收到ACK,然后重发,但重发后仍然没有收到ACK。
可能的原因:
1. WiFi模块没有正确接收到数据,因此没有回复ACK。
2. WiFi模块回复了ACK,但设备没有正确接收到(比如串口接收问题)。
针对第2点,我们检查串口接收中断是否正常工作。在USART2_IRQHandler中,我们只处理了USART_IT_RXNE(接收寄存器非空中断),并读取数据到环形缓冲区。但是,我们并没有在代码中看到对环形缓冲区的读取有长度限制或错误处理。
另外,在`gizProtocolGetOnePacket`函数中,从环形缓冲区中解析一个完整的数据包。这个函数可能会因为数据包不完整或校验错误而返回-2(校验失败)或其他错误。
日志中出现了“Warning:gizProtocolResendData”,说明确实发生了超时重发。我们需要确保WiFi模块处于正常工作状态,并且串口通信正常。
建议的调试步骤:
1. 检查硬件连接,特别是USART2的TX(PA2)和RX(PA3)是否与WiFi模块交叉连接(即设备的TX接模块的RX,设备的RX接模块的TX)。
2. 检查波特率,确保设备与WiFi模块的波特率一致(通常为9600,115200等)。
3. 在串口初始化后,发送AT指令测试WiFi模块是否正常工作(如果模块支持AT指令)。
4. 在代码中增加调试信息,比如在每次发送和接收时打印数据,以便分析通信过程。
由于用户提到“配置入网有问题”,我们还需要检查配置入网的函数`gizwitsSetMode`。这个函数用于设置WiFi模块的工作模式(如SoftAP或AirLink模式)。在调用这个函数后,如果模块没有正确响应,就会导致超时。
在`gizwitsSetMode`函数中,发送命令后调用了`gizProtocolWaitAck`,该函数设置了等待ACK的标志。然后,在`gizProtocolAckHandle`中会检查是否超时,超时则重发。
如果多次重发后仍然失败,函数就返回,但配置模式可能没有成功。
因此,我们需要确保在调用`gizwitsSetMode`之前,WiFi模块已经准备好接收命令。例如,模块上电后需要一定的初始化时间,建议在模块上电后延迟一段时间再发送配置命令。
另外,检查`gizwitsSetMode`中发送的命令是否符合协议。我们可以通过串口调试工具捕获设备与WiFi模块之间的通信数据,以确定问题所在。
由于代码较长,我们只分析可能的问题点。具体的修复可能需要根据实际调试结果进行。
下面,我们给出一个修改建议:在发送配置命令前,先发送一个简单的命令(如AT)来测试模块是否就绪。但注意,该代码中的协议是机智云自定义协议,不是AT命令。
因此,我们只能按照机智云的协议进行。我们可以在设备启动后,先尝试获取模块信息(使用`gizwitsGetModuleInfo`),以确认通信是否正常。
另外,在`gizwitsInit`函数中,初始化了环形缓冲区,并重置了协议相关的变量。这个函数应该在系统启动时调用一次。
总结:由于问题可能涉及硬件和软件,我们首先确保硬件连接正确,然后通过打印调试信息来跟踪通信过程。
由于用户没有提供完整的工程和硬件信息,我们只能提供这些建议。
下面,我们给出一个修改示例,在协议处理中增加更多的调试信息,以便定位问题。
例如,在`gizwitsHandle`函数中,当接收到一个数据包时,打印数据包的内容。在发送数据时,也打印发送的内容。
但是请注意,在嵌入式设备中,打印调试信息可能会影响实时性,所以仅用于调试。
修改`gizwitsHandle`函数,在接收到数据包时打印:
```c
// 在 ret = gizProtocolGetOnePacket(&pRb, gizwitsProtocol.protocolBuf, &protocolLen); 之后
if(0 == ret)
{
GIZWITS_LOG("Get One Packet!\n");
// 打印接收到的数据包
GIZWITS_LOG("RX: ");
for(uint16_t i=0; i<protocolLen; i++)
{
GIZWITS_LOG("%02X ", gizwitsProtocol.protocolBuf[i]);
}
GIZWITS_LOG("\n");
}
```
同样,在发送数据的地方,比如`gizwitsSetMode`函数中,在调用`uartWrite`之后,打印发送的数据。
另外,在USART2的中断服务程序中,也可以打印接收到的每个字节(注意,这样会打印很多,谨慎使用)。
通过以上调试信息,我们可以判断数据是否正确发送和接收。
由于用户的问题描述有限,我们只能提供这些建议。如果问题仍然存在,需要进一步检查硬件和模块状态。
最后,我们回答用户的问题:配置入网有问题,可能是由于串口通信问题导致命令发送后没有收到ACK,建议检查硬件连接和波特率,并增加调试信息。
由于代码较长,我们只修改了部分代码用于调试。用户可以根据需要添加调试信息。
注意:调试完成后,应移除不必要的调试打印,以减少资源占用。
下面,我们给出修改后的`gizwitsHandle`函数的部分代码(仅添加调试打印):</think>根据您提供的代码,这是一个嵌入式设备与机智云(Gizwits)物联网平台通信的协议实现。代码主要实现了与WiFi模块的通信协议处理、数据点管理、事件处理等功能。我将分析关键部分并提供解决方案。
### 主要问题分析
1. **日志显示"Warning: timeout, resend data"**:表明设备与WiFi模块通信超时
2. **"配置入网有问题"**:设备无法成功连接WiFi网络
3. **DHT11传感器数据读取正常**:温度湿度数据正常上报
### 解决方案
需要修复WiFi配置入网问题,以下是关键修改点:
#### 1. 修复WiFi配置模式设置
在`gizwitsSetMode`函数中添加重试机制:
```c
int32_t gizwitsSetMode(uint8_t mode)
{
int32_t ret = 0;
uint8_t retry = 0;
const uint8_t max_retry = 3; // 最大重试次数
do {
switch(mode) {
// ... 现有代码 ...
case WIFI_SOFTAP_MODE:
case WIFI_AIRLINK_MODE:
// ... 现有配置代码 ...
break;
// ... 其他模式 ...
}
// 添加配置结果检查
if(gizwitsProtocol.waitAck.flag == 0) {
GIZWITS_LOG("配置模式 %d 成功\n", mode);
return 0; // 成功
}
retry++;
GIZWITS_LOG("配置失败,重试 %d/%d\n", retry, max_retry);
delay_ms(500); // 添加延时
} while(retry < max_retry);
GIZWITS_LOG("ERR: 配置模式 %d 失败\n", mode);
return -1; // 失败
}
```
#### 2. 增强串口通信可靠性
在`uart2_init`函数中优化串口配置:
```c
void uart2_init(u32 bound) {
// ... 现有代码 ...
// 添加串口错误中断使能
USART_ITConfig(USART2, USART_IT_ORE, ENABLE); // 过载错误
USART_ITConfig(USART2, USART_IT_NE, ENABLE); // 噪声错误
USART_ITConfig(USART2, USART_IT_FE, ENABLE); // 帧错误
// ... 现有代码 ...
}
// 添加串口错误处理
void USART2_IRQHandler(void) {
if(USART_GetITStatus(USART2, USART_IT_ORE) != RESET) {
USART_ClearITPendingBit(USART2, USART_IT_ORE);
USART_ReceiveData(USART2); // 清除溢出
}
if(USART_GetITStatus(USART2, USART_IT_NE) != RESET) {
USART_ClearITPendingBit(USART2, USART_IT_NE);
}
if(USART_GetITStatus(USART2, USART_IT_FE) != RESET) {
USART_ClearITPendingBit(USART2, USART_IT_FE);
}
// ... 现有接收处理 ...
}
```
#### 3. 优化WiFi状态检测
在`gizProtocolModuleStatus`中添加详细状态日志:
```c
static int8_t gizProtocolModuleStatus(protocolWifiStatus_t *status) {
// ... 现有代码 ...
// 添加详细状态日志
GIZWITS_LOG("WiFi状态: onboarding=%d, softap=%d, station=%d, binding=%d\n",
status->ststus.types.onboarding,
status->ststus.types.softap,
status->ststus.types.station,
status->ststus.types.binding);
GIZWITS_LOG("连接状态: con_route=%d, con_m2m=%d, app=%d\n",
status->ststus.types.con_route,
status->ststus.types.con_m2m,
status->ststus.types.app);
// ... 现有事件处理 ...
}
```
#### 4. 添加配置超时处理
在协议处理状态机中添加超时检测:
```c
// 全局变量
static uint32_t configStartTime = 0;
static uint8_t isConfiguring = 0;
void gizwitsSetMode(uint8_t mode) {
// ... 现有代码 ...
configStartTime = gizGetTimerCount();
isConfiguring = 1;
}
void gizwitsHandle(dataPoint_t *currentData) {
// 添加配置超时检测
if(isConfiguring && (gizGetTimerCount() - configStartTime > 30000)) { // 30秒超时
GIZWITS_LOG("ERR: 配置超时!\n");
isConfiguring = 0;
// 触发错误处理
gizwitsProtocol.issuedProcessEvent.event[gizwitsProtocol.issuedProcessEvent.num] = WIFI_CONFIG_TIMEOUT;
gizwitsProtocol.issuedProcessEvent.num++;
}
// ... 现有处理代码 ...
}
```
### 关键函数说明
1. **`gizwitsHandle`**:主协议处理函数,负责数据解析、事件分发
2. **`gizDataPoint2Event`**:将原始数据转换为事件
3. **`gizDevReportPolicy`**:实现数据上报策略(立即上报+定时上报)
4. **`gizwitsSetMode`**:设置WiFi工作模式(SoftAP/AirLink等)
5. **`gizProtocolAckHandle`**:ACK处理与超时重传机制
### 相关建议
1. 检查硬件连接:确保USART2(TX-PA2/RX-PA3)与WiFi模块正确连接
2. 验证波特率:确保设备与WiFi模块使用相同波特率(通常115200)
3. 添加LED指示:在配置过程中添加LED状态指示
4. 使用示波器:检查串口信号质量
###
rbWrite WARN: Failed to queue data: 0x00DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56UART1 and UART2 initialized. ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00ERR: Failed to rbWrite WARN: Failed to queue data: 0x00rbCreate Success DHT11 OK: T=29, H=56Warning:gizProtocolResendData 590 2 0Resending data, attempt 1/2DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 OK: T=29, H=56DHT11 我完全跟着你改为什么还是一样的 /** ************************************************************ * @file gizwits_protocol.c * @brief Corresponding gizwits_product.c header file (including product hardware and software version definition) * @author Gizwits * @date 2017-07-19 * @version V03030000 * @copyright Gizwits * * @note 机智云.只为智能硬件而生 * Gizwits Smart Cloud for Smart Products * 链接|增值ֵ|开放|中立|安全|自有|自由|生态 * www.gizwits.com * ***********************************************************/ #include "ringBuffer.h" #include "gizwits_product.h" #include "dataPointTools.h" #define SEND_MAX_TIME 200 // 单次重发等待时间(毫秒) #define SEND_MIN_INTERVAL 100 // 最小重发间隔(毫秒) /** Protocol global variables **/ gizwitsProtocol_t gizwitsProtocol; /**@name The serial port receives the ring buffer implementation * @{ */ rb_t pRb; ///< Ring buffer structure variable static uint8_t rbBuf[RB_MAX_LEN]; ///< Ring buffer data cache buffer /**@} */ /** * @brief Write data to the ring buffer * @param [in] buf : buf adress * @param [in] len : byte length * @return correct : Returns the length of the written data failure : -1 */ int32_t gizPutData(uint8_t *buf, uint32_t len) { int32_t count = 0; if(NULL == buf) { GIZWITS_LOG("ERR: gizPutData buf is empty \n"); return -1; } count = rbWrite(&pRb, buf, len); if(count != len) { GIZWITS_LOG("ERR: Failed to rbWrite \n"); return -1; } return count; } /** * @brief Protocol header initialization * * @param [out] head : Protocol header pointer * * @return 0, success; other, failure */ static int8_t gizProtocolHeadInit(protocolHead_t *head) { if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolHeadInit head is empty \n"); return -1; } memset((uint8_t *)head, 0, sizeof(protocolHead_t)); head->head[0] = 0xFF; head->head[1] = 0xFF; return 0; } /** * @brief Protocol ACK check processing function * * @param [in] data : data adress * @param [in] len : data length * * @return 0, suceess; other, failure */ static int8_t gizProtocolWaitAck(uint8_t *gizdata, uint32_t len) { if(NULL == gizdata) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); memcpy((uint8_t *)gizwitsProtocol.waitAck.buf, gizdata, len); gizwitsProtocol.waitAck.dataLen = (uint16_t)len; gizwitsProtocol.waitAck.flag = 1; gizwitsProtocol.waitAck.sendTime = gizGetTimerCount(); return 0; } /** * @brief generates "controlled events" according to protocol * @param [in] issuedData: Controlled data * @param [out] info: event queue * @param [out] dataPoints: data point data * @return 0, the implementation of success, non-0, failed */ static int8_t ICACHE_FLASH_ATTR gizDataPoint2Event(gizwitsIssued_t *issuedData, eventInfo_t *info, dataPoint_t *dataPoints) { if((NULL == issuedData) || (NULL == info) ||(NULL == dataPoints)) { GIZWITS_LOG("gizDataPoint2Event Error , Illegal Param\n"); return -1; } /** Greater than 1 byte to do bit conversion **/ if(sizeof(issuedData->attrFlags) > 1) { if(-1 == gizByteOrderExchange((uint8_t *)&issuedData->attrFlags,sizeof(attrFlags_t))) { GIZWITS_LOG("gizByteOrderExchange Error\n"); return -1; } } if(0x01 == issuedData->attrFlags.flagFan_OnOff) { info->event[info->num] = EVENT_Fan_OnOff; info->num++; dataPoints->valueFan_OnOff = gizStandardDecompressionValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } if(0x01 == issuedData->attrFlags.flagLED_OnOff) { info->event[info->num] = EVENT_LED_OnOff; info->num++; dataPoints->valueLED_OnOff = gizStandardDecompressionValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)&issuedData->attrVals.wBitBuf,sizeof(issuedData->attrVals.wBitBuf)); } return 0; } /** * @brief contrasts the current data with the last data * * @param [in] cur: current data point data * @param [in] last: last data point data * * @return: 0, no change in data; 1, data changes */ static int8_t ICACHE_FLASH_ATTR gizCheckReport(dataPoint_t *cur, dataPoint_t *last) { int8_t ret = 0; static uint32_t lastReportTime = 0; uint32_t currentTime = 0; if((NULL == cur) || (NULL == last)) { GIZWITS_LOG("gizCheckReport Error , Illegal Param\n"); return -1; } currentTime = gizGetTimerCount(); if(last->valueFan_OnOff != cur->valueFan_OnOff) { GIZWITS_LOG("valueFan_OnOff Changed\n"); ret = 1; } if(last->valueLED_OnOff != cur->valueLED_OnOff) { GIZWITS_LOG("valueLED_OnOff Changed\n"); ret = 1; } if(last->valuetemp != cur->valuetemp) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuetemp Changed\n"); ret = 1; } } if(last->valuehumi != cur->valuehumi) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuehumi Changed\n"); ret = 1; } } if(last->valuelight != cur->valuelight) { if(currentTime - lastReportTime >= REPORT_TIME_MAX) { GIZWITS_LOG("valuelight Changed\n"); ret = 1; } } if(1 == ret) { lastReportTime = gizGetTimerCount(); } return ret; } /** * @brief User data point data is converted to wit the cloud to report data point data * * @param [in] dataPoints: user data point data address * @param [out] devStatusPtr: wit the cloud data point data address * * @return 0, the correct return; -1, the error returned */ static int8_t ICACHE_FLASH_ATTR gizDataPoints2ReportData(dataPoint_t *dataPoints , devStatus_t *devStatusPtr) { if((NULL == dataPoints) || (NULL == devStatusPtr)) { GIZWITS_LOG("gizDataPoints2ReportData Error , Illegal Param\n"); return -1; } gizMemset((uint8_t *)devStatusPtr->wBitBuf,0,sizeof(devStatusPtr->wBitBuf)); gizStandardCompressValue(Fan_OnOff_BYTEOFFSET,Fan_OnOff_BITOFFSET,Fan_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueFan_OnOff); gizStandardCompressValue(LED_OnOff_BYTEOFFSET,LED_OnOff_BITOFFSET,LED_OnOff_LEN,(uint8_t *)devStatusPtr,dataPoints->valueLED_OnOff); gizByteOrderExchange((uint8_t *)devStatusPtr->wBitBuf,sizeof(devStatusPtr->wBitBuf)); devStatusPtr->valuetemp = gizY2X(temp_RATIO, temp_ADDITION, dataPoints->valuetemp); devStatusPtr->valuehumi = gizY2X(humi_RATIO, humi_ADDITION, dataPoints->valuehumi); devStatusPtr->valuelight = exchangeBytes(gizY2X(light_RATIO, light_ADDITION, dataPoints->valuelight)); return 0; } /** * @brief This function is called by the Gagent module to receive the relevant protocol data from the cloud or APP * @param [in] inData The protocol data entered * @param [in] inLen Enter the length of the data * @param [out] outData The output of the protocol data * @param [out] outLen The length of the output data * @return 0, the implementation of success, non-0, failed */ static int8_t gizProtocolIssuedProcess(char *did, uint8_t *inData, uint32_t inLen, uint8_t *outData, uint32_t *outLen) { uint8_t issuedAction = inData[0]; if((NULL == inData)||(NULL == outData)||(NULL == outLen)) { GIZWITS_LOG("gizProtocolIssuedProcess Error , Illegal Param\n"); return -1; } if(NULL == did) { memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent, 0, sizeof(eventInfo_t)); switch(issuedAction) { case ACTION_CONTROL_DEVICE: gizDataPoint2Event((gizwitsIssued_t *)&inData[1], &gizwitsProtocol.issuedProcessEvent,&gizwitsProtocol.gizCurrentDataPoint); gizwitsProtocol.issuedFlag = ACTION_CONTROL_TYPE; outData = NULL; *outLen = 0; break; case ACTION_READ_DEV_STATUS: if(0 == gizDataPoints2ReportData(&gizwitsProtocol.gizLastDataPoint,&gizwitsProtocol.reportData.devStatus)) { memcpy(outData+1, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(gizwitsReport_t)); outData[0] = ACTION_READ_DEV_STATUS_ACK; *outLen = sizeof(gizwitsReport_t)+1; } else { return -1; } break; case ACTION_W2D_TRANSPARENT_DATA: memcpy(gizwitsProtocol.transparentBuff, &inData[1], inLen-1); gizwitsProtocol.transparentLen = inLen - 1; gizwitsProtocol.issuedProcessEvent.event[gizwitsProtocol.issuedProcessEvent.num] = TRANSPARENT_DATA; gizwitsProtocol.issuedProcessEvent.num++; gizwitsProtocol.issuedFlag = ACTION_W2D_TRANSPARENT_TYPE; outData = NULL; *outLen = 0; break; default: break; } } return 0; } /** * @brief The protocol sends data back , P0 ACK * * @param [in] head : Protocol head pointer * @param [in] data : Payload data * @param [in] len : Payload data length * @param [in] proFlag : DID flag ,1 for Virtual sub device did ,0 for single product or gateway * * @return : 0,Ack success; * -1,Input Param Illegal * -2,Serial send faild */ static int32_t gizProtocolIssuedDataAck(protocolHead_t *head, uint8_t *gizdata, uint32_t len, uint8_t proFlag) { int32_t ret = 0; uint8_t tx_buf[RB_MAX_LEN]; uint32_t offset = 0; uint8_t sDidLen = 0; uint16_t data_len = 0; uint8_t *pTxBuf = tx_buf; if(NULL == gizdata) { GIZWITS_LOG("[ERR] data Is Null \n"); return -1; } if(0x1 == proFlag) { sDidLen = *((uint8_t *)head + sizeof(protocolHead_t)); data_len = 5 + 1 + sDidLen + len; } else { data_len = 5 + len; } GIZWITS_LOG("len = %d , sDidLen = %d ,data_len = %d\n", len,sDidLen,data_len); *pTxBuf ++= 0xFF; *pTxBuf ++= 0xFF; *pTxBuf ++= (uint8_t)(data_len>>8); *pTxBuf ++= (uint8_t)(data_len); *pTxBuf ++= head->cmd + 1; *pTxBuf ++= head->sn; *pTxBuf ++= 0x00; *pTxBuf ++= proFlag; offset = 8; if(0x1 == proFlag) { *pTxBuf ++= sDidLen; offset += 1; memcpy(&tx_buf[offset],(uint8_t *)head+sizeof(protocolHead_t)+1,sDidLen); offset += sDidLen; pTxBuf += sDidLen; } if(0 != len) { memcpy(&tx_buf[offset],gizdata,len); } tx_buf[data_len + 4 - 1 ] = gizProtocolSum( tx_buf , (data_len+4)); ret = uartWrite(tx_buf, data_len+4); if(ret < 0) { GIZWITS_LOG("uart write error %d \n", ret); return -2; } return 0; } /** * @brief Report data interface * * @param [in] action : PO action * @param [in] data : Payload data * @param [in] len : Payload data length * * @return : 0,Ack success; * -1,Input Param Illegal * -2,Serial send faild */ static int32_t gizReportData(uint8_t action, uint8_t *gizdata, uint32_t len) { int32_t ret = 0; protocolReport_t protocolReport; if(NULL == gizdata) { GIZWITS_LOG("gizReportData Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&protocolReport); protocolReport.head.cmd = CMD_REPORT_P0; protocolReport.head.sn = gizwitsProtocol.sn++; protocolReport.action = action; protocolReport.head.len = exchangeBytes(sizeof(protocolReport_t)-4); memcpy((gizwitsReport_t *)&protocolReport.reportData, (gizwitsReport_t *)gizdata,len); protocolReport.sum = gizProtocolSum((uint8_t *)&protocolReport, sizeof(protocolReport_t)); ret = uartWrite((uint8_t *)&protocolReport, sizeof(protocolReport_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); return -2; } gizProtocolWaitAck((uint8_t *)&protocolReport, sizeof(protocolReport_t)); return ret; }/** * @brief Datapoints reporting mechanism * * 1. Changes are reported immediately * 2. Data timing report , 600000 Millisecond * *@param [in] currentData : Current datapoints value * @return : NULL */ static void gizDevReportPolicy(dataPoint_t *currentData) { static uint32_t lastRepTime = 0; uint32_t timeNow = gizGetTimerCount(); if((1 == gizCheckReport(currentData, (dataPoint_t *)&gizwitsProtocol.gizLastDataPoint))) { GIZWITS_LOG("changed, report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); } if((0 == (timeNow % (600000))) && (lastRepTime != timeNow)) { GIZWITS_LOG("Info: 600S report data\n"); if(0 == gizDataPoints2ReportData(currentData,&gizwitsProtocol.reportData.devStatus)) { gizReportData(ACTION_REPORT_DEV_STATUS, (uint8_t *)&gizwitsProtocol.reportData.devStatus, sizeof(devStatus_t)); } memcpy((uint8_t *)&gizwitsProtocol.gizLastDataPoint, (uint8_t *)currentData, sizeof(dataPoint_t)); lastRepTime = timeNow; } } /** * @brief Get a packet of data from the ring buffer * * @param [in] rb : Input data address * @param [out] data : Output data address * @param [out] len : Output data length * * @return : 0,Return correct ;-1,Return failure;-2,Data check failure */ static int8_t gizProtocolGetOnePacket(rb_t *rb, uint8_t *gizdata, uint16_t *len) { int32_t ret = 0; uint8_t sum = 0; int32_t i = 0; uint8_t tmpData; uint16_t tmpLen = 0; uint16_t tmpCount = 0; static uint8_t protocolFlag = 0; static uint16_t protocolCount = 0; static uint8_t lastData = 0; static uint8_t debugCount = 0; uint8_t *protocolBuff = gizdata; protocolHead_t *head = NULL; if((NULL == rb) || (NULL == gizdata) ||(NULL == len)) { GIZWITS_LOG("gizProtocolGetOnePacket Error , Illegal Param\n"); return -1; } tmpLen = rbCanRead(rb); if(0 == tmpLen) { return -1; } for(i=0; i<tmpLen; i++) { ret = rbRead(rb, &tmpData, 1); if(0 != ret) { if((0xFF == lastData) && (0xFF == tmpData)) { if(0 == protocolFlag) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; protocolFlag = 1; } else { if((protocolCount > 4) && (protocolCount != tmpCount)) { protocolBuff[0] = 0xFF; protocolBuff[1] = 0xFF; protocolCount = 2; } } } else if((0xFF == lastData) && (0x55 == tmpData)) { } else { if(1 == protocolFlag) { protocolBuff[protocolCount] = tmpData; protocolCount++; if(protocolCount > 4) { head = (protocolHead_t *)protocolBuff; tmpCount = exchangeBytes(head->len)+4; if (tmpCount >= MAX_PACKAGE_LEN || tmpCount <= 4) { protocolFlag = 0; protocolCount = 0; GIZWITS_LOG("ERR:the data length is too long or too small, will abandon \n"); } if(protocolCount == tmpCount) { break; } } } } lastData = tmpData; debugCount++; } } if((protocolCount > 4) && (protocolCount == tmpCount)) { sum = gizProtocolSum(protocolBuff, protocolCount); if(protocolBuff[protocolCount-1] == sum) { *len = tmpCount; protocolFlag = 0; protocolCount = 0; debugCount = 0; lastData = 0; return 0; } else { protocolFlag = 0; protocolCount = 0; return -2; } } return 1; } /** * @brief Protocol data resend * The protocol data resend when check timeout and meet the resend limiting * @param none * * @return none */ static void gizProtocolResendData(void) { if(0 == gizwitsProtocol.waitAck.flag || gizwitsProtocol.waitAck.num >= SEND_MAX_NUM) { return; } uint32_t now = gizGetTimerCount(); if(now - gizwitsProtocol.waitAck.sendTime < SEND_MIN_INTERVAL) { return; } GIZWITS_LOG("Resending data, attempt %d/%d\n", gizwitsProtocol.waitAck.num+1, SEND_MAX_NUM); int ret = uartWrite(gizwitsProtocol.waitAck.buf, gizwitsProtocol.waitAck.dataLen); if(ret == gizwitsProtocol.waitAck.dataLen) { gizwitsProtocol.waitAck.sendTime = now; gizwitsProtocol.waitAck.num++; } else { GIZWITS_LOG("ERR: resend failed, ret=%d\n", ret); } } /** * @brief Clear the ACK protocol message * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolWaitAckCheck(protocolHead_t *head) { protocolHead_t *waitAckHead = (protocolHead_t *)gizwitsProtocol.waitAck.buf; if(NULL == head) { GIZWITS_LOG("ERR: data is empty \n"); return -1; } if(waitAckHead->cmd+1 == head->cmd) { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } return 0; } /** * @brief Send general protocol message data * * @param [in] head : Protocol header address * * @return : Return effective data length;-1,return failure */ static int32_t gizProtocolCommonAck(protocolHead_t *head) { int32_t ret = 0; protocolCommon_t ack; if(NULL == head) { GIZWITS_LOG("ERR: gizProtocolCommonAck data is empty \n"); return -1; } memcpy((uint8_t *)&ack, (uint8_t *)head, sizeof(protocolHead_t)); ack.head.cmd = ack.head.cmd+1; ack.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); ack.sum = gizProtocolSum((uint8_t *)&ack, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&ack, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief ACK processing function * Time-out 200ms no ACK resend,resend two times at most * @param none * * @return none */ static void gizProtocolAckHandle(void) { if(1 == gizwitsProtocol.waitAck.flag) { if(SEND_MAX_NUM > gizwitsProtocol.waitAck.num) { // Time-out no ACK resend if(SEND_MAX_TIME < (gizGetTimerCount() - gizwitsProtocol.waitAck.sendTime)) { GIZWITS_LOG("Warning:gizProtocolResendData %d %d %d\n", gizGetTimerCount(), gizwitsProtocol.waitAck.sendTime, gizwitsProtocol.waitAck.num); gizProtocolResendData(); gizwitsProtocol.waitAck.num++; } } else { memset((uint8_t *)&gizwitsProtocol.waitAck, 0, sizeof(protocolWaitAck_t)); } } } /** * @brief Protocol 4.1 WiFi module requests device information * * @param[in] head : Protocol header address * * @return Return effective data length;-1,return failure */ static int32_t gizProtocolGetDeviceInfo(protocolHead_t * head) { int32_t ret = 0; protocolDeviceInfo_t deviceInfo; if(NULL == head) { GIZWITS_LOG("gizProtocolGetDeviceInfo Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&deviceInfo); deviceInfo.head.cmd = ACK_GET_DEVICE_INFO; deviceInfo.head.sn = head->sn; memcpy((uint8_t *)deviceInfo.protocolVer, protocol_VERSION, 8); memcpy((uint8_t *)deviceInfo.p0Ver, P0_VERSION, 8); memcpy((uint8_t *)deviceInfo.softVer, SOFTWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.hardVer, HARDWARE_VERSION, 8); memcpy((uint8_t *)deviceInfo.productKey, PRODUCT_KEY, strlen(PRODUCT_KEY)); memcpy((uint8_t *)deviceInfo.productSecret, PRODUCT_SECRET, strlen(PRODUCT_SECRET)); memset((uint8_t *)deviceInfo.devAttr, 0, 8); deviceInfo.devAttr[7] |= DEV_IS_GATEWAY<<0; deviceInfo.devAttr[7] |= (0x01<<1); deviceInfo.ninableTime = exchangeBytes(NINABLETIME); #ifdef DATA_CONFIG_ENABLE deviceInfo.DataLen = exchangeBytes(GIZ_DATA_LEN); sprintf(deviceInfo.Data,"apName=%s&apPwd=%s&cfgMode=%s",AP_NAME,AP_PWD,CFG_MODE); #endif deviceInfo.head.len = exchangeBytes(sizeof(protocolDeviceInfo_t)-4); deviceInfo.sum = gizProtocolSum((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); ret = uartWrite((uint8_t *)&deviceInfo, sizeof(protocolDeviceInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.7 Handling of illegal message notification * @param[in] head : Protocol header address * @param[in] errno : Illegal message notification type * @return 0, success; other, failure */ static int32_t gizProtocolErrorCmd(protocolHead_t *head,errorPacketsType_t errno) { int32_t ret = 0; protocolErrorType_t errorType; if(NULL == head) { GIZWITS_LOG("gizProtocolErrorCmd Error , Illegal Param\n"); return -1; } gizProtocolHeadInit((protocolHead_t *)&errorType); errorType.head.cmd = ACK_ERROR_PACKAGE; errorType.head.sn = head->sn; errorType.head.len = exchangeBytes(sizeof(protocolErrorType_t)-4); errorType.error = errno; errorType.sum = gizProtocolSum((uint8_t *)&errorType, sizeof(protocolErrorType_t)); ret = uartWrite((uint8_t *)&errorType, sizeof(protocolErrorType_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } return ret; } /** * @brief Protocol 4.13 Get and process network time * * @param [in] head : Protocol header address * * @return 0, success; other, failure */ static int8_t gizProtocolNTP(protocolHead_t *head) { protocolUTT_t *UTTInfo = (protocolUTT_t *)head; if(NULL == head) { GIZWITS_LOG("ERR: NTP is empty \n"); return -1; } memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.year,(uint8_t *)UTTInfo->time, 7); memcpy((uint8_t *)&gizwitsProtocol.TimeNTP.ntp,(uint8_t *)UTTInfo->ntp_time, 4); gizwitsProtocol.TimeNTP.year = exchangeBytes(gizwitsProtocol.TimeNTP.year); gizwitsProtocol.TimeNTP.ntp =exchangeWord(gizwitsProtocol.TimeNTP.ntp); gizwitsProtocol.NTPEvent.event[gizwitsProtocol.NTPEvent.num] = WIFI_NTP; gizwitsProtocol.NTPEvent.num++; gizwitsProtocol.issuedFlag = GET_NTP_TYPE; return 0; } /** * @brief Protocol 4.4 Device MCU restarts function * @param none * @return none */ static void gizProtocolReboot(void) { uint32_t timeDelay = gizGetTimerCount(); /*Wait 600ms*/ while((gizGetTimerCount() - timeDelay) <= 600); mcuRestart(); } /** * @brief Protocol 4.5 :The WiFi module informs the device MCU of working status about the WiFi module * @param[in] status WiFi module working status * @return none */ static int8_t gizProtocolModuleStatus(protocolWifiStatus_t *status) { static wifiStatus_t lastStatus; if(NULL == status) { GIZWITS_LOG("gizProtocolModuleStatus Error , Illegal Param\n"); return -1; } status->ststus.value = exchangeBytes(status->ststus.value); //OnBoarding mode status if(lastStatus.types.onboarding != status->ststus.types.onboarding) { if(1 == status->ststus.types.onboarding) { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_AIRLINK; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: AirLink mode\n"); } } else { if(1 == status->ststus.types.softap) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_SOFTAP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: SoftAP or Web mode\n"); } if(1 == status->ststus.types.station) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_STATION; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("OnBoarding: Station mode\n"); } } } //binding mode status if(lastStatus.types.binding != status->ststus.types.binding) { lastStatus.types.binding = status->ststus.types.binding; if(1 == status->ststus.types.binding) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in binding mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_BINDING; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out binding mode\n"); } } //router status if(lastStatus.types.con_route != status->ststus.types.con_route) { lastStatus.types.con_route = status->ststus.types.con_route; if(1 == status->ststus.types.con_route) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected router\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_ROUTER; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected router\n"); } } //M2M server status if(lastStatus.types.con_m2m != status->ststus.types.con_m2m) { lastStatus.types.con_m2m = status->ststus.types.con_m2m; if(1 == status->ststus.types.con_m2m) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: connected m2m\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_M2M; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: disconnected m2m\n"); } } //APP status if(lastStatus.types.app != status->ststus.types.app) { lastStatus.types.app = status->ststus.types.app; if(1 == status->ststus.types.app) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: app connect\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_DISCON_APP; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: no app connect\n"); } } //test mode status if(lastStatus.types.test != status->ststus.types.test) { lastStatus.types.test = status->ststus.types.test; if(1 == status->ststus.types.test) { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_OPEN_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: in test mode\n"); } else { gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_CLOSE_TESTMODE; gizwitsProtocol.wifiStatusEvent.num++; GIZWITS_LOG("WiFi status: out test mode\n"); } } gizwitsProtocol.wifiStatusEvent.event[gizwitsProtocol.wifiStatusEvent.num] = WIFI_RSSI; gizwitsProtocol.wifiStatusEvent.num++; gizwitsProtocol.wifiStatusData.rssi = status->ststus.types.rssi; GIZWITS_LOG("RSSI is %d \n", gizwitsProtocol.wifiStatusData.rssi); gizwitsProtocol.issuedFlag = WIFI_STATUS_TYPE; return 0; } /**@name Gizwits User API interface * @{ */ /** * @brief gizwits Protocol initialization interface * Protocol-related timer, serial port initialization * Datapoint initialization * @param none * @return none */ void gizwitsInit(void) { pRb.rbCapacity = RB_MAX_LEN; pRb.rbBuff = rbBuf; if(0 == rbCreate(&pRb)) { GIZWITS_LOG("rbCreate Success \n"); } else { GIZWITS_LOG("rbCreate Faild \n"); } memset((uint8_t *)&gizwitsProtocol, 0, sizeof(gizwitsProtocol_t)); } /** * @brief WiFi configure interface * Set the WiFi module into the corresponding configuration mode or reset the module * @param[in] mode :0x0, reset the module ;0x01, SoftAp mode ;0x02, AirLink mode ;0x03, Production test mode; 0x04:allow users to bind devices * @return Error command code */ int32_t gizwitsSetMode(uint8_t mode) { int32_t ret = 0; protocolCfgMode_t cfgMode; protocolCommon_t setDefault; switch(mode) { case WIFI_RESET_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_SET_DEFAULT; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_SOFTAP_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_AIRLINK_MODE: gizProtocolHeadInit((protocolHead_t *)&cfgMode); cfgMode.head.cmd = CMD_WIFI_CONFIG; cfgMode.head.sn = gizwitsProtocol.sn++; cfgMode.cfgMode = mode; cfgMode.head.len = exchangeBytes(sizeof(protocolCfgMode_t)-4); cfgMode.sum = gizProtocolSum((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); ret = uartWrite((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&cfgMode, sizeof(protocolCfgMode_t)); break; case WIFI_PRODUCTION_TEST: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_PRODUCTION_TEST; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_NINABLE_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_NINABLE_MODE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; case WIFI_REBOOT_MODE: gizProtocolHeadInit((protocolHead_t *)&setDefault); setDefault.head.cmd = CMD_REBOOT_MODULE; setDefault.head.sn = gizwitsProtocol.sn++; setDefault.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); setDefault.sum = gizProtocolSum((uint8_t *)&setDefault, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&setDefault, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&setDefault, sizeof(protocolCommon_t)); break; default: GIZWITS_LOG("ERR: CfgMode error!\n"); break; } return ret; } /** * @brief Get the the network time * Protocol 4.13:"Device MCU send" of "the MCU requests access to the network time" * @param[in] none * @return none */ void gizwitsGetNTP(void) { int32_t ret = 0; protocolCommon_t getNTP; gizProtocolHeadInit((protocolHead_t *)&getNTP); getNTP.head.cmd = CMD_GET_NTP; getNTP.head.sn = gizwitsProtocol.sn++; getNTP.head.len = exchangeBytes(sizeof(protocolCommon_t)-4); getNTP.sum = gizProtocolSum((uint8_t *)&getNTP, sizeof(protocolCommon_t)); ret = uartWrite((uint8_t *)&getNTP, sizeof(protocolCommon_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getNTP, sizeof(protocolCommon_t)); } /** * @brief Get Module Info * * @param[in] none * @return none */ void gizwitsGetModuleInfo(void) { int32_t ret = 0; protocolGetModuleInfo_t getModuleInfo; gizProtocolHeadInit((protocolHead_t *)&getModuleInfo); getModuleInfo.head.cmd = CMD_ASK_MODULE_INFO; getModuleInfo.head.sn = gizwitsProtocol.sn++; getModuleInfo.type = 0x0; getModuleInfo.head.len = exchangeBytes(sizeof(protocolGetModuleInfo_t)-4); getModuleInfo.sum = gizProtocolSum((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); ret = uartWrite((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); if(ret < 0) { GIZWITS_LOG("ERR[NTP]: uart write error %d \n", ret); } gizProtocolWaitAck((uint8_t *)&getModuleInfo, sizeof(protocolGetModuleInfo_t)); } /** * @brief Module Info Analyse * * @param [in] head : * * @return 0, Success, , other,Faild */ static int8_t gizProtocolModuleInfoHandle(protocolHead_t *head) { protocolModuleInfo_t *moduleInfo = (protocolModuleInfo_t *)head; if(NULL == head) { GIZWITS_LOG("NTP is empty \n"); return -1; } #if MODULE_TYPE memcpy((uint8_t *)&gizwitsProtocol.gprsInfoNews,(uint8_t *)&moduleInfo->gprsModuleInfo, sizeof(gprsInfo_t)); #else memcpy((uint8_t *)&gizwitsProtocol.wifiModuleNews,(uint8_t *)&moduleInfo->wifiModuleInfo, sizeof(moduleInfo_t)); #endif gizwitsProtocol.moduleInfoEvent.event[gizwitsProtocol.moduleInfoEvent.num] = MODULE_INFO; gizwitsProtocol.moduleInfoEvent.num++; gizwitsProtocol.issuedFlag = GET_MODULEINFO_TYPE; return 0; } /** * @brief Protocol handling function * * @param [in] currentData :The protocol data pointer * @return none */ int32_t gizwitsHandle(dataPoint_t *currentData) { int8_t ret = 0; #ifdef PROTOCOL_DEBUG uint16_t i = 0; #endif uint8_t ackData[RB_MAX_LEN]; uint16_t protocolLen = 0; uint32_t ackLen = 0; protocolHead_t *recvHead = NULL; char *didPtr = NULL; uint16_t offset = 0; if(NULL == currentData) { GIZWITS_LOG("GizwitsHandle Error , Illegal Param\n"); return -1; } /*resend strategy*/ gizProtocolAckHandle(); ret = gizProtocolGetOnePacket(&pRb, gizwitsProtocol.protocolBuf, &protocolLen); if(0 == ret) { GIZWITS_LOG("Get One Packet!\n"); #ifdef PROTOCOL_DEBUG GIZWITS_LOG("WiFi2MCU[%4d:%4d]: ", gizGetTimerCount(), protocolLen); for(i=0; i<protocolLen;i++) { GIZWITS_LOG("%02x ", gizwitsProtocol.protocolBuf[i]); } GIZWITS_LOG("\n"); #endif recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; switch (recvHead->cmd) { case CMD_GET_DEVICE_INTO: gizProtocolGetDeviceInfo(recvHead); break; case CMD_ISSUED_P0: GIZWITS_LOG("flag %x %x \n", recvHead->flags[0], recvHead->flags[1]); //offset = 1; if(0 == gizProtocolIssuedProcess(didPtr, gizwitsProtocol.protocolBuf+sizeof(protocolHead_t)+offset, protocolLen-(sizeof(protocolHead_t)+offset+1), ackData, &ackLen)) { gizProtocolIssuedDataAck(recvHead, ackData, ackLen,recvHead->flags[1]); GIZWITS_LOG("AckData : \n"); } break; case CMD_HEARTBEAT: gizProtocolCommonAck(recvHead); break; case CMD_WIFISTATUS: gizProtocolCommonAck(recvHead); gizProtocolModuleStatus((protocolWifiStatus_t *)recvHead); break; case ACK_REPORT_P0: case ACK_WIFI_CONFIG: case ACK_SET_DEFAULT: case ACK_NINABLE_MODE: case ACK_REBOOT_MODULE: gizProtocolWaitAckCheck(recvHead); break; case CMD_MCU_REBOOT: gizProtocolCommonAck(recvHead); GIZWITS_LOG("report:MCU reboot!\n"); gizProtocolReboot(); break; case CMD_ERROR_PACKAGE: break; case ACK_PRODUCTION_TEST: gizProtocolWaitAckCheck(recvHead); GIZWITS_LOG("Ack PRODUCTION_MODE success \n"); break; case ACK_GET_NTP: gizProtocolWaitAckCheck(recvHead); gizProtocolNTP(recvHead); GIZWITS_LOG("Ack GET_UTT success \n"); break; case ACK_ASK_MODULE_INFO: gizProtocolWaitAckCheck(recvHead); gizProtocolModuleInfoHandle(recvHead); GIZWITS_LOG("Ack GET_Module success \n"); break; default: gizProtocolErrorCmd(recvHead,ERROR_CMD); GIZWITS_LOG("ERR: cmd code error!\n"); break; } } else if(-2 == ret) { //Check failed, report exception recvHead = (protocolHead_t *)gizwitsProtocol.protocolBuf; gizProtocolErrorCmd(recvHead,ERROR_ACK_SUM); GIZWITS_LOG("ERR: check sum error!\n"); return -2; } switch(gizwitsProtocol.issuedFlag) { case ACTION_CONTROL_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)&gizwitsProtocol.gizCurrentDataPoint, sizeof(dataPoint_t)); memset((uint8_t *)&gizwitsProtocol.issuedProcessEvent,0x0,sizeof(gizwitsProtocol.issuedProcessEvent)); break; case WIFI_STATUS_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.wifiStatusEvent, (uint8_t *)&gizwitsProtocol.wifiStatusData, sizeof(moduleStatusInfo_t)); memset((uint8_t *)&gizwitsProtocol.wifiStatusEvent,0x0,sizeof(gizwitsProtocol.wifiStatusEvent)); break; case ACTION_W2D_TRANSPARENT_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.issuedProcessEvent, (uint8_t *)gizwitsProtocol.transparentBuff, gizwitsProtocol.transparentLen); break; case GET_NTP_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.NTPEvent, (uint8_t *)&gizwitsProtocol.TimeNTP, sizeof(protocolTime_t)); memset((uint8_t *)&gizwitsProtocol.NTPEvent,0x0,sizeof(gizwitsProtocol.NTPEvent)); break; case GET_MODULEINFO_TYPE: gizwitsProtocol.issuedFlag = STATELESS_TYPE; gizwitsEventProcess(&gizwitsProtocol.moduleInfoEvent, (uint8_t *)&gizwitsProtocol.wifiModuleNews, sizeof(moduleInfo_t)); memset((uint8_t *)&gizwitsProtocol.moduleInfoEvent,0x0,sizeof(moduleInfo_t)); break; default: break; } gizDevReportPolicy(currentData); return 0; } /** * @brief gizwits report transparent data interface * The user can call the interface to complete the reporting of private protocol data * @param [in] data :Private protocol data * @param [in] len :Private protocol data length * @return 0,success ;other,failure */ int32_t gizwitsPassthroughData(uint8_t * gizdata, uint32_t len) { int32_t ret = 0; uint8_t tx_buf[MAX_PACKAGE_LEN]; uint16_t data_len = 6 + len; // 修复作用域问题 if(NULL == gizdata || len > (MAX_PACKAGE_LEN - 10)) { GIZWITS_LOG("[ERR] Invalid params\n"); return -1; } // 协议头构建 tx_buf[0] = 0xFF; tx_buf[1] = 0xFF; tx_buf[2] = (uint8_t)(data_len >> 8); tx_buf[3] = (uint8_t)(data_len); tx_buf[4] = CMD_REPORT_P0; tx_buf[5] = gizwitsProtocol.sn++; tx_buf[6] = 0x00; // flag tx_buf[7] = 0x00; // flag tx_buf[8] = ACTION_D2W_TRANSPARENT_DATA; // 数据拷贝 memcpy(&tx_buf[9], gizdata, len); // 校验和计算 tx_buf[data_len + 4 - 1] = gizProtocolSum(tx_buf, data_len + 4 - 1); ret = uartWrite(tx_buf, data_len + 4); if(ret < 0) { GIZWITS_LOG("ERR: uart write error %d\n", ret); } gizProtocolWaitAck(tx_buf, data_len + 4); return (ret == (data_len + 4)) ? 0 : -2; } /**@} */ #include "sys.h" #include "usart.h" #include "gizwits_product.h" #if 1 #pragma import(__use_no_semihosting) //ҪࠢѨҪք֧Ԗگ˽ struct __FILE { int handle; }; FILE __stdout; //֨ӥ_sys_exit()ӔҜĢʹԃѫܺģʽ void _sys_exit(int x) { x = x; } int fputc(int ch, FILE *f) { while((USART1->SR&0X40)==0); USART1->DR = (u8) ch; return ch; } #endif #if EN_USART1_RX //ɧڻʹŜޓ˕ //Ԯࠚ1אؾϱԌѲ //עӢ,ׁȡUSARTx->SRŜҜĢĪĻǤĮքխϳ u8 USART_RX_BUF[USART_REC_LEN]; //ޓ˕ۺԥ,خճUSART_REC_LENٶؖޚ. //ޓ˕״̬ //bit15ì ޓ˕ΪԉҪ־ //bit14ì ޓ˕ս0x0d //bit13~0ì ޓ˕սքԐЧؖޚ˽Ŀ u16 USART_RX_STA=0; //ޓ˕״̬Ҫ݇ void uart1_init(u32 bound){ //GPIOࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //ʹŜUSART1ìGPIOAʱד //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART1, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א USART_Cmd(USART1, ENABLE); //ʹŜԮࠚ1 } void uart2_init(u32 bound){ //GPIOࠚʨ׃ GPIO_InitTypeDef GPIO_InitStructure; USART_InitTypeDef USART_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); //ʹŜUSART2ìGPIOAʱד RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //USART1_TX GPIOA.9 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //شԃΆάˤԶ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.9 //USART1_RX GPIOA.10Եʼۯ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//ءࠕˤɫ GPIO_Init(GPIOA, &GPIO_InitStructure);//ԵʼۯGPIOA.10 //Usart1 NVIC Ƥ׃ NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//ȀռԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2; //ؓԅЈܶ3 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨրʹŜ NVIC_Init(&NVIC_InitStructure); //ٹߝָ֨քӎ˽ԵʼۯVIC݄զǷ //USART Եʼۯʨ׃ USART_InitStructure.USART_BaudRate = bound;//ԮࠚҨ͘Ê USART_InitStructure.USART_WordLength = USART_WordLength_8b;//ؖӤΪ8λ˽ߝٱʽ USART_InitStructure.USART_StopBits = USART_StopBits_1;//һٶֹͣλ USART_InitStructure.USART_Parity = USART_Parity_No;//ϞǦżУҩλ USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//ϞӲݾ˽ߝ·࠘׆ USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //˕עģʽ USART_Init(USART2, &USART_InitStructure); //ԵʼۯԮࠚ1 USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//ߪǴԮࠚޓ˜א USART_Cmd(USART2, ENABLE); //ʹŜԮࠚ1 // 添加串口错误中断使能 USART_ITConfig(USART2, USART_IT_ORE, ENABLE); // 过载错误 USART_ITConfig(USART2, USART_IT_NE, ENABLE); // 噪声错误 USART_ITConfig(USART2, USART_IT_FE, ENABLE); // 帧错误 } void USART1_IRQHandler(void) //Ԯࠚ1אؾϱԌѲ { u8 Res; if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) //ޓ˕א(ޓ˕սք˽ߝҘѫˇ0x0d 0x0aޡβ) { USART_ClearITPendingBit(USART1,USART_IT_RXNE); Res =USART_ReceiveData(USART1); //ׁȡޓ˕սք˽ߝ } } void USART2_IRQHandler(void) { u8 Res; uint32_t status = USART_GetITStatus(USART2, USART_IT_ORE | USART_IT_NE | USART_IT_FE | USART_IT_PE); // 处理所有可能的错误标志 if(status != RESET) { if(USART_GetITStatus(USART2, USART_IT_ORE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_ORE); USART_ReceiveData(USART2); // 必须读取DR寄存器清除ORE GIZWITS_LOG("USART2 ORE error\n"); } if(USART_GetITStatus(USART2, USART_IT_NE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_NE); GIZWITS_LOG("USART2 Noise error\n"); } if(USART_GetITStatus(USART2, USART_IT_FE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_FE); GIZWITS_LOG("USART2 Framing error\n"); } if(USART_GetITStatus(USART2, USART_IT_PE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_PE); GIZWITS_LOG("USART2 Parity error\n"); } } // 正常数据接收处理 if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) { USART_ClearITPendingBit(USART2, USART_IT_RXNE); Res = USART_ReceiveData(USART2); if(gizPutData(&Res, 1) != 1) { GIZWITS_LOG("WARN: Failed to queue data: 0x%02X\n", Res); } } } #endif
<think>我们注意到日志中出现了多次"ERR: Failed to rbWrite"和"WARN: Failed to queue data: 0x00"的错误。这表示环形缓冲区写入失败,可能是缓冲区已满导致的。
同时,在串口中断处理函数中,我们尝试将接收到的数据放入环形缓冲区,但是写入失败。
为了解决这个问题,我们需要:
1. 检查环形缓冲区的实现,确保在缓冲区满时能够正确处理(例如,覆盖旧数据或者丢弃新数据,根据需求选择)。
2. 增加缓冲区大小(如果当前缓冲区太小)。
3. 优化数据处理速度,确保主循环能够及时处理缓冲区中的数据,避免堆积。
但是,从日志中我们看到,在初始化时已经打印了"rbCreate Success",说明环形缓冲区初始化成功。
另外,我们还看到"Warning:gizProtocolResendData 590 2 0"和"Resending data, attempt 1/2",这表明协议层在重发数据。
结合以上信息,我们怀疑:
- 环形缓冲区可能因为数据处理不及时而被填满。
- 或者,串口接收中断频率过高,导致写入缓冲区的速度大于处理速度。
我们需要在环形缓冲区写入函数中增加缓冲区满的处理逻辑。目前,当缓冲区满时,`rbWrite`函数会返回0(表示写入0个字节),从而导致`gizPutData`返回错误。
我们可以修改环形缓冲区,使其在满时覆盖最旧的数据(即循环覆盖),或者丢弃新数据。根据协议,我们可能需要确保数据包的完整性,所以这里选择丢弃新数据(因为覆盖可能导致数据包不完整,更难处理)。
但是,由于我们使用的是机智云协议,数据包是以0xFF 0xFF开头,如果丢弃单个字节可能导致整个数据包无效。因此,我们也可以考虑增大缓冲区。
然而,从代码中看到,环形缓冲区的大小为`RB_MAX_LEN`,我们需要确认这个值是否足够大。通常,我们可以将其设置为最大数据包长度的两倍以上。
另一种方法是:在中断服务程序中,如果缓冲区满,则丢弃整个数据包(直到下一个0xFF 0xFF头)。但这需要更复杂的逻辑。
我们先尝试增大缓冲区大小,并确保主循环处理速度足够快(减少主循环中不必要的延时)。
但是,我们已经在主循环中加入了延时`Delay_ms(200);`,这可能导致处理速度不够。我们可以减少这个延时。
具体修改如下:
1. 增大环形缓冲区大小,将`RB_MAX_LEN`从原来的值(可能是256)增大到512或者1024。
2. 减少主循环中的延时,例如从200ms减少到50ms。
此外,我们还需要检查环形缓冲区的实现,确保在缓冲区满时,`rbWrite`函数不会导致错误。
由于我们没有提供`ringBuffer.c`的代码,我假设环形缓冲区实现是标准的。我们可以修改`gizPutData`函数,使其在缓冲区满时丢弃数据,但记录警告(而不是返回错误),因为中断服务程序中无法等待缓冲区空闲。
修改`gizPutData`函数,当`rbWrite`返回0(即缓冲区满)时,我们记录警告并返回-1,但不会导致系统死锁。
但是,在中断服务程序中,我们无法处理这种情况,只能丢弃数据。因此,我们需要在环形缓冲区中实现一个安全的写入,即使缓冲区满也不至于崩溃。
由于时间关系,我们选择增大缓冲区并减少主循环延时。
另外,我们注意到在`gizwitsHandle`函数中,我们每5秒打印一次缓冲区状态(之前修改时加入的),这可以帮助我们监控。
我们进行如下修改:
步骤1:增大缓冲区大小
在`ringBuffer.h`中,将`RB_MAX_LEN`定义为1024。
步骤2:减少主循环中的延时
在`main.c`的while循环中,将`Delay_ms(200);`修改为`Delay_ms(50);`。
步骤3:在环形缓冲区满时,我们记录错误,但避免系统崩溃。
但是,我们还需要检查环形缓冲区的实现,确保在多任务环境(中断和主循环)下的数据一致性(通过关中断等方式保护)。
由于没有提供环形缓冲区的代码,我们假设它是安全的。
如果问题仍然存在,我们需要在`gizPutData`函数中加入缓冲区满时的丢弃策略,并记录丢弃的字节数。
修改`gizPutData`函数如下:
```c
int32_t gizPutData(uint8_t *buf, uint32_t len)
{
int32_t count = 0;
if(NULL == buf)
{
GIZWITS_LOG("ERR: gizPutData buf is empty \n");
return -1;
}
// 检查缓冲区剩余空间
if (rbCanWrite(&pRb) < len) {
GIZWITS_LOG("WARN: RingBuffer full, discard %d bytes\n", len);
return -2; // 返回错误,表示丢弃
}
count = rbWrite(&pRb, buf, len);
if(count != len)
{
GIZWITS_LOG("ERR: Failed to rbWrite \n");
return -1;
}
return count;
}
```
这样,当缓冲区空间不足时,我们直接丢弃整个数据(一个字节也不写入),并记录警告。这样虽然会丢失数据,但不会导致写入部分数据而破坏数据包。
但是,在中断中,我们每次只写入一个字节,所以这里丢弃一个字节。由于协议数据包以0xFF 0xFF开头,丢弃一个字节可能导致后续数据包无法识别。因此,更好的做法是增大缓冲区,并加快处理速度。
我们综合以上方法进行修改。
另外,我们注意到在USART2中断服务程序中,我们使用了`GIZWITS_LOG`打印,这本身可能会占用较长时间,并且可能引起重入问题(如果`GIZWITS_LOG`使用串口发送)。因此,在中断中应避免打印日志。
我们可以将错误日志记录改为设置标志位,在主循环中打印。
由于时间关系,我们先尝试增大缓冲区并减少主循环延时,同时修改`gizPutData`在缓冲区满时丢弃数据。
如果问题仍然存在,则需要进一步优化。
现在,我们进行如下修改:
1. 将`ringBuffer.h`中的`RB_MAX_LEN`改为1024。
2. 修改`main.c`中主循环的延时为50ms。
3. 修改`gizPutData`函数,在写入前检查剩余空间,不足则丢弃并返回错误。
修改后的`gizPutData`如上。
同时,在中断服务程序中,如果`gizPutData`返回错误,我们只记录一次(避免在中断中频繁打印),但这里我们已经在`gizPutData`中记录了日志(注意,在中断中调用`GIZWITS_LOG`可能不安全,因此我们可能需要改变方式)。
由于我们的`GIZWITS_LOG`可能是通过串口输出,而在中断中调用串口输出函数可能会导致中断嵌套或长时间占用中断,因此我们建议在中断中不要直接调用`GIZWITS_LOG`。
我们可以改为设置一个标志,然后在主循环中打印。但为了快速解决问题,我们暂时在中断中保留日志,但减少日志量(例如,只记录一次丢弃事件,而不是每个字节都记录)。
或者,我们可以将日志信息存入一个缓冲区,在主循环中打印。
这里,我们先采用简单方法:在中断中不记录每个丢弃的字节,而是记录一个计数器,然后在主循环中打印这个计数器。
具体修改:
在中断服务程序中:
```c
void USART2_IRQHandler(void)
{
static uint32_t discardCount = 0; // 丢弃字节计数器
// ... 错误处理
if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)
{
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
Res = USART_ReceiveData(USART2);
if(gizPutData(&Res, 1) != 1)
{
discardCount++; // 增加丢弃计数
}
}
// 这里我们无法打印,所以将discardCount作为全局变量,在主循环中打印并清零
}
```
然后,在主循环中定期打印这个丢弃计数。
但是,为了快速解决问题,我们选择在中断中不记录日志,而是直接丢弃。因为如果缓冲区满,说明系统已经无法及时处理,再记录日志可能加重负担。
因此,我们暂时移除中断中的日志,只保留`gizPutData`中的日志(该函数在中断中被调用,所以同样存在风险)。我们考虑将`gizPutData`中的日志改为设置标志位。
修改如下:
在`gizwits_protocol.c`中:
```c
// 定义全局变量用于记录丢弃事件
static uint32_t rbDiscardCount = 0;
int32_t gizPutData(uint8_t *buf, uint32_t len)
{
// ... 参数检查
if (rbCanWrite(&pRb) < len) {
rbDiscardCount += len; // 记录丢弃的字节数
return -2;
}
// ... 正常写入
}
```
然后在`gizwitsHandle`函数中,每次处理协议前检查并打印这个计数:
```c
int32_t gizwitsHandle(dataPoint_t *currentData)
{
// 在协议处理前添加缓冲区监控
static uint32_t lastLogTime = 0;
uint32_t now = gizGetTimerCount();
if (rbDiscardCount > 0) {
GIZWITS_LOG("WARN: %d bytes discarded due to ringbuffer full\n", rbDiscardCount);
rbDiscardCount = 0;
}
if(now - lastLogTime > 5000) // 每5秒记录一次
{
GIZWITS_LOG("Buffer Stats: Used=%d/%d, Pkts=%d\n",
rbCanRead(&pRb), pRb.rbCapacity,
gizwitsProtocol.waitAck.num);
lastLogTime = now;
}
// ... 原有处理逻辑
}
```
这样,我们将日志放在主循环中,避免在中断中打印。
总结修改点:
1. 增大环形缓冲区大小(RB_MAX_LEN=1024)。
2. 主循环延时减少到50ms。
3. 在`gizPutData`中,当缓冲区空间不足时,记录丢弃的字节数(不写入缓冲区),并在主循环中打印丢弃总数。
4. 在`gizwitsHandle`中,每5秒打印缓冲区使用情况。
请根据以上修改代码。
注意:如果问题仍然存在,可能需要进一步优化协议处理速度,或者检查是否有其他性能瓶颈。
由于我们无法看到完整的环形缓冲区实现,请确保环形缓冲区的`rbCanWrite`和`rbWrite`函数是线程安全的(在中断和主循环中调用时,不会出现竞争条件)。通常,这需要关中断或者使用原子操作。
例如,在`rbWrite`和`rbRead`中,操作头尾指针时应暂时关闭中断,以避免指针被破坏。
如果环形缓冲区实现没有保护,则需要添加保护。例如:
```c
// 在ringBuffer.c中
// 假设我们使用关中断来保护
#define RB_ENTER_CRITICAL() __disable_irq()
#define RB_EXIT_CRITICAL() __enable_irq()
int32_t rbWrite(rb_t* rb, uint8_t* data, int32_t len)
{
int32_t i;
RB_ENTER_CRITICAL();
// 写入操作
RB_EXIT_CRITICAL();
return len;
}
```
同样,在`rbRead`中也要加入关中断保护。
由于我们不知道具体实现,这里只是提醒。
请根据上述建议修改代码,然后重新测试。
如果问题解决,则最好;如果还有问题,请提供更多日志。
注意:在中断服务程序中,我们调用`gizPutData`,而`gizPutData`又调用了`rbWrite`和`rbCanWrite`,这些函数必须保证是中断安全的。
最后,如果可能,尝试提高串口波特率,确保能够及时传输数据。
由于修改点较多,请逐步测试。
我们首先修改环形缓冲区大小和主循环延时,然后加入丢弃计数,最后考虑环形缓冲区的线程安全。
如果问题仍然存在,请提供修改后的日志。</think>### 问题分析与解决方案
从日志中可以看出,核心问题在于环形缓冲区写入失败:"ERR: Failed to rbWrite" 和 "WARN: Failed to queue data: 0x00"。这表明缓冲区已满或写入操作失败。以下是完整的解决方案:
### 1. 环形缓冲区优化
#### 修改 `gizPutData()` 函数:
```c
int32_t gizPutData(uint8_t *buf, uint32_t len)
{
if (NULL == buf) {
GIZWITS_LOG("ERR: gizPutData buf is empty\n");
return -1;
}
// 检查缓冲区空间
int32_t freeSpace = rbCanWrite(&pRb);
if (freeSpace < len) {
GIZWITS_LOG("WARN: Buffer full! Free: %d, Need: %d\n", freeSpace, len);
return -2; // 返回特定错误码
}
int32_t count = rbWrite(&pRb, buf, len);
if (count != len) {
GIZWITS_LOG("ERR: Partial write: %d/%d bytes\n", count, len);
return -1;
}
return count;
}
```
#### 在中断服务程序中处理缓冲区满的情况:
```c
void USART2_IRQHandler(void)
{
static uint32_t discardCount = 0; // 丢弃数据计数器
static uint32_t lastLogTime = 0; // 最后记录时间
// ... [错误处理代码保持不变] ...
if (USART_GetITStatus(USART2, USART_IT_RXNE) != RESET) {
USART_ClearITPendingBit(USART2, USART_IT_RXNE);
uint8_t Res = USART_ReceiveData(USART2);
// 尝试写入缓冲区
if (gizPutData(&Res, 1) != 1) {
discardCount++;
// 每100个丢弃字节记录一次
uint32_t now = gizGetTimerCount();
if (discardCount % 100 == 0 && now - lastLogTime > 1000) {
GIZWITS_LOG("WARN: %d bytes discarded\n", discardCount);
lastLogTime = now;
}
}
}
}
```
### 2. 协议重发机制优化
#### 添加重发控制参数:
```c
// 在文件头部添加
#define SEND_MAX_RETRY 3 // 最大重试次数
#define SEND_RETRY_INTERVAL 100 // 重试间隔(ms)
```
#### 修改 `gizProtocolResendData()`:
```c
static void gizProtocolResendData(void)
{
if (0 == gizwitsProtocol.waitAck.flag ||
gizwitsProtocol.waitAck.num >= SEND_MAX_RETRY) {
return;
}
uint32_t now = gizGetTimerCount();
if (now - gizwitsProtocol.waitAck.lastTry < SEND_RETRY_INTERVAL) {
return;
}
GIZWITS_LOG("Resending data, attempt %d/%d\n",
gizwitsProtocol.waitAck.num + 1, SEND_MAX_RETRY);
int ret = uartWrite(gizwitsProtocol.waitAck.buf,
gizwitsProtocol.waitAck.dataLen);
if (ret == gizwitsProtocol.waitAck.dataLen) {
gizwitsProtocol.waitAck.lastTry = now;
gizwitsProtocol.waitAck.num++;
} else {
GIZWITS_LOG("ERR: Resend failed, code: %d\n", ret);
}
}
```
### 3. 缓冲区监控与诊断
#### 在 `gizwitsHandle()` 中添加:
```c
int32_t gizwitsHandle(dataPoint_t *currentData)
{
static uint32_t lastStatTime = 0;
uint32_t now = gizGetTimerCount();
// 每5秒记录一次缓冲区状态
if (now - lastStatTime > 5000) {
int32_t used = rbCanRead(&pRb);
int32_t free = rbCanWrite(&pRb);
int32_t capacity = pRb.rbCapacity;
GIZWITS_LOG("Buffer Stats: Used=%d, Free=%d/%d, PendingAck=%d\n",
used, free, capacity, gizwitsProtocol.waitAck.num);
lastStatTime = now;
}
// ... [原有处理逻辑] ...
}
```
### 4. 主循环优化
#### 减少延时,增加数据处理频率:
```c
while (1) {
// ... [数据采集和控制逻辑] ...
// 减少延时,增加处理频率
Delay_ms(20); // 从200ms减少到20ms
// 特殊处理:当缓冲区快满时加速处理
if (rbCanWrite(&pRb) < 50) {
for (int i = 0; i < 5; i++) {
gizwitsHandle(¤tDataPoint);
Delay_ms(5);
}
}
}
```
### 关键问题分析
1. **缓冲区溢出**:
- 数据接收速度 > 数据处理速度
- 解决方案:增加缓冲区监控和加速处理机制
2. **协议重发风暴**:
- 重发机制过于激进导致网络拥塞
- 解决方案:添加重发间隔控制和最大重试限制
3. **中断处理瓶颈**:
- 中断中执行日志记录导致性能下降
- 解决方案:将日志移至主循环,中断中只记录计数
### 调试建议
1. **优先级调整**:
```c
// 提高串口中断优先级
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
```
2. **流量控制**:
```c
// 在协议处理函数中添加
if (rbCanRead(&pRb) > 300) {
GIZWITS_LOG("CRITICAL: Buffer overload! Flushing...\n");
rbFlush(&pRb); // 需要实现此函数
}
```
3. **协议分析**:
- 使用逻辑分析仪捕获USART2数据
- 分析机智云协议交互模式
- 检查波特率是否匹配(115200)
### 最终优化策略
1. **增加缓冲区大小**:
```c
// 在 ringBuffer.h 中修改
#define RB_MAX_LEN 2048 // 从1024增加到2048
```
2. **实现紧急处理模式**:
```c
void handleBufferEmergency(void)
{
if (rbCanWrite(&pRb) < 100) {
// 临时提高处理频率
for (int i = 0; i < 10; i++) {
gizwitsHandle(¤tDataPoint);
Delay_ms(1);
}
// 如果仍然不足,丢弃旧数据
if (rbCanWrite(&pRb) < 50) {
uint8_t dummy;
while (rbCanRead(&pRb) > 100) {
rbRead(&pRb, &dummy, 1);
}
GIZWITS_LOG("EMERGENCY: Dumped %d bytes\n", rbCanRead(&pRb));
}
}
}
```
### 相关问题
阅读全文
相关推荐

















