#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#define SBL_SUCCESS 0
#define SBL_ARGUMENT_ERROR 1
#define SBL_PORT_ERROR 2
#define SBL_ERROR 3
#define SBL_CC2650_MAX_MEMREAD_WORDS 128 // 请替换为实际值
#define SBL_CC2650_ACCESS_WIDTH_32B 4 // 请替换为实际值
uint32_t readMemory32(uint32_t ui32StartAddress, uint32_t ui32UnitCount, uint32_t *pui32Data) {
uint32_t retCode = SBL_SUCCESS;
bool bSuccess = false;
// 检查输入参数
if((ui32StartAddress & 0x03)) {
setState(SBL_ARGUMENT_ERROR, "readMemory32(): Start address (0x%08X) must be a multiple of 4.\n", ui32StartAddress);
return SBL_ARGUMENT_ERROR;
}
// 设置进度
setProgress(0);
if(!isConnected()) {
return SBL_PORT_ERROR;
}
unsigned char pcPayload[6];
uint32_t responseData[SBL_CC2650_MAX_MEMREAD_WORDS];
uint32_t chunkCount = ui32UnitCount / SBL_CC2650_MAX_MEMREAD_WORDS;
if(ui32UnitCount % SBL_CC2650_MAX_MEMREAD_WORDS) chunkCount++;
uint32_t remainingCount = ui32UnitCount;
for(uint32_t i = 0; i < chunkCount; i++) {
uint32_t dataOffset = (i * SBL_CC2650_MAX_MEMREAD_WORDS);
uint32_t chunkStart = ui32StartAddress + dataOffset;
uint32_t chunkSize = min(remainingCount, SBL_CC2650_MAX_MEMREAD_WORDS);
remainingCount -= chunkSize;
// 构建有效载荷
ulToCharArray(chunkStart, (char *)&pcPayload[0]);
pcPayload[4] = SBL_CC2650_ACCESS_WIDTH_32B;
pcPayload[5] = chunkSize;
// 设置进度
setProgress(((i * 100) / chunkCount));
// 发送命令
if((retCode = sendCmd(SblDeviceCC2650_CMD_MEMORY_READ, (char *)pcPayload, 6)) != SBL_SUCCESS) {
return retCode;
}
// 接收命令响应(ACK/NAK)
if((retCode = getCmdResponse(&bSuccess)) != SBL_SUCCESS) {
return retCode;
}
if(!bSuccess) {
return SBL_ERROR;
}
// 接收4B响应
uint32_t expectedBytes = chunkSize * 4;
uint32_t recvBytes = expectedBytes;
if((retCode = getResponseData((char*)responseData, &recvBytes)) != SBL_SUCCESS) {
// 以NAK响应
sendCmdResponse(false);
return retCode;
}
if(recvBytes != expectedBytes) {
// 以NAK响应
sendCmdResponse(false);
setState(SBL_ERROR, "Didn't receive 4 B.\n");
return SBL_ERROR;
}
memcpy(&pui32Data[dataOffset], responseData, expectedBytes);
// 以ACK响应
sendCmdResponse(true);
}
// 设置进度
setProgress(100);
return SBL_SUCCESS;
}
// 其他相关函数的原型和定义(ulToCharArray, min, setProgress, isConnected, sendCmd, getCmdResponse, getResponseData, sendCmdResponse, setState)应根据您的代码库相应添加
代码行解释:
1-6: 导入必要的头文件并定义宏。
7-10: 定义readMemory32函数,其接受三个参数:开始地址,单位数量和数据指针。
12: 定义retCode变量并初始化为SBL_SUCCESS,该变量用于存储函数的返回代码。
13: 定义bSuccess变量并初始化为false,该变量用于存储命令响应的成功或失败状态。
15-20: 检查输入的开始地址是否为4的倍数。如果不是,则设置状态并返回错误代码。
22-25: 设置进度为0,并检查设备是否已连接。如果未连接,则返回端口错误代码。
27-32: 定义必要的变量,并计算读取操作将被分割成多少块。
34-63: 使用循环来读取内存块。在每次迭代中,计算当前块的大小和起始地址,并构建发送命令的有效载荷。
65-71: 发送读取命令,并检查是否收到了成功的响应(ACK)。如果收到的是失败响应(NAK),则返回错误代码。
73-86: 接收数据响应,并检查是否收到了预期的字节数。如果收到的字节数不匹配,则返回错误代码。
88: 使用memcpy函数将接收到的数据复制到输出缓冲区。memcpy(&pui32Data[dataOffset], responseData, expectedBytes);这个啥意思
ChatGPT
这行代码使用memcpy函数来将从设备读取到的数据复制到输出数组中的适当位置。
解析每个部分:
memcpy: 这是一个标准C库函数,用于从源地址复制n个字节到目标地址。
&pui32Data[dataOffset]: 这是目标地址的计算方法。pui32Data是一个指向uint32_t数组的指针,dataOffset是我们要开始复制的目标数组的偏移量(以32位字为单位)。&pui32Data[dataOffset]计算得到了指向目标数组中适当位置的指针。
responseData: 这是源地址,它是一个包含我们刚刚从设备读取到的数据的数组。
expectedBytes: 这是我们想要复制的字节数量。它是由chunkSize * 4计算得出的,表示我们想要复制的字节数(注意我们在这里是按字节而不是按32位字来计算的)。
综合起来,这行代码的意义是:“将responseData数组中的expectedBytes字节数的数据复制到pui32Data数组中,开始于dataOffset位置”。它是在把分块读取的数据汇总到一个大数组中的步骤。
90-93: 发送成功响应(ACK)并更新进度。
95-98: 更新进度为100%并返回成功代码。
注意:此代码需要与其他相关函数(如ulToCharArray, min, setProgress, isConnected, sendCmd, getCmdResponse, getResponseData, sendCmdResponse, setState等)一起使用,这些函数应根据您的代码库适当定义。