PY32F072_64K
以下 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 = 0x08000000 --目标芯片flash烧录起始地址
FLASH_PAGE_SIZE = 1024 --目标芯片flash页(page)大小
program_syscall = {
breakpoint = 0x20000001,
static_base = 0x20000400,
stack_pointer = 0x20000908
}
flash_algo = {
init = 0x200001A9,
uninit = 0x20000205,
erase_chip = 0x2000021F,
erase_sector = 0x200002AD,
program_page = 0x20000323,
program_buffer = 0x20000408,
algo_start = 0x20000000,
program_buffer_size = 0x00000100
}
flash_code = {
0xE00ABE00, 0x062D780D, 0x24084068, 0xD3000040, 0x1E644058, 0x1C49D1FA, 0x2A001E52, 0x4770D1F2,
0x4770BA40, 0x4770BAC0, 0x43412128, 0x18894AE8, 0xB2C96B89, 0x60114AE7, 0x43412128, 0x18894AE4,
0x04096B89, 0x4AE30E09, 0x21286111, 0x4AE04341, 0x6B891889, 0x0DC901C9, 0x60514ADE, 0x43412128,
0x18894ADB, 0xB2C96C09, 0x60914ADA, 0x43412128, 0x18894AD7, 0x01496C09, 0x4AD60D49, 0x212860D1,
0x4AD34341, 0x6C891889, 0x0BC903C9, 0x61514AD1, 0x43412128, 0x18894ACE, 0x03C96D09, 0x4ACD0BC9,
0x21286191, 0x4ACA4341, 0x6D891889, 0x4AC9B289, 0x212861D1, 0x4AC64341, 0x6D891889, 0x4AC50C09,
0x47706211, 0x48C4B500, 0x21076840, 0x40080349, 0x444949C2, 0x48C06008, 0x0C006840, 0x49BC0400,
0x43086A09, 0x604849BC, 0x48BBBF00, 0x21016800, 0x40080289, 0xD1F84288, 0xF7FF2004, 0xBD00FF95,
0x684048B5, 0x03492107, 0x49B44388, 0x68094449, 0x49B14308, 0x48B16048, 0x68004448, 0x03492101,
0xD0231A40, 0xD0171A40, 0xD00B1A40, 0xD1271A40, 0x684048A9, 0x04000C00, 0x6A0949A5, 0x49A64308,
0xE0276048, 0x684048A4, 0x04000C00, 0x698949A0, 0x49A14308, 0xE01D6048, 0x6840489F, 0x04000C00,
0x6909499B, 0x499C4308, 0xE0136048, 0x6840489A, 0x04000C00, 0x68894996, 0x49974308, 0xE0096048,
0x68404895, 0x04000C00, 0x68094991, 0x49924308, 0xBF006048, 0xBF00BF00, 0x6800488F, 0x02892101,
0x42884008, 0x4770D1F8, 0x4603B530, 0x4615460C, 0x498C488B, 0x488C6088, 0xF7FF6088, 0x4889FF83,
0x21016900, 0x49874308, 0x46086108, 0x14C96A00, 0x42884008, 0x4885D006, 0x60084985, 0x60482006,
0x60884884, 0x6A00487F, 0x03092101, 0x42884008, 0x4881D006, 0x21FF6840, 0x43083181, 0x6048497E,
0xBD302000, 0x4602B500, 0xFF7AF7FF, 0x69404875, 0x07C92101, 0x49734308, 0x20006148, 0x4871BD00,
0x21016900, 0x496F4308, 0x46086108, 0x21046940, 0x496C4308, 0x46086148, 0x21016940, 0x43080609,
0x61484968, 0x210120FF, 0x600806C9, 0x8F4FF3BF, 0x4869E008, 0x217F6800, 0x49674308, 0x48676008,
0x60084963, 0x6900485F, 0x04092101, 0x28004008, 0x485CD1EF, 0x21046940, 0x495A4388, 0x46086148,
0x21016940, 0x43880609, 0x61484956, 0x69004608, 0x0FC007C0, 0xD1072800, 0x69004608, 0x43082101,
0x61084950, 0x47702001, 0xE7FC2000, 0x484D4601, 0x22016900, 0x4A4B4310, 0x46106110, 0x14D26940,
0x4A484310, 0x46106150, 0x22016940, 0x43100612, 0x61504A44, 0x600820FF, 0x8F4FF3BF, 0x4846E008,
0x227F6800, 0x4A444310, 0x48446010, 0x60104A40, 0x6900483C, 0x04122201, 0x28004010, 0x4839D1EF,
0x11526940, 0x4A374390, 0x46106150, 0x22016940, 0x43900612, 0x61504A33, 0x47702000, 0x20014603,
0xB5304770, 0x1DC84603, 0x0A0130F8, 0x482D0209, 0x24016900, 0x4C2B4320, 0xE0456120, 0x69404829,
0x43202401, 0x61604C27, 0x69404620, 0x06242401, 0x4C244320, 0x20006160, 0x0084E00E, 0x00855914,
0x283E515C, 0x4C1FD106, 0x25016964, 0x432C04ED, 0x616C4D1C, 0xB2E01C44, 0xD3EE2840, 0x8F4FF3BF,
0x481DE008, 0x247F6800, 0x4C1B4320, 0x481B6020, 0x60204C17, 0x69004813, 0x04242401, 0x28004020,
0x4810D1EF, 0x08406940, 0x4C0E0040, 0x46206160, 0x24016940, 0x43A00624, 0x61604C0A, 0x330133FF,
0x320132FF, 0x390139FF, 0xD1B72900, 0xBD302000, 0x1FFF3200, 0x40022100, 0x40021000, 0x00000004,
0x45670123, 0x40022000, 0xCDEF89AB, 0x00005555, 0x40003000, 0x00000FFF, 0x40002C00, 0x0000AAAA,
0x00000000, 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