历史上的今天
返回首页

历史上的今天

今天是:2024年09月19日(星期四)

正在发生

2018年09月19日 | 使用Cubemx移植FatFs到stm32

2018-09-19 来源:eefocus

在大型的存储器中,没有文件系统是万万不可行的,你不可能每次要打开一个文件都要从头到尾扫描一遍存储器,几兆的小存储器还好,几G甚至几T的存储器就根本没办法这么做了。而且有了文件系统也可以方便的管理使用各类文件。

这一次使用Cubemx生成FatFs的初始化代码,然后做最后的移植工作。本人使用的是stm32f767的野火的板子。

介绍一下FafFs

系统架构

FatFs是一种中间层,可以屏蔽硬件的差异,移植起来非常方便



移植需要注意的地方

你需要提供FatFs需要的底层I/O函数,需要的函数如下表,但是并不是全部函数都需要,你只需要提供必需的disk_status disk_initialize disk_read 和你需要的就可以。


开始移植

配置Cubemx

因为我准备的是W25Q128上的FatFs,CubeMX上面没有,所以要选择user-defined


接下来是在Configuration里面配置FatFs,因为需要读取的文件是中文的,所以要配置为中文,然后为以后可能还有别的存储器预留空位,所以配置VOLUMES为3


还有就是在project setting里面把stack设置的大点


此外就是W25Q128的基本配置,这些就不提供了,网上有,可以参考微雪课堂里的配置。

接下来就是生成代码了

补完底层I/O函数

打开user_disko.c这个文件,可以看到CubeMX自动生成的函数原型。由于我需要读写磁盘,所以我需要补全这些所有的函数USER_initialize USER_status USER_read USER_write USER_ioctl

遇到问题和解决问题

f_mount返回FR_DISK_ERR

这个问题困扰了我好几个小时,我从f_mount->get_ldnumber用printf找了差不多1个小时的BUG,发现找不到问题,突然间发现我f_mount还调用了一个函数find_volume,而且就算这里出现了问题,就换方向一路追踪find_volume->check_fs->move_window->disk_read,发现是disk_read返回的错误,看到这我就傻眼了,觉得不可能啊,因为我之前读取写入flash都是没有问题的。

第二天脑袋比较清醒了,首先先测试初始化是否成功,在读取成功flash id后确定了初始化成功。

然后再来看看disk_read,它使用的是我提供的一个全局的disk io驱动来读取disk,结构体类型如下


typedef struct

 

{

 

 uint8_t                 is_initialized[_VOLUMES];

 

 const Diskio_drvTypeDef *drv[_VOLUMES];

 

 uint8_t                 lun[_VOLUMES];

 

 volatile uint8_t        nbr;

 

}Disk_drvTypeDef;

 

所以我回到了userdiskio.c查看我的USERread函数

 

DRESULT USER_read (

   BYTE pdrv,      /* Physical drive nmuber to identify the drive */

   BYTE *buff,     /* Data buffer to store read data */

   DWORD sector,   /* Sector address in LBA */

   UINT count      /* Number of sectors to read */

)

 

{

 

 /* USER CODE BEGIN READ */

 

 FLASH_DEBUG_FUNC();

 

 DRESULT res = RES_ERROR;

 

   if ((Stat & STA_NOINIT))

 

   {

 

       res = RES_NOTRDY;

 

   }

 

 else

 

 {

 

   sector+=1536;//扇区偏移,外部Flash文件系统空间放在外部Flash后面6M空间

 

   res = BSP_QSPI_Read(buff, sector <<12, count<<12);

 

 }

 

   return res;  

 

 /* USER CODE END READ */

 

}


我在USER_read的else括号中加了一个printf,结果发现调用f_mount时,居然没有进入这个else语句,然后我开始怀疑这个Stat有问题,所以我把if的条件去掉了,直接执行sector+=1536;res = BSP_QSPI_Read(buff, sector <<12, count<<12);这条语句,发现FatFs挂载成功。


很激动,原来问题在于Stat的状态没有更新,因为Stat一开始定义的时候是定义为STA_NOINIT。


/* Disk status */


static volatile DSTATUS Stat = STA_NOINIT;


