[方案相关] 【华大测评】为HC32F460外部Flash制作FLM

[复制链接]
6198|16
 楼主| 纪国圣 发表于 2021-12-5 16:05 | 显示全部楼层 |阅读模式
HC32F460开发板自带了一颗8M的FLASH:W25Q64,这么大的FLASH不装点什么感觉有点浪费,但是要装满的话需要单独写一个程序,这在实际开发中失衡麻烦的一件事。于是最近抽空做了一个FLM,分享给大家。大家也可以根据自己的需要自己写一个。
首先从keil安装目录下拷贝一份FLM模板工程:
1.PNG
再搜寻FlashOS.h,添加到模板工程中:
2.PNG
选择型号HC32F460PETB:
3.PNG
如图设置FlashDevice:
4.PNG
从官方例程中拷贝W25Qxx驱动至模板工程中:
5.PNG
再将相关文件如QSPI、CLK设置文件等拷贝至模板工程中:
6.PNG
如图设置Options:
7.PNG
添加相关文件至模板工程中:
8.PNG
按FlashPrg文件添加初始化,擦除与写函数:
9.PNG
编译生成FLM文件:
10.PNG
修改文件名并拷贝至keil/ARM/Flash中:
11.PNG
加载FLM文件。可以看到此时keil已识别FLM并可以加载了:
12.PNG
13.PNG
将IROM2设为W25Q64的地址:
14.PNG
编写一个大数组并设置地址为IROM2:
15.PNG
下载错误?看了一下是RAM for Algorithm设置小了:
16.PNG
增大RAM for Algorithm:
17.PNG
重新编译下载,可以通过Memory看到data常量成功写入:
18.PNG
19.PNG
最后说一下,W25Q64的驱动设置必须按如下设置,如果直接使用官方的配置,会发现写入的数据有误:
20.PNG
工程文件如下:
_Template.zip (98.62 KB, 下载次数: 69)
HC32F460_QSPI.zip (4.35 MB, 下载次数: 79)
HC32F460_QSPI_Download.zip (2.9 MB, 下载次数: 85)
HC32F460_W25Qxx.zip (247.96 KB, 下载次数: 77)

weifeng90 发表于 2021-12-5 17:44 来自手机 | 显示全部楼层
这个不错,学习了。
chenjun89 发表于 2021-12-5 19:17 来自手机 | 显示全部楼层
不错,谢谢楼主分享经验。
WoodData 发表于 2021-12-6 09:40 | 显示全部楼层

不错,谢谢楼主分享经验。
cyclefly 发表于 2021-12-6 17:56 | 显示全部楼层
棒~~很不错啊
ddxx 发表于 2021-12-7 08:32 | 显示全部楼层
这个很好,谢谢了。
数码小叶 发表于 2021-12-8 14:26 | 显示全部楼层
不错,谢谢楼主分享经验。
andygirl 发表于 2021-12-8 16:21 | 显示全部楼层
厉害厉害,非常敬业
skyred 发表于 2022-1-19 15:55 | 显示全部楼层
了不起,感谢楼主的讲解
jheng 发表于 2022-7-19 17:18 | 显示全部楼层
if (memcmp(data, pFlashReadAddr, (uint32_t)bufferLen) != 0)
一次性比较27421个字节可以比较吗?为啥还要4k一次处理
 楼主| 纪国圣 发表于 2022-7-19 17:42 | 显示全部楼层
jheng 发表于 2022-7-19 17:18
if (memcmp(data, pFlashReadAddr, (uint32_t)bufferLen) != 0)
一次性比较27421个字节可以比较吗?为啥还 ...

这样写的原因是如果有错误可以确定出错的位置,同时如果一次性检查那么多字节,内存不一定够用,最后你还要考虑程序的可移植。
jheng 发表于 2022-7-20 09:57 | 显示全部楼层
纪国圣 发表于 2022-7-19 17:42
这样写的原因是如果有错误可以确定出错的位置,同时如果一次性检查那么多字节,内存不一定够用,最后你还 ...

我的意思是程序看着是一次性比较的,bufferlen并不是4k
jheng 发表于 2022-7-20 10:59 | 显示全部楼层
9376162d76f5ded941.png
没有设置断点,但是报这个错误
towp007 发表于 2022-7-21 23:08 | 显示全部楼层
烧录的时候需要把校验去掉才不报错误,也无法仿真查看烧录对没有,希望楼主能够再讲清楚一些。

1.我使用2线的QSPI在外面把驱动测试 能够使用,烧录的时候那0x20000 设置不了这么大,不超过65536.
 楼主| 纪国圣 发表于 2022-7-23 09:32 | 显示全部楼层
本帖最后由 纪国圣 于 2022-7-23 09:49 编辑
jheng 发表于 2022-7-20 09:57
我的意思是程序看着是一次性比较的,bufferlen并不是4k

重温了一遍程序,你指出的部分确实有点问题,从通用性考虑应该4K一比较,并且在flashAddr += FLASH_SECTOR_SIZE;后面加上一个指向data[]数组的指针偏移。这样比较好。这里偷了个懒,先获取外部FLASH存储位置的指针,然后与data直接比较,这在大数据量下容易出问题。容易误解的地方是
  1. flashAddr += FLASH_SECTOR_SIZE;
  2.             if (flashAddr >= FLASH_MAX_ADDR)
  3.             {
  4.                 flashAddr = 0u;
  5.             }
其实在这个测试程序中是没必要的,当时移植没删掉,给大家造成误解,抱歉。
感谢指出错误。
 楼主| 纪国圣 发表于 2022-7-23 09:34 | 显示全部楼层
jheng 发表于 2022-7-20 10:59
没有设置断点,但是报这个错误

我这边没有重现这个错误,所以没办法提出有效的建议。我这边是用的是V5.31版本。可以换个版本试试。
 楼主| 纪国圣 发表于 2022-7-23 10:05 | 显示全部楼层
本帖最后由 纪国圣 于 2022-7-23 10:17 编辑
towp007 发表于 2022-7-21 23:08
烧录的时候需要把校验去掉才不报错误,也无法仿真查看烧录对没有,希望楼主能够再讲清楚一些。

1.我使用2 ...

烧录的时候那0x20000 设置不了这么大?工程其他地方有没有修改?至于烧录后是否正确,写一个比较函数,如:
  1. const uint8_t data[] = {数据};
  2. uint32_t flashAddr = 0u;
  3. uint8_t *pDataAddr = data;
  4. uint8_t *pFlashReadAddr = (uint8_t *)((uint32_t)QSPI_BUS_ADDRESS);
  5. uint32_t i = 0;
  6. for (i = 0;i < 最大的sector;i++)
  7. {
  8.         pFlashReadAddr = (uint8_t *)((uint32_t)QSPI_BUS_ADDRESS + flashAddr);
  9.         /* Compare txBuffer and flash */
  10.         if (memcmp(pDataAddr, pFlashReadAddr, FLASH_SECTOR_SIZE) != 0)
  11.         {
  12.                 失败
  13.         }
  14.         else
  15.         {
  16.                 成功
  17.         }
  18.        
  19.         flashAddr += FLASH_SECTOR_SIZE;
  20.         pDataAddr+= FLASH_SECTOR_SIZE;
  21. }



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

本版积分规则

77

主题

407

帖子

5

粉丝
快速回复 在线客服 返回列表 返回顶部