基于Keil生成外部Nor Flash下载算法,并使用J-Flash直接烧录(以W25Q64为例)

这篇具有很好参考价值的文章主要介绍了基于Keil生成外部Nor Flash下载算法,并使用J-Flash直接烧录(以W25Q64为例)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

需要的软件:
Keil
STM32CubeMX
J-Flash

参考文档:
方法1:在Keil中点击Help→uVision Help,然后再搜索框中输入FLM,点击列出主题,可以看到生成下载算法的大致步骤:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash

方法2:在ARM Keil官网,搜索KAN333,可以找到生成算法说明的PDF文档以及例程源码。链接
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash

方法3:在Keil安装路径下Keil_v5\ARM\Flash_Template,找到Abstract.txt,打开后有一个生成算法说明的文档。链接
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
先说一下大致原理,生成的算法文件也就是FLM文件,实际上会先下载进你板子的RAM中,然后在板子的RAM中运行,进而去写外部Nor Flash或者片内Flash。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
参考上面任意一个说明文档都可以,但是不要完全按照上面描述的来,我之前是按照第二个方法下载的pdf来的,但是折腾了两天才有结果,下面是具体实现的方法。

1.复制Keil安装路径下Keil_v5\ARM\Flash_Template文件夹,并重命名为自己的算法工程名,我这以STM32L4xx_W25Q64为例。
2.将文件夹的只读属性取消,并将keil工程的名字改为自己的工程名。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
3.打开工程,选择魔术棒,在Device一栏中选择自己板子上对应的MCU,在Target一栏中ARM Compiler保持默认V5就好,不用像PDF中描述的一样改成V6的,两个版本用的编译方法不一样,V6版本的生成的FLM文件小一点,但是好像没办法使用MicroLIB,会报错。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
在Output一栏中改为自己工程的名字
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
User一栏中不要动,cmd.exe /C copy “Objects%L” ".@L.FLM"在工程编译后会执行。
C/C++和Asm中确认Read-Only Position Independent和Read-Write Position Independent勾选,表明这个是与位置无关的算法,因为要放在RAM中执行。C/C++一栏中Define中对应填入需要的宏,代码量不大的话编译器优化等级可以设置为0,后边会提到代码量具体有什么限制。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
Linker一栏中使用自定义分散加载文件,保持默认就好。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
4.打开Manage Run-Time Environment,勾选如下内容,并点击绿色按钮,启动STM32CubeMX。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
5.在STM32CubeMX中配置工程,先配置为自己需要的时钟频率,不要像PDF中一样保持默认,不然的话时钟频率只有4M。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
然后配置好SPI,GPIO等,如果有需要的话也可以配置一下串口用于输出Log,我是配置了两个LED灯,一个用于指示擦除,一个用于指示编写。
在Project Manager中,Project一栏中不用像PDF中描述的勾选Do not generate the main(),这样会生成main函数,可以用于测试生成的代码是否可用,不用自己写。
Code Generator一栏中按如下勾选:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
Advanced Settings一栏保持函数调用。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
然后点击Generate Code生成代码。

6.在STM32L4xx_W25Q64\RTE\Device\STM32L431CCTx\STCubeGenerated\MDK-ARM路径下,打开生成的的工程,然后可以在里面测试一下生成的工程,添加一下自己的读写外部Nor Flash的代码,能正常操作就行。

7.回到生成算法的工程里面,把main.c中的main函数屏蔽掉,否则在生成算法文件的时候会报错。此外也不要像PDF中描述的重新定义HAL_InitTick(),HAL_Delay()等几个函数,因为使用HAL库的话用到的一些超时检测什么的都会有影响。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash

8.在Device目录右键Options for Component Class ‘Device’,选择启动文件,取消勾选Include in target build。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
9.新建一个目录,添加自己操作外部Nor Flash的代码和System文件。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
10.实现FlashDev.c,这个是设备描述文件,改为自己合适的就好。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
Device Type根据实际设置。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
Device Start Address可以直接从0x00000000开始,这样就不用在FlashPrg.c中额外处理地址。

