梦回青春 发表于 2025-11-15 01:03:13

关于STC-ISP串口发送文件的问题 | 已清楚





发送文件比较大,为了正确传输。需要分包发送 + 应答式发送
测试发现文件大小必须是数据包的整数倍,如果有余数则不发送。
请问下这个问题怎么解决?还是我哪里设置错了。

神农鼎 发表于 2025-11-15 08:35:20

用最新软件测试下

深圳国芯人工智能有限公司-工具软件

梦回青春 发表于 2025-11-15 22:12:16

神农鼎 发表于 2025-11-15 08:35
用最新软件测试下

深圳国芯人工智能有限公司-工具软件



试过了,还是不行。
有的文件数据大小不好分完整的包。或者单包的数量很小,包的总数很多,传输效率太低。
要是能发送剩余的字节数,或者自动补全也行。大不了过滤无效字节。

zhp 发表于 2025-11-17 12:15:59

梦回青春 发表于 2025-11-15 22:12
试过了,还是不行。
有的文件数据大小不好分完整的包。或者单包的数量很小,包的总数很多,传输效率太 ...
串口助手发送文件,目前的设计就是数据不足,自动填0补全
我测试的数据如下:


我看你发送的最后一包数据也有自动填0补全


可能是你的计数器少计了一包

附件是我的测试代码,你可以测试看看

梦回青春 发表于 2025-11-17 13:06:04

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;
        }
}


梦回青春 发表于 2025-11-17 13:14:02

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]
查看完整版本: 关于STC-ISP串口发送文件的问题 | 已清楚