跳到主要内容

HC32F460_512K

以下 Lua 脚本代码实现了擦除+烧录功能。

--[[
该 Lua 脚本代码实现功能: 当检测到按键按下后,对 xxx 型号单片机的 flash 先执行整片擦除(chip erase)
,然后将 FW.bin 文件按单片机页(page)大小,逐页写入单片机 flash 中,最后将 bin 文件的 CRC32 值和芯片中已烧录
内容的 CRC32 值进行对比,二者一样则说明 bin 文件烧录成功。
]]--


------以下内容由Keil Pack 提供的对应单片机型号的 XXX.flm flash 编程算法文件通过 flm2lua.exe 工具软件一键自动生成------
--开发者如果需要烧录其他型号的arm cortex-m mcu,请自行用 flm2lua.exe 工具生成后覆盖下面的内容

FLASH_START_ADDR = 0x00000000 --目标芯片flash烧录起始地址
FLASH_PAGE_SIZE = 2048 --目标芯片flash页(page)大小

program_syscall = {
breakpoint = 0x20000001,
static_base = 0x20000550,
stack_pointer = 0x20000B54
}

flash_algo = {
init = 0x2000020D,
uninit = 0x2000036D,
erase_chip = 0x20000101,
erase_sector = 0x2000017D,
program_page = 0x20000271,

program_buffer = 0x20000554,
algo_start = 0x20000000,
program_buffer_size = 0x00000200
}

