无聊中,喷喷调试中得到的经验,挣点莫元吧。 
移植fatfs 0.09,stm32f103vet6, sdio 4bit模式,fwlib还是用2.03,移植很顺利,diskio.c写了几句就能跑,f_mount,读写通过。 
读出640x480x16bit bitmap文件显示,出现问题,f_read()每次只能读512byte,超出就出现读数据错:每次读一行1280Byte,出现一条竖线;分成3次读就没问题。虽然也能用,不免有点太监的感觉。 
跟踪问题,f_read() --> SD_ReadBlock()-->DMA_RxConfiguration(),猜到这是DMA 32Bit的问题:SDIO的FIFO是32Bit的,DMA接收地址要u32 *, 最低2Bit为0; 读的时候这个基地址由fatfs的f_read()、SD_ReadBlock()分配,fatfs中保存1-Sector(512Bytes)缓存,每次f_read()时,主程序传来readbuffer, 先将sector buffer中“剩余”的bytes用mem_cpy送给readbuffer, 不够再启动SD_ReadBlock()读; 又分成两种情况:要读的不足1Sector,以fatfs的sector buffer作为DMA接收区,再mem_cpy给readbuffer; 要读的是整数sector,就直接以readbuffer作为DMA接收区。 
问题就出在这第二种情况:这时的read buffer即使初始是4Byte对齐的(u32 *),加上sector buffer中“剩余”Bytes的偏移之后,也不会是确保4Byte对齐的了。具体到bitmap文件读:先读文件头70Byte,fatfs读512Byte,剩余442Byte;读一行1280Byte,送m_FileIo_Buf[]作为接收区,2KByte; fatfs先将442Byte送给m_FileIo_Buf,启动SD_ReadBlock(), 从m_FileIo_Buf+442位置接收DMA...出错了,地址A1不是0! 
这个问题谁都没错,fatfs和sdio都是按自己正确的方式工作。开发板们给出的例程,f_read()读512内Byte,也不会错... 
想一次读超过512的话,解决的办法: 
定义: 
u8 m_FileIo_Buf[2048]  __attribute__((aligned(4)));               //接收缓冲区 
#define M_FileAlignAdj(pFile)       (4 - (512 - ((uint32_t)((pFile)->fptr) & 0x01FF)) & 0x0003) 
程序中: 
     u8* ptr; 
       //读文件 
        ptr = m_FileIo_Buf; 
        ptr += M_FileAlignAdj(bmpfile); 
        res = f_read(bmpfile, ptr, bytes_per_row, &bytenum); 
       //从ptr处读数据.... 
原理很简单:每次读的接收指针ptr在m_FileIo_Buf[]的前4Byte之间移动,经过f_read()之后,DMA接收SD Sector数据时一定是(u32 *)地址。 
这个小小的问题折腾了3天,有够无聊。公示出来也许可以减少别人的重复的无聊。 
 
 |