硬汉嵌入式论坛

 找回密码
 立即注册
查看: 322|回复: 14
收起左侧

[RL-FlashFS] RL-FLASHFS +W25Q64,F103与F407使用表现差别巨大,找不到原因求助

[复制链接]

1

主题

12

回帖

15

积分

新手上路

积分
15
发表于 2024-4-11 19:18:22 | 显示全部楼层 |阅读模式
本帖最后由 littlestone08 于 2024-4-11 19:41 编辑

使用W25Q64,
KEIL4 +MDK4,使用标准库,照参考的代码写了驱动后,基本上没有遇到什么问题,运行自带的File_ex1例子,状态非常好。
于是,同样的代码换成STM32F407, 单片机,连引脚名都没有换,结果就悲剧了,表现如下:
  • 运行"dir"命令时非常慢,文件越大越慢,发现是最终是调用了"ffind"最后到驱动的ReadData函数,似乎是把文件的所有内容都枚举了一遍,最要命的是ReadData读一次只读4字节或8字节,但同样在STM32F103上,也是4字节或8字节的调用,就非常快。经过打印驱动调用过程信息对比,M4的单片机上,似乎枚举了文件的所有内容,而F103上只枚举了需要的部分。
  • 运行"type"命令(程序中逐个字符读取),同样的情况,F103,瞬间读完1000行文本,而F407则是肉眼可见的慢的速度在打印(使用的是SEGGER RTT,非阻塞SKIP)
  • F103建立好1000行的文本,拆下芯片放到F407的板子上,仅读取和列出,速度依然很慢。而F407建立好的文件的芯片,放到F103的板子上,速度也很快,说明不是芯片上存储内容差异引起的,进一步推论F407的驱动的代码应该也是没有问题的,要不然,把W25Q64换到  F103的板子上,多少会出现问题。
  • 怀疑M3和M4链接的代码不同,但是因为不是开源,也没有办法验证,于是换了KEIL5+RTE+CUBEMX方式,重新实现了一遍,以为能解决问题,折腾好几天,跑通了,在F407上速度与KEIL4上一样的慢。

抓狂了。Q网络上搜索,似乎RL-FLASH +NOR的贴子并不多,更不用说F407指定型号。Q

以上对比是在相同级别的SPI时钟速度上对比(示波器对比),按说,相同的开发环境,库版本,相同的开发环境和驱动,不应该出现这么大的差别。不知道有没有大佬遇到过可以指点一下或讨论下。

如果有需要,我可以贴出代码或以附件的形式给出完整的工程,在此多谢
回复

使用道具 举报

1

主题

12

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-4-12 08:52:14 | 显示全部楼层
看来是发错版块了,看到有一个专门的“文件系统”的版本块,管理如果能挪一下位置最好了。

“文件系统”的那一块也浏览了一个遍,也说EFS有慢的问题,但应该都是可以接受的那种,而我的这个F407上是出奇的不正常。
今天早上又试了一下F103的速度非常的正常,多创建几个“大文件”也是很不错
JLinkRTTViewer_PK2dZEHDyH.gif
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
发表于 2024-4-12 09:35:40 | 显示全部楼层
F4系列确实没有做SPI Flash的FlashFS例子,方便的话,分享你的工程看下。标准库版的就行。
回复

使用道具 举报

1

主题

12

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-4-12 10:50:50 | 显示全部楼层
本帖最后由 littlestone08 于 2024-4-12 11:38 编辑

感谢老大回复, 附件如下:
  • Src_FromSS.zip:项目包,为了减少影响,删减了很多无关的功能,只留下RTT输出,用了RTOS。
  • comm.zip: 为了方便项目公用RTT,打包在COMM中,项目中打开后可能需要重新修改下里面引用文件的路径。

里面的东西基本上都是F103移过来的,尤其是驱动文件,就担心有些许的不同可能会造成影响。

前两天不知道怎么回事,在SPI长时间访问的时候(比如,执行DIR命令,SPI总线上不停的发出命令),RTT输出就乱了,感觉好像是把缓冲中的数据无规律的发送出来, 不知道如何解决,可能会影响您调试。
-----------
刚抓的效果,与上一个F103的效果对比。可以看到:

  • 建立了三个小文件,就已经无法使用了;
  • DIR命令输出的时候,越到后面越慢得无法忍受,而且RTT不停的乱输出,我猜测可能是代码中有什么问题,因为这个问题是突然出现的,原来也是同样的慢,也拿不准是不是有关联?
  • TYPE打印输出时,输出时间越长,每个字符输出速度越慢,1000行的数据时间太久,没法做动图上传上来。
  • 在KEIL5+RTE中,也是同样的慢,但直接使用驱动函数访问存储时明显没有什么问题,速度是可以的。
---------------
老大的回复让我又看见曙光,希望可以有时间指点一番,如果确实不行,我也就死心了

F107速度慢演示

F107速度慢演示

Comm.zip

57.46 KB, 下载次数: 1

Src_FromSS.7z

428.05 KB, 下载次数: 1

回复

使用道具 举报

1

主题

12

回帖

15

积分

新手上路

积分
15
 楼主| 发表于 2024-4-12 11:19:33 | 显示全部楼层
本帖最后由 littlestone08 于 2024-4-12 11:52 编辑

这个图是KEIL5+RTE+DRIVER的形式,使用DIR命令的效果要稍快一点,(KEIL4中 DIR执行后,如果有1000行的数据文件, 会等至少20分钟才能输出),但与F103那个表现正常的比起来,还是差太多了,。
做了一个直接使用DRIVER中的ReadData读数据的功能,看显示的速度来说,函数本身应该是没问题的,DIR命令表现也比KEIL4中的要稍好一点点,但也是不正常。
打印的时候,似乎是越到后面输出越慢,难道是每输出一个字符的时候,都是把前面的都读出来?

(图中有RTT抽风式的间歇输出,会影响分析,请海涵)
-------------

附图

1000行文件打印输出,字符输出较慢

1000行文件打印输出,字符输出较慢

dir+type输出

dir+type输出

直接使用驱动函数ReadData读数据并RTT输出,佐证ReadData函数应该是正常的