接下来就是查找disk的状态没有更新的原因。回到一开始找到返回错误信息的函数find_volume,它的执行过程相当于get_ldnumber->disk_initialize->check_fs...一开始就是到了check_fs这一步的时候报错,停止程序的,我们可以发现,这个过程并没有调用到用户定义的USER_status或FatFs定义的disk_status来检查disk的状态更新。


所以我在初始化中加入了检查disk的状态的代码


DSTATUS USER_initialize (

   BYTE pdrv           /* Physical drive nmuber to identify the drive */

)

 

{

 

 /* USER CODE BEGIN INIT */

 

 Stat = USER_status(pdrv);

 

 return BSP_QSPI_Init(); /* Flash的初始化 */

 

 /* USER CODE END INIT */

 

}


效果很好,disk的状态更新成功,f_mount挂载正常。


f_open返回FR_INVALID_NAME


好不容易挂载成功了,但是读写还是失败,第一反应是可能在编码上出错了,因为我的工程没有包括cc936.c这个文件,而野火官方的工程却包括了,我怀疑是不是这一点导致无法读取中文,从而FR_INVALID_NAME。


但是我现在还不知道FatFs是怎么调用cc936.c这个文件的,只能先从f_open跟踪进去看看。


f_open->follow_path,打LOG发现是follow_path中的create_name返回的FR_INVALID_NAME


进入create_name找到返回FR_INVALID_NAME的语句


...

 

mem_set(sfn, ' ', 11);

 

...

 

for (;;;) {

 

   ...

 

   if (c == '.' || i >= ni) {        /* End of body or over size? */

 

           if (ni == 11 || c != '.') return FR_INVALID_NAME;   /* Over size or invalid dot */

 

           i = 8; ni = 11;             /* Goto extension */

 

           continue;

 

   }

 

   ...

 

}


由于对于文件名一开始只分配了11个空间,但是我的文件名却超过了11个空间,所以导致了这个问题,在我将我的文件名减少后,问题解决。

文件名长度才11有点短,但是可以通过修改支持长文件名来支持。


在支持长文件名后,读写长文件名没有问题了


可以改进的地方

本工程没有加入RTC的支持,所以没有去实现get_fattime,因此不支持多磁盘,想支持多磁盘需要实现get_fattime

本工程已上传github

https://github.com/greedyhao/stm32

———— / END / ————


推荐阅读

史海拾趣

申风(everanalog)公司的发展小趣事

随着技术实力的不断提升和产品线的日益丰富,申风(everanalog)公司开始积极拓展市场。公司凭借优质的产品和服务,逐渐在国内市场上树立了良好的品牌形象。同时,公司也积极开展国际合作,与国际知名企业建立了战略合作关系,共同推动集成电路产业的发展。这些合作不仅为公司带来了更多的商业机会,也提升了公司在国际市场上的竞争力。

广东奥科公司的发展小趣事

在国内市场取得一定成绩后,广东奥科公司开始积极拓展国际市场。公司参加了多个国际电子展会,与国际知名企业建立了合作关系,成功将产品打入国际市场。同时,广东奥科公司还注重品牌建设,通过提升产品质量和服务水平,逐渐树立了良好的品牌形象。这些努力使得广东奥科公司在国际市场上也获得了广泛的认可和好评。

HDP_Power公司的发展小趣事

随着电子技术的快速发展,广东奥科公司意识到只有不断创新才能在市场中立足。公司加大了对研发的投入,引进了一批高素质的研发人才,并建立了完善的研发体系。经过多次尝试和实验,广东奥科公司成功开发出了多款具有创新性和竞争力的电子产品,这些产品不仅性能卓越,而且设计独特,深受消费者的喜爱。这些技术突破和产品创新为广东奥科公司赢得了市场的认可,也推动了公司的快速发展。

Herley New York公司的发展小趣事

随着电子技术的快速发展,广东奥科公司意识到只有不断创新才能在市场中立足。公司加大了对研发的投入,引进了一批高素质的研发人才,并建立了完善的研发体系。经过多次尝试和实验,广东奥科公司成功开发出了多款具有创新性和竞争力的电子产品,这些产品不仅性能卓越,而且设计独特,深受消费者的喜爱。这些技术突破和产品创新为广东奥科公司赢得了市场的认可,也推动了公司的快速发展。

