keil下载程序具体过程4:flash下载算法

这篇具有很好参考价值的文章主要介绍了keil下载程序具体过程4:flash下载算法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

引言

        本篇文章将介绍flash算法文件,阐述从jlink如何下载镜像文件写入到内部的falsh。

一、XIP

        在谈flash下载算法文件时,先说明XIP是什么。

        芯片的启动方式有很多种:可以从RAM中启动、内部的flash、外部的flash等等(还有从sd卡、emmc、nor flash、nand flash等),这里我们只考虑内部的flash的情况。
        我们都知道flash只是一块ROM,flash有两种类型,分为nor flash、nand flash,一般32位处理器里面使用的是nor flash作为ROM,存放镜像文件。

        在专业课(计算机组成原理或者操作系统)中,有提到,CPU从内存(RAM)中读取、运行程序。但在stm32这种微处理器上,一般都是直接从内部的flash启动。这牵扯到一个技术,叫做XIP(eXecute In Place ),即芯片内执行。其含义就是CPU直接从存储器读取指令,将指令送给译码器和执行器等部件使用。 有了XIP就不必将代码读取到RAM中,可以直接在flash运行。好处即是程序代码无需占用内存,减少内存的要求。XIP是复杂性和速度的权衡,而这就意味着XIP通常仅用于BIOS或RAM极度短缺(MCU的情况就是如此)的情况。

要实现XIP,必须要有如下几个条件:
1. 存储器必须提供与内存相似的接口给CPU。
2. 该接口必须提供足够快的读取操作,并具有随机访问模式。
3. 如有文件系统,则需要提供合适的映射功能
4. 程序链接时需要知道存储器的地址或地址与位置无关。
5. 程序不能修改已加载映像中的数据。

因为nor flash和EEPROM通常能满足上述要求,所以其可以XIP。 而nand flash因为有地址,数据,命令共用IO口的问题,cpu发送来地址之后,还要nand flahs控制器再处理一下才能得到数据,因此不适合(不是不能XIP,只是不适合)。nor flash的访问和RAM类似,提供地址,就可以得到数据。因此,一般处理器内部都是使用nor flash作为XIP的方案,而且,nor flash读取速度比nand flash要快很多。

        当bin文件经过JLink、SW-DP接口,经过AHB-DP将数据传到AHB总线上之后,已经具备可以写入到falsh里面的条件了。这里随便找了一个芯片内部图作为例子。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

        从上图中可以看到,FLASH上面有Controller接口、XIP接口、EEPROM仿真接口。Controller接口就是我们在平常使用程序往flash写入数据的控制部分(一般流程是:先解锁flash写保护、写入数据、上锁写保护)。这个例子应该很容易想起来的,不懂的可以搜索一下:stm32往内部flash写入数据。就可以得到相关信息了。这里我们写入bin文件到flash同样通过Controller接口。
        SWD接口将数据传到AHB-DP、到总线之后,就会在控制信号的指引下,控制Controller,然后将bin文件写入到flash,写入完成、校验之后,就可以reset启动芯片了,使用XIP技术,从flash某个地址启动(常用的stm32一般是0x08000000)。

        知道了往哪里写之后,也大概了解了数据写入的流程,那么该如何写?这里就要用到了flash下载算法了。

二、FLM文件

        FLM文件是keil进行代码下载时的必须文件,该文件主要包含被下载芯片的存储器的相关信息(芯片型号、存储器页大小等)和存储器写入算法。FLM文件本质上也是一种ELF(Executable and Linkable Format)文件,ELF文件的具体格式我们放到后面介绍。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

         上图中就是FLM文件,他指导jlink如何下载镜像文件。镜像文件本质上就是一堆二进制,我们都知道keil会生成axf文件、hex、bin文件,镜像文件其实就是bin文件,下载到flash里面的内容就是bin文件的内容。算法的名字叫做NEW_DEVICE.FLM,路径在keil的安装目录里面:ARM\PACK\ARM\CMSIS\4.5.0\Device\ARM\Flash。

        在C:\Keil_v5\ARM\Flash_Template(默认安装的情况下)下面会有一个keil工程,这个工程就是keil官方提供给我们制作flash下载算法的。

