H7-TOOL自制Flash读写保护算法系列,为华大电子CIU32F003制作使能和解除算法,支持在线烧录和脱机烧录使用2025-06-20

说明:

很多IC厂家仅发布了内部Flash算法文件,并没有提供读写保护算法文件,也就是选项字节算法文件,需要我们制作。

实际上当前已经发布的TOOL版本,已经自制很多了,比如已经支持的兆易创新大部分型号,新唐的大部分型号等。但是依然有些厂家还没自制,所以陆续开始为这些厂家提供读写保护支持。

近期已经自制了STM32H7全系列,N32G003,N32G031, N32G423x, STM32U5全系列和凌欧LKS32MC03X,复旦微FM33LE系列,凌欧的LKS32MC45x,LKS32MC05x,LKS32MC08x提供Flash保护支持

这次为华大电子的CIU32F003系列提供支持

实现效果:

从2.30版本开始将正式带此支持,支持解除和使能。

实现代码和原理

通过H7-TOOL的LUA小程序就可以方便的实现保护解除和使能,不需要自制算法文件。

对应的代码如下,这个不需要用户去管,已经封装到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_MODE_IDLE       = 0x00000000
local FLASH_MODE_PROGRAM    = 0x00000002
local FLASH_MODE_PAGE_ERASE = 0x00000004
 
local 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                 = 0x7C6E8391
 
local OB_UNLOCK_KEY1         = 0x6A894D7B
local OB_UNLOCK_KEY2         = 0x7C311F5A
 
--判断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_BSY) == 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 i
        local ob_16
        --local usertmp
 
        print("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 do
                ob_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()
        end
 
        delayms(500)
 
        pg_reset(100)
 
        return err
end

通过TOOL的寄存器检测功能可以了解各种寄存器地址和状态信息,大大方便算法文件自制:

相关推荐
(Charon)16 小时前
【C++】定时器进阶:使用最小堆管理定时任务
c++·算法
hansang_IR16 小时前
【题解】 [省选联考 2021 A/B 卷] 卡牌游戏
c++·算法
这个DBA有点耶16 小时前
COUNT慢不是因为用了*,是这5个原因——1000万行数据实测+执行计划深度解析
数据库·mysql·算法
贾伟康16 小时前
【口算王|01】HarmonyOS ArkTS 口算题生成实战:按年级、运算类型和难度生成可控题目
算法·harmonyos·arkts·随机生成·口算题
lzx_00216 小时前
C++11(一)
开发语言·c++·算法
529宝宝起名网17 小时前
用 Python 实现名字寓意评分算法:基于 NLP 语义分析的名字内涵深度评估
python·算法·自然语言处理
带多刺的玫瑰18 小时前
Leecode#26刷题之删除有序数组中的重复项
数据结构·算法·leetcode
en.en..18 小时前
C语言核心解析:#define与typedef本质区别
开发语言·c++·算法
wabs66621 小时前
关于二叉树【429.N叉树的层序遍历的思考】
数据结构·c++·算法·leetcode·二叉树
hetao173383721 小时前
2026-09-08 hetao1733837 的刷题记录
c++·算法