MDK編程算法
用過MDK下載程序的小夥伴可能都知道,在下載程序以前須要都在Debug設置的Flash Download子選項卡選擇編程算法。大多數時候,html
咱們只要安裝了芯片包以後,就能夠直接獲得對應的編程算法,並不須要咱們去修改它。可是,當你是一個芯片包的開發者,或者你有獨特redis
的下載需求(好比在你的程序里加入一些校驗信息),這個時候你就須要去了解它了!算法
編程算法呢,說白就其實也就是一段程序,主要功能就是擦除相應的內存塊,並將咱們的程序寫入到相應的內存區域上去。express
在你點擊下載按鈕的時候,這段程序會被先下載到RAM上(RAM for Algorithm上的設置),而後纔會經過它,將你的程序寫入到編程
指定的內存區域內。app
實現一個本身的編程算法
怎麼去實現一個本身的編程算法?首先咱們找到本身的MDK的安裝路徑,進入到ARM\Flash文件夾下(例如:D:\Keil_v5\ARM\Flash)。ide
這裏有個編程算法的工程模板,複製這個工程到你的工程文件夾下,重命名你本身的想要的名字。函數
打開工程,裏面主要有兩個文件 FlashPrg.c 和 FlashDev.c:ui
FlashDev.c主要實現了一個設備相關的結構體(根據本身的Flash狀況去實現)this
好比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
從上面咱們就能夠看出了,下載程序的時候就是調用了上面的幾個函數,跟咱們本身寫Flash沒有太大的區別。那麼程序都編程完成以後,
怎麼生成FLM文件呢?咱們先編譯工程,完成以後你去看你的工程輸出目錄,這個時候你就已經能夠找到FLM後綴的文件了,這個就是你本身
的編程算法,把它複製到 ' MDK安裝路徑 '\ARM\Flash下面就能夠了,在選項卡里選擇你本身的編程算法就能夠使用了。
結束
到這裏,你已經能夠本身實現一個編程算法了。可是細心的小夥伴可能會發現,這個過程下來其實和咱們本身的項目工程沒有什麼區別,
可是爲何咱們本身的工程就生成不了FLM文件呢?哈哈,小夥伴能夠本身看一看編譯的日誌,有沒有相似下面的日誌
原來.FLM文件跟.axf文件是同樣的,就是改了一下文件後綴。具體.axf文件又是什麼呢?哈哈, 我就不說了,感興趣的小夥伴們能夠本身去了解一下!
原文出處:https://www.cnblogs.com/jiuliblog-2016/p/11907019.html