说明:
很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。
实际上当前已经发布的TOOL版本,已经自制很多了。但是依然有些厂家还没自制,所以陆续开始为这些厂家提供读写保护支持。
实现效果:
本次添加国民技术的N32G003,从2.26版本开始将正式带此支持,支持解除和使能。
实现代码和原理
通过H7-TOOL的LUA小程序就可以方便的实现保护解除和使能,不需要自制算法文件。
对应的代码如下,这个不需要用户去管,已经封装到TOOL里面了,这里给大家分享是方便大家了解:
--寄存器
local FLASH_FLASHKEY = 0x40022004
local FLASH_OPTKEY = 0x40022008
local FLASH_CTRL = 0x40022010
local FLASH_FLASH_STS = 0x4002200C
local FLASH_OB_Address = 0x1FFFF600
--寄存器bit
local CTRL_Set_OPTER = 0x00000020
local CTRL_Set_START = 0x00000040
local CTRL_Reset_OPTER = 0x0000FFDF
local CTRL_Set_OPTPG = 0x00000010
local FLASH_FLAG_PGERR = 0x00000004 -- /*!< FLASH Program error flag */
local FLASH_FLAG_WRPERR = 0x00000010 -- /*!< FLASH Write protected error flag */
local FLASH_FLAG_EOP = 0x00000020 -- /*!< FLASH End of Operation flag */
local FLASH_STS_CLRFLAG = 0x34 -- (FLASH_FLAG_PGERR | FLASH_FLAG_WRPERR | FLASH_FLAG_EOP)
local FLASH_RDP_RDP1 = 0x000000FF -- /*!< Read protection option byte */
local FLASH_USER_USER = 0x00FF0000 -- /*!< User option byte */
local FLASH_FLAG_BUSY = 0x00000001 -- /*!< FLASH Busy flag */
local OBR_USER_MSK = 0x000000FC
local L1_RDP_Key = 0xFFFF00A5
--常量值
local UNLOCK_KEY1 = 0x45670123
local UNLOCK_KEY2 = 0xCDEF89AB
local OB_UNLOCK_KEY1 = 0x45670123
local OB_UNLOCK_KEY2 = 0xCDEF89AB
--判断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 FLASH_WaitForLastOpt(void)
local i
local reg = {}
for i = 1, 5000, 1 do
reg = {pg_read32(FLASH_FLASH_STS)}
if (CheckFlagQuit0(reg, FLASH_FLAG_BUSY) == 0) then
break
end
delayms(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_8
local ob1
--local usertmp
print("MCU_ProgOptionBytes()")
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)
--FLASH->CTRL |= CTRL_Set_OPTER;
--value,re = pg_read32(0x40022010)
--value = (value | CTRL_Set_OPTER)
--print(string.format("(0x40022010) = 0x%x",value))
pg_write32(FLASH_CTRL, 0x220)
--FLASH->CTRL |= CTRL_Set_START;
--value,re = pg_read32(0x40022010)
--value = (value | CTRL_Set_START)
--print(string.format("(0x40022010) = 0x%x",value))
pg_write32(FLASH_CTRL, 0x260)
-- 等的操作完成
FLASH_WaitForLastOpt()
-- FLASH.FLASH_STS = 0x34
-- FLASH_ClearFlag(FLASH_STS_CLRFLAG)
pg_write32(FLASH_FLASH_STS, FLASH_STS_CLRFLAG)
-- if the erase operation is completed, disable the OPTER Bit
-- FLASH->CTRL &= CTRL_Reset_OPTER;
-- value,re = pg_read32(0x40022010)
-- value = (value & CTRL_Reset_OPTER)
-- print(string.format("(0x40022010) = 0x%x",value))
pg_write32(FLASH_CTRL, 0x200)
-- Enable the Option Bytes Programming operation
-- FLASH->CTRL |= CTRL_Set_OPTPG;
-- value,re = pg_read32(0x40022010)
-- print(string.format("(0x40022010) = 0x%x",value))
-- value = (value | CTRL_Set_OPTPG)
pg_write32(FLASH_CTRL, 0x210)
-- FLASH.FLASH_OB 解除保护
-- value,re = pg_read32(0x4002201C)
-- usertmp = ((value & OBR_USER_MSK) << 0x0E)
-- usertmp = ((L1_RDP_Key & FLASH_RDP_RDP1) | usertmp)
-- print(string.format("(0x4002201C) = 0x%x",value))
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, ob1)
-- 等的操作完成
FLASH_WaitForLastOpt()
delayms(500)
return err
end
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
通过TOOL的寄存器检测功能可以了解各种寄存器地址和状态信息,大大方便算法文件自制:
微信公众号:armfly_com