超霸(GP)公司的发展小趣事

绿索超容在追求经济效益的同时,始终不忘履行社会责任。公司积极响应国家绿色发展的号召,致力于环保事业和可持续发展。在产品研发和生产过程中,绿索超容始终坚持绿色、低碳、环保的理念,采用环保材料和工艺,减少对环境的影响。此外,公司还积极参与社会公益活动,为社会贡献自己的力量。这些举措不仅提升了绿索超容的企业形象,也为其在电子行业中树立了良好的口碑。

Cystech公司的发展小趣事

C-TECH Co., Ltd非常重视人才培养和团队建设。公司注重员工的培训和发展,为员工提供广阔的职业发展空间和良好的工作环境。同时,公司还积极引进优秀人才,打造了一支高素质、专业化的团队。正是凭借这支优秀的团队,C-TECH Co., Ltd在电子行业中不断创新和突破,取得了令人瞩目的成绩。

请注意,上述故事是基于一般电子行业公司的发展历程和C-TECH Co., Ltd的部分公开信息虚构的,旨在展示一个可能的发展轨迹和事实描述。具体公司的实际情况可能有所不同。

问答坊 | AI 解惑

航海设备专用液晶显示器WEDC LCD

ENH038QD1-450/650 尺寸大小: 3.8" 分辨率: QVGA 320 x 240 接口: 6-bits TTL interface 亮度 : 450/650nit(cd/m2) 对比度:高对比度、大开口率 显示模式:Normally White 响应时间:Rise 30ms/ Fall 50ms 功耗:3.4W 工作温度: -30℃--- ...…

查看全部问答>

2009IEEE工程管理与服务科学国际会议征文klj

EMS 2009 Call for Papers: Sept. 20-22, 2009, Beijing, China ====================================================================== The 3rd Int’l Conference on Engineering Management and Service Sciences (EMS 2009) CALL FOR PAP ...…

查看全部问答>

lbing7来拿分

对于我这个刚入门的人,lbing7能耐心讲解基础,十分感谢。 由于到目前问的问题都是十分基础的,我就不写出来了。…

查看全部问答>

准备酝酿一个玩wince的人的开心网

我们刚创建的wince家园,想让所有玩wince的人变成朋友。 logo都没来得及做。想先看看坛子上面兄弟的看法。 目的是想找同道之人共同参与,共同出出好点子,让我们搞wince的变成一个强大的同盟。 试运行网站 http://www.armce.cn/ 嘿嘿~~~ 预祝xd ...…

查看全部问答>

wince 问题!!!!!!

有高人知道在wince工程下面 怎么给lable button等控件添加背景图片么?…

查看全部问答>

如何通过2440spi总线读写外设的寄存器?

平台:arm开发板,用spi总线外接1个fir红外芯片,s3c2440 + linux2.6.24.7 现在2440这边已经做好了,insmod bitbang.ko,s3c24xx.ko,insmod spidev.ko,用testspi,用示波器可以测到时钟和数据的波形都是对的,但不知道如何读写fir的寄存器?以前都 ...…

查看全部问答>

请教版主STM323.0的库函数有没有IIC的问题?

请教版主STM32 3.0的库函数有没有IIC的问题? 正准备做个项目希望 版主 给个答复!!…

查看全部问答>

收到348的套件了,说一下

收到套件 ,发现原装的也是配了很多made in china的东东? [ 本帖最后由 pig163xx 于 2011-10-29 22:10 编辑 ]…

查看全部问答>

请大家注意,用F28027的Lib可能存在Bug!

最近一直在学习F28027的库开发模式,用下来感觉其实一般,Ti官方的手册中也没有一个标准,什么函数什么时候调用,前后有什么顺序要求,就是给了一些例子和函数说明,看起来有些模糊。今天在调试SCI的程序,突然发现用库模式的SCI_LOOPBack_INITTrup ...…

查看全部问答>

launchpad c2000毕设,求高手!求意见!

以LaunchPadXL-C2000为核心板,设计一款可实现正弦波、方波和三角波信号输出的多函数信号发生器。信号频率0.1Hz-1MHz,输出幅度0.1V-5V可调,信号类型、频率及幅度均由按键选定。…

查看全部问答>