为什么要自制:
很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。
实际上当前已经发布的TOOL版本,已经自制很多了,比如已经支持的兆易创新大部分型号,新唐的大部分型号等。但是依然有些厂家还没自制,所以陆续开始为这些厂家提供读写保护支持。
近期已经自制了STM32H7全系列,N32G003,N32G031, N32G423x, STM32U5全系列和凌欧LKS32MC03X,复旦微FM33LE系列,凌欧的LKS32MC45x,LKS32MC05x,LKS32MC08x提供Flash保护支持,以及华大电子的CIU32F003系列
本次自制:
前几天完成了CIU32F003系列Flash读写保护算法自制,所以就准备也CIU32L051也添加上,结果创造了史上最多锁死次数,而且在1个小时内完成。
之前最多锁死次数一直由NXP的S32K和英飞凌的CYT3B保持,锁死了3-4块,这几个板子略贵些,一块200-300. 锁死一个肉疼,因为锁死后这个板子彻底就废了,单买芯片也不便宜。
1、操作前我已经把参考手册里面选项字节操作步骤反复研究,包括SDK代码实现也反复做寄存器操作步骤深究。最终实现的LUA代码也是完全按照这个步骤来的。
2、操作选项字节最重要的一个,不要断电上电复位,一旦断电选项字节将生效,如果有错误的配置将锁死芯片。手持操作先把默认的24个选项字节值读取出来。使用LUA小程序将默认值写入,实际测试重新断电上电完全没问题,也就是操作是可以的。
3、但修改了RDP读保护配置后,问题来了。
第1次锁死:整个选项字节擦除后,仅修改RDP,重新上电直接锁死,使用官方串口ISP也已经识别不到。

第2次锁死:修改了第1次经验,所有24字节都写入默认值,仅修改RDP,重新上电还是锁死。
第3-5次锁死:发现这个RDP不能修改0xAA以外的值,一改就锁死。导致我屡试不爽,一块接着一块被锁死,根本停不下来,上瘾了,必须换个值再测一次,结果一下子锁死三块。但是有256个值呢,都试试就太惨了。
暂时先收手了,这么锁下去可遭不住。改天先在芯片内部运行SDK程序,看看效果正常不,估计有什么机关没注意到。
配置代码如下,保锁死,需要Level2彻底锁死保护可用,注意这个不需要用户去管,如果要整合是最终封装到TOOL里面了,这里给大家分享是方便大家了解:
[Lua] 纯文本查看 复制代码
--寄存器
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_CR_OPT_ERASE = 0x00000010
local FLASH_CR_PG_MODE = 0x00000001
local CTRL_Set_OPTER = 0x00000020
local CTRL_Set_START = 0x00000040
local CTRL_Reset_OPTER = 0x00003FDF
local CTRL_Set_OPTPG = 0x00000010
local FLASH_FLAG_EOP = 0x01000000
local FLASH_FLAG_WRPERR = 0x00000010
local FLASH_FLAG_PROGERR = 0x00000008
local FLASH_FLAG_FSTERR = 0x00000004
local FLASH_FLAG_BSY = 0x00010000
local FLASH_FLAG_ALL_ERR = 0x0000001c -- FLASH_FLAG_PROGERR FLASH_FLAG_WRPERR FLASH_FLAG_FSTERR
local FLASH_FLAG_ALL_ERR1 = 0x0100001c -- FLASH_FLAG_ALL_ERR FLASH_FLAG_EOP
local OBR_USER_MSK = 0x0000001C
local L1_RDP_Key = 0xFFFF00A5
--常量值
local UNLOCK_KEY1 = 0xE57A1A85
local UNLOCK_KEY2 = 0x7C6E8391
local OB_UNLOCK_KEY1 = 0x6A894D7B
local OB_UNLOCK_KEY2 = 0x7C311F5A
--判断data数组标志,全部为0则退出
function CheckFlagQuit0(data, mask)
local i
local ret
ret = data & mask
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_BSY) == 0) then
break
end
delayms(1)
end
-- std_flash_clear_flag(FLASH_FLAG_ALL_ERR | FLASH_SR_EOP);
pg_write32(FLASH_FLASH_STS, FLASH_FLAG_ALL_ERR1)
end
local err = "OK"
local ob_8
local ob1
--local usertmp
print("MCU_ProgOptionBytes()")
pg_init()
--pg_reset(100)
ob1 = pg_read32(FLASH_CTRL)
print_hex(ob1)
re, data = pg_read_mem(FLASH_OB_Address, 24)
print_hex(data)
pg_write32(FLASH_FLASH_STS, FLASH_FLAG_ALL_ERR)
pg_write32(FLASH_FLASHKEY, UNLOCK_KEY1)
pg_write32(FLASH_FLASHKEY, UNLOCK_KEY2)
--pg_write32(FLASH_FLASH_STS, FLASH_STS_CLRFLAG)
--FLASH_WaitForLastOpt()
pg_write32(FLASH_OPTKEY, OB_UNLOCK_KEY1)
pg_write32(FLASH_OPTKEY, OB_UNLOCK_KEY2)
ob1 = pg_read32(FLASH_CTRL)
print_hex(ob1)
-- std_flash_opt_erase_start();
FLASH_WaitForLastOpt()
print("EARSER FLASH_CTRL = ")
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_OPT_ERASE)
FLASH_WaitForLastOpt()
----------------------------------------------------------------------------
--FLASH->CR |= FLASH_CR_PG_MODE;
print("PROG FLASH_CTRL = ")
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_PG_MODE)
--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, 0xff5500aa)
--pg_write32(FLASH_OB_Address, 0xffff0000)
-- 等的操作完成
FLASH_WaitForLastOpt()
-- FLASH->CR &= (~FLASH_CR_PG_MODE)
pg_write32(FLASH_CTRL, 0)
-------------------------------------------------------------------------
FLASH_WaitForLastOpt()
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_PG_MODE)
pg_write32(FLASH_OB_Address+4, 0xcede3121)
FLASH_WaitForLastOpt()
pg_write32(FLASH_CTRL, 0)
-------------------------------------------------------------------------
FLASH_WaitForLastOpt()
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_PG_MODE)
pg_write32(FLASH_OB_Address+8, 0xfe0001ff)
FLASH_WaitForLastOpt()
pg_write32(FLASH_CTRL, 0)
-------------------------------------------------------------------------
FLASH_WaitForLastOpt()
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_PG_MODE)
pg_write32(FLASH_OB_Address+12, 0xffff0000)
FLASH_WaitForLastOpt()
pg_write32(FLASH_CTRL, 0)
-------------------------------------------------------------------------
FLASH_WaitForLastOpt()
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_PG_MODE)
pg_write32(FLASH_OB_Address+16, 0xfe0001ff)
FLASH_WaitForLastOpt()
pg_write32(FLASH_CTRL, 0)
-------------------------------------------------------------------------
FLASH_WaitForLastOpt()
print_hex(pg_read32(FLASH_CTRL))
pg_write32(FLASH_CTRL, FLASH_CR_PG_MODE)
pg_write32(FLASH_OB_Address+20, 0xffff0000)
FLASH_WaitForLastOpt()
pg_write32(FLASH_CTRL, 0)
--pg_write32(FLASH_CTRL, 0x08000000)
re, data = pg_read_mem(FLASH_OB_Address, 24)
print_hex(data)
--pg_reset(100)
delayms(2000)
|