MDK程序下载 ---- FLM文件

MDK编程算法

  用过MDK下载程序的小伙伴可能都知道,在下载程序之前需要都在Debug设置的Flash Download子选项卡选择编程算法。大多数时候,

我们只要安装了芯片包之后,就可以直接得到对应的编程算法,并不需要我们去修改它。但是,当你是一个芯片包的开发者,或者你有独特

的下载需求(比如在你的程序里加入一些校验信息),这个时候你就需要去了解它了!

 

 

  编程算法呢,说白就其实也就是一段程序,主要功能就是擦除相应的内存块,并将我们的程序写入到相应的内存区域上去。

在你点击下载按钮的时候,这段程序会被先下载到RAM上(RAM for Algorithm上的设置),然后才会通过它,将你的程序写入到

指定的内存区域内。

 

实现一个自己的编程算法

  怎么去实现一个自己的编程算法?首先我们找到自己的MDK的安装路径,进入到ARM\Flash文件夹下(例如:D:\Keil_v5\ARM\Flash)。

这里有个编程算法的工程模板,复制这个工程到你的工程文件夹下,重命名你自己的想要的名字。

 

   打开工程,里面主要有两个文件 FlashPrg.c 和 FlashDev.c:

 

  FlashDev.c主要实现了一个设备相关的结构体(根据自己的Flash情况去实现)

 

   

  比如STM32L051实现如下:

 

 

  FlashPrg.c实现了几个Flash编程相关的函数:

 

   根据自己的需要去实现,STM32L051实现如下:

  1 /* -----------------------------------------------------------------------------
  2  * Copyright (c) 2014 ARM Ltd.
  3  *
  4  * This software is provided 'as-is', without any express or implied warranty. 
  5  * In no event will the authors be held liable for any damages arising from 
  6  * the use of this software. Permission is granted to anyone to use this 
  7  * software for any purpose, including commercial applications, and to alter 
  8  * it and redistribute it freely, subject to the following restrictions:
  9  *
 10  * 1. The origin of this software must not be misrepresented; you must not 
 11  *    claim that you wrote the original software. If you use this software in
 12  *    a product, an acknowledgment in the product documentation would be 
 13  *    appreciated but is not required. 
 14  * 
 15  * 2. Altered source versions must be plainly marked as such, and must not be 
 16  *    misrepresented as being the original software. 
 17  * 
 18  * 3. This notice may not be removed or altered from any source distribution.
 19  *   
 20  *
 21  * $Date:        18. November 2014
 22  * $Revision:    V1.00
 23  *  
 24  * Project:      Flash Programming Functions for ST STM32L0xx Flash
 25  * --------------------------------------------------------------------------- */
 26 
 27 /* History:
 28  *  Version 1.00
 29  *    Initial release
 30  */ 
 31 
 32 #include "FlashOS.H"        // FlashOS Structures
 33 
 34 typedef volatile unsigned char  vu8;
 35 typedef volatile unsigned long  vu32;
 36 typedef volatile unsigned short vu16;
 37 
 38 #define M8(adr)  (*((vu8  *) (adr)))
 39 #define M16(adr) (*((vu16 *) (adr)))
 40 #define M32(adr) (*((vu32 *) (adr)))
 41 
 42 // Peripheral Memory Map
 43 #define IWDG_BASE       0x40003000
 44 #define FLASH_BASE      0x40022000
 45 
 46 #define IWDG            ((IWDG_TypeDef *) IWDG_BASE)
 47 #define FLASH           ((FLASH_TypeDef*) FLASH_BASE)
 48 
 49 #define FLASH_MEMORY
 50 
 51 // Independent WATCHDOG
 52 typedef struct {
 53   vu32 KR;                                      // offset  0x000 Key register (IWDG_KR)
 54   vu32 PR;                                      // offset  0x004 Prescaler register (IWDG_PR)
 55   vu32 RLR;                                     // offset  0x008 Reload register (IWDG_RLR)
 56   vu32 SR;                                      // offset  0x00C Status register (IWDG_SR)
 57 } IWDG_TypeDef;
 58 
 59 // Flash Registers
 60 typedef struct {
 61   vu32 ACR;                                     // offset  0x000 Flash access control register (FLASH_ACR)
 62   vu32 PECR;                                    // offset  0x004 Flash program erase control register (FLASH_PECR)
 63   vu32 PDKEYR;                                  // offset  0x008 Flash power down key register (FLASH_PDKEYR)
 64   vu32 PEKEYR;                                  // offset  0x00C Flash program erase key register (FLASH_PEKEYR)
 65   vu32 PRGKEYR;                                 // offset  0x010 Flash program memory key register (FLASH_PRGKEYR)
 66   vu32 OPTKEYR;                                 // offset  0x014 Flash option key register (FLASH_OPTKEYR)
 67   vu32 SR;                                      // offset  0x018 Flash status register (FLASH_SR)
 68   vu32 OPTR;                                    // offset  0x01C Option byte register (FLASH_OBR)
 69   vu32 WRPRT;                                   // offset  0x020 Flash write protection register (FLASH_WRPR)
 70 } FLASH_TypeDef;
 71 
 72 
 73 // Flash Keys
 74 #define FLASH_PEKEY1           (0x89ABCDEFul)
 75 #define FLASH_PEKEY2           (0x02030405ul)
 76 #define FLASH_PRGKEY1          (0x8C9DAEBFul)
 77 #define FLASH_PRGKEY2          (0x13141516ul)
 78 #define FLASH_OPTKEY1          (0xFBEAD9C8ul)
 79 #define FLASH_OPTKEY2          (0x24252627ul)
 80 
 81 // Flash program erase control register (FLASH_PECR) definitions
 82 #define FLASH_PELOCK           (0x00000001ul)            // FLASH_PECR and data memory lock 
 83 #define FLASH_PRGLOCK          (0x00000002ul)            // Program memory lock
 84 #define FLASH_OPTLOCK          (0x00000004ul)            // Option bytes block lock
 85 #define FLASH_PROG             (0x00000008ul)            // Program memory selection
 86 #define FLASH_DATA             (0x00000010ul)            // Data memory selection
 87 #define FLASH_OPT              (0x00000020ul)            // Option Bytes memory selection
 88 #define FLASH_FIX              (0x00000100ul)            // Fixed time data write for Byte, Half Word and Word programming
 89 #define FLASH_ERASE            (0x00000200ul)            // Page or Double Word erase mode
 90 #define FLASH_FPRG             (0x00000400ul)            // Half Page/Double Word programming mode
 91 #define FLASH_GBHF_ER          (0x00000800ul)            // Global Half Erase mode
 92 
 93 // Flash status register (FLASH_SR) definitions
 94 #define FLASH_BSY              (0x00000001ul)     // Write/erase operations in progress  
 95 #define FLASH_EOP              (0x00000002ul)            // End of operation
 96 #define FLASH_ENDHV            (0x00000004ul)            // End of high voltage
 97 #define FLASH_WRPERR           (0x00000100ul)            // Write protected error
 98 #define FLASH_PGAERR           (0x00000200ul)            // Programming alignment error
 99 #define FLASH_SIZERR           (0x00000400ul)            // Size error
