xsyyhz 发表于 2023-7-20 10:29:30

RL-FlashFS 使用spi flash 避坑总结

1.ffree返回结果不靠谱,即使调用fflush也不会刷新,必须fclose 后才会更新,做应用层要注意下;

2.SPI Flash Driver中ProgramPage必须以4倍字节操作,否者跑时间长了就会出现诡异现象,比如ffree返回一个很大值,hardfault等,ReadData也必须4倍字节操作;
3.fwrite 必须保证有足够空间,否则必失败,后续其他操作也失败(靠ffree查询剩余空间不靠谱)


问题2卡了我一个星期,都快要放弃了,多谢硬汉哥期间支持。

eric2013 发表于 2023-7-20 11:40:55

谢谢楼主分享,非常宝贵的经验。

ifree 发表于 2023-10-12 07:45:26

最近也想研究用RL-Flash+RL-USB做一个将SPI Flash通过USB模拟成U盘的实验,有没有教程参考啊?硬汉哥没有做RL-Flash的教程,给的例子也没找到SPI Flash做的。

eric2013 发表于 2023-10-12 14:59:47

ifree 发表于 2023-10-12 07:45
最近也想研究用RL-Flash+RL-USB做一个将SPI Flash通过USB模拟成U盘的实验,有没有教程参考啊?硬汉哥没有做 ...

FlashFS用于SPI Flash是嵌入式文件系统EFS格式,不是FAT格式,不能模拟U盘。

ifree 发表于 2023-10-12 17:40:19

eric2013 发表于 2023-10-12 14:59
FlashFS用于SPI Flash是嵌入式文件系统EFS格式,不是FAT格式,不能模拟U盘。

这样的话,我打算单片机的数据采集存储到SPI Flash当中,然后在用U盘的形式展现给用户就不能实现了吗?应该用什么方法呢?

eric2013 发表于 2023-10-12 18:26:38

ifree 发表于 2023-10-12 17:40
这样的话,我打算单片机的数据采集存储到SPI Flash当中,然后在用U盘的形式展现给用户就不能实现了吗?应 ...
强行移植个fatfs+usb即可

ifree 发表于 2023-10-15 09:50:07

spi接口接的flash芯片,可以选用nand或mci卡的方式来支持模拟u盘吗?感觉rl_flash是根据配置的是m0还是n0来选择不同的驱动,从而决定用什么文件系统的。这样说来,是不是按照sd卡或nand 的驱动方式提供驱动接口给fs就可以呢?

eric2013 发表于 2023-10-16 07:34:45

ifree 发表于 2023-10-15 09:50
spi接口接的flash芯片,可以选用nand或mci卡的方式来支持模拟u盘吗?感觉rl_flash是根据配置的是m0还是n0来 ...

可以的。

ifree 发表于 2023-10-20 19:51:26


我在F1的单片机上移植RL-FlashFS,测试以下内容。
------------------------------------------------
请选择串口操作命令,电脑键盘打印数字即可:
首次使用,如果操作NOR,务必调用串口命令1,进行NOR Flash的低级格式化和文件系统格式化
0 - 读取FlashID
1 - 显示卡容量和剩余容量
2 - 显示卡根目录下的文件
3 - 创建三个text文本并使用不同函数写入内容
4 - 使用三个不同函数读取文本
5 - 删除文件夹和文件
6 - 测试文件读写速度
7 - 写数据到CSV文件中
8 - 从CSV文件中读数据
9 - 读串行Flash, 地址:0x0,长度:4096字节
A - 写串行Flash, 地址:0x0,长度:4096字节

