[开发资料] CW32L012实现外部flash下载算法

[复制链接]
30|1
Haizangwang 发表于 2025-10-9 12:02 | 显示全部楼层 |阅读模式
通过网盘分享的文件:cw32外部flash下载算法源码.zip

链接: https://pan.baidu.com/s/1-svjiviNAkuxRShuk0rNEg?pwd=CW32 提取码: CW32

文件说明
1._Template 为keil 的下载算法模板

2.cw32l012_exflash_down 为cw32平台下的实际测试工程源代码

3.cw32l012_w25qxx.FLM 为生成的FLM下载文件

Q:什么是外部flash 下载算法?
外部flash或者内置的片上flash,都是编译器通过调用写好的FLM文件来实现下载,单片机内部的安装pack包就会有(官方实现),外部flash的情况比较复杂,例如用的哪种flash,用的什么接口,都是不定的,没有办法写好一个通用的下载算法,这里也只是介绍一个通用的方法,实际需要按情况修改。

注意本例程的FLM文件信息如下

1.基于CW32L012

2.使用W25Q128作为外置flash

3.使用SPI3 资源,IO 分配为

SPI3_CS PA8

SPI3_SCK PA9

SPI3_MISO PA10

SPI3_MOSI PA11

4.额外使用了一个开关IO ,PA6 为打开外设的电源控制IO

5.本案例用的外部16mz晶振

Q:外部flash对单片机的性能有要求吗?
没有太大要求。下载算法是加载到RAM中的,对flash 没有要求,RAM通常4K或者以上就可以运行下载算法(当然你的代码要简洁)。例如你的RAM是4K 你的下载算法生成的代码空间就要小于4K,8K就小于8K。

Q:为什么需要外部flash算法?
外部flash算法是用来节省内部flash空间的,在一些应用中,图片数据,字模数据比较占用单片机内存空间,在内存小的单片机中,是存不下这些数据的,通过在一些设置和下载算法,可以将工程中的常量保存到外部flash。

Q:为什么不用其他方式对外部flash下载数据?
1.用文件系统方式。会增加复杂度,增加性能占用。对于性能低的单片机,需要快速传输的数据不适合再走文件系统的接口。

2.用其他方法直接下载数据,比如专门下载数据的工程,或者专门的编程器,这些方案是可以,但是一方面是下载就非常麻烦,另一方面是对于数据的绝对地址管理起来费劲。

下载算法实现需要准备:
1.官方单片机的库文件(或者准备一个工程模板)

2.对应的flash驱动文件

3.Keil对于下载算法编写的工程模板

具体步骤大致分为以下几步
1.复制keil官方下载算法工程,同时复制FlashOS.H文件到工程根目录,然后还需要去配置对应的单片机型号,添加CMSIS的核心文件,最后修改一下文件包含路径使其能编译。编译器最好用AC6,选择代码空间优化。

7326668e733c564b98.png

2572468e733c0c206a.png

6391168e733bcb6c2f.png


2454668e733b838516.png

395168e733b4a8db8.png

2.修改flashDev.C中的文件,使其符合实际应用需求

1491668e733af5e4ef.png

3.添加对应单片机的库文件并编译,注意:
a.因为下载算法生成的是与位置无关的代码,添加进去的所有文件,所有函数都会参与编译,因此只可以添加需要的文件,文件中有用不到的函数还需要屏蔽!!!

b.注意不需要启动文件!!!

1872568e733a92a9f9.png

▲这里只添加用的到的文件

8447968e733a2c94f1.png

▲这里大部分用不到的代码都屏蔽

4.添加对应型号的flash驱动,并能正常编译

3912568e7339de8846.png

▲Spi 底层外设初始化Nor flash 驱动函数

5.编写初始化my_main函数,初始化外设,并能正常编译

1362768e73397ab43c.png


9022568e7338ff3874.png

6.编写flashPrg.c文件,需要实现以下函数,有缺失的自行补齐。这一步是最关键的,最核心的。
http://a.int Init (unsigned long adr, unsigned long clk, unsigned long fnc)

1833968e7338be9481.png

http://b.int UnInit (unsigned long fnc)

7596868e7338847a47.png

http://c.int EraseChip (void)

4950668e733834d0f0.png

http://d.int EraseSector (unsigned long adr)

8400068e7337e8dff0.png

http://e.int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf)

2603668e733799f8b5.png

http://f.int BlankCheck (unsigned long adr,unsigned long sz,unsigned char pat)

8706468e733759f46c.png

g.unsigned long Verify(unsigned long adr,unsigned long sz,unsigned char *buf)

3208668e733719928a.png

对应为初始化、去初始化、全片擦除、扇区擦除、扇区写入、擦除检测、校验。

以上这些函数都要有,但函数内部有些可以不去实现。

正常编译到这一步就完成了。

7.配置编译文件输出路径
cmd.exe /C copy "Objects\%L" ".\@L.FLM"

cmd.exe /C copy ".\@L.FLM" "C:\user_app\keil5\ARM\Flash\@L.FLM"

注意:第二条的路径和keil安装路径有关,需要根据实际情况修改。

5847068e73367609d0.png

8.正常编译结果如下

4169268e733635aaeb.png

下载算法使用
1.添加下载算法

1493068e7335c7e172.png

2.配置下载算法所使用的RAM空间大小为实际RAM的大小

3873668e7335619936.png

3.将需要放到外部flash的资源独立一个c文件保存,并配置存储地址
例如下图测试文件,定义两个const类型的字符串,指定存储地址为0x9000000开始。

4347068e7335173483.png

4.编译查看是否分配到外置flash上
如下图,识别到一个16M的外置flash,已经使用了3.66%,实际数据是一些图片数据,一共有600K字节。

5683668e7334c51a8a.png

5.如何读取这个数据呢
和普通spi flash 一样,仍然要发送命令的方式来读取,只不过地址为显性的一个地址,也不需要人为去记。

例如下面这个测试程序

定义了两个const类型的数据,数据读取时,直接取地址符取出编译器分配的地址,然后减去一个基地址偏移0x90000000,然后得到的地址就是实际nor flash 需要发送访问的地址

9643868e73346bd959.png

5483468e7334229ed0.png

6.实际测试串口打印验证
如下图的测试结果,地址就是我们要求的0x9000000开始的,数据读出来的也是实际存储的数据

8464568e7333d38f9a.png

————————————————
版权声明:本文为CSDN博主「CW32生态社区」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/2302_81038468/article/details/152278705

AdaMaYun 发表于 2025-10-10 13:26 | 显示全部楼层
非常详细的操作文档
您需要登录后才可以回帖 登录 | 注册

本版积分规则

85

主题

270

帖子

0

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