zoukankan      html  css  js  c++  java
  • 【STM32】如何将资源烧写至外部flash,如spi-flash

    STM32将资源烧写至外部flash方式大致分为通过IDE与应用程序一起和通过CubeProgranmmer单独烧写两种:

    方式一、使用IDE加载烧写算法,烧录应用程序时一并写入,具体就是修改分散加载链接脚本将部分常量数据移至外部flash,烧写算法制作工程如下

    主要实现两个文件,接口实现文件 <FLashPrg.c> 和设备描述文件 <FLashPrg.c>

    FLashPrg.c

     1 /**************************************************************************//**
     2  * @file     FlashDev.c
     3  * @brief    Flash Device Description for New Device Flash
     4  * @version  V1.0.0
     5  * @date     10. January 2018
     6  ******************************************************************************/
     7 /*
     8  * Copyright (c) 2010-2018 Arm Limited. All rights reserved.
     9  *
    10  * SPDX-License-Identifier: Apache-2.0
    11  *
    12  * Licensed under the Apache License, Version 2.0 (the License); you may
    13  * not use this file except in compliance with the License.
    14  * You may obtain a copy of the License at
    15  *
    16  * www.apache.org/licenses/LICENSE-2.0
    17  *
    18  * Unless required by applicable law or agreed to in writing, software
    19  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
    20  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    21  * See the License for the specific language governing permissions and
    22  * limitations under the License.
    23  */
    24  
    25 #include "..FlashOS.H"        // FlashOS Structures
    26 
    27 
    28 struct FlashDevice const FlashDevice  =  {
    29     FLASH_DRV_VERS,             // Driver Version, do not modify!
    30     "STM32F429_W25Q128",        // Device Name 
    31     EXTSPI,                     // Device Type
    32     0x90000000,                 // Device Start Address
    33     0x01000000,                 // Device Size in Bytes (256kB)
    34     256,                        // Programming Page Size
    35     0,                          // Reserved, must be 0
    36     0xFF,                       // Initial Content of Erased Memory
    37     100,                        // Program Page Timeout 100 mSec
    38     3000,                       // Erase Sector Timeout 3000 mSec
    39 
    40 // Specify Size and Address of Sectors
    41     0x001000, 0x000000,         // Sector Size  8kB (8 Sectors)
    42 //    0x010000, 0x010000,         // Sector Size 64kB (2 Sectors) 
    43 //    0x002000, 0x030000,         // Sector Size  8kB (8 Sectors)
    44     SECTOR_END
    45 };

    FLashPrg.c

      1 /**************************************************************************//**
      2  * @file     FlashPrg.c
      3  * @brief    Flash Programming Functions adapted for New Device Flash
      4  * @version  V1.0.0
      5  * @date     10. January 2018
      6  ******************************************************************************/
      7 /*
      8  * Copyright (c) 2010-2018 Arm Limited. All rights reserved.
      9  *
     10  * SPDX-License-Identifier: Apache-2.0
     11  *
     12  * Licensed under the Apache License, Version 2.0 (the License); you may
     13  * not use this file except in compliance with the License.
     14  * You may obtain a copy of the License at
     15  *
     16  * www.apache.org/licenses/LICENSE-2.0
     17  *
     18  * Unless required by applicable law or agreed to in writing, software
     19  * distributed under the License is distributed on an AS IS BASIS, WITHOUT
     20  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     21  * See the License for the specific language governing permissions and
     22  * limitations under the License.
     23  */
     24  
     25 #include "..FlashOS.H"        // FlashOS Structures
     26 #include ".flashsp_spi_flash.h"
     27 
     28 
     29 #define PAGE_SIZE               SPI_FLASH_PageSize
     30 
     31 
     32 uint8_t auxBuf[PAGE_SIZE];
     33 uint32_t baseAddr;
     34 
     35 /* 
     36    Mandatory Flash Programming Functions (Called by FlashOS):
     37                 int Init        (unsigned long adr,   // Initialize Flash
     38                                  unsigned long clk,
     39                                  unsigned long fnc);
     40                 int UnInit      (unsigned long fnc);  // De-initialize Flash
     41                 int EraseSector (unsigned long adr);  // Erase Sector Function
     42                 int ProgramPage (unsigned long adr,   // Program Page Function
     43                                  unsigned long sz,
     44                                  unsigned char *buf);
     45 
     46    Optional  Flash Programming Functions (Called by FlashOS):
     47                 int BlankCheck  (unsigned long adr,   // Blank Check
     48                                  unsigned long sz,
     49                                  unsigned char pat);
     50                 int EraseChip   (void);               // Erase complete Device
     51       unsigned long Verify      (unsigned long adr,   // Verify Function
     52                                  unsigned long sz,
     53                                  unsigned char *buf);
     54 
     55        - BlanckCheck  is necessary if Flash space is not mapped into CPU memory space
     56        - Verify       is necessary if Flash space is not mapped into CPU memory space
     57        - if EraseChip is not provided than EraseSector for all sectors is called
     58 */
     59 
     60 
     61 /*
     62  *  Initialize Flash Programming Functions
     63  *    Parameter:      adr:  Device Base Address
     64  *                    clk:  Clock Frequency (Hz)
     65  *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
     66  *    Return Value:   0 - OK,  1 - Failed
     67  */
     68 
     69 int Init (unsigned long adr, unsigned long clk, unsigned long fnc)
     70 {
     71     /* Add your Code */
     72     baseAddr = adr;
     73     SPI_FLASH_Init();
     74     return (0);                                  // Finished without Errors
     75 }
     76 
     77 
     78 /*
     79  *  De-Initialize Flash Programming Functions
     80  *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
     81  *    Return Value:   0 - OK,  1 - Failed
     82  */
     83 
     84 int UnInit (unsigned long fnc)
     85 {
     86     /* Add your Code */
     87     return (0);                                  // Finished without Errors
     88 }
     89 
     90 
     91 /*
     92  *  Erase complete Flash Memory
     93  *    Return Value:   0 - OK,  1 - Failed
     94  */
     95 
     96 int EraseChip (void)
     97 {
     98     /* Add your Code */
     99     SPI_FLASH_BulkErase();
    100     return (0);                                  // Finished without Errors
    101 }
    102 
    103 
    104 /*
    105  *  Erase Sector in Flash Memory
    106  *    Parameter:      adr:  Sector Address
    107  *    Return Value:   0 - OK,  1 - Failed
    108  */
    109 
    110 int EraseSector (unsigned long adr)
    111 {
    112     /* Add your Code */
    113     SPI_FLASH_SectorErase(adr - baseAddr);
    114     return (0);                                  // Finished without Errors
    115 }
    116 
    117 
    118 /*
    119  *  Program Page in Flash Memory
    120  *    Parameter:      adr:  Page Start Address
    121  *                    sz:   Page Size
    122  *                    buf:  Page Data
    123  *    Return Value:   0 - OK,  1 - Failed
    124  */
    125 
    126 int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf)
    127 {
    128     /* Add your Code */
    129     SPI_FLASH_PageWrite(buf, adr - baseAddr, sz);
    130     return (0);                                  // Finished without Errors
    131 }
    132 
    133 /*  
    134  *  Verify Flash Contents
    135  *    Parameter:      adr:  Start Address
    136  *                    sz:   Size (in bytes)
    137  *                    buf:  Data
    138  *    Return Value:   (adr+sz) - OK, Failed Address
    139  */
    140 
    141 /*
    142    Verify function is obsolete because all other function leave 
    143     the SPIFI in memory mode so a memory compare could be used.
    144  */
    145 unsigned long Verify (unsigned long adr, unsigned long sz, unsigned char *buf)
    146 {
    147     int i;
    148     SPI_FLASH_BufferRead(auxBuf, adr - baseAddr, sz);
    149     for (i = 0; i < PAGE_SIZE; i++) {
    150         if (auxBuf[i] != buf[i]) {
    151             return (adr + i);               // Verification Failed (return address)
    152         }
    153     }
    154     return (adr + sz);                      // Done successfully
    155 }

    修改好适配自己的硬件接口,编译会生成 .FLM格式的烧写算法文件,实际是通过如下命令生成的

      

    方式二、使用编程工具STM32CubeProgrammer,将数据直接烧写至外部flash,烧写算法制作工程如下

     主要实现两个文件,接口实现文件 <Loader_Src.c> 和设备描述文件 <Dev_Inf.c>

    Dev_Inf.c

     1 #include "Dev_Inf.h"
     2 
     3 /* This structure containes information used by ST-LINK Utility to program and erase the device */
     4 #if defined (__ICCARM__)
     5 __root struct StorageInfo const StorageInfo  =  {
     6 #else
     7 struct StorageInfo const StorageInfo  =  {
     8 #endif
     9     "M25P64_STM3210E-EVAL",         // Device Name + version number
    10     SPI_FLASH,                      // Device Type
    11     0x00000000,                     // Device Start Address
    12     0x00800000,                     // Device Size in Bytes (8MBytes/64Mbits)
    13     0x00000100,                     // Programming Page Size 16Bytes
    14     0xFF,                           // Initial Content of Erased Memory
    15 // Specify Size and Address of Sectors (view example below)
    16     0x00000080, 0x00010000,         // Sector Num : 128 ,Sector Size: 64KBytes
    17     0x00000000, 0x00000000,
    18 };
    19 
    20 /*                                  Sector coding example
    21     A device with succives 16 Sectors of 1KBytes, 128 Sectors of 16 KBytes,
    22     8 Sectors of 2KBytes and 16384 Sectors of 8KBytes
    23 
    24     0x00000010, 0x00000400,         // 16 Sectors of 1KBytes
    25     0x00000080, 0x00004000,         // 128 Sectors of 16 KBytes
    26     0x00000008, 0x00000800,         // 8 Sectors of 2KBytes
    27     0x00004000, 0x00002000,         // 16384 Sectors of 8KBytes
    28     0x00000000, 0x00000000,         // end
    29   */

    Loader_Src.c

      1 #include "stm32f10x.h"
      2 #include "stm32_eval_spi_flash.h"
      3 #include "stm3210e_eval.h"
      4 
      5 
      6 /**
      7   * Description :
      8   * Initilize the MCU Clock, the GPIO Pins corresponding to the
      9   * device and initilize the FSMC with the chosen configuration
     10   * Inputs    :
     11   *      None
     12   * outputs   :
     13   *      R0     : "1"             : Operation succeeded
     14   *               "0"             : Operation failure
     15   * Note: Mandatory for all types of device
     16   */
     17 int Init (void)
     18 {
     19     SystemInit();
     20     sFLASH_Init();
     21     return 1;
     22 }
     23 
     24 
     25 /**
     26   * Description :
     27   * Read data from the device
     28   * Inputs    :
     29   *      Address       : Write location
     30   *      Size          : Length in bytes
     31   *      buffer        : Address where to get the data to write
     32   * outputs   :
     33   *      R0     : "1"             : Operation succeeded
     34   *               "0"             : Operation failure
     35   * Note: Mandatory for all types except SRAM and PSRAM
     36   */
     37 int Read (uint32_t Address, uint32_t Size, uint8_t* buffer)
     38 {
     39     sFLASH_ReadBuffer(buffer, Address, Size);
     40     return 1;
     41 }
     42 
     43 
     44 /**
     45   * Description :
     46   * Write data from the device
     47   * Inputs    :
     48   *      Address       : Write location
     49   *      Size          : Length in bytes
     50   *      buffer        : Address where to get the data to write
     51   * outputs   :
     52   *      R0           : "1"             : Operation succeeded
     53   *                     "0"             : Operation failure
     54   * Note: Mandatory for all types except SRAM and PSRAM
     55   */
     56 int Write (uint32_t Address, uint32_t Size, uint8_t* buffer)
     57 {
     58     sFLASH_WriteBuffer(buffer, Address, Size);
     59     return 1;
     60 }
     61 
     62 
     63 /**
     64   * Description :
     65   * Erase a full sector in the device
     66   * Inputs    :
     67   *     None
     68   * outputs   :
     69   *     R0     : "1" : Operation succeeded
     70   *              "0" : Operation failure
     71   * Note: Not Mandatory for SRAM PSRAM and NOR_FLASH
     72   */
     73 int MassErase (void)
     74 {
     75     sFLASH_EraseBulk();
     76     return 1;
     77 }
     78 
     79 /**
     80   * Description :
     81   * Erase a full sector in the device
     82   * Inputs    :
     83   *      SectrorAddress    : Start of sector
     84   *      Size          : Size (in WORD)
     85   *      InitVal       : Initial CRC value
     86   * outputs   :
     87   *     R0     : "1" : Operation succeeded
     88   *              "0" : Operation failure
     89   * Note: Not Mandatory for SRAM PSRAM and NOR_FLASH
     90   */
     91 int SectorErase (uint32_t EraseStartAddress, uint32_t EraseEndAddress)
     92 {
     93     EraseStartAddress = EraseStartAddress -  EraseStartAddress % 0x10000;
     94 
     95     while (EraseEndAddress >= EraseStartAddress) {
     96         sFLASH_EraseSector(EraseStartAddress);
     97         EraseStartAddress += 0x10000;
     98     }
     99 
    100     return 1;
    101 }
    102 
    103 /**
    104   * Description :
    105   * Calculates checksum value of the memory zone
    106   * Inputs    :
    107   *      StartAddress  : Flash start address
    108   *      Size          : Size (in WORD)
    109   *      InitVal       : Initial CRC value
    110   * outputs   :
    111   *     R0             : Checksum value
    112   * Note: Optional for all types of device
    113   */
    114 uint32_t CheckSum(uint32_t StartAddress, uint32_t Size, uint32_t InitVal)
    115 {
    116     uint8_t missalignementAddress = StartAddress % 4;
    117     uint8_t missalignementSize = Size ;
    118     int cnt;
    119     uint32_t Val;
    120     uint8_t value;
    121 
    122     StartAddress -= StartAddress % 4;
    123     Size += (Size % 4 == 0) ? 0 : 4 - (Size % 4);
    124 
    125     for(cnt = 0; cnt < Size ; cnt += 4) {
    126         sFLASH_ReadBuffer(&value, StartAddress, 1);
    127         Val = value;
    128         sFLASH_ReadBuffer(&value, StartAddress + 1, 1);
    129         Val += value << 8;
    130         sFLASH_ReadBuffer(&value, StartAddress + 2, 1);
    131         Val += value << 16;
    132         sFLASH_ReadBuffer(&value, StartAddress + 3, 1);
    133         Val += value << 24;
    134 
    135         if(missalignementAddress) {
    136             switch (missalignementAddress) {
    137                 case 1:
    138                     InitVal += (uint8_t) (Val >> 8 & 0xff);
    139                     InitVal += (uint8_t) (Val >> 16 & 0xff);
    140                     InitVal += (uint8_t) (Val >> 24 & 0xff);
    141                     missalignementAddress -= 1;
    142                     break;
    143 
    144                 case 2:
    145                     InitVal += (uint8_t) (Val >> 16 & 0xff);
    146                     InitVal += (uint8_t) (Val >> 24 & 0xff);
    147                     missalignementAddress -= 2;
    148                     break;
    149 
    150                 case 3:
    151                     InitVal += (uint8_t) (Val >> 24 & 0xff);
    152                     missalignementAddress -= 3;
    153                     break;
    154             }
    155         } else if((Size - missalignementSize) % 4 && (Size - cnt) <= 4) {
    156             switch (Size - missalignementSize) {
    157                 case 1:
    158                     InitVal += (uint8_t) Val;
    159                     InitVal += (uint8_t) (Val >> 8 & 0xff);
    160                     InitVal += (uint8_t) (Val >> 16 & 0xff);
    161                     missalignementSize -= 1;
    162                     break;
    163 
    164                 case 2:
    165                     InitVal += (uint8_t) Val;
    166                     InitVal += (uint8_t) (Val >> 8 & 0xff);
    167                     missalignementSize -= 2;
    168                     break;
    169 
    170                 case 3:
    171                     InitVal += (uint8_t) Val;
    172                     missalignementSize -= 3;
    173                     break;
    174             }
    175         } else {
    176             InitVal += (uint8_t) Val;
    177             InitVal += (uint8_t) (Val >> 8 & 0xff);
    178             InitVal += (uint8_t) (Val >> 16 & 0xff);
    179             InitVal += (uint8_t) (Val >> 24 & 0xff);
    180         }
    181 
    182         StartAddress += 4;
    183     }
    184 
    185     return (InitVal);
    186 }
    187 
    188 
    189 /**
    190   * Description :
    191   * Verify flash memory with RAM buffer and calculates checksum value of
    192   * the programmed memory
    193   * Inputs    :
    194   *      FlashAddr     : Flash address
    195   *      RAMBufferAddr : RAM buffer address
    196   *      Size          : Size (in WORD)
    197   *      InitVal       : Initial CRC value
    198   * outputs   :
    199   *     R0             : Operation failed (address of failure)
    200   *     R1             : Checksum value
    201   * Note: Optional for all types of device
    202   */
    203 uint64_t Verify (uint32_t MemoryAddr, uint32_t RAMBufferAddr, uint32_t Size, uint32_t missalignement)
    204 {
    205     uint32_t InitVal = 0;
    206     uint32_t VerifiedData = 0;
    207     uint8_t TmpBuffer = 0x00;
    208     uint64_t checksum;
    209     Size *= 4;
    210 
    211     checksum = CheckSum((uint32_t)MemoryAddr + (missalignement & 0xf), Size - ((missalignement >> 16) & 0xF), InitVal);
    212 
    213     while (Size > VerifiedData) {
    214         sFLASH_ReadBuffer(&TmpBuffer, MemoryAddr + VerifiedData, 1);
    215 
    216         if (TmpBuffer != *((uint8_t*)RAMBufferAddr + VerifiedData))
    217             return ((checksum << 32) + MemoryAddr + VerifiedData);
    218 
    219         VerifiedData++;
    220     }
    221 
    222     return (checksum << 32);
    223 }

    修改好适配自己的硬件接口,编译会生成 .stldr格式的烧写算法文件,实际是通过如下命令生成的

  • 相关阅读:
    JSTL基础知识
    EL表达式基础知识
    Log4Net使用详解
    ViewState存储到服务器
    WCF通信过程
    值类型与引用类型总结
    使用 HttpWebRequest 发送模拟 POST 请求
    OOP组合和继续的优缺点
    XPath在asp.net中查询XML
    Equal 和==比较
  • 原文地址:https://www.cnblogs.com/skullboyer/p/13812510.html
Copyright © 2011-2022 走看看