工程配置主要介绍以下6点:
(1) ota文件生成
(2) 画面配置
(3) lua api介绍
(4) 串口升级ota流程图
(5) lua 串口升级源码
(6) lua sd卡升级源码
5.2.1 ota文件生成
在 visualtft软件菜单栏点击
,将弹出【量产下载】弹窗界面,如图5-3所示:
图5-3 量产下载
点击【ota升级包…】,打包生产ota.bin文件,如图5-4所示
图5-4 ota文件生成
注意:
ota文件可以指定或全部文件打包升级,相关下载项说明如下所示:
-
下载图片资源:gif、iocn、图片等。增加、修改、删除图片 ui,应勾选此项。
-
下载触碰配置:控件、lua、工程相设置参数。增加控件(非图片)、修改、删除等,应勾选该项。
-
下载字库资源:增加、删除、修改字库样式或增加一个字体大小等,应勾选该项。
-
下载音频文件:增加、删除、修改音频文件等,应该勾选此项。
-
下载音频文件:增加、删除、修改视频文件等,应该勾选此项。
-
下载音频文件:增加、删除、修改系统键盘等,应该勾选此项。
即用户修改对应下载项后,打包内容可选择为“指定文件”。
5.2.2 画面配置
本例程,只配置下载部分的画面及控件,在米乐体育官方下载主页面(画面id0)中,添加以下控件:
-
控件id88 :文本控件,显示下载信息。本例程中显示下载进度、解压进度。
-
控件id188:进度条控件,显示下载信息。本例程中显示下载进度、解压进度。
本例程中,屏幕初上电始化后,在lua脚本设置文本控件、进度条控件隐藏。当用户单片机发送开始升级指令时,显示出控件id88、id188。如图5-5所示:
图5-5 画面配置
5.2.3 lua api介绍
本例程中,ota升级相关api如下:
1. ota_init(md5, filesize, addr)
设置ota写入参数
-
md5:字符串,固定为‘0123456789abcdef’
-
filesize:ota.bin文件的大小,单位:byte
-
addr:固定为0x800000(16进制)
如ota.bin文件大小为17542byte,则ota_init(‘0123456789abcdef’, 17542, 0x800000)。
2. ota_write(writetb)
ota写入,用户调用ota_write(writetb),将writetb数据写入到0x800000地址。
-
writetb:写入字节数据,写入大小为2048 byte,不足2048byte补零。写入该地址的数据掉电后不清除。
3. ota_check_upgrade(state)
ota.bin文件校验、解压。当用户将ota.bin文件传输完毕后,调用ota_check_upgrade(state)对ota.bin进行先校验在解压,解压成功后即已经升级完成,屏幕自动重启。
4. ota_destroy()
清除ota数据:对0x800000地址写入的数据清除。
5. on_ota_progress(status,value)
ota校验、解压回调。当用户ota_check_upgrade(state)函数后,会自动回到该api。
-
status:状态。1-校验过程,2-校验结果,3-解压过程,4解压结果
-
value:处理结果。
5.2.4 串口升级ota流程图
m系列串口屏需要使用 ota.bin 文件进行升级,ota.bin 生成方式参考ota文件生成章节。详细指令可参考附录a。升级流程如图5-6所示:
图5-6 ota流程
5.2.5 lua 串口升级源码
1. 初始化加载
本例程中,采用大彩协议自定义指令实现(ee b6 … ff fc ff ff),且ota实现已封装在‘ota.lua’中。用户需要在‘main.lua’处理以下关键点:
注意:ota.lua文件里面也需要更改画面id以及控件id
-
初始化:加载ota.lua文件
-
初始化:初始化隐藏ota 升级的进度
-
串口回调:判断是否是b6指令
代码如程序清单 1所示。
程序清单 1 main.lua初始化
--------------------------------------------------------------------------
-------------------------screen id define strat----------------------------
--------------------------------------------------------------------------
--screen id variant: define rule 'sc_' name
sc_lock = 0 --升级画面的id
--------------------------------------------------------------------------
--------------------------- screen id define end ---------------------------
--------------------------------------------------------------------------
function on_init()
dofile('ota.lua') --加载ota.lua文件
my_assecc_ota(0) --隐藏ota升级进度
end
function on_uart_recv_data(packet)
collectgarbage("collect")
local isota = packet[1]
print('> funcode = '..string.format('x', packet[2]))
if isota == 0xb6
then
ota_operating(packet) --ota处理流程
end
end
2.开始下载
当屏幕接收到用户主板发送开始下载指令(ee b6 len 88 11 baudrate filesize down_name ff fc ff ff),先判断文件大小和文件名称是否合法,在显示下载进度部分的控件→响应主板→ota_init(先清除备份区,在初始化) →提升波特率。代码如程序清单 1所示。
程序清单 2 开始下载
--uart ota transmission operation
function ota_operating(packet)
local datalen = (packet[2] << 8) | packet[3]
local funcode = packet[4]
local cur_screen = get_current_screen()
if funcode == ota_code
then
local child_code = packet[5]
local down_name = ''
if child_code == _start_down
then
baudrate = uart_get_baudrate()
local baudratetemp = 115200
baudratetemp = (packet[6] << 24) |
(packet[7] << 16) |
(packet[8] << 8) |
(packet[9] << 0)
filesize = (packet[10] << 24) |
(packet[11] << 16) |
(packet[12] << 8) |
(packet[13] << 0)
for i = 14, (#(packet) - 4)
do
down_name = down_name..string.char(packet[i])
end
if down_name == filename and filesize > 0
then
my_assecc_ota(1)
down_state = 1
change_screen(sc_lock)
my_uartsend_ota(child_code, ota_suc)
if en_ota_sd == 1
then
......
else
pre_sn = -1
ota_cnt = 0
ota_writetb = {}
ota_writebyte = 0
transfersize = 0
set_value(sc_lock, 88, 0)
set_text(sc_lock,
188,
'downloading : 0 %
[ '..math.ceil(transfersize)..' byte / '..
math.ceil(filesize)..' byte ]')
ota_destroy()
ota_addr = ota_init('0123456789abcdef', filesize, 0x800000)
end
uart_set_baudrate(baudratetemp)
else
my_uartsend_ota(child_code, ota_nodown)
end
......
end
end
end
3. 数据包
当屏幕接收到用户主板发送的数据指令(ee b6 len 88 22 sn packet checksum ff fc ff ff),先判断数据包长度和大小、sn、校验码等是否合法。在传输累计2048字节后(传输4次,每次512字节)则调用ota_write(ota_writetb)写到0x800000地址。若最后一次写入的数据累计后不足2048字节,屏幕自动补零写入。代码如程序清单 3所示。
程序清单 3 ota写入
--uart ota transmission operation
function ota_operating(packet)
local datalen = (packet[2] << 8) | packet[3]
local funcode = packet[4]
local cur_screen = get_current_screen()
if funcode == ota_code
then
--ee b6 len(2byte) 88 11 filesize(4byte) filename ff fc ff ff
local child_code = packet[5]
local down_name = ''
if child_code == _start_down
then
......
elseif child_code == _dwoning
then
--ee b6 len(2byte) 88 22 01 00 00 11 11 check_h check_l ff fc ff ff
local sn = packet[6]
if pre_sn == 255
then
pre_sn = -1
end
print(' > pre_sn = '..pre_sn..' / sn = '..sn)
if pre_sn 1 == sn
then
local packsize = #(packet) - 13 1
if packsize > 0 and packsize <= otauartpacketsize
then
if ((packsize 13) == (#(packet) 1)) and
(((#(packet) 1) - 13) > 0)
then
local ischeckture = my_checksum(packet)
if ischeckture == 1
then
transfersize = packsize transfersize
local prg = string.format ('%.1f', ((transfersize *
100) / filesize))
set_value(sc_lock, 88, math.ceil((transfersize *
1000) / filesize))
set_text(sc_lock, 188, 'downloading : '..prg..' %
[ '..math.ceil(transfersize)..' byte / '..math.ceil(filesize)..' byte ]')
for i = 7, (#(packet) - 6)
do
ota_writetb[ota_writebyte] = packet[i]
ota_writebyte = ota_writebyte 1
end
if #(ota_writetb) >= 0
then
local isotawrite = 0
ota_cnt = ota_cnt 1
if ota_cnt == 4
then
isotawrite = 1
elseif ota_cnt < 4 and transfersize == filesize
then
isotawrite = 1
end
if isotawrite == 1
then
if #(ota_writetb) <= 2047
then
for i = (#(ota_writetb) 1), 2047
do
ota_writetb[ota_writebyte] = 0x00
ota_writebyte = ota_writebyte 1
end
end
......
local _write = ota_write(ota_writetb)
ota_cnt = 0
ota_writebyte = 0
ota_writetb = {}
end
pre_sn = sn
my_uartsend_ota(child_code, ota_suc, pre_sn)
end
end
else
--check sum error
my_uartsend_ota(child_code,
ota_packet_checkfail, (pre_sn 1))
end
else
--size > 512byte error
print(' > packet size > '..otauartpacketsize..' error !')
end
else
--sn error
my_uartsend_ota(child_code, ota_snfail, (pre_sn 1))
end
......
end
end
end
4. 下载完成
当屏幕接收到用户主板确认升级的指令(ee b6 len 88 33 01 ff fc ff ff),则调用ota_check_upgrade(1)开始进入校验解压过程。代码如程序清单 4所示。
程序清单 4 开始升级
--uart ota transmission operation
function ota_operating(packet)
local datalen = (packet[2] << 8) | packet[3]
local funcode = packet[4]
local cur_screen = get_current_screen()
if funcode == ota_code
then
--ee b6 len(2byte) 88 11 filesize(4byte) filename ff fc ff ff
local child_code = packet[5]
local down_name = ''
if child_code == _start_down
then
......
elseif child_code == _dwoning
then
......
elseif child_code == _end_down and down_state == 1
then
local isupdata = packet[6]
if isupdata == 0x01
then
my_uartsend_ota(child_code, ota_suc)
......
ota_check_upgrade(1)
end
......
end
end
end
5. 校验解压
当屏幕进入升级过程,会自动调用on_ota_progress(status,value)进入校验、解压过程,校验中→校验结果→解压中→解压结果→恢复波特率→重启,代码程序清单 5所示。
程序清单 5 校验解压
function on_ota_progress(status,value)
--checking
if status == 1 and value == 0
then
set_value(sc_lock, 88, value)
set_text(sc_lock, 188, '')
refresh_screen()
--check result
elseif status == 2
then
my_uartsend_ota(_file_check, value)
--unpacking
elseif status == 3
then
set_value(sc_lock, 88, value*10)
set_text(sc_lock, 188, 'flash_updatesects : '..value..' %')
refresh_screen()
--unpacking result
elseif status == 4
then
my_uartsend_ota(_unzip, value)
print('> baudrate = '..baudrate)
uart_set_baudrate(baudrate)
delay_ms(100)
end
end
5.2.6 lua sd升级源码
本例程中,用户还可以将ota.bin文件放在sd卡中进行升级,本例程中已将sd升级功能封装在‘ota.lua’中,用户只需要在sd插入回调函数里调用my_sd_updata
ota()即可。代码程序清单 5所示。
程序清单 6 sd卡升级源码
--main.lua
function on_sd_inserted(dir)
my_sd_updataota()
end
--ota.lua
--sd update ota
function my_sd_updataota()
local finish = 0
if file_open(sd_path, 1) == true
then
size = file_size()
ota_destroy()
local sdota_addr = ota_init('0123456789abcdef', size, 0x800000)
--ota resume
if sdota_addr > 0
then
file_seek(sdota_addr)
end
while(true)
do
local rddata = file_read(2048)
if #(rddata) < 2047
then
for i = (#(rddata) 1), 2047
do
rddata[i] = 0x00
end
finish=1
end
ota_write(rddata)
print('> finish = '..finish)
if finish == 1 then
break
end
end
file_close()
my_assecc_ota(1)
ota_check_upgrade(1)
end
end