H7-TOOL自制Flash讀防寫演算法系列,為兆易創新GD32E23X製作使能和解除演算法,支援線上燒錄和離線燒錄使用(2024-10-29)

硬汉嵌入式發表於2024-10-30

說明:

很多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[i] & 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的暫存器檢測功能可以瞭解各種暫存器地址和狀態資訊,大大方便演算法檔案自制:

相關文章