打开之后很简单,就两个文件

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

 FlashDev.c就只有一个struct FlashDevice类型的结构体,上图是一个例子,具体定义在FlashOS.H中。

struct FlashSectors {
    unsigned long szSector; // Sector Size in Bytes
    unsigned long AddrSector; // Address of Sector
};
struct FlashDevice {
    unsigned short Vers; // Version Number and Architecture
    char DevName[128]; // Device Name and Description
    unsigned short DevType; // Device Type: ONCHIP, EXT8BIT, EXT16BIT, ...
    unsigned long DevAdr; // Default Device Start Address
    unsigned long szDev; // Total Size of Device
    unsigned long szPage; // Programming Page Size
    unsigned long Res; // Reserved for future Extension
    unsigned char valEmpty; // Content of Erased Memory
    unsigned long toProg; // Time Out of Program Page Function
    unsigned long toErase; // Time Out of Erase Sector Function
    struct FlashSectors sectors[SECTOR_NUM];
};

从上面的结构体中我们可以知道,我们的flash地址、大小、扇区大小等信息,这些都会在下载bin文件的时候用到。

在FlashDev.c中,我们可以看到16行,表示flash设备的类型,有如下几种情况。

#define UNKNOWN 0 // Unknown
#define ONCHIP 1 // On-chip Flash Memory
#define EXT8BIT 2 // External Flash Device on 8-bit Bus
#define EXT16BIT 3 // External Flash Device on 16-bit Bus
#define EXT32BIT 4 // External Flash Device on 32-bit Bus
#define EXTSPI 5 // External Flash Device on SPI

17--23就是指flash的参数,有多大,每页多少字节等等。
FlashPrg.c里面就只是一些函数的接口,具体有哪些函数接口在下面。

// Flash Programming Functions (Called by FlashOS)
extern int Init (unsigned long adr, // Initialize Flash
                    unsigned long clk,
                    unsigned long fnc);
extern int UnInit (unsigned long fnc); // De-initialize Flash
extern int BlankCheck (unsigned long adr, // Blank Check
                        unsigned long sz,
                        unsigned char pat);
extern int EraseChip (void); // Erase complete Device
extern int EraseSector (unsigned long adr); // Erase Sector Function
extern int ProgramPage (unsigned long adr, // Program Page Function
                        unsigned long sz,
                        unsigned char *buf);
extern unsigned long Verify (unsigned long adr, // Verify Function
                                unsigned long sz,
                                unsigned char *buf);

其实就是对flash的操作,以前搞过spi flash(就是w25qxx系列),对上面的回调函数很好理解。
直接将keil官方提供的例子进行编译,如下图。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

 其他的跟keil生成程序一样,画横线的log是在编译结束之后,将axf拷贝位flx文件,从这里可以看出,
flm文件其实就是axf文件,看看二者的文件大小,均为10500Byte。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

 axf文件是什么?是在bin文件的基础山添加了地址信息和调试信息的文件。使用记事本打开,确实有调试信息。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

 能生成axf文件,说明有sct(分散加载文件)指导整个工程,生成axf,我们在keil配置里面找到之后,发现只有一个叫做Target.lin的文件,打开之后看到:

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

 跟平常见到的sct文件不太一样。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

 其实,本质上并无差别,无非就是指定code中的各种属性(RO、RW、ZI)放到某些位置。

三、操作flash接口

        现在来看看FlashPrg.c里面的函数接口。

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

功能:用于初始化Flash
adr参数表示设备基地址(Base Address)
clk参数表示时钟频率
adr参数表示功能码(1 - 擦除, 2 - 程序, 3 -验证)

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

功能:将代码写入到flash中。
adr参数表示flash起始地址
sz参数表示写入数据的大小
buf参数表示缓存区
这里强调一点,falsh是以块为单位组织的,在FlashDev里面也有指定,大小为szPage。主机系统往flash写入数据的时候会确保不会出现跨块写入数据(就是一块一块的写入)。在前面的内容中,

T5324 000:563.106 Data: 88 08 00 20 D5 01 00 10 8B 0A 00 10 65 0A 00 10 ...
T5324 000:563.126 CPU_WriteMem(512 bytes @ 0x20000670)