------
命令0,1,2,9,A都成功,但是3号命令失败。
/*
*********************************************************************************************************
*        函 数 名: CreateNewFile
*        功能说明: 创建三个text文本,分别使用fwrite,fprintf和fputs写数据。
*        形    参: _path,U盘,SD卡和NAND
*        返 回 值: 无
*********************************************************************************************************
*/
static void CreateNewFile(char *_path)
{
        const uint8_t WriteText[] = {"武汉安富莱电子有限公司\r\n2015-09-06\r\nwww.armfly.com\r\nWWW.ARMFLY.COM"};
        const uint8_t WriteText1[] = {"武汉安富莱电子有限公司\r"};
        FILE *fout;
        uint32_t bw;
        uint32_t i = 2;
        uint8_t result;
        char namepath;

   
    result = finit(_path);
        if(result != NULL)
        {
                /* 如果挂载失败,务必不要再调用FlashFS的其它API函数,防止进入硬件异常 */
                printf("初始化文件系统失败 (%s)\r\n", ReVal_Table);
                return;      
        }
        else
        {
                printf("初始化文件系统成功 (%s)\r\n", ReVal_Table);
        }
   
        /* 加载 */
        result = fmount(_path);
       
        if(result != NULL)
        {
                /* 如果挂载失败,务必不要再调用FlashFS的其它API函数,防止进入硬件异常 */
                printf("挂载文件系统失败 (%s)\r\n", ReVal_Table);
                goto access_fail;
        }
        else
        {
                printf("挂载文件系统成功 (%s)\r\n", ReVal_Table);
        }
   
        printf("------------------------------------------------------------------\r\n");
       
        /**********************************************************************************************************/
        /* 打开文件test1.txt,如果没有txt文件会自动创建*/
        sprintf(namepath, "%s\\test1.txt", _path);
        fout = fopen (namepath, "w");
        if (fout != NULL)
        {
                printf("打开文件\\test1.txt成功,如果没有子文件夹和txt文件会自动创建\r\n");
                /* 写数据 */
                bw = fwrite (WriteText, sizeof(uint8_t), sizeof(WriteText)/sizeof(uint8_t), fout);
                if(bw == sizeof(WriteText)/sizeof(uint8_t))
                {
                        printf("写入内容成功\r\n");
                }
                else
                {
                        printf("写入内容失败\r\n");
                }
               
                /* 关闭文件 */
                fclose(fout);
        }
        else
        {
                printf("打开文件%s失败\r\n", namepath);
        }
       
        /**********************************************************************************************************/
        /* 打开文件test2.txt,如果没有txt文件会自动创建*/
        sprintf(namepath, "%s\\test2.txt", _path);
        fout = fopen (namepath, "w");
        if (fout != NULL)
        {
                printf("打开文件\\test2.txt成功,如果没有子文件夹和txt文件会自动创建\r\n");
               
                /* 写数据 */
                bw = fprintf (fout, "%d %d %f\r\n", i, i*5, i*5.55f);
               
                /* 使用函数ferror检测是否发生过错误 */
                if (ferror(fout) != NULL)
                {
                        printf("写入内容失败\r\n");
                }
                else
                {
                        printf("写入内容成功\r\n");       
                }
               
                /* 关闭文件 */
                fclose(fout);
        }
        else
        {
                printf("打开文件%s失败\r\n", namepath);
        }
       
        /**********************************************************************************************************/
        /* 打开文件test3.txt,如果没有txt文件会自动创建*/
        sprintf(namepath, "%s\\test3.txt", _path);   
        fout = fopen (namepath, "w");
        if (fout != NULL)
        {
                printf("打开文件\\test3.txt成功,如果没有子文件夹和txt文件会自动创建\r\n");
               
                /* 写数据 */
                fputs((const char *)WriteText1, fout);
               
                /* 使用函数ferror检测是否发生过错误 */
                if (ferror(fout) != NULL)
                {
                        printf("写入内容失败\r\n");
                }
                else
                {
                        printf("写入内容成功\r\n");       
                }
               
                /* 关闭文件 */
                fclose(fout);
        }
        else
        {
                printf("打开文件%s失败\r\n", namepath);
        }

access_fail:       
        /* 卸载 */
        result = funmount(_path);
        if(result != NULL)
        {
                printf("卸载文件系统失败\r\n");
        }
        else
        {
                printf("卸载文件系统成功\r\n");
        }
   
    result = funinit(_path);
        if(result != NULL)
        {
                printf("复位文件系统失败 (%s)\r\n", ReVal_Table);
        }
        else
        {
                printf("复位文件系统成功 (%s)\r\n", ReVal_Table);
        }

        printf("------------------------------------------------------------------\r\n");
}


执行返回的数据如下

【3 - CreateNewFile】
初始化文件系统成功 (fsOK:成功)
挂载文件系统成功 (fsOK:成功)
------------------------------------------------------------------
打开文件F0:\test1.txt失败
打开文件F0:\test2.txt失败
打开文件F0:\test3.txt失败
卸载文件系统成功
复位文件系统成功 (fsOK:成功)
------------------------------------------------------------------


这个该从哪个方向去查找问题呢?

eric2013 发表于 2023-10-21 09:22:01

ifree 发表于 2023-10-20 19:51
我在F1的单片机上移植RL-FlashFS,测试以下内容。
------------------------------------------------
...

先执行下整片擦除,然后文件系统格式化,再操作试试。

过河卒 发表于 2023-12-27 15:55:41

求教,在F407的单片机上移植RL-FlashFS
打开文件F0:\test2.txt成功
打开文件F0:\test\test2.txt失败
fmkdir失败

过河卒 发表于 2023-12-27 15:58:19

求教,在F407的单片机上移植RL-FlashFS
打开文件F0:\test1.txt成功
打开文件F0:\test\test1.txt失败

eric2013 发表于 2023-12-28 08:23:09

过河卒 发表于 2023-12-27 15:55
求教,在F407的单片机上移植RL-FlashFS
打开文件F0:\test2.txt成功
打开文件F0:\test\test2.txt失败


移植到SPI Flash还是SD卡上。

过河卒 发表于 2023-12-28 10:15:23

SPI Flash上
页: [1]
查看完整版本: RL-FlashFS 使用spi flash 避坑总结