#include <stdint.h>
#include <stdbool.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 {
// … 假设这里有一些成员
} SblDevice;
typedef struct {
// … 假设这里有一些成员
} ComType;
bool isInitiated(ComType* com);
void setState(uint32_t state, const char* message, …);
uint32_t readBytes(ComType* com, unsigned char* buffer, uint32_t length);
uint32_t getCmdResponse(SblDevice* device, bool* bAck, uint32_t ui32MaxRetries, bool bQuietTimeout)
{
unsigned char pIn[2];
memset(pIn, 0, 2);
uint32_t numBytes = 0;
uint32_t retry = 0;
*bAck = false;
uint32_t bytesRecv = 0;
if (!isInitiated(device->m_pCom))
{
setState(SBL_PORT_ERROR, "COM port not initiated.\n");
return SBL_PORT_ERROR;
}
do
{
numBytes = readBytes(device->m_pCom, pIn, 2);
bytesRecv += numBytes;
retry++;
} while ((bytesRecv < 2) && (retry < ui32MaxRetries));
if (bytesRecv < 2)
{
if (!bQuietTimeout)
{
setState(SBL_TIMEOUT_ERROR, "Timed out waiting for ACK/NAK. No response from device.\n");
}
return SBL_TIMEOUT_ERROR;
}
else
{
if (pIn[0] == 0x00 && pIn[1] == 0xCC)
{
*bAck = true;
return setState(SBL_SUCCESS);
}
else if (pIn[0] == 0x00 && pIn[1] == 0x33)
{
return setState(SBL_SUCCESS);
}
else
{
setState(SBL_ERROR, "ACK/NAK not received. Expected 0x00 0xCC or 0x00 0x33, received 0x%02X 0x%02X.\n", pIn[0], pIn[1]);
return SBL_ERROR;
}
}
return SBL_ERROR;
}
代码解释
这个getCmdResponse函数是一个状态机,用于处理与设备的通信协议。它尝试读取来自设备的ACK(Acknowledgement)或NAK(Negative Acknowledgement)响应,并根据收到的响应返回相应的状态代码。
预处理指令和包含: 先定义必要的头文件和宏。宏定义了一些状态代码,用于表示函数的返回状态。
结构体定义: 定义了两个结构体SblDevice和ComType,它们在这里主要作为占位符,表示你的代码库中的实际结构体。
辅助函数: 定义了几个辅助函数的原型,这些函数似乎是从您的SblDevice和m_pCom对象中调用的。这些函数的实际实现应该在其他地方在您的代码库中定义。
函数参数: 将bool &bAck更改为bool* bAck,因为C语言不支持引用作为函数参数。更改后,我们通过指针来修改bAck的值。
内存清零和初始化变量: 通过memset初始化pIn数组为0,初始化其他必要的局部变量。
检查初始化: 检查COM端口是否已经初始化。如果没有,则设置错误状态并返回错误代码。
读取响应: 进入do-while循环,尝试读取来自设备的2个字节。它将继续尝试,直到读取到足够的字节或达到最大重试次数。
处理响应: 根据收到的字节来处理响应。如果没有收到足够的字节,它将设置超时错误。如果它接收到了有效的ACK或NAK响应,它将设置相应的状态。
错误处理: 如果收到的响应不是有效的ACK或NAK,它将设置一个错误状态,并返回错误代码。
这个C版本的代码应该具有与给定的C++代码相同的功能,但你需要确保isInitiated, setState和readBytes这些函数在你的代码库中有适当的C语言实现。