写入是以512B大小的内容往flash写入。其他的函数都比较好理解,就不细讲了。

回过头来再看jlink下载日志(写入flash的部分已删掉):

T5324 000:386.354 JLINK_WriteMem(0xE0001000, 0x1C Bytes, ...)
T5324 000:386.358 Data: 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ...
T5324 000:386.372 CPU_WriteMem(28 bytes @ 0xE0001000)
T5324 000:390.509 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:390.517 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:390.720 CPU_WriteMem(1648 bytes @ 0x20000000)
T5324 000:527.583 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T5324 000:527.598 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T5324 000:527.622 CPU_WriteMem(1648 bytes @ 0x20000000)
.....
T1A34 000:768.192 JLINK_WriteMem(0x20000000, 0x670 Bytes, ...)
T1A34 000:768.209 Data: 00 BE 0A E0 0D 78 2D 06 68 40 08 24 40 00 00 D3 ...
T1A34 000:768.232 CPU_WriteMem(1648 bytes @ 0x20000000)
T1A34 000:884.512 JLINK_WriteMem(0x20000000, 0x2 Bytes, ...)
T1A34 000:884.533 Data: FE E7
T1A34 000:884.552 CPU_WriteMem(2 bytes @ 0x20000000)

以下的部分内容,有些是猜测(根据自己的实践和网上的内容进行合理猜测)。
T5324 000:386.354:跟DWT通信,开始写入flash算法(也就时一段短的程序)。

T5324 000:390.509:将flash写入算法的内容写入到RAM中,地址在这里设置。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

         之后,通过jlink,按照块(512B)大小发送程序的镜像文件(内容和bin文件一样),由flash写入算法接受数据,将镜像文件写入到flash中。最后完成校验、复位等工作(还有一些工作就不展开了,跟本文内容不是很紧密),jlink就可以断开了。

        这部内容简单的总结下就是:jlink先和M3内核沟通,然后将flash下载算法传输到到RAM中,再发送bin文件到RAM中,由flash下载算法将RAM中的bin文件(前面接受到的)写入到内部的flash。最后进行校验,复位(若有)等扫尾工作。

        到这里也明白了,下载bin文件到flah中的过程,其实是由我们指定的(flm文件),这个flm文件一般由芯片厂商提供,keil只是将这个接口(具体的下载bin的过程)开放出去了,各个芯片厂家适配他们自己的芯片。

四、芯片启动过程

        bin下载的过程基本上已经讲完了,如果还有内容的话,以后再更。最后谈一谈芯片如何启动。再说明芯片启动之前,我们先看看芯片的地址空间。

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

         上面时M3内核定义的地址空间使用,一般芯片厂商会根据自己的需要,在划分的区域里面实现自己的地址划分。(博主这里不想找了,就简单的画一个我需要讲解的部分,作为说明素材)

keil at49f040.flx,ARM体系,嵌入式硬件,stm32,arm开发,单片机,mcu

         玩过stm32的同学应该知道,stm32有两个boot引脚:boot0、boot1,二者配合起来选择从哪里启动(boot[0:1] 均为0的时候从内部flash启动,也就是从地址0x0800  0000,其他的情况从RAM或者外部flash启动,现在各位同学应该知道如果从外部flash启动该如何做了0^0)。

        在配置boot0/1为低电平时,芯片从0x0800  0000地址出读取两个字,一个sp,一个pc,然后配置中断向量表、进入复位中断(就是startup_stm32xxxx.s的内容)。但按理说,pc、sp一开始的值应该为0,那如何跳到0x0800  0000进而读取那里的bin文件呢?问题就在Boot里面

        看上图,Boot是一段代码,由厂商烧录。芯片在启动的时候,pc值为0,运行Boot程序,Boot程序会去检测boot0/1引脚,进而决定是从内部flash还是ram或者其他的地方启动(其实就是一个地址的区别,内部flash启动就是0x0800  0000,ram就是0x2000 0000),之后跳转到0x0800  0000(boot0/1为低电平),下面才是startup_stm32xxxx.s的内容。文章来源地址https://www.toymoban.com/news/detail-768128.html

