完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
我正在使用 nucleo-f7 开发板作为数据记录器的基础。记录器使用三个带 DMA 的 spi 从设备从传感器套件中获取数据流,并将其写入带有偶尔数据头的 USB 闪存驱动器。我遇到的问题是我偶尔会有很长的写入时间。
我正在将数据从三个单独的 A2D 写入三个单独的文件。通常f_write数据到U盘的时间在600ms左右,但偶尔会跳到1800ms。目前,系统使用 DMA TC 中断将数据从较小的 4096 字节 DMA 缓冲区写入一个大得多的 90 KB 循环“数据缓冲区”。我已将这些数据缓冲区设置得尽可能大,以帮助解决随机写入延迟问题,但对于单一模式,这种偶尔的 1200 毫秒延迟太多了,会导致系统溢出每个数据缓冲区。 以下是控制文件系统和控制 DMA 缓冲区传输的主要函数。我希望得到一些建议,以限制这种随机的额外时间延迟,或者其他与我处理数据写入的方式有关的问题。 //将数据从 DMA 缓冲区写入大模态数据缓冲区 //仅在 DMA ISR 期间发生 void dma2Buffer(数据*模态) { uint8_t *dataBuffer = modality->dataBuffer; uint8_t *dmaBuffer = &modality->dmaBuffer[ (modality->dmaFlag * DMA_WRITE_SIZE) ]; //它是 0 或 4096,因为缓冲区是 8192 字节,这意味着前半部分或后半部分 uint32_t dmaPtr = 模态->dmaPtr; //将数据从DMA缓冲区复制到大数据缓冲区 memcpy(&dataBuffer[dmaPtr], dmaBuffer, DMA_WRITE_SIZE); //交换 DMA 缓冲区标志 modality->dmaPtr = (modality->dmaPtr + DMA_WRITE_SIZE) % modality->maxBufferSize; 模态->bufferSize += DMA_WRITE_SIZE; 模态->dmaFlag = !模态->dmaFlag; 如果(模态->缓冲区大小>模态->最大缓冲区大小) 模态->overrunFlag = TRUE; } //将大模态数据缓冲区中的数据写入U盘文件 //发生在dmaStateMachine void buffer2Usb(data* modality, _Bool istimeBlock) { //纠正溢出条件 如果(模态->overrunFlag) { correctOverrun(模态); } //标记检查是否到了写入数据头的时间 如果(模态-> hdrFlag) { usbWriteHdr(模态,isTimeBlock); } //将数据从数据缓冲区写入USB文件 如果(是时间块) { writeData(模态,TIME_MSG_SIZE,isTimeBlock); } else if( modality->bufferSize < (modality->dataBlockSize - modality->dataTilNextBlock) ) //将dataBuffer的内容写入闪存驱动器,直到下一个数据块开始 { writeData(模态, 模态->bufferSize, isTimeBlock); } else //将整个dataBuffer写入U盘 { writeData(模态, (模态->dataBlockSize - 模态->dataTilNextBlock), isTimeBlock ); 模态->hdrFlag = TRUE; } //如果缓冲区中没有数据,则将 dataRdy Flag 设置为 False 如果(模态->bufferSize == 0) { 模态->dataRdyFlag = FALSE; } } //将writeSize中指定的字节数写入模态文件 static void writeData(data* modality, int writeSize, _Bool isTimeMsg) { int bytesWritten = 0; //检查缓冲区中是否没有数据,如果是则返回 如果(模态->bufferSize <= 0) 返回; if( modality->usbPtr + writeSize >= modality->maxBufferSize) //如果缓冲区循环。 { bytesWritten = usbWrite(modality, (modality->maxBufferSize - modality->usbPtr), isTimeMsg ); 模态->缓冲区大小-= bytesWritten; 模态->dataTilNextBlock += bytesWritten; writeSize -= bytesWritten; 模态->usbPtr = 0;//设置回缓冲区的开头 bytesWritten = usbWrite(模态, writeSize, isTimeMsg); 模态->缓冲区大小-= bytesWritten; 模态->dataTilNextBlock += bytesWritten; modality->usbPtr = (modality->usbPtr + bytesWritten) % modality->maxBufferSize; } 别的 { bytesWritten = usbWrite(模态, writeSize, isTimeMsg); 模态->缓冲区大小-= bytesWritten; 模态->dataTilNextBlock += bytesWritten; modality->usbPtr = (modality->usbPtr + bytesWritten) % modality->maxBufferSize; } } //文件系统函数 //打开模态的单个文件 void newFile(int id) { //打开单独的模态文件 文件名生成(id); checkForErrors(id, f_open( &usbFiles[id], FileName, FILEMODE), 3); //扩展文件以在闪存驱动器上预分配空间 f_expand(&usbFiles[id], (FSIZE_t)(dataBlockSize[id] * 3600), 1); //重置文件字节写入计数器 当前文件大小[id] = 0; //最大支持的文件数为24个,即8 * 3个文件。这会在达到每个目录支持的最大数量后创建一个新目录 如果((文件数%24)==0) 根目录(); } //将数据写入正确模态文件的文件系统接口 int usbWrite(数据*模态,int writeSize,_Bool isTimeBlock) { int bytesWritten = 0; int id = modality->id; uint8_t *buffer = &(modality->dataBuffer[modality->usbPtr]); 如果(是时间块) { int offset = findTimeMsg(buffer, modality->id); 如果(偏移量!= 0) { buffer = &(modality->dataBuffer[modality->usbPtr + offset]); //如有必要,调整时间块相对于其余数据的位置 } } checkForErrors(id, f_write(&usbFiles[id], buffer, writeSize, (void *)&bytesWritten), 1); curFileSize[模态->id] += bytesWritten; 返回 bytesWritten; } //每 60 秒同步一次文件 无效同步文件(无效) { checkForErrors(MAG, f_sync(&usbFiles[MAG]), 0); checkForErrors(ACS, f_sync(&usbFiles[ACS]), 0); checkForErrors(SES, f_sync(&usbFiles[SES]), 0); } |
|
相关推荐
1个回答
|
|
USB 闪存——类似于 SD、eMMC、CF 或任何其他托管闪存——有自己的控制器,它处理闪存本身所需的一切,包括 ECC 管理、擦除和移动块,因为磨损均衡。换句话说,您无法影响这些操作需要多长时间,并且无法保证这些操作的时间(有*一些*保证的相对罕见的设备,主要是针对高端专业摄影的 Compact Flash) /视听市场;CF/USB 中可能有一些,我不关注这个细分市场)。
如果您想要保证延迟,请使用 NOR FLASH。是的,对于兆比特来说它是昂贵的,这是保证访问时间的价格(以及耐久性和保留,这在托管 FLASH 中也往往被忽略)。 |
|
|
|
只有小组成员才能发言,加入小组>>
请教:在使用UDE STK时,单片机使用SPC560D30L1,在配置文件怎么设置或选择?里面只有SPC560D40的选项
2742 浏览 1 评论
3244 浏览 1 评论
请问是否有通过UART连接的两个微处理器之间实现双向值交换的方法?
1813 浏览 1 评论
3653 浏览 6 评论
6044 浏览 21 评论
1342浏览 4评论
203浏览 3评论
对H747I-DISCO写程序时将CN2的st-link复用为usart1,再次烧录时无法检测到stlink怎么解决?
356浏览 2评论
STM32G474RE芯片只是串口发个数据就发烫严重是怎么回事?
446浏览 2评论
STM32处理增量式编码器Z信号如何判断中断是正转的还是反向转的?
275浏览 2评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-27 18:40 , Processed in 1.182582 second(s), Total 75, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号