Programming Page Size根据自己的外部Nor Flash设置,比如W25Q64每页256字节,设置为256的话一个扇区就需要多次调用ProgramPage()函数,所以可以直接设置成一个扇区大小(4096),这样调用ProgramPage()函数的时候直接写一个扇区。

Specify Size and Address of Sectors指的是扇区划分,比如有的MCU有不同大小的扇区,第一个参数就是扇区大小,第二个参数就是扇区起始地址;比如W25Q64,每个扇区都是16个页,每个页256字节,所以第一个参数就是0x001000(4096),第二个表示从0地址开始,如果有其他的扇区大小类型,在SECTOR_END之前添加。

Erase Sector Timeout为擦除超时时间,全片擦除也受这个参数影响,W25Q64全片擦除需要14s左右,所以适当设置大一点。

10.实现FlashPrg.c,必须要实现的函数是Init,UnInit,EraseChip,EraseSector,ProgramPage。可根据需要实现的函数Verify,BlankCheck。

Init函数需要初始化时钟,GPIO,SPI等,正确执行返回0,执行错误返回1。不要像PDF中一样关中断,因为需要用到滴答定时器中断。

int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
  int ret = 0;
  volatile int i;
  volatile unsigned char * ptr = (volatile unsigned char * )&hspi2;

  for (i = 0; i < sizeof(hspi2); i++) {
    *ptr++ = 0U;
  }
  SystemInit();
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_InitLed();
  if(W25Q64_Init() != W25Q64_ID)
  {
	ret = 1;
  }
  return (ret);                                  // Finished without Errors
}

UnInit函数可以什么都不做,因为我在擦除和写的时候翻转LED,所以添加了关LED操作。

int UnInit (unsigned long fnc) {

  HAL_GPIO_WritePin(Prog_Led_GPIO_Port,Prog_Led_Pin,GPIO_PIN_RESET);
  HAL_GPIO_WritePin(Erase_Led_GPIO_Port,Erase_Led_Pin,GPIO_PIN_RESET);
  return (0);                                  // Finished without Errors
}

擦除分为全片擦除和擦除扇区,流程图如下:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
EraseChip函数直接调用自己的全片擦除函数。

int EraseChip (void) {
	
  HAL_GPIO_TogglePin(Erase_Led_GPIO_Port,Erase_Led_Pin);
  W25Q64_Erase_Chip();
  return (0);                                  // Finished without Errors
}

EraseSector 函数直接调用自己的擦除扇区函数。

int EraseSector (unsigned long adr) {
	
  HAL_GPIO_TogglePin(Erase_Led_GPIO_Port,Erase_Led_Pin);
  W25Q64_Erase_Sector((uint32_t)adr);
  return (0);                                  // Finished without Errors
}

ProgramPage函数直接调用自己的写扇区函数。要写的大小跟FlashDev.c中的Programming Page Size大小一致。写Flash流程图如下:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash

int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {

  HAL_GPIO_TogglePin(Prog_Led_GPIO_Port,Prog_Led_Pin);
//	W25Q64_Write_Page(buf,(uint32_t)adr,(uint16_t)sz);
  W25Q64_Write_Sector(buf,(uint32_t)adr,(uint16_t)sz);
  return (0);                                  // Finished without Errors
}

Verify和BlankCheck函数可以不实现。
Verify函数作用是判断写成功了多少字节数据,这个值跟FlashDev.c中Device Start Address值有关,如果Device Start Address值不为0,那么就是Device Start Address加上写成功了多少字节。校验函数流程图:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash

unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf) {
  uint32_t i;
  W25Q64_ReadData(W25Q64_BufferA,(uint32_t)adr,(uint16_t)sz);
  for (i = 0; i < sz; i++) 
  {
	if (W25Q64_BufferA[i] != buf[i]) 
	{
	  return (adr + i); 
	}
  }
  return (adr + sz); 
}

BlankCheck函数作用是在擦除块的时候判断一下这个块需不需要擦除,实际上就是比较块内的值是不是都是FlashDev.c中定义的Initial Content of Erased Memory值一样,如果有一个字节不是,说明块需要擦除。

int BlankCheck (unsigned long adr, unsigned long sz, unsigned char pat) {
  uint32_t i, j;
  uint32_t read_len = 0;
  if((adr + sz) > W25Q64_TOTAL_NUM)
  {
	return (1);
  }
  for (i = 0; i < sz; i += W25Q64_SECTOR_NUM) 
  {
	if(sz >= W25Q64_SECTOR_NUM)
	{
		read_len = W25Q64_SECTOR_NUM;
	}
	else
	{
		read_len = sz;
	}
	W25Q64_ReadData(W25Q64_BufferA,(adr+i),read_len);
	for(j = 0; j < read_len; j++)
	{
	  if (W25Q64_BufferA[j] != pat) 
	    return (1);
	}
	sz -= read_len;
  }
  return (0);                           // Memory is blank
}

然后编译之后就会生成下载算法文件FLM。注意不要添加太多没用的调试代码,否则会导致生成的代码量太大,就不得不提高优化等级,还可能导致生成的算法文件使用时报错。可以在编译之后通过map文件确认一下代码占用的空间,不能超过RAM的大小,因为算法是需要在RAM中运行的。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
如果算法代码量太大,可能会导致报错RAM area configured for this target is too small.
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash

11.将生成的下载算法文件复制到Keil_v5\ARM\Flash路径下,就可以在KEIL中看到。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
12.在J-link安装目录下SEGGER\JLink_V640\Devices中新建一个文件夹,比如命名为W25Qxx,然后把下载算法文件复制过来。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
13.在SEGGER\JLink_V640路径下打开JLinkDevices文件,在末尾添加如下内容。

  <!--         -->
  <!-- W25QXX  -->
  <!--         -->
<Device>
<ChipInfo Vendor="W25QXX" Name="STM32L4xx_W25Q64" Core="JLINK_CORE_CORTEX_M4" WorkRAMAddr="0x20000000" WorkRAMSize="0x0000C000"/>
<FlashBankInfo Name="SPI Flash" BaseAddr="0x00000000" MaxSize="0x00800000" Loader="Devices/W25Qxx/STM32L4xx_W25Q64.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" AlwaysPresent="1"/>
</Device>

WorkRAMAddr和WorkRAMSize就是自己MCU的RAM参数,BaseAddr和MaxSize设置的和FlashDev.c中一样。

之后就可以使用J-Flash直接把数据烧写进外部Nor Flash中。

测试:
使用J-Flash新建工程,选择下载算法文件。
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
全片擦除:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
擦除扇区:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
写入:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
Flash为空:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
Flash不为空:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash
写入并校验:
flash下载算法,单片机,STM32,C语言,单片机,stm32,Nor Flash文章来源地址https://www.toymoban.com/news/detail-549992.html

到了这里,关于基于Keil生成外部Nor Flash下载算法,并使用J-Flash直接烧录(以W25Q64为例)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【FLASH存储器系列五】SPI NOR FLASH芯片使用指导之一

    👉个人主页: highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容   目录 1芯片简介 2引脚定义 3功能框图 4器件操作 4.1操作框图 4.2标准SPI 4.3DaulSPI 4.4QaudSPI 4.5QPI 4.6DTR(W25Q128不支持) 4.73-字节/4-字节地址模式(W25Q128只支持3字节) 4.8保持

    2023年04月19日
    浏览(45)
  • 解决keil-5中stm32f103系列使用ST-Link下载程序时不能连接的问题。“flash download failed ”

    出现的问题如下: 解决方法如下: 因为新版的Keil 加入了下载器的校验机制,所以我们需要替换掉新版编译器下的原文件 需要这个文件的评论下方留言记得留言哦。 一、解压后得到 STlink 文件夹,整个文件夹替换到 软件安装目录下 /ARM 处即可 二、更新下载器固件(更新一次

    2024年02月12日
    浏览(81)
  • STM32CubeMX学习笔记(48)——USB接口使用(MSC基于外部Flash模拟U盘)

    USB(Universal Serial BUS)通用串行总线 ,是一个外部总线标准,用于规范电脑与外部设备的连接和通讯。是应用在 PC 领域的接口技术。USB 接口支持设备的即插即用和热插拔功能。USB 是在 1994 年底由英特尔、康柏、IBM、Microsoft 等多家公司联合提出的。 USB 发展到现在已经有 US

    2024年01月16日
    浏览(48)
  • Nor Flash和Nand Flash的区别——笔记

    NorFlash: 串行存储器、读取速度比较快(比NandFlash快),适合用于存储程序代码和执行代码,但NorFlash写入速度比较慢、容量比较小。 数据线和地址线是分开的。 NandFlash: 并行存储器、写入速度比较快(比NorFlash快)、容量比较大,适合用于存储大量数据。但NandFlash读取速度

    2024年02月08日
    浏览(32)
  • SPI 及 NOR Flash 介绍

    1.SPI的含义 SPI:串行外设设备接口(Serial Peripheral Interface),是一种高速的,全双工,同步的通信总线。SPI接口主要应用在存储芯片、AD转换器以及LCD中。SPI接口主要应用在存储芯片、AD转换器以及LCD中。 SPI 的引脚信息: MISO(Master In / Slave Out)主设备数据输入,从设备数据

    2024年02月12日
    浏览(35)
  • STM32 NOR_FLASH 学习

    FLASH是常用的,用于存储数据的半导体器件,它具有容量大,可重复擦写、按“扇区/块”擦除、掉电后数据可继续保存的特性。 NOR FLASH的单位是MB,EEPROM的单位是KB。 NM25Q128,是NOR FLASH的一种,是诺存公司生产的一种SPI FLASH,具有SPI接口。相似的还有W25Q128、BY25Q128,这三者都

    2024年02月07日
    浏览(29)
  • 关于解决keil5在仿真器下载时出现error: flash download failed - “Cortex-M3”的问题

    这个问题搞得我到凌晨03:00左右才睡,必须的记一下,避免以后又忘了。    出现这种情况也是一般在被下载到不同flash型号的芯片才会有的(我第一次下载到STM32F103VET6上没问题,但是换成STM32F103RBT6时就出现这问题了),正常添加步骤是这样的, 图1 添加芯片flash步骤    但

    2024年02月16日
    浏览(142)
  • 【FLASH存储器系列四】NAND和NOR两种Flash的本质区别是什么?

    👉个人主页: highman110 👉作者简介:一名硬件工程师,持续学习,不断记录,保持思考,输出干货内容 目录 1 Nand 和Nor的区别 2 从存储原理上分析这些区别的原因         1、为什么nor flash的读取速度比nand flash要稍快?         2、为什么nand flash的容量比nor flash更大?

    2024年02月20日
    浏览(44)
  • EEPROM,NOR Flash,NAND Flash,eMMC,UFS,SSD分别和主要参数及特性

    EEPROM、NOR Flash、NAND Flash、eMMC、UFS、SSD都是非易失性存储器,但它们在架构、存储容量、读写速度、功耗、价格等方面存在不同,具体如下: EEPROM:EEPROM(Electrically Erasable Programmable Read-Only Memory)是一种用于存储非易失性数据的闪存存储器。它比 NOR Flash和 NAND Flash容量小、价

    2024年02月16日
    浏览(43)
  • stm32基于HAL库驱动外部SPI flash制作虚拟U盘

    📌参考文章: https://xiaozhuanlan.com/topic/6058234791 🎞实现效果演示: 🔖上图中的读到的 FLASH_ID 所指的是针对不同容量,所对应的ID。 🔖在电脑端,支持对虚拟出来的存储器进行读写操作。 ✨如果设计成一块PCB,可以制作成一个微小容量的移动U盘。 🌿基于STM32F103,HAL库生成

    2024年02月11日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包