到了这里,关于keil下载程序具体过程4:flash下载算法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【Keil5】Keil查看程序占用flash大小

    我们在挑选一款单片机的时候,会查询单片机的主频、内部flash和RAM、封装、各种外设接口资源。其中flash和RAM大小尤为重要。 以STM32H750VBT6为例,其内部flash只有128KB,RAM却有1056KB。 该选型手册可在该链接中免积分下载:STM32系列产品选型手册 该型号的flash容量比F103ZET6的512

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

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

    2024年02月16日
    浏览(156)
  • fpga 下载程序到 flash 后重新上电不能自动加载程序

    可能是接的调试器没有断电,断电一次再给调试器上电。如果调试器一直连着可以连续断电上电fpga开发板,直到成功。fpga貌似上电后什么程序都不加载则引脚为高电平,而vivado默认.xdc的BITSTREAM.CONFIG.UNUSEDPIN(未使用的引脚)是PULLDOWN,或者自己设置为PULLNONE,这样假如fpga引脚

    2024年02月07日
    浏览(59)
  • 成功解决keil识别不到单片机芯片,下载不了程序

    我的芯片是STM32F429,正点原子的阿波罗。 今天使用开发板做实验,突然找不到芯片了, 以前下载的PWM波也运行不了 。查找了好久,原来是芯片锁了,终于解决了。 我是第二种办法实现给芯片解锁的,第一种是我猜测的。 解决办法: 第一种: 先给驱动板上电,boot0接到3.3

    2024年02月15日
    浏览(36)
  • 040-第三代软件开发-全新波形抓取算法

    : Qt 、 Qml 、 抓波 、 截获 、 波形 欢迎来到我们的 QML C++ 项目!这个项目结合了 QML(Qt Meta-Object Language)和 C++ 的强大功能,旨在开发出色的用户界面和高性能的后端逻辑。 在项目中,我们利用 QML 的声明式语法和可视化设计能力创建出现代化的用户界面。通过直观

    2024年02月06日
    浏览(38)
  • STM32烧写程序:Keil5使用ST-link下载程序

    首先需要连接ST-link到电路板: STM32烧写程序:ST-link V2调试下载器实物和连接方式 然后安装ST-link驱动: STM32程序烧写:ST-link驱动下载和安装 编译一个无错误的工程 点击工具栏的魔法锤 点击Debug,选择ST-Link Debugger 然后点击Settings ST-LINK/V2适配器,SW模式,看芯片是否被识别

    2023年04月08日
    浏览(97)
  • KEIL_MDK下载程序到MSP432卡慢问题解决

    所用单片机型号:MSP432P401r 我们在用KEIL_MDK编程后对MSP432下载时, 总是很卡慢 , 有时还可能会造成计算机卡死,这 是因为板载驱动未更新 此时我们就需要下载TI公司官方的 CCS编程软件 ,来对其进行 固件更新 即可, 更新的是板子,不是计算机,所以更新一下板子的固件后

    2024年02月16日
    浏览(51)
  • J-LINK J-FLASH 下载STM32单片机程序使用教程

    J-LINK J-FLASH 下载程序使用教程 -V1.0 2023.05.09 Introduction 本教程用于演示如何使用JLINK V9配套J-FLASH软件烧写更新MCU程序的教程 安装提供的 JLINK驱动程序。JLink_Windows_V722a.rar。全程默认安装,只能安装在C盘,不可安装于其它盘。 安装驱动完成后,将JLINK V9仿真器上USB口插上电脑,

    2024年02月11日
    浏览(47)
  • keil下载程序后,单片机不自动运行, 需要断电重启的解决方法

    如题,在很多时候,我们KEIL下进行程序开发,编绎完成后会下载到单片机中执行程序,看看运行结果。有时候却发现程序下载后单片机不自动运行,需要断电重启才会运行的问题。 经过从网络上多方查找,最后找到解决方案。原因如下: 首先:我们看一下程序下载的配置,

    2024年02月14日
    浏览(66)
  • 49个过程背诵方法

    五大过程组:启规执监收  需要死记住,五个比较好记按照顺序启动规划执行监控结束   十大过程:整范进,成质源,疯(风)狗(沟)踩(采)人  过程数量: 7  6  6    4   3 6     7            3             3           4 记住每个过程有几个过程,方便记不住的

    2024年02月08日
    浏览(32)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包