說明:
很多IC廠家僅發布了內部Flash算法文件,并沒有提供讀寫保護算法文件,也就是選項字節算法文件,需要我們制作。
實際上當前已經發布的TOOL版本,已經自制很多了,比如已經支持的兆易創新大部分型號,新唐的大部分型號等。但是依然有些廠家還沒自制,所以陸續開始為這些廠家提供讀寫保護支持。
近期已經自制了STM32H7全系列,N32G003,N32G031,??N32G423x, STM32U5全系列和凌歐LKS32MC03X,復旦微FM33LE系列,凌歐的LKS32MC45x,LKS32MC05x,LKS32MC08x提供Flash保護支持
這次為華大電子的CIU32F003系列提供支持
?
實現效果:
從2.30版本開始將正式帶此支持,支持解除和使能。
實現代碼和原理
通過H7-TOOL的LUA小程序就可以方便的實現保護解除和使能,不需要自制算法文件。
對應的代碼如下,這個不需要用戶去管,已經封裝到TOOL里面了,這里給大家分享是方便大家了解:
--寄存器
local FLASH_FLASHKEY = 0x40022008
local FLASH_OPTKEY = 0x4002200C
local FLASH_CTRL = 0x40022014
local FLASH_FLASH_STS = 0x40022010
local FLASH_OB_Address = 0x1FFF0000--寄存器bit
local FLASH_MODE_IDLE = 0x00000000
local FLASH_MODE_PROGRAM = 0x00000002
local FLASH_MODE_PAGE_ERASE = 0x00000004local FLASH_FLAG_EOP = 0x01000000
local FLASH_FLAG_BSY = 0x00010000
local FLASH_FLAG_OPTVERR = 0x00008000
local FLASH_FLAG_WRPERR = 0x00000010 --常量值
local UNLOCK_KEY1 = 0xE57A1A85
local UNLOCK_KEY2 = 0x7C6E8391local OB_UNLOCK_KEY1 = 0x6A894D7B
local OB_UNLOCK_KEY2 = 0x7C311F5A--判斷data數組標志,全部為0則退出
function CheckFlagQuit0(data, mask)local ilocal retif (MULTI_MODE > 0) thenret = 0for i = 1, MULTI_MODE, 1 doret = ret | (data[i] & mask)endelseret = data[1] & maskendreturn ret
end--等待超時,(解除讀保護時會執行全面擦除)
function FLASH_WaitForLastOpt(void)local ilocal reg = {}for i = 1, 5000, 1 doreg = {pg_read32(FLASH_FLASH_STS)}if (CheckFlagQuit0(reg, FLASH_FLAG_BSY) == 0) thenbreakenddelayms(1)end
end--芯片專有的解除保護函數
function MCU_RemoveProtect(void)MCU_ProgOptionBytes(OB_SECURE_OFF)
end--沒有FLM的MCU,用腳本實現編程OB。 返回 "OK" or "error"
function MCU_ProgOptionBytes(ob)local err = "OK"local ob_8local ob1local ilocal ob_16--local usertmpprint("MCU_ProgOptionBytes()")pg_reset(100)pg_write32(FLASH_FLASHKEY, UNLOCK_KEY1)pg_write32(FLASH_FLASHKEY, UNLOCK_KEY2)pg_write32(FLASH_OPTKEY, OB_UNLOCK_KEY1)pg_write32(FLASH_OPTKEY, OB_UNLOCK_KEY2)-- std_flash_set_operate_mode(mode);pg_write32(FLASH_CTRL, FLASH_MODE_PAGE_ERASE)-- *(uint32_t *)address = 0xFFFFFFFF;pg_write32(FLASH_OB_Address, 0xFFFFFFFF)FLASH_WaitForLastOpt()pg_write32(FLASH_FLASH_STS, (FLASH_FLAG_EOP | FLASH_FLAG_WRPERR))-- std_flash_set_operate_mode(FLASH_MODE_IDLE);pg_write32(FLASH_CTRL, FLASH_MODE_IDLE)-- must added by 2013 FLASH_WaitForLastOpt()ob_8 = hex_to_bin(ob) --hex字符串轉為二進制數組--print_hex(ob_8)for i = 0, 2, 1 doob_16 = string.byte(ob_8, i*2 + 1) + (string.byte(ob_8, i*2 + 2)<<8)+ (((~string.byte(ob_8, i*2 + 1)) << 16) & 0xFF0000)+ (((~string.byte(ob_8, i*2 + 2)) << 24) & 0xFF000000) -- std_flash_set_operate_mode(FLASH_MODE_PROGRAM);pg_write32(FLASH_CTRL, FLASH_MODE_PROGRAM)--ob_8 = hex_to_bin(ob) --hex字符串轉為二進制數組--ob1 = string.byte(ob_8, 1) + (((string.byte(ob_8, 2)) << 16) & 0xFF0000)pg_write32(FLASH_OB_Address+i*4, ob_16)--print_hex(ob_16)--delayms(5)FLASH_WaitForLastOpt()-- std_flash_clear_flag(FLASH_FLAG_ALL_ERR | FLASH_SR_EOP);pg_write32(FLASH_FLASH_STS, (FLASH_FLAG_EOP | FLASH_FLAG_WRPERR))--std_flash_set_operate_mode(FLASH_MODE_IDLE);pg_write32(FLASH_CTRL, FLASH_MODE_IDLE)--FLASH_WaitForLastOpt()enddelayms(500)pg_reset(100)return err
end
通過TOOL的寄存器檢測功能可以了解各種寄存器地址和狀態信息,大大方便算法文件自制: