GD32 flash FMC/bootloade操作

    GD32的Flash的名字是FMC,BOOT的操作主要基于这些进行实现


    .GD32有三种启动模式,对应的存储介质均是芯片内置的,他们是: 1)用户闪存=芯片内置的闪存2)SRAM =芯片内置的RAM区,就是内存啦0.3)系统存储器=芯片内部一块特定的区域,芯片出厂时在这个区域预置了一段引导程序,就是通常说的ISP程序。这个区域的内容在芯片出厂后没有人能够修改或擦除,即它是一个ROM区。    在每个GD32的芯片上都有两个管脚BOOT1和BOOT0,两个这管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序1)BOOT1 = X BOOT0 = 0从用户闪存启动,这是正常的工作模式。2)BOOT1 = 0 BOOT0 = 1从系统存储器启动,这种模式启动的程序功能由厂家设置3) BOOT1 = 1 BOOT0 = 1从内置SRAM启动,这种模式可用于调试。    要注意的是,一般不使用内置SRAM启动(BOOT1 = 1 BOOT0 = 1),因为SRAM 电后数据就丢失。多数情况下SRAM只是在调试时使用,也可以做其他一些用途。如做故障的局部诊断,写一段小程序加载到SRAM中诊断板上的其他电路,或用此方法读写板上的闪存EEPROM或等。还可以通过这种方法解除内部闪存的读写保护,当然解除读写保护的同时闪光的内容也被自动清除,以防止恶意的软件拷贝。一般BOOT0和BOOT1跳线都跳到0(地)    在GD32的芯片函数库gd32f1x0_fmc.c中,我们可以查找到这样的函数:









/ **



  * @brief编程BOOT1选项位。   * @参数OB_BOOT1:法定参数可以是以下值之一:  * @arg   OB_BOOT1_RESET   * @arg OB_BOOT1_SET * @retval FMC状态:FMC_READY,FMC_BSY,FMC_WRPERR,FMC_PGERR或FMC_TIMEOUT_ERR   * / FMC_State FMC_OB_BOOTConfig (uint8_t OB_BOOT1){     FMC_State temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);     if(temp_state == FMC_READY)    {           / *设置OBPG位* /         FMC-> CMR | = FMC_CMR_OBPG;         OB-> USER = OB_BOOT1 | 0xEF;         / *等待FMC就绪* /         temp_state = FMC_WaitReady(FMC_TIMEOUT_COUNT);         如果(temp_state!= FMC_TIMEOUT_ERR)








  






  




        {             / *复位OBPG位* /             FMC-> CMR&= ~FMC_CMR_OBPG;         }     }     / *返回FMC状态* /     return temp_state; }     由函数描述我们可以得到,该函数的作用是清空或者重置BOOT1位,他的参数是OB_BOOT1_RESET,OB_BOOT1_SET(在对应的头文件中进行定义)/ ** @defgroup FMC_Option_Bytes_BOOT1   * @ {   * / #define OB_BOOT1_RESET((uint8_t)0x00)/ *!#define OB_BOOT1_SET((uint8_t)0x10)/ *!    BOOT1和BOOT0的作用是决定程序以哪种方式进入,那么从GD的startup_gd32f1x0.s中我们可以知道,在0x08000000开始启动的重映射。这是什么原因:原因是由于STM32设计的Flash起始地址是在0x0800 0000位置开始的。全部代码都只能从这里开始存储。


















    理论上,CM3中规定上电后CPU是从0地址开始执行,但是这里中断向量表却被烧写在0x0800 0000地址里,那启动时不会中断向量表了?既然CM3定下的规矩是从0地址启动,SMT32当然不能破坏ARM定下的“规矩”,所以它做了一个启动映射的过程,就是和芯片上总能见到的BOOT0和BOOT1有关了,当选择从主闪存启动模式后,芯片一上电,Flash的0x0800 0000地址被映射到0地址处,不影响CM3内核的读取,所以这时的CM3既可以在0地址处访问中断向量表,也可以在0x0800 0000地址处理问中断向量表,而代码还是在0x0800 0000地址处存储的。这就是最难理解的地方,其实,这是基本上所有的ARM芯片采用的启动映射方法.ARM7,ARM9没有内部Flash的通常都是这样做的。


    理解上述描述之后,我们来学习一下OTA固件升级原理:
    OTA设计升级很重要的一个工作就是首先规划好闪存区域的布局,清晰地知道引导程序,应用程序以及下载的的的.bin文件在闪存中放置的位置
    OTA固件升级其实就是IAP应用编程,要完成固件升级需要设计两个程序,一个为引导加载程序,另外一个为应用程序。通常我们是在应用程序中建立套接字连接来发起HTTP请求去查询服务器是否有新的固件并进行下载的,并且在片外的闪存中修改和存储固件的参数信息,而引导程序的程序主要检查固件的参数信息并且如果需要就负责将应用程序下载的固件从片外Flash搬运到片内Flash,然后跳到那里运行 1.Bootloader角色主要完成的:     1)读取固件参数信息;      2)判断是否需要更新,如果不需要直接跳到应用区域执行;



     3)如果需要更新,则将固件搬到应用区域,并且更新固件参数信息(表示已将更新过该固件了),跳到求最后应用程序      角色主要完成的:     1)发送HTTP请求查询服务器最新固件信息;      2)当前固件做对比,如果发送HTTP请求查询服务器最新固件信息; 2)当前固件做对比,如果需要更新,就进行下载;      3)将下载的固件写到规划好的OTA固件存储区;      4)更新固件参数回写片外闪存,最后进行软件复位;      这里也相应地首先完成网络上固件下载的完整性校验,以确保在网络下载下来的固件是完整的,然后在写进OTA固件存储区域的时候也需要再进行校验计算,以在引导加载程序在搬运固件时校验确保完整性。引导程序放置在片内闪存的0x08000000地址,大小为64K,STM32上设备电后首先跳到里执行;(主闪存存储器被选为启动区域)2.应用放置在片内的Flash的0x08010000地址; 3.PARAMETER_1和PARAMETER_2(备份用)记录固件参数信息的区域,它们放在片外的闪存; 4. OTA_TEMP区域为OTA固件存储区域,放置片外闪存,应用从网络下载仓库文件然后写到该区域,而引导程序从这个区域搬运固件到应用区域。














    从上面可以看出,不管是引导程序还是应用都需要做好片内闪存驱动和片外的闪存驱动来进行闪光操作     内容参考:HTTPS://blog.csdn.net/yueqian_scut/article/details/ 52804009








    






你可能感兴趣的:(底层)