flash_code = {
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x4770BA40, 0x4770BAC0, 0x0030EA4F, 0x00004770, 0x5001F24A, 0x8008490A, 0x7800480A, 0x0007F020,
0x39264908, 0x0026F881, 0x68004807, 0x00F0F020, 0x60084905, 0x49032001, 0x70081D09, 0x00004770,
0x4005440E, 0x40054026, 0x40010408, 0x5101F24A, 0x80114A16, 0x6A094916, 0x0170F021, 0x4A143110,
0xF2406211, 0x68094104, 0x0001F001, 0x4911B150, 0x60114A11, 0x68094911, 0x01F0F021, 0x4A0F3140,
0xE0096011, 0x4A0C490E, 0x490C6011, 0xF0216809, 0x315001F0, 0x60114A09, 0x4A052100, 0x7011322A,
0x4A032105, 0x1026F882, 0x00004770, 0x4005440E, 0x40054000, 0x10102781, 0x4005410C, 0x40010408,
0x10101F81, 0x4603B570, 0xE003460C, 0x5B01F814, 0x5B01F803, 0xF1A21E15, 0xD1F70201, 0x0000BD70,
0xF000B510, 0xF7FFF9AF, 0x481BFF93, 0xF0206800, 0x1C400001, 0x60084918, 0x68004608, 0x0070F020,
0x60083050, 0x68004608, 0x7080F420, 0x7080F500, 0xF44F6008, 0xF2414410, 0x60202034, 0xF000E001,
0x480DF991, 0x68001D00, 0x7080F400, 0xD0F62800, 0xF988F000, 0x68004808, 0x0070F020, 0x60084906,
0x68004608, 0x0001F020, 0xF7FF6008, 0xF000FF7F, 0x2000F979, 0x0000BD10, 0x4001040C, 0x4604B530,
0xF7FF4D20, 0xF000FF55, 0x481FF96D, 0xF0206800, 0x1C400001, 0x6008491C, 0x68004608, 0x0070F020,
0x60083040, 0x68004608, 0x7080F420, 0x7080F500, 0xF0006008, 0xBF00F957, 0x60202000, 0xF952F000,
0xF000E001, 0x4810F94F, 0x68001D00, 0x7080F400, 0x1E68B910, 0xD1F41E05, 0xF944F000, 0x6800480A,
0x0070F020, 0x60084908, 0x68004608, 0x0001F020, 0xF0006008, 0xF7FFF937, 0xF000FF39, 0x2000F933,
0x0000BD30, 0x00030D40, 0x4001040C, 0x4604B570, 0x4616460D, 0x49124811, 0x48126008, 0x48106008,
0x6800300C, 0x7080F420, 0x7080F500, 0x310C490C, 0xF24A6008, 0x490C5001, 0x480C8008, 0xF4206A00,
0xF50040E0, 0x490940C0, 0xF44F6208, 0x49064025, 0xF0008008, 0x2000F907, 0x0000BD70, 0xFFFF0123,
0x40010400, 0xFFFF3210, 0x4005440E, 0x40054000, 0x45F8E92D, 0x460C4680, 0xF04F4615, 0x900030FF,
0xF0004F38, 0x4838F8EF, 0xF0206800, 0x1C400001, 0x60084935, 0x68004608, 0x0070F020, 0x60083020,
0x68004608, 0x7080F420, 0x7080F500, 0x46466008, 0xF000BF00, 0xF04FF8D7, 0xE0240A00, 0xF8D2F000,
0x68284F28, 0x1D366030, 0xF0001D2D, 0xE001F8CB, 0xF8C8F000, 0x1D004824, 0xF4006800, 0xB9107080,
0x1E071E78, 0xB917D1F4, 0xE8BD2001, 0x481E85F8, 0x68001D00, 0x000FF000, 0xF000B118, 0x2001F8B3,
0xF10AE7F3, 0xEBBA0A01, 0xD3D70F94, 0x0003F004, 0xF004B138, 0x46290203, 0xF7FF4668, 0x9800FEE3,
0x4F10C601, 0xF000E001, 0x480FF89D, 0x68001D00, 0x7080F400, 0x1E78B910, 0xD1F41E07, 0x2001B90F,
0xF000E7D3, 0x4808F88F, 0xF0206800, 0x49060070, 0x46086008, 0xF0206800, 0x60080001, 0xF882F000,
0xE7C22000, 0x00030D40, 0x4001040C, 0x4604B510, 0xF878F000, 0x68004808, 0x7080F420, 0x60084906,
0x60082001, 0x60082000, 0x49031E40, 0x6008390C, 0xF868F000, 0xBD102000, 0x4001040C, 0x41F0E92D,
0x460E4605, 0xF04F4617, 0x46A80800, 0xE0082400, 0xF858F000, 0x1B01F818, 0x42815D38, 0xE002D000,
0x42B41C64, 0xBF00D3F4, 0xE8BD1928, 0xBF0081F0, 0xF1A01E01, 0xD1FB0001, 0x00004770, 0x481FB510,
0x481F6802, 0xF3C06800, 0x481D0481, 0xF3C06800, 0xB90C2303, 0xE0081192, 0xD1012C01, 0xE0041292,
0xD1012C02, 0xE0001312, 0xB10B1392, 0xD1022B0F, 0xF83AF000, 0xF003E020, 0xB1180001, 0xF000B9E2,
0xE019F833, 0x0002F003, 0xD1042802, 0xD1132A01, 0xF82AF000, 0xF003E010, 0x28040004, 0x2A02D104,
0xF000D10A, 0xE007F821, 0x0008F003, 0xD1032808, 0xD1012A03, 0xF818F000, 0x0000BD10, 0x40049404,
0x40010680, 0x4807B500, 0xF3C06800, 0xB9084000, 0xF816F000, 0x68004803, 0x0001F000, 0xF7FFB908,
0xBD00FFAD, 0x40010680, 0x49034802, 0x48036008, 0x47706008, 0xFFFF0123, 0x40049408, 0xFFFF3210,
0x4823B510, 0xB2926842, 0x68004822, 0x4481F3C0, 0x68004820, 0x6303F3C0, 0x1192B90C, 0x2C01E008,
0x1292D101, 0x2C02E004, 0x1312D101, 0x1392E000, 0x2001B90B, 0x2000E000, 0xD1012B0F, 0xE0002101,
0x43082100, 0xF000B110, 0xE020F827, 0x0001F003, 0xB9E2B118, 0xF820F000, 0xF003E019, 0x28020002,
0x2A01D104, 0xF000D113, 0xE010F817, 0x0004F003, 0xD1042804, 0xD10A2A02, 0xF80EF000, 0xF003E007,
0x28080008, 0x2A03D103, 0xF000D101, 0xBD10F805, 0x40049000, 0x40010680, 0x49034802, 0x48036088,
0x47706088, 0xFFFF0123, 0x40049000, 0xFFFF3210, 0x00000000
}

------以上内容由Keil Pack 提供的对应单片机型号的 XXX.flm flash 编程算法文件通过 flm2lua.exe 工具软件一键自动生成------




------以下内容由Keil Pack 提供的对应单片机型号的 STM32Fxxx_OPT.FLM flash 编程算法文件通过 flm2lua.exe 工具软件一键自动生成------
--开发者如果需要擦除其他型号的arm cortex-m mcu的读保护opt区域,请自行用 flm2lua.exe 工具生成后填充下面的内容

-- <如果不需要擦除类似STM32单片机的OPT区域,这里无需填充> --

