第47章 STM32F429的SPI 总线应用之SPI Flash的MDK下载算法制作

发布者:Aningmeng最新更新时间:2022-04-21 来源: eefocus关键字:STM32F429  SPI  总线  Flash  MDK 手机看文章 扫描二维码
随时随地手机看文章

47.1 初学者重要提示

  SPI Flash的相关知识点可以看第31章和32章。

  SPI Flash下载算法文件直接采用HAL库制作,方便大家自己修改。

47.2 MDK下载算法基础知识

Flash编程算法是一种用于擦除应用程序或将应用程序下载到Flash的程序代码。MDK本身支持的各种器件都自带下载算法,存放在MDK各种器件的软件包里面,以STM32F4为例,算法存放在KeilSTM32F4xx_DFP2.15.0CMSISFlash(软件包版本不同,数值2.15.0不同),但不支持的需要我们自己制作,本章教程为此而生。


47.2.1 程序能够通过下载算法下载到芯片的核心思想

认识到这点很重要:通过MDK创建一批与地址信息无关的函数,实现的功能主要有初始化,擦除,编程,读取,校验等,然后MDK调试下载阶段,会将算法文件加载到芯片的内部RAM里面(加载地址可以通过MDK设置),然后MDK通过与这个算法文件的交互,实现程序下载,调试阶段数据读取等操作。


47.2.2 算法程序中擦除操作执行流程

擦除操作大致流程:

  加载算法到芯片RAM。

  执行初始化函数Init。

  执行擦除操作,根据用户的MDK配置,这里可以选择整个芯片擦除或者扇区擦除。

  执行Uinit函数。

  操作完毕。

47.2.3 算法程序中编程操作执行流程

编程操作大致流程:

  针对MDK生成的axf可执行文件做Init初始化,这个axf文件是指的大家自己创建应用程序生成的。

  查看Flash算法是否在FLM文件。如果没有在,操作失败。如果在:

  加载算法到RAM。

  执行Init函数。

  加载用户到RAM缓冲。

  执行Program Page页编程函数。

  执行Uninit函数。

  操作完毕。

47.2.4 算法程序中校验操作执行流程

校验操作大致流程:

  校验要用到MDK生成的axf可执行文件。校验就是axf文件中下载到芯片的程序和实际下载的程序读出来做比较。

  查看Flash算法是否在FLM文件。如果没有在,操作失败。如果在:

  加载算法到RAM。

  执行Init函数。

  查看校验算法是否存在

  如果有,加载应用程序到RAM并执行校验。

  如果没有,计算CRC,将芯片中读取出来的数据和RAM中加载应用计算输出的CRC值做比较。

  执行Uninit函数。

  替换BKPT(BreakPoint断点指令)为 B. 死循环指令。

  执行RecoverySupportStop,恢复支持停止。

  执行DebugCoreStop,调试内核停止。

  运行应用:

  执行失败。

  执行成功,再执行硬件复位。

  操作完毕,停止调试端口。

47.3 创建MDK下载算法通用流程

下面是MDK给的一种大致操作流程,不限制必须采用这种方法,自己创建也可以的。


47.3.1 第1步,使用MDK提供好的程序模板

位于路径:KeilARMPackARMCMSISversionDevice_Template_Flash。


效果如下:

47.3.2 第2步,修改工程名

MDK提供的工程模板原始名字是NewDevice.uvprojx,大家可以根据自己的需要做修改。比如修改为MyDevice.uvprojx。


47.3.3 第3步,修改使用的器件

在MDK的Option选项里面设置使用的器件。

47.3.4 第4步,修改输出算法文件的名字

这个名字是方便用户查看的,比如设置为stm32h7,那么输出的算法文件就是stm32h7.flm。


注:MDK这里设置的名字与下面位置识别出来的算法名无关:

这个名字是在FlashDev.c里面定义的。


47.3.5 第5步,修改编程算法文件FlashPrg.c

模板工程里面仅提供了接口函数,内容需要用户自己填。


