硬汉嵌入式论坛

 找回密码
 立即注册
查看: 346|回复: 3
收起左侧

[脱机烧录] 为H7-TOOL脱机烧录再次自制Flash读写保护算法,创造史上最多锁死次数,一块接一块根本停不下来

[复制链接]

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2025-6-30 08:28:23 | 显示全部楼层 |阅读模式
为什么要自制:

很多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程序,看看效果正常不,估计有什么机关没注意到。

123345.png

配置代码如下,保锁死,需要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)











回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2025-6-30 08:38:33 | 显示全部楼层
   过几天再买10颗芯片,主要是要支持下Level1保护,毕竟可以恢复,Level2会彻底锁死无法恢复
回复

使用道具 举报

1

主题

131

回帖

139

积分

初级会员

积分
139
发表于 2025-6-30 10:46:53 | 显示全部楼层
联系一下原厂呢?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
 楼主| 发表于 2025-6-30 11:01:37 | 显示全部楼层
nnqtdf 发表于 2025-6-30 10:46
联系一下原厂呢?

准备C代码测试下,看看他们原始的SDK API正常不
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 06:57 , Processed in 0.041180 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表