------以上内容由Keil Pack 提供的对应单片机型号的 STM32Fxxx_OPT.FLM flash 编程算法文件通过 flm2lua.exe 工具软件一键自动生成------




BIN_FILE_NAME = "FW.bin" --bin文件名称
CRC32_ENABLE = 1 --1:使能CRC32校验, 0:不使能
SWCLK, SWDIO, RESET = "D6", "D5", "D7" --烧录器SWD接口引脚
ButtonIO = "D3"
GreenLedIO = "D2"
RedLedIO = "D1"
PowerIO = "D4"

--10ms中断回调函数
function LIB_10msTimerCallback()
--喂狗
LIB_WatchDogFeed()
end

--整片擦除,烧录,校准
function SWD_DownLoadFlash()
local Re=1 --ok
local Err

print("Start download flash ==================>>>")

--加载由flm文件生成的flash算法
LIB_SwdLoadFlashAlgo(flash_algo, program_syscall, flash_code)

--SWD初始化
Re,Err = LIB_SwdTarget("INIT_DEBUG")
if Re == 0 then print(Err) return Re else print("INIT_DEBUG ok") end
--复位目标芯片并进入flash编程模式,加载flash算法到SRAM
Re,Err = LIB_SwdTarget("TARGET_INIT", FLASH_START_ADDR, 0, 0, 0)
if Re == 0 then print(Err) return Re else print("TARGET_INIT ok") end
--擦除整片flash
Re,Err = LIB_SwdTarget("TARGET_ERASECHIP", 0, 0, 0, 0)
if Re == 0 then print(Err) return Re else print("TARGET_ERASECHIP ok") end

--读bin文件并烧入目标芯片flash中。每次读FLASH_PAGE_SIZE字节(比如1024字节),数量不够的用0xff凑
local readflag = 1
local addr = 0
local content_cnt = 0 --统计烧入的bin字节数量
local page_cnt = 0 --统计实际烧入的page数量

--按目标芯片page大小读取bin文件,每读取一个page烧录一个page,直到读完bin文件为止
while readflag == 1 do
LIB_GpioToggle(GreenLedIO)--绿切换亮灭,实现闪烁
GC(1)--内存回收,防止溢出
read_number, read_content = LIB_FastRdTf(BIN_FILE_NAME, addr, FLASH_PAGE_SIZE)
if read_number > 0 then
content_cnt = content_cnt + read_number
page_cnt = page_cnt + 1
--擦除扇区(前面已经chip擦除了,这里不需要扇区擦除,也因为每个单片机的扇区结构大小不一,不适合循环规律擦除)
--Re,Err = LIB_SwdTarget("TARGET_ERASESECTOR", addr, 0, 0, 0)
--if Re == 0 then print(Err) return Re else print("TARGET_ERASESECTOR ok") end
--按FLASH_PAGE_SIZE的大小进行页写,但read_content中的元素个数是可以小于页大小的
Re,Err = LIB_SwdTarget("TARGET_WR_PAGE", addr, FLASH_PAGE_SIZE, read_content)
if Re == 0 then print(Err) return Re else print(string.format("WRITE PAGE 0x%08X ok", addr+FLASH_START_ADDR)) end
addr = addr + FLASH_PAGE_SIZE
end
--已读完
if read_number < FLASH_PAGE_SIZE then
readflag = 0
end
end

LIB_GpioWrite(GreenLedIO, 1)--绿灯灭

--打印flash烧录总结信息:
print(string.format("Download bin file(%d bytes), actually writed:%d bytes (%d pages), page_size=%d",content_cnt,page_cnt*FLASH_PAGE_SIZE,page_cnt,FLASH_PAGE_SIZE))

--如果是空文件,则报错
if addr <= 0 then
print("Bin file zero size!")
return 0
end

--CRC32校验
if CRC32_ENABLE == 1 then
print("Start CRC32 check...")
--记录烧录文件BIN_FILE的CRC32值
LIB_SwdTarget("TARGET_CRC32_FINAL")
--"TARGET_RD_CRC32CHECK": 开始计算目标芯片中已烧录的内容CRC32,并和BIN_FILE的CRC32对比
r1,r2,r3,r4 = LIB_SwdTarget("TARGET_RD_CRC32CHECK")
--crc报错
if r1 == 0 then
print(string.format("CRC32 fail, crc_flash=0x%08X,crc_file=0x%08X",r3,r4))
return r1
else
print("CRC32 chek ok!")
end
end

--目标芯片执行flash算法uninit,结束烧录状态
Re,Err = LIB_SwdTarget("TARGET_UNINIT", 0, 0, 0, 0)
if Re == 0 then print(Err) return Re else print("TARGET_UNINIT ok") end

