說明:
很多IC廠家僅釋出了內部Flash演算法檔案,並沒有提供讀防寫演算法檔案,也就是選項位元組演算法檔案,需要我們製作。
實際上當前已經發布的TOOL版本,已經自制很多了。但是依然有些廠家還沒自制,所以陸續開始為這些廠家提供讀防寫支援。
近期已經自制了STM32H7全系列,N32G003,N32G031, STM32U5全系列和凌歐LKS32MC03X。
之前我們已經為兆易創新自制了GD32E50x,GD32E10x,GD32F3x0,GD32F4xx,GD32F10x,GD32F20x,GD32F30x,GD32F1x0,GD32C10x等系列的選項位元組程式設計演算法功能,含讀防寫。
這次為GD32E23x系列也提供支援。
實現效果:
從2.27版本開始將正式帶此支援,支援解除和使能。
實現程式碼和原理
透過H7-TOOL的LUA小程式就可以方便的實現保護解除和使能,不需要自制演算法檔案。
對應的程式碼如下,這個不需要使用者去管,已經封裝到TOOL裡面了,這裡給大家分享是方便大家瞭解:
FLASH_KEYR = 0x40022004 FLASH_OPTKEYR = 0x40022008 FLASH_KEY1 = 0x45670123 FLASH_KEY2 = 0xCDEF89AB FMC_STAT = 0x4002200C FMC_CTL = 0x40022010 FMC_CTL_OBPG = 0x00000010 FMC_CTL_OBER = 0x00000020 FMC_CTL_START = 0x00000040 FMC_STAT_BUSY = 0x00000001 FMC_STAT_PGERR = 0x00000004 FMC_STAT_PGAERR = 0x00000008 FMC_STAT_WPERR = 0x00000010 FMC_STAT_ENDF = 0x00000020 --判斷data陣列標誌,全部為0則退出 function CheckFlagQuit0(data, mask) local i local ret if (MULTI_MODE > 0) then ret = 0 for i = 1, MULTI_MODE, 1 do ret = ret | (data[i] & mask) end else ret = data[1] & mask end return ret end --晶片專有的解除保護函式 function MCU_RemoveProtect(void) MCU_ProgOptionBytes(OB_SECURE_OFF) end function FMC_WaitBusy(ob) local i local reg for i = 1, 50, 1 do reg = {pg_read32(FMC_STAT)} if (CheckFlagQuit0(reg, FMC_STAT_BUSY) == 0) then break end delayms(10) end end --沒有FLM的MCU,用指令碼實現程式設計OB。 返回 "OK" or "error" function MCU_ProgOptionBytes(ob) local i local reg local ob_8 local ob_32 local ob_read = {} local err = "OK" local ch_num if (MULTI_MODE > 0) then ch_num = MULTI_MODE else ch_num = 1 end pg_write32(FLASH_KEYR, FLASH_KEY1) pg_write32(FLASH_KEYR, FLASH_KEY2) pg_write32(FLASH_OPTKEYR, FLASH_KEY1) pg_write32(FLASH_OPTKEYR, FLASH_KEY2) --start erase the option bytes pg_write32(FMC_CTL, pg_read32(FMC_CTL) | FMC_CTL_OBER) pg_write32(FMC_CTL, pg_read32(FMC_CTL) | FMC_CTL_START) FMC_WaitBusy() reg = pg_read32(FMC_CTL) reg = reg & ~FMC_CTL_OBER pg_write32(FMC_CTL, reg) --reset the OBER bit pg_write32(FMC_CTL, pg_read32(FMC_CTL) | FMC_CTL_OBPG) --set the OBPG bi ob_8 = hex_to_bin(ob) --hex字串轉為二進位制陣列 for i = 0, 3, 1 do ob_32 = string.byte(ob_8, 2 * i + 1) + (((~string.byte(ob_8, 2 * i + 1)) << 8) & 0xFF00) + (((string.byte(ob_8, 2 * i + 2)) << 16) & 0xFF0000) + (((~string.byte(ob_8, 2 * i + 2)) << 24) & 0xFF000000) pg_write32(0x1FFFF800 + 4 * i, ob_32) FMC_WaitBusy() end pg_write32(FMC_CTL, pg_read32(FMC_CTL) & ~FMC_CTL_OBPG) --reset the OBPG bit --校驗 for i = 0, 3, 1 do ob_32 = string.byte(ob_8, 2 * i + 1) + (((~string.byte(ob_8, 2 * i + 1)) << 8) & 0xFF00) + (((string.byte(ob_8, 2 * i + 2)) << 16) & 0xFF0000) + (((~string.byte(ob_8, 2 * i + 2)) << 24) & 0xFF000000) ob_read = {pg_read32(0x1FFFF800 + 4 * i)} for j = 1,ch_num,1 do if (ob_32 ~= ob_read[j]) then err = "error" end end end return err end
透過TOOL的暫存器檢測功能可以瞭解各種暫存器地址和狀態資訊,大大方便演算法檔案自制: