#include <stdint.h>
#include <stdio.h>
#include <string.h>
#define SBL_DEFAULT_RETRY_COUNT 3
#define SBL_PORT_ERROR 1
#define SBL_TIMEOUT_ERROR 2
#define SBL_SUCCESS 0
#define SBL_ERROR 3
typedef struct {
// … 用于表示COM类型的其他成员变量
int (*isInitiated)();
uint32_t (readBytes)(unsigned char, uint32_t);
void (*flushBuffers)();
} ComType;
typedef struct {
ComType* m_pCom;
// … 用于表示SblDevice的其他成员变量
void (setState)(uint32_t, const char, …);
} SblDevice;
uint8_t generateCheckSum(uint32_t, char*, uint32_t);
uint32_t getResponseData(SblDevice* device, char* pcData, uint32_t* ui32MaxLen, uint32_t ui32MaxRetries)
{
uint32_t numBytes = 0;
uint32_t retry = 0;
unsigned char pcHdr[2];
uint32_t numPayloadBytes;
uint8_t hdrChecksum, dataChecksum;
uint32_t bytesRecv = 0;
device->setState(SBL_SUCCESS, "");
if (!device->m_pCom->isInitiated())
{
device->setState(SBL_PORT_ERROR, "COM port not initiated.\n");
return SBL_PORT_ERROR;
}
memset(pcHdr, 0, 2);
do
{
bytesRecv += device->m_pCom->readBytes(&pcHdr[bytesRecv], (2 - bytesRecv));
retry++;
} while ((bytesRecv < 2) && retry < ui32MaxRetries);
if (bytesRecv < 2)
{
device->setState(SBL_TIMEOUT_ERROR, "Timed out waiting for data header from device.\n");
return SBL_TIMEOUT_ERROR;
}
numPayloadBytes = pcHdr[0] - 2;
hdrChecksum = pcHdr[1];
if (numPayloadBytes > *ui32MaxLen)
{
device->setState(SBL_ERROR, "Error: Device sending more data than expected. \nMax expected was %d, sent was %d.\n", *ui32MaxLen, (numPayloadBytes + 2));
device->m_pCom->flushBuffers();
return SBL_ERROR;
}
bytesRecv = 0;
do
{
bytesRecv += device->m_pCom->readBytes((unsigned char*)&pcData[bytesRecv], (numPayloadBytes - bytesRecv));
retry++;
} while (bytesRecv < numPayloadBytes && retry < ui32MaxRetries);
if (bytesRecv < numPayloadBytes)
{
*ui32MaxLen = bytesRecv;
device->setState(SBL_TIMEOUT_ERROR, "Timed out waiting for data from device.\n");
return SBL_TIMEOUT_ERROR;
}
dataChecksum = generateCheckSum(0, pcData, numPayloadBytes);
if (dataChecksum != hdrChecksum)
{
device->setState(SBL_ERROR, "Checksum verification error. Expected 0x%02X, got 0x%02X.\n", hdrChecksum, dataChecksum);
return SBL_ERROR;
}
*ui32MaxLen = bytesRecv;
return SBL_SUCCESS;
}
代码功能解释
这段代码是一个C语言版本的getResponseData函数,它尝试从一个设备读取响应数据。下面是各部分的功能详解:
函数签名和结构体定义:定义了与原C++代码中的类等效的结构体和函数。
变量初始化:初始化了几个局部变量用于后续的数据处理和计数。
状态设置和端口检查:首先设置状态为SBL_SUCCESS,然后检查COM端口是否已初始化。如果没有初始化,它将设置一个错误状态并返回错误代码。
数据头读取:尝试读取2字节的数据头,包含负载长度和校验和,使用循环直到满足条件或达到最大重试次数。
负载长度和校验和验证:验证从数据头读取的负载长度和校验和是否在允许的范围内。
负载数据读取:尝试读取负载数据,再次使用循环直到满足条件或达到最大重试次数。
校验和验证:验证接收到的数据的校验和是否与数据头中的校验和匹配。
返回和更新:最后,如果一切顺利,它将更新ui32MaxLen的值并返回SBL_SUCCESS。
这段代码的功能是保持和原始的C++代码相同的功能,但使用C语言的语法和结构。注意,这里的generateCheckSum和其他几个函数需要根据您的实际代码和需求来实现和调整。