100 #define FLASH_OPTVERR          (0x00000800ul)            // Option validity error
101 
102 #define FLASH_ERRs         (FLASH_PGAERR | FLASH_WRPERR | FLASH_SIZERR | FLASH_OPTVERR)
103 
104 // Option byte register (FLASH_OBR) definitions
105 #define FLASH_IWDG_SW       (0x00100000ul)            // Software IWDG or Hardware IWDG selected
106 
107 /*
108  *  Initialize Flash Programming Functions
109  *    Parameter:      adr:  Device Base Address
110  *                    clk:  Clock Frequency (Hz)
111  *                    fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
112  *    Return Value:   0 - OK,  1 - Failed
113  */
114 
115 #ifdef FLASH_MEMORY
116 int Init (unsigned long adr, unsigned long clk, unsigned long fnc) {
117 
118       FLASH->SR |= FLASH_ERRs;                  // clear error flags
119 
120       // Unlock PECR Register    
121       FLASH->PEKEYR = FLASH_PEKEY1;
122       FLASH->PEKEYR = FLASH_PEKEY2;
123 
124       // Unlock Program Matrix    
125       FLASH->PRGKEYR = FLASH_PRGKEY1;
126       FLASH->PRGKEYR = FLASH_PRGKEY2;  
127 
128 
129   return (0);
130 }
131 #endif  // FLASH_MEMORY
132 
133 /*
134  *  De-Initialize Flash Programming Functions
135  *    Parameter:      fnc:  Function Code (1 - Erase, 2 - Program, 3 - Verify)
136  *    Return Value:   0 - OK,  1 - Failed
137  */
138 
139 #ifdef FLASH_MEMORY
140 int UnInit (unsigned long fnc) {
141 
142   switch (fnc) {
143     case 1:
144     case 2:
145       // Lock PECR register and program matrix
146       FLASH->PECR |= FLASH_PRGLOCK;             // Program memory lock
147       FLASH->PECR |= FLASH_PELOCK;              // FLASH_PECR and data memory lock
148     break;
149   }
150 
151       return (0);
152 }
153 #endif  // FLASH_MEMORY
154 
155 /*
156  *  Erase Sector in Flash Memory
157  *    Parameter:      adr:  Sector Address
158  *    Return Value:   0 - OK,  1 - Failed
159  */
160 
161 #ifdef FLASH_MEMORY
162 int EraseSector (unsigned long adr) {
163 
164   FLASH->PECR |= FLASH_ERASE;                   // Page or Double Word Erase enabled
165   FLASH->PECR |= FLASH_PROG;                    // Program memory selected
166      
167   M32(adr) = 0x00000000;                        // write '0' to the first address to erase page
168 
169   while (FLASH->SR & FLASH_BSY) {
170     IWDG->KR = 0xAAAA;                          // Reload IWDG
171   }
172 
173   FLASH->PECR &= ~FLASH_ERASE;                  // Page or Double Word Erase disabled
174   FLASH->PECR &= ~FLASH_PROG;                   // Program memory deselected   
175 
176   return (0);                                   // Done
177 }
178 #endif  // FLASH_MEMORY
179 
180 /*
181  *  Program Page in Flash Memory
182  *    Parameter:      adr:  Page Start Address
183  *                    sz:   Page Size
184  *                    buf:  Page Data
185  *    Return Value:   0 - OK,  1 - Failed
186  */
187 
188 #ifdef FLASH_MEMORY
189 int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) {
190   unsigned long  cnt;
191   unsigned long i;
192 
193   sz = (sz + 63) & ~63;                        // adjust programming size
194 
195   for (i = 0; i < (sz / 64); i++) {
196     FLASH->PECR |= FLASH_FPRG;                 // Half Page programming mode enabled
197     FLASH->PECR |= FLASH_PROG;                 // Program memory selected
198                                                
199     cnt = 64;                                  
200     while (cnt ) {                             
201        M32(adr) = *((unsigned long *)buf);     // Program Word
202        adr += 4;                               
203        buf += 4;                               
204        cnt -= 4;                               
205     }                                          
206                                                
207     while (FLASH->SR & FLASH_BSY) {            
208       IWDG->KR = 0xAAAA;                       // Reload IWDG
209     }                                          
210                                                
211     if (FLASH->SR & (FLASH_ERRs)) {            // Check for Errors
212       FLASH->SR |= FLASH_ERRs;                 // clear error flags
213       return (1);                              // Failed
214     }                                          
215                                                
216     FLASH->PECR &= ~FLASH_FPRG;                // Half Page programming mode disabled
217     FLASH->PECR &= ~FLASH_PROG;                // Program memory deselected   
218   }                                            
219                                                
220   return (0);                                   // Done
221 }
222 #endif  // FLASH_MEMORY
FlashPrg.c

  

  从上面我们就可以看出了,下载程序的时候就是调用了上面的几个函数,跟我们自己写Flash没有太大的区别。那么程序都编程完成之后,

怎么生成FLM文件呢?我们先编译工程,完成之后你去看你的工程输出目录,这个时候你就已经可以找到FLM后缀的文件了,这个就是你自己

的编程算法,把它复制到 ' MDK安装路径 '\ARM\Flash下面就可以了,在选项卡里选择你自己的编程算法就可以使用了。

  

结束

  到这里,你已经可以自己实现一个编程算法了。但是细心的小伙伴可能会发现,这个过程下来其实和我们自己的项目工程没有什么区别,

但是为什么我们自己的工程就生成不了FLM文件呢?哈哈,小伙伴可以自己看一看编译的日志,有没有类似下面的日志

 

   原来.FLM文件跟.axf文件是一样的,就是改了一下文件后缀。具体.axf文件又是什么呢?哈哈, 我就不说了,感兴趣的小伙伴们可以自己去了解一下!

 

posted @ 2019-11-21 18:12  JiuLiBlog  阅读(15857)  评论(1编辑  收藏  举报