/* 

   Mandatory Flash Programming Functions (Called by FlashOS):

                int Init        (unsigned long adr,   // Initialize Flash

                                 unsigned long clk,

                                 unsigned long fnc);

                int UnInit      (unsigned long fnc);  // De-initialize Flash

                int EraseSector (unsigned long adr);  // Erase Sector Function

                int ProgramPage (unsigned long adr,   // Program Page Function

                                 unsigned long sz,

                                 unsigned char *buf);


   Optional  Flash Programming Functions (Called by FlashOS):

                int BlankCheck  (unsigned long adr,   // Blank Check

                                 unsigned long sz,

                                 unsigned char pat);

                int EraseChip   (void);               // Erase complete Device

      unsigned long Verify      (unsigned long adr,   // Verify Function

                                 unsigned long sz,

                                 unsigned char *buf);


       - BlanckCheck  is necessary if Flash space is not mapped into CPU memory space

       - Verify       is necessary if Flash space is not mapped into CPU memory space

       - if EraseChip is not provided than EraseSector for all sectors is called

*/


/*

 *  Initialize Flash Programming Functions

 *    Parameter:      adr:  Device Base Address

 *                    clk:  Clock Frequency (Hz)

 *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)

 *    Return Value:   0 - OK,  1 - Failed

 */


int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {


  /* Add your Code */

  return (0);                                  // Finished without Errors

}



/*

 *  De-Initialize Flash Programming Functions

 *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)

 *    Return Value:   0 - OK,  1 - Failed

 */


int UnInit (unsigned long fnc) {


  /* Add your Code */

  return (0);                                  // Finished without Errors

}



/*

 *  Erase complete Flash Memory

 *    Return Value:   0 - OK,  1 - Failed

 */


int EraseChip (void) {


  /* Add your Code */

  return (0);                                  // Finished without Errors

}



/*

 *  Erase Sector in Flash Memory

 *    Parameter:      adr:  Sector Address

 *    Return Value:   0 - OK,  1 - Failed

 */


int EraseSector (unsigned long adr) {


  /* Add your Code */

  return (0);                                  // Finished without Errors

}



/*

 *  Program Page in Flash Memory

 *    Parameter:      adr:  Page Start Address

 *                    sz:   Page Size

 *                    buf:  Page Data

 *    Return Value:   0 - OK,  1 - Failed

 */


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


  /* Add your Code */

  return (0);                                  // Finished without Errors

}

47.3.6 第6步,修改配置文件FlashDev.c

模板工程里面提供简单的配置说明:


struct FlashDevice const FlashDevice  =  {

   FLASH_DRV_VERS,             // Driver Version, do not modify!

   "New Device 256kB Flash",   // Device Name 

   ONCHIP,                     // Device Type

   0x00000000,                 // Device Start Address

   0x00040000,                 // Device Size in Bytes (256kB)

   1024,                       // Programming Page Size

   0,                          // Reserved, must be 0

   0xFF,                       // Initial Content of Erased Memory

   100,                        // Program Page Timeout 100 mSec

   3000,                       // Erase Sector Timeout 3000 mSec


// Specify Size and Address of Sectors

   0x002000, 0x000000,         // Sector Size  8kB (8 Sectors)

   0x010000, 0x010000,         // Sector Size 64kB (2 Sectors) 

   0x002000, 0x030000,         // Sector Size  8kB (8 Sectors)

   SECTOR_END

};

注:名字New Device 256kB Flash就是我们第4步所说的。MDK的Option选项里面会识别出这个名字。


47.3.7 第7步,保证生成的算法文件中RO和RW段的独立性,即与地址无关

C和汇编的配置都勾选上:

汇编:


如果程序的所有只读段都与位置无关,则该程序为只读位置无关(ROPI, Read-only position independence)。ROPI段通常是位置无关代码(PIC,position-independent code),但可以是只读数据,也可以是PIC和只读数据的组合。选择“ ROPI”选项,可以避免用户不得不将代码加载到内存中的特定位置。这对于以下例程特别有用:


(1)加载以响应运行事件。


