硬汉嵌入式论坛

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

[BOOT/IAP] STM32H750使用QSPI在外置flash运行程序导致串口收发异常

[复制链接]

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2023-7-28 16:47:13 | 显示全部楼层 |阅读模式
请教下论坛里的大佬们,有在实际项目中用过外置flash运行程序吗?
最近在尝试外置flash运行程序,用了一块小小的开发板,板载100pin的H750VBT6和8MB的QSPI flash:W25Q64;
程序主要配置如下:bootloader放在内置flash,其他所有程序包括中断服务函数都放在外置flash,开启ICache,仅使用AXI SRAM,QSPI时钟频率100M,同时开启8个串口,用dma1每隔250us循环发送固定数据给从机,用串口idle中断+dma2接收从机回复的数据,dma1+dma2的16个通道全部用满,发送是NORMAL模式,目前发现一些很奇怪的问题:

1.使用内置flash运行上述程序时,没有任何异常,串口dma收发非常稳定;
2.使用外置flash运行上述程序时,偶尔出现串口收发异常,异常分为两种情况:
①发送数据异常:逻辑分析仪显示要发送的数据错误,比如0x63变成了0xC3,或者直接framing error,无法解析出正常数据;
②接收数据异常:逻辑分析仪显示要接收的数据正确,J-Link仿真界面显示要接收的数据错误,比如逻辑分析仪显示正常的0x06,而H750中的程序却解析成了0x86。


下图分别是逻辑分析仪抓取的发送异常和仿真界面抓取的接收异常

发送异常

发送异常
         

接收异常

接收异常



关于第①点中的串口发送异常,目前没发现什么线索;
关于第②点中的串口接收异常,我查看了H750的系统结构图,一度怀疑是因为我用了AXI SRAM,导致QSPI在读取flash的时候和DMA抢占了AXI总线,使DMA传输效率降低,在DMA未完成数据传输的情况下,CPU提前对目标地址进行数据解析,导致出错(开启DCache会加剧这种情况),所以我尝试把RAM切换到AHB SRAM1,和DMA通过AHB总线直连,减少总线竞争,但改善效果并不明显,依然存在接收错误的现象;后来又调整了AXI互联寄存器中ASIB IN1的优先级为最高,效果依然不明显。

AXI

AXI
     

ASIB

ASIB


此外,用的串口越多,异常出现频率越高,减少到4个串口时异常明显减少,示波器显示QSPI将8个串口的中断函数取完要耗时近80us,缩减串口数量后,通讯时间缩短,错误现象也随之减少,所以我觉得导致异常的根本原因还是在于H750和外置FLASH的通讯。

请教下论坛的朋友们有这方面的经验吗?是我的程序配置有问题吗?还是和总线抢占或硬件有关呢?有关的话,有什么解决方案么?再不行的话,我打算直接换个好点的开发板试试

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106731
QQ
发表于 2023-7-28 18:38:24 | 显示全部楼层
1、开启DCache,然后配置AXI SRAM配置MPU/Cache,直接关闭读写Cache,这种函数测试下。

[C] 纯文本查看 复制代码
    /* 最高性能,读Cache和写Cache都开启 */        
#if 0
        /* 配置AXI SRAM的MPU属性为Write back, Read allocate,Write allocate */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

        HAL_MPU_ConfigRegion(&MPU_InitStruct);

    /* 最低性能,读Cache和写Cache都关闭 */
 #else
        /* 配置AXI SRAM的MPU属性为NORMAL, NO Read allocate,NO Write allocate */
        MPU_InitStruct.Enable           = MPU_REGION_ENABLE;
        MPU_InitStruct.BaseAddress      = 0x24000000;
        MPU_InitStruct.Size             = MPU_REGION_SIZE_512KB;
        MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
        MPU_InitStruct.IsBufferable     = MPU_ACCESS_NOT_BUFFERABLE;
        MPU_InitStruct.IsCacheable      = MPU_ACCESS_NOT_CACHEABLE;
        MPU_InitStruct.IsShareable      = MPU_ACCESS_NOT_SHAREABLE;
        MPU_InitStruct.Number           = MPU_REGION_NUMBER0;
        MPU_InitStruct.TypeExtField     = MPU_TEX_LEVEL1;
        MPU_InitStruct.SubRegionDisable = 0x00;
        MPU_InitStruct.DisableExec      = MPU_INSTRUCTION_ACCESS_ENABLE;

        HAL_MPU_ConfigRegion(&MPU_InitStruct);
#endif



2、开启QSPI Flash的最高Cache性能

3.png

3、开启最高QSPI Flash性能也不行的话,考虑部分代码加载到其他RAM区测试下(不要再加载到AXI SRAM),直接右击分组设置就行,看看改善多少:

https://www.armbbs.cn/forum.php?mod=viewthread&tid=101011

回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-7-31 15:24:20 | 显示全部楼层
eric2013 发表于 2023-7-28 18:38
1、开启DCache,然后配置AXI SRAM配置MPU/Cache,直接关闭读写Cache,这种函数测试下。

[mw_shl_code=c, ...

感谢硬汉哥回复,目前确定接收错误就是由AXI总线抢占导致的,在开始数据解析前等待DMA传输标志位可以避免这个问题
回复

使用道具 举报

19

主题

234

回帖

291

积分

高级会员

积分
291
发表于 2023-7-31 16:50:55 | 显示全部楼层
厉害

不知道把这部分代码放到内部RAM去运行效果会不会好一点
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-7-31 19:03:16 | 显示全部楼层
tovinz 发表于 2023-7-31 16:50
厉害

不知道把这部分代码放到内部RAM去运行效果会不会好一点

理论上可行,我还没试过,但我觉得最稳妥最安全的做法,依然是通过DMA传输标志位来确定传输是否完成,缺点是实时性降低,而且对数据有了长度限制,网上看到过很多用串口空闲+DMA进行接收的例子,不知道他们有没有处理过类似问题
回复

使用道具 举报

19

主题

234

回帖

291

积分

高级会员

积分
291
发表于 2023-7-31 19:28:54 | 显示全部楼层
jyklll 发表于 2023-7-31 19:03
理论上可行,我还没试过,但我觉得最稳妥最安全的做法,依然是通过DMA传输标志位来确定传输是否完成,缺 ...

为什么说会降低实时性呢,感觉等待DMA传输完成也不会耗时太久吧,不过看你250us的包周期确实已经很快了。
包长问题多多少少会存在,毕竟要事先准备一个确定大小的缓冲区给DMA。要是接收的包过长可以把DMA的传输完成中断打开处理一下溢出就行了吧。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
 楼主| 发表于 2023-8-1 19:02:27 | 显示全部楼层
tovinz 发表于 2023-7-31 19:28
为什么说会降低实时性呢,感觉等待DMA传输完成也不会耗时太久吧,不过看你250us的包周期确实已经很快了。 ...

我也是新手,了解的还不多哈~~有时可能会遇到从机突然断线停止通讯的情况,为了防止无限等待DMA标志位,还要做个超时处理,我觉得这或多或少会降低一点实时性吧
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-5-2 22:43 , Processed in 0.272753 second(s), 29 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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