直接使用驱动函数ReadData读数据并RTT输出,佐证ReadData函数应该是正常的
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106771
QQ
发表于 2024-4-13 09:09:27 | 显示全部楼层
littlestone08 发表于 2024-4-12 10:50
感谢老大回复, 附件如下:
  • Src_FromSS.zip:项目包,为了减少影响,删减了很多无关的功能,只留下RTT ...

  • 有一种情况不知道你排查了没,标准库使用MDK4里面的FlashFS可以方便的裸机测试,测试过裸机方式没。
    回复

    使用道具 举报

    1

    主题

    12

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2024-4-13 11:16:53 | 显示全部楼层
    没有试,意思是有可能是任务的优先级太低?所以会慢?我抽空就去试一下。测试完了及时反馈,感谢提供思路。

    -----------------------------------------
    另外,M4和M3的CAN控制器的寄存器应该是差不多的用法吧?我粗粗看了一下手册,应该没有什么特别注意的地方吧?

    回复

    使用道具 举报

    1

    主题

    12

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2024-4-14 10:52:27 | 显示全部楼层
    eric2013 发表于 2024-4-13 09:09
    有一种情况不知道你排查了没,标准库使用MDK4里面的FlashFS可以方便的裸机测试,测试过裸机方式没。

    已经测试过下面的过程

    • Keil4裸机执行问题表象无改善
    • 降低过SPI频率,现象无改善
    • Keil5+MDK5+RTOS2去掉过OS无改善(因为FS-FLASHFS与OS绑定,也是预料之内)
    • 直接使用驱动函数读取数据,无错误数据,速度也很快
    • 以前Keil4中也使用标准库函数实现的替换掉现在使用的寄存器方式的写法,现象相同,所以后来测试都是以寄存器驱动文件为主

    -----------
    现在经过测试,又设置下面的场景进行测试:
         都使用KEIL4环境,F103与F407都格式化,并增加一个10行的小文本文件,保证芯片内容相同,并使用TYPE命令输出,记录ReadData驱动函数的调用次数
    现象总结:
    日志输出格式为[时间]RdDat:[目标地址]-[长度]...[结束时间OK
    • 初始化文件系统时,调用的ReadData次数相同(正常)
    • 使用的输出函数相同,都是使用putchar单个字符输出,但103的输出是整个文件内容输出了,而F407是与驱动调用部分混合的(不知道为什么)
    • 二者格式化调用EraseSection过程相同(正常)
    • 读取目标文件并打印输出,F407调用ReadData的次数不正常的多。(不正常)
    • DIR命令时,F407调用ReadData的次数不正常的过多(不正常)
    • 数据量过大后,RTT输出紊乱(不正常)
    •   二块电路板,把W25Q64拆下来互换,重复测试,现象相同(以前也测试过,但是没有记录日志,这次是为了保存RTT日志)

    f103部分日志

    f103部分日志

    f407部分日志

    f407部分日志



    个人分析:
    • 每个字符输出(每个字符在FLASH中占4个字节),似乎都是重新从最原始的SECTOR读取,逐个枚举直到找到目标字符,即想读取第3个字符,似乎有点像链表,不访问前面就访问不了后面,文件中越是到后面的内容,越是读取的次数多。
    • 数一下读取第一个字符,调用了5次ReadData,第二个字符6次,第三个字符7次,佐证分析的第1点,而F103的文件中则没有这样的规划
    • 第7次读取时,F103读取了320个字符,而F407仅读取了1个字符,似乎是F103的程序启用了某种缓存机制,而F407则只是字节直接读FLASH(没有能力分析文件的数据结构)

    不同.png
    附件中在完整的TYPE 10.TXT命令后的RTT记录输出。关键点应该是这里望老大分析下。



    10行文本对比记录.7z

    76.77 KB, 下载次数: 0

    F103与F407输出10行文本文件的驱动调用对比

    回复

    使用道具 举报

    1

    主题

    12

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2024-4-14 11:04:20 | 显示全部楼层
    本帖最后由 littlestone08 于 2024-4-14 19:47 编辑
    eric2013 发表于 2024-4-13 09:09
    有一种情况不知道你排查了没,标准库使用MDK4里面的FlashFS可以方便的裸机测试,测试过裸机方式没。

    因为去掉RTX和不去掉没有什么区别,所以继续使用OS进行测试,由于看现象是因为F407未使用缓存,尝试各任务STACK多增加了1K,Startup.s文件中的定义也增加了一倍,但运行后是问题现象依旧,没有任何改善。

    RL-FLASH中NOR的选项很少,尝试找有没有BUFFER开关类似设置的地方,但尝试无果
    回复

    使用道具 举报

    1万

    主题

    6万

    回帖

    10万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    106771
    QQ
    发表于 2024-4-16 08:47:20 | 显示全部楼层
    littlestone08 发表于 2024-4-13 11:16
    没有试,意思是有可能是任务的优先级太低?所以会慢?我抽空就去试一下。测试完了及时反馈,感谢提供思路。 ...

    F1和F4的CAN一样。
    回复

    使用道具 举报

    1万

    主题

    6万

    回帖

    10万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    106771
    QQ
    发表于 2024-4-16 08:50:18 | 显示全部楼层
    littlestone08 发表于 2024-4-14 11:04
    因为去掉RTX和不去掉没有什么区别,所以继续使用OS进行测试,由于看现象是因为F407未使用缓存,尝试各任 ...

    驱动上还有一个地方可以看下,就是你看下F4的SPI Flash驱动底层设计,他的SPI上拉电阻使能没。可以使能了试试。
    回复

    使用道具 举报

    1

    主题

    12

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2024-4-20 16:16:23 | 显示全部楼层
    eric2013 发表于 2024-4-16 08:50
    驱动上还有一个地方可以看下,就是你看下F4的SPI Flash驱动底层设计,他的SPI上拉电阻使能没。可以使能了 ...

    还真没有注意W25Q芯片有上拉电阻使能的地方,我现在就去看手册。
    回复

    使用道具 举报

    1

    主题

    12

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2024-4-20 16:27:53 | 显示全部楼层
    本帖最后由 littlestone08 于 2024-4-20 16:52 编辑
    eric2013 发表于 2024-4-16 08:50
    驱动上还有一个地方可以看下,就是你看下F4的SPI Flash驱动底层设计,他的SPI上拉电阻使能没。可以使能了 ...

    因为修改帖子需要等审核出来,我直接再回复一下。
    刚才应该是理解错了,应该说的是F4芯片的SPI接口上拉使能吧。初始化部分是用标准库写的,用的是带上拉的,按说应该没问题。
    CC795DC0-DC9C-4b8a-A9AB-961A85276724.png
    -----------------
    另外,硬汉哥对8楼的那个调用ReadData函数的调用有什么看法吗?因为看起来F407上只会4字节4 字节的读,而且读下一个字符必须要先读出上一个字符,像是磁带的顺序存储一样,这个表现我感觉很关键,因为ReadData是被动调用的,而在F103上就不会这样,就是不知道为什么F407会这样。能抽空看一下?
    回复

    使用道具 举报

    1万

    主题

    6万

    回帖

    10万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    106771
    QQ
    发表于 2024-4-21 00:47:18 | 显示全部楼层
    littlestone08 发表于 2024-4-20 16:27
    因为修改帖子需要等审核出来,我直接再回复一下。
    刚才应该是理解错了,应该说的是F4芯片的SPI接口上拉 ...

    你的F4系列底层也是用的类似这种代码吧

    这个是FlashFS提供好的一个驱动

    [C] 纯文本查看 复制代码
    /*
    *********************************************************************************************************
    *
    *        模块名称 : SPI驱动模块
    *        文件名称 : SPI_STM32F103.c
    *        版    本 : V1.0
    *        说    明 : 本驱动是基于bsp_spi_bus.c文件实现。
    *              (1)使用FlashFS的SPI FLASH文件系统前务必先调用初始化函数bsp_InitSPIBus(在函数bsp.c中初始化)。
    *              (2)本文件使用的是官方模板,用户只需添加函数功能即可,故不对变量定义和函数名做重新规范。
    *              
    *        修改记录 :
    *                版本号  日期        作者     说明
    *                V1.0    2015-09-09 Eric2013  正式发布
    *
    *        Copyright (C), 2015-2020, 安富莱电子 [url]www.armfly.com[/url]
    *
    *********************************************************************************************************
    */
    #include <File_Config.h>
    #include "bsp.h"
    
    
    /*
    **********************************************************************************************************
                                                                                            宏定义
    **********************************************************************************************************
    */
    /*
       SPI 驱动定义
       spi0_drv: 第一个SPI设备驱动
       spi1_drv: 第二个SPI设备驱动
    */
    
    #define __DRV_ID  spi0_drv
    #define __FPCLK   72000000
    
    /* SPI_SR位定义 */
    #define RXNE    0x01
    #define TXE     0x02
    #define BSY     0x80
    #define FPCLK   (__FPCLK/1000)
    
    /* 串行Flsh的片选GPIO端口  */
    #define SPI_SelectHard            SPI1
    #define SF_RCC_CS                         RCC_APB2Periph_GPIOF
    #define SF_PORT_CS                        GPIOF
    #define SF_PIN_CS                        GPIO_Pin_11
    #define SF_CS_0()                        SF_PORT_CS->BRR = SF_PIN_CS
    #define SF_CS_1()                        SF_PORT_CS->BSRR = SF_PIN_CS
    
    /*
    **********************************************************************************************************
                                                                                            宏定义
    **********************************************************************************************************
    */
    
    /* SPI驱动接口函数 */
    static BOOL Init (void);
    static BOOL UnInit (void);
    static U8   Send (U8 outb);
    static BOOL SendBuf (U8 *buf, U32 sz);
    static BOOL RecBuf (U8 *buf, U32 sz);
    static BOOL BusSpeed (U32 kbaud);
    static BOOL SetSS (U32 ss);
    
    /* SPI 设备驱动控制块 */
    SPI_DRV __DRV_ID = {
      Init,
      UnInit,
      Send,
      SendBuf,
      RecBuf,
      BusSpeed,
      SetSS,
      NULL
    };
    
    
    /*
    *********************************************************************************************************
    *        函 数 名: Init
    *        功能说明: 初始化SPI设备,这里仅初始化了SPI Flash的片选,SPI初始化调用函数bsp_InitSPIBus()实现
    *        形    参: 无
    *        返 回 值: __TRUE
    *********************************************************************************************************
    */
    static BOOL Init (void)
    {
            /*
              安富莱STM32-V4 开发板口线分配:  串行Flash型号为 W25Q128 (104MHz)
              片选 PF8/SF_CS
            */
            GPIO_InitTypeDef GPIO_InitStructure;
    
            /* 使能GPIO 时钟 */
            RCC_APB2PeriphClockCmd(SF_RCC_CS, ENABLE);
    
            /* 配置片选口线为推挽输出模式 */
            SF_CS_1();                /* 片选置高,不选中 */
            GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
            GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
            GPIO_InitStructure.GPIO_Pin = SF_PIN_CS;
            GPIO_Init(SF_PORT_CS, &GPIO_InitStructure);
            return (__TRUE);
    }
    
    /*
    *********************************************************************************************************
    *        函 数 名: UnInit
    *        功能说明: 卸载SPI设备,正常情况下此函数实现卸载需要将SPI接口设置为初始化状态,即未开启状态。
    *             由于多个设备使用SPI接口,这里仅是将片选至高。
    *        形    参: 无
    *        返 回 值: __TRUE
    *********************************************************************************************************
    */
    static BOOL UnInit (void)
    {
      SF_CS_1();
    
      return (__TRUE);
    }
    
    /*
    *********************************************************************************************************
    *        函 数 名: Send
    *        功能说明: 发送一个字节数据
    *        形    参: 无
    *        返 回 值: SPI接口返回值
    *********************************************************************************************************
    */
    static U8 Send (U8 outb)
    {
            /* 通过SPI接口读写一个字节 */
            SPI_SelectHard->DR = outb;
    
            /* 等待数据接收完毕 */
            while (!(SPI_SelectHard->SR & RXNE));
            return (SPI_SelectHard->DR);
    }
    
    /*
    *********************************************************************************************************
    *        函 数 名: SendBuf
    *        功能说明: 通过SPI接口发送多个字节
    *        形    参: buf 数据地址
    *             sz  发送数据大小
    *        返 回 值: __TRUE
    *********************************************************************************************************
    */
    static BOOL SendBuf (U8 *buf, U32 sz)
    {
            U32 i;
    
            for (i = 0; i < sz; i++)
            {
                    SPI_SelectHard->DR = buf[i];
                    /* 等待发送完成 */
                    while (!(SPI_SelectHard->SR & TXE));
                    SPI_SelectHard->DR;
            }
           
            /* 等待接收完成 */
            while (SPI_SelectHard->SR & (BSY | RXNE))
            {
                    SPI_SelectHard->DR;
            }
            return (__TRUE);
    }
    
    /*
    *********************************************************************************************************
    *        函 数 名: RecBuf
    *        功能说明: 通过SPI接口接收多个字节
    *        形    参: buf 数据地址
    *             sz  接收数据大小
    *        返 回 值: __TRUE
    *********************************************************************************************************
    */
    static BOOL RecBuf (U8 *buf, U32 sz)
    {
            U32 i;
    
            for (i = 0; i < sz; i++)
            {
                    SPI_SelectHard->DR = 0xFF;
                    /* 等待接收完成 */
                    while (!(SPI_SelectHard->SR & RXNE));
                    buf[i] = SPI_SelectHard->DR;
            }
            return (__TRUE);
    }
    
    /*
    *********************************************************************************************************
    *        函 数 名: BusSpeed
    *        功能说明: 设置SPI速度,驱动SPI Flash使用的是18MHz
    *        形    参: buf 数据地址
    *             sz  接收数据大小
    *        返 回 值: __TRUE
    *********************************************************************************************************
    */
    static BOOL BusSpeed (U32 kbaud)
    {
            U8 br;
    
            if      (kbaud >= FPCLK / 2)   br = 0;                       /* FPCLK/2    */
            else if (kbaud >= FPCLK / 4)   br = 1;                       /* FPCLK/4    */
            else if (kbaud >= FPCLK / 8)   br = 2;                       /* FPCLK/8    */
            else if (kbaud >= FPCLK / 16)  br = 3;                       /* FPCLK/16   */
            else if (kbaud >= FPCLK / 32)  br = 4;                       /* FPCLK/32   */
            else if (kbaud >= FPCLK / 64)  br = 5;                       /* FPCLK/64   */
            else if (kbaud >= FPCLK / 128) br = 6;                       /* FPCLK/128  */
            else                           br = 7;                       /* FPCLK/256  */
    
            SPI_SelectHard->CR1 = (SPI_SelectHard->CR1 & ~(7 << 3)) | (br << 3);
            return (__TRUE);
    }
    
    /*
    *********************************************************************************************************
    *        函 数 名: BusSpeed
    *        功能说明: 设置SPI速度,驱动SPI Flash使用的是18MHz
    *        形    参: ss
    *             0 表示选中设备
    *             1 表示取消选中
    *        返 回 值: __TRUE
    *********************************************************************************************************
    */
    static BOOL SetSS (U32 ss) {
            if(ss == 0)
            {
                    bsp_SpiBusEnter();        /* 占用SPI总线, 用于总线共享 */
                   
                    bsp_SPI_Init(SPI_Direction_2Lines_FullDuplex | SPI_Mode_Master | SPI_DataSize_8b
                            | SPI_CPOL_High | SPI_CPHA_2Edge | SPI_NSS_Soft | SPI_BaudRatePrescaler_4 | SPI_FirstBit_MSB);
                    SF_CS_0();
                   
            }
            else
            {
                    SF_CS_1();
                    bsp_SpiBusExit();        /* 释放SPI总线, 用于总线共享 */
            }
           
      return (__TRUE);
    }
    
    /***************************** 安富莱电子 [url]www.armfly.com[/url] (END OF FILE) ********************************
    回复

    使用道具 举报

    1

    主题

    12

    回帖

    15

    积分

    新手上路

    积分
    15
     楼主| 发表于 2024-4-22 10:29:21 | 显示全部楼层
    eric2013 发表于 2024-4-21 00:47
    你的F4系列底层也是用的类似这种代码吧

    这个是FlashFS提供好的一个驱动

    感谢硬汉大佬。

    我以前用过这个类似的代码试过,不过和我原来的效果不多,所以就还用我当前的代码试。

    我现在用这个代码再试下,反馈结果上来。如果还不行,暂时放弃,想办法用下littleFS了。
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

    GMT+8, 2024-5-5 22:04 , Processed in 0.352364 second(s), 29 queries .

    Powered by Discuz! X3.4 Licensed

    Copyright © 2001-2023, Tencent Cloud.

    快速回复 返回顶部 返回列表