(2)在不同情况下使用其他例程的不同组合加载到内存中。


(3)在执行期间映射到不同的地址。


 


使用Read-Write position independence同理,表示的可读可写数据段。


47.3.8 第8步,将程序可执行文件axf修改为flm格式

通过下面的命令就可以将生成的axf可执行文件修改为flm。

47.3.9 第9步,分散加载设置

我们这里的分散加载文件直接使用MDK模板工程里提供好的即可,无需任何修改。

分散加载文件中的内容如下:


; Linker Control File (scatter-loading)

;


PRG 0 PI               ; Programming Functions

{

  PrgCode +0           ; Code

  {

    * (+RO)

  }

  PrgData +0           ; Data

  {

    * (+RW,+ZI)

  }

}


DSCR +0                ; Device Description

{

  DevDscr +0

  {

    FlashDev.o

  }

}

--diag_suppress L6305用于屏蔽L6503类型警告信息。


特别注意,设置了分散加载后,此处的配置就不再起作用了:


47.4 SPI Flash的MDK下载算法制作

下面将QSPI Flash算法制作过程中的几个关键点为大家做个说明。


47.4.1 第1步,制作前重要提示

这两点非常重要:


  程序里面不要开启任何中断,全部查询方式。

  HAL库里面各种时间基准相关的API全部处理掉。简单省事些,我们这里是直接注释,采用死等即可。无需做超时等待,因为超时后,已经意味着操作失败了,跟死等没有区别。

47.4.2 第2步,准备一个工程模板

 推荐大家直接使用我们本章工程准备好的模板即可,如果大家自己制作,注意一点,请使用当前最新的HAL库。


47.4.3 第3步,修改HAL库

大家可以更新需要修改以下三个文件(当前配套程序未做修改):

47.4.4 第4步,时钟初始化

我们已经用不到滴答定时器了,直接在bsp.c文件里面对滴答初始化函数做重定向:


