关于STC-ISP串口发送文件的问题 | 已清楚
发送文件比较大,为了正确传输。需要分包发送 + 应答式发送
测试发现文件大小必须是数据包的整数倍,如果有余数则不发送。
请问下这个问题怎么解决?还是我哪里设置错了。
用最新软件测试下
深圳国芯人工智能有限公司-工具软件
神农鼎 发表于 2025-11-15 08:35
用最新软件测试下
深圳国芯人工智能有限公司-工具软件
试过了,还是不行。
有的文件数据大小不好分完整的包。或者单包的数量很小,包的总数很多,传输效率太低。
要是能发送剩余的字节数,或者自动补全也行。大不了过滤无效字节。
梦回青春 发表于 2025-11-15 22:12
试过了,还是不行。
有的文件数据大小不好分完整的包。或者单包的数量很小,包的总数很多,传输效率太 ...
串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:
我看你发送的最后一包数据也有自动填0补全
可能是你的计数器少计了一包
附件是我的测试代码,你可以测试看看
zhp 发表于 2025-11-17 12:15
串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:
麻烦帮我看下代码
/**
***********************************************************
* @brief 文件烧录
* @param
* @return
* @note 命令格式:FT+WR+FILE=<"文件名称">,<文件大小>,<数据包大小>,<"数据请求命令">,<\r\n><crc>
* 示例: FT+WR+FILE="0:pictrue.bmp",5054,133,"FT_REQ",\r\ncrc
***********************************************************
*/
void Fatfs_FileBurnTask(void)
{
static UartWriteFatfsState state = FAT_WAIT_CMD;
static uint8_t reqCnt = 0;// 数据请求次数
static bool reqFlag = true; // true-立即请求,false-每隔N秒请求
uint16_t crc_code = 0;
switch(state)
{
case FAT_WAIT_CMD:
g_pktRcvdLen = UartRecvData_Get(g_recvBuf);
if(g_pktRcvdLen == 0)
{
return; // 未接收到命令
}
if(g_pktRcvdLen < DATA_PACK_LEN_MIN)
{
ClearRecvBuf();
return;// 数据包长度不足
}
if(strstr((const char*)g_recvBuf,"FT+WR+FILE") != NULL)
{
fileInfo.crc = g_recvBuf << 8 | g_recvBuf;
crc_code = usMBCRC16(g_recvBuf, g_pktRcvdLen - 2);
if(crc_code != fileInfo.crc)
{
ClearRecvBuf();
printf("FT_CRC_ERROR\r\n");
return;// crc校验错误
}
// 获取文件信息
memset(fileInfo.fileName, 0, FILE_NAME_MAX);
memset(fileInfo.dataReqCmd, 0, DATA_REQ_MAX);
int ret = sscanf((char*)g_recvBuf, "FT+WR+FILE=\"%[^\"]\",%u,%u,\"%[^\"]\"",
fileInfo.fileName, &fileInfo.fileSize, &fileInfo.packLen, fileInfo.dataReqCmd);
if(ret != 4)
{
ClearRecvBuf();
printf("FT_CMD_ERROR\r\n");
return;// 指令错误
}
ClearRecvBuf();
// 打印参数信息
printf("fileName : %s\r\n",fileInfo.fileName);
printf("fileSize : %u\r\n", fileInfo.fileSize);
printf("packLen : %u\r\n", fileInfo.packLen);
printf("dataReqCmd : %s\r\n", fileInfo.dataReqCmd);
printf("crc : 0x%X\r\n", fileInfo.crc);
if(Fatfs_InitState_Get() == false)
{
state = FAT_WAIT_CMD;
printf("fatfs init fail\r\n");
return; // 文件系统参数失败
}
if(f_open(&file, (const char*)fileInfo.fileName, FA_CREATE_ALWAYS | FA_WRITE) != FR_OK) // 创建一个文件,如果文件存在就覆盖掉,允许写操作
{
printf("file open fail\r\n");
return;// 打开文件失败
}
fileInfo.writeLen = 0; // 计数清零
sysTime = GetSysRunTime(); // 保存系统运行时间
state = FAT_RECV_DATA;
}
break;
case FAT_RECV_DATA:
g_pktRcvdLen = UartRecvData_Get(g_recvBuf);
if(g_pktRcvdLen == 0)
{
//没有接收到数据,每隔5秒发送一次输请求指令
if((GetSysRunTime() - sysTime > 5000U) || (reqFlag == true))
{
reqFlag = false;
UartSendData(fileInfo.dataReqCmd); // 发送数据请求
sysTime = GetSysRunTime(); // 保存系统运行时间
reqCnt++;
if(reqCnt == 12)
{
reqCnt = 0;
f_close(&file);// 关闭文件
f_unlink((const char*)fileInfo.fileName); // 删除文件
state = FAT_WAIT_CMD;
printf("recv timeout\r\n");// 接收超时
}
}
}
else
{
reqCnt = 0;// 请求计数清零
if(g_pktRcvdLen < DATA_PACK_LEN_MIN)
{
return; // 数据包长度不符,继续等待。
}
fileInfo.crc = g_recvBuf << 8 | g_recvBuf;
crc_code = usMBCRC16(g_recvBuf, g_pktRcvdLen - 2);
if(crc_code != fileInfo.crc)
{
ClearRecvBuf();
f_close(&file);// 关闭文件
f_unlink((const char*)fileInfo.fileName); // 删除文件
state = FAT_WAIT_CMD;
printf("FT_DATA_CRC_ERROR\r\n");
return;// 数据crc校验错误
}
// 到这里已经接到到一帧正确的数据
uint32_t writeNum = 0;
if (f_write(&file, g_recvBuf, g_pktRcvdLen - 2, &writeNum) != FR_OK)
{
ClearRecvBuf();
f_close(&file);// 关闭文件
f_unlink((const char*)fileInfo.fileName); // 删除文件
state = FAT_WAIT_CMD;
printf("FT_DATA_WRITE_FAIL\r\n");
return;// 数据写入失败
}
if(writeNum != g_pktRcvdLen - 2)
{
printf("write error\r\n");
}
reqFlag = true;
printf("writeLen = %u\r\n", fileInfo.writeLen);
ClearRecvBuf();// 数据存储区清零
fileInfo.writeLen += writeNum;// 成功写入的数据计数
if(fileInfo.writeLen == fileInfo.fileSize)
{
uint32_t fileSize = f_size(&file);
printf("fileSize = %u\r\n", fileSize);
f_close(&file);// 关闭文件
state = FAT_WRITE_END;
}
}
break;
case FAT_WRITE_END:
printf("file write end\r\n");
printf("data = %u\r\n", fileInfo.writeLen);
state = FAT_WAIT_CMD;
break;
default:
state = FAT_WAIT_CMD;
break;
}
}
zhp 发表于 2025-11-17 12:15
串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:
谢谢您的提醒,我找到问题了。下面代码出现问题了,
printf提前打印信息了。而且还需要减去无效数据。
printf("writeLen = %u\r\n", fileInfo.writeLen);
ClearRecvBuf();// 数据存储区清零
fileInfo.writeLen += writeNum;// 成功写入的数据计数
if(fileInfo.writeLen == fileInfo.fileSize)
{
uint32_t fileSize = f_size(&file);
printf("fileSize = %u\r\n", fileSize);
f_close(&file);// 关闭文件
state = FAT_WRITE_END;
}
页:
[1]