工程配置主要介绍以下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('%02X', 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