说明: 
很多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 
 
 |