print("End download flash success! (^_^)")

return Re
end

--擦除类似STM32单片机的OPT区域(读保护),这个函数不是必须的
function SWD_EraseOpt()
local Re=1 --ok
local Err

print("Start erase opt ==================>>>")

--加载由flm文件生成的flash算法
LIB_SwdLoadFlashAlgo(flash_opt_algo, program_opt_syscall, flash_opt_code)

--SWD初始化
Re,Err = LIB_SwdTarget("INIT_DEBUG")
if Re == 0 then print(Err) return Re else print("INIT_DEBUG ok") end
--复位目标芯片并进入flash编程模式,加载flash算法到SRAM
Re,Err = LIB_SwdTarget("TARGET_INIT", 0, 0, 0, 0)
if Re == 0 then print(Err) return Re else print("TARGET_INIT ok") end
--擦除opt中的内容
Re,Err = LIB_SwdTarget("TARGET_ERASECHIP", 0, 0, 0, 0)
if Re == 0 then print(Err) return Re else print("TARGET_ERASECHIP ok") end
--目标芯片执行flash算法uninit
Re,Err = LIB_SwdTarget("TARGET_UNINIT", 0, 0, 0, 0)
if Re == 0 then print(Err) return Re else print("TARGET_UNINIT ok") end

print("End erase opt success! (^_^)")

return Re
end

--各种初始化代码
--LIB_SystemLogEnable() --使能系统日志,该功能平时不需要
--LIB_LuaTfLogEnable() --使能lua代码中print可以在tf卡上生成日志,该功能平时不需要
--LIB_LuaTfLogDisable()
LIB_LuaHeapExpand("20KB") --烧录时比较费空间,从底层申请扩展20KB空间
LIB_UsbConfig("CDC")--使能usb转串口print打印功能
LIB_ButtonConfig("BTN3",ButtonIO,"L")-- 烧录按键初始化
LIB_GpioOutputConfig("D0","STANDARD")--DNLD IO始化,目前暂时没用
LIB_GpioWrite("D0", 0)
LIB_GpioOutputConfig(PowerIO,"STANDARD")--3V3 Power Mos控制IO始化
LIB_GpioWrite(PowerIO, 1)--给目标芯片供电
LIB_GpioOutputConfig(GreenLedIO,"STANDARD")--绿灯初始化
LIB_GpioWrite(GreenLedIO, 0)--绿灯亮
LIB_GpioOutputConfig(RedLedIO,"STANDARD")--红灯初始化
LIB_GpioWrite(RedLedIO, 1)--红灯灭
--初始SWD离线烧录功能(基于ARM-CMSIS DAP), "D5","D6","D7"分别对应SWCLK, SWDIO, RESET引脚
LIB_ArmSwdConfig(SWCLK, SWDIO, RESET, 72000000, 4000000, CRC32_ENABLE)
--配置开始工作,溢出时间为10秒
LIB_WatchDogConfig("10S")
--使能10ms中断定时器
LIB_10msTimerConfig("ENABLE")

print("Start up~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")

--开始大循环
while(GC(1) == true)
do
key_value = LIB_ButtonQuery("BTN3")
--如果检测到烧录按键短按动作,则启动一次 flash 烧录
if key_value == 1 then
--绿灯亮,红灯灭
LIB_GpioWrite(GreenLedIO, 0)
LIB_GpioWrite(RedLedIO, 1)

--如果需要擦除类似stm32这种单片机的opt读保护
OptEraseOk = 1
if flash_opt_algo~= nil then
if SWD_EraseOpt() ~= 1 then --opt擦除失败
OptEraseOk = 0
print("Erase opt fail! (T_T)")
end
end

--开始烧录
if SWD_DownLoadFlash() == 1 and OptEraseOk== 1 then --成功
print("All finished successed! (^_^)")
LIB_GpioWrite(GreenLedIO, 0)--绿灯亮
LIB_GpioWrite(RedLedIO, 1)--红灯灭
else --失败
print("Download fail! (T_T)")
LIB_GpioWrite(GreenLedIO, 1)--绿灯灭
LIB_GpioWrite(RedLedIO, 0)--红灯亮
end
LIB_SwdTarget("SWD_OFF")--结束,让烧录器的swd接口呈高阻态
LIB_GpioWrite(PowerIO, 0)--目标芯片断电重启
LIB_DelayMs(100)--延时100ms
LIB_GpioWrite(PowerIO, 1)--目标芯片上电
end
end