说明:
很多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 & 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的寄存器检测功能可以了解各种寄存器地址和状态信息,大大方便算法文件自制:
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/Simon223/article/details/143367898
|