/*

*********************************************************************************************************

[1] [2] [3]
关键字:STM32F429  SPI  总线  Flash  MDK 引用地址:第47章 STM32F429的SPI 总线应用之SPI Flash的MDK下载算法制作

上一篇:第48章 STM32F429的内部Flash和SPI Flash都使用MDK下载
下一篇:第46章 STM32F429的DMA2D应用之刷色块,位图和Alpha混合

推荐阅读最新更新时间:2024-02-22 12:48

C8051F330 Flash访问单元
简介:最近写的一个小程序,贡献给大家参考。C8051F330 Flash访问单元。 头文件自己搞吧,不贴了,写Flash时候记得先要擦除。 代码如下 /* 02 ================================================================================ 03 File Name : Flash.c 04 Description : C8051F330 Flash操作单元 06 Version : V1.0 11 ================================================================
[单片机]
PIC单片机与串行闪存的SPI接口设计
(冀科双实科技有限公司,石家庄 050081) 引 言 PIC单片机以性能稳定、品种众多等特点在工业控制、仪器仪表、家电、通信等领域得到广泛应用。虽然很多型号自身集成了存储器,但在很多情况下难以满足系统对大容量存储的要求,需要外扩非易失性的存储器。与并行Flash存储器相比,串行Flash存储器占用MCU引脚少,体积小,易于扩展,接线简单,工作可靠,故而越来越多地应用在各类电子产品和工业测控系统中。本文主要讨论PIC16F877A单片机与串行闪存M25P16之间的SPI通信,在要求大容量数据存储且MCU引脚资源有限的情况下具有实用价值。 1 SPI工作原理 SPI(Serial Periphe
[网络通信]
PIC单片机与串行闪存的<font color='red'>SPI</font>接口设计
在P87LPC764单片机I2C总线系统中扩展LCD显示器
1 引言    I2C总线是Philips公司推出的芯片间串行传输总线。它仅用串行数据线(SDA)和串行时钟线(SCL)两根连线便实现了完善的全双工同步数据传送,并可很方便地构成多机系统和外围器件扩展系统。    本文介绍在P87LPC764单片机中利用I2C总线系统中典型的LCD驱动控制器件PCF8577C来扩展256段静态LCD的电路设计方法。 2 硬件电路设计 2.1 P87LPC764单片机的I2C总线接口    P87LPC764是Philips公司生产的一种小封装、低成本、高性能的单片机(具体内容见参考文献2)。它采用80C51加速处理器结构,片内带有支持I2C总线的硬件接口。当激活I2C总线时,P87L
[单片机]
SD卡的SPI模式的初始化顺序
为了使SD卡初始化进入SPI模式,我们需要使用的命令有3个:CMD0,ACMD41,CMD55(使用ACMD类的指令前应先发CMD55,CMD55起到一个切换到ACMD类命令的作用)。 为什么在使用CMD0以后不使用CMD1?CMD1是MMC卡使用的指令,虽然本文并不想讨论MMC卡的问题,但是我还是要说:为了实现兼容性,上电或者发送CMD0后,应该首先发送CMD55+ACMD41确认是否有回应,如果有回应则为SD卡,如果等回应超时,则可能是MMC卡,再发CMD1确认。 正确的回应内容应该是: CMD0 0x01(SD卡处于in-idle-state) CMD55 0x01(SD卡处于in-idle-state) AC
[单片机]
S3C2440从NAND Flash启动和NOR FLASH启动的问题
1.为什么NAND FLASH不能直接运行程序     NAND FLASH本身是连接到了控制器上而不是系统总线上。CPU运行机制为:CPU启动后是要取指令执行的,如果是SROM、NOR FLASH 等之类的,CPU 通过地址线发个地址就可以取得指令并执行,NAND FLASH不行,因为NAND FLASH 是管脚复用,它有自己的一套时序,这样CPU无法取得可以执行的代码,也就不能初始化系统了。     NAND FLASH是顺序存取设备,不能够被随机访问,程序就不能够分支或跳转,这样你如何去设计程序。     U-BOOT 支持ARM、 PowerPC等多种架构的处理器,也支持Linux、NetBSD和VxWorks等多种操作系
[单片机]
S3C2440从NAND <font color='red'>Flash</font>启动和NOR <font color='red'>FLASH</font>启动的问题
基于CAN总线的电控自动离合器控制器的设计与实现
随着社会的发展, 人们对汽车的舒适性和安全性要求越来越高, 而手动档汽车因其繁重的选换档及离合器操作增加了驾驶难度。对于驾驶新手而言,又会产生坡道起步易熄火、油耗大、离合器磨损严重等问题 。自动档汽车虽然驾驶操作简单, 但其造价高,开发难度大。本文设计的电控自动离合器ACS(Automatic Clutch System) 是在手动变速箱基础上安装电控系统,取消离合踏板,实现自动离合。ACS 的优势十分明显:与手动挡相比,其驾驶操控更为简单, 具有加速快、驾驶舒适的特点; 与自动变速器汽车相比,ACS 具有造价便宜、维修方便、经济、省油。 1 系统功能 ACS 将现代电子控制技术用于控制干式摩擦离合器, 模拟优秀驾驶员的操纵动作和
[单片机]
基于CAN<font color='red'>总线</font>的电控自动离合器控制器的设计与实现
虚拟仪器的软硬件系统设计在现场总线中的应用
1、引言 PXI(PCI面向仪器的扩展)是一个新的模块化仪器平台,它能够提供高性能的测量,而价格并不十分昂贵。利用PXI模块化仪器,您可以充分享受开放式工业标准化PC技术所带来的低成本、简便易用性、灵活性及高性能等优点。PXI的核心技术是CompactPCI工业计算机体系结构、Microsoft Windows 软件及VXI的定时和触发功能。 2、电子测量仪器的发展 电子测量仪器发展至今,大体可分为四代:模拟仪器、数字化仪器、智能仪器和虚拟仪器。 第一代模拟仪器,这类仪器在某些实验室仍能看到,如指针式万用表、晶体管电压表等。 第二代数字化仪器,这类仪器目前相当普及,如数字电压表、数字频率计等。这类仪器将模拟信号的测量转
[测试测量]
虚拟仪器的软硬件系统设计在现场<font color='red'>总线</font>中的应用
CAN总线在机电一体化中的应用
0、引言 在传统的液压控制系统中,对系统的控制主要采用机械手段。而采用传统的机械方法控制液压系统,使得整个系统的体积增大,同时增加系统复杂度和维护难度。随着计算机技术、现场总线技术及人工智能等技术的发展,使越来越复杂的液压控制系统有良好的发展前景。基于以上特点,该试验台采用CAN总线技术实现实时控制,用于液压软管脉冲压力试验,对被试件施加脉冲压力以测试软管的寿命。 1、CAN接口电路的设计 CAN总线节点接口电路如图1所示。P89LPC932是单片封装的高性能、低功耗的带片内8KFlash的微控制器,其指令执行时间只需2到4个时钟周期,6倍于标准80C51器件。P 89LPC932内部主要集成了字节方式的
[单片机]
CAN<font color='red'>总线</font>在机电一体化中的应用

推荐帖子

C600编程中语句的优化案例
、if...else...语句的优化(一)1、源代码:if(sub(ltpg,LTP_GAIN_THR1)=0)//ltpgLTP_GAIN_THR1时进入,如果ltpgLTP_GAIN_THR1,则adapt=1{adapt=0;}else{if(sub(ltpg,LTP_GAIN_THR2)=0){adapt=1;}}else{adapt=2;}
Jacktang 微控制器 MCU
zigbee被锁了,有没有哪位高手知道解锁啊
zigbee被锁了,原先的程序还在正常执行,但现在下不进程序了zigbee被锁了,有没有哪位高手知道解锁啊zigbee是协议标准,谈不上什么被锁的问题,你应该是说MCU吧,解锁要看是什么型号。嗯,是说MCU,问题似乎找到了,应该是下载器的电平问题回复沙发chunyang的帖子
hytz845 RF/无线
新手请教,关于开发在WINCE上运行的程序
现在有个任务,在一个扫描仪上做个程序.扫描仪的系统为WINCE.NET,版本4.2我用VS.NET2005建了一个WINCE5.0的程序,部署时报错,发生了通常表示安装被损坏的错误.修复VS也没用.又建了一个PocketPC2003的程序,部署时扫描仪端报错.想请教,一般大家都用什么工具开发WINCE上的程序,VS2005就这么被放弃了吗?新手请教,关于开发在WINCE上运行的程序
zany.peng WindowsCE
请问如果30层的PCB,共有多厚?
来自EEWORLD合作群:armlinuxfpga嵌入0(49900581)请问如果30层的PCB,共有多厚?只有想不到,没有做不到啊,哈哈1个CM吧以后元件不用剪脚啦!估计板子上100uF以下的电容都不需要了随便用两层当电容就行做30层板,得用贴片啦。挖个洞,真正的嵌入式其实30层并不是每一层都是线路层,反而大部分都是接地层和屏蔽层我正在设计一种更强大的电路结构...两连是PCB,中间夹元件发明一种取代三极管就发了超级无敌多层引脚集成电路怎么焊
IC-若尘 PCB设计
Hercules TMS570培训学习分享
HerculesTMS570培训学习分享培训内容在附件HerculesTMS570培训学习分享学学!570比较新吧学习了谢谢分享
anvy178 微控制器 MCU
产生负电压——为什么需要在降压-升压电路中进行电平转换
问题:为什么需要电平转换?答案:反相降压-升压电路通常用于从正电压产生负电源电压。最重要的一步是确保正确产生负电压。但是,如果电源由主应用电路控制或监控,则可能还需要电平转换电路。该电路以地为基准,而反相降压-升压电源电路的GND引脚连接到所产生的负电压。简介反相降压-升压电路产生的负电压幅度可以高于或低于可用正电压的幅度。例如,从+12V可以生成-8V,甚至-14V。当使用具有反相降压-升压电路的开关稳压器IC时,系统可能需要设计通信引脚。如果确
okhxyyo 电源技术
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved