本帖最后由 卡米拉 于 2021-1-13 17:48 编辑
串口升级ota.bin演示(升级后,屏幕显示彩色圆圈) 一、适合范围 本文档适合医用级的串口屏产品使用。
二、开发环境版本 1.VisualTFT软件版本:V3.0.1.1137及以上的版本。 版本查看: 1)打开VisualTFT软件启动页面如图21软件版本,右上角会显示的软件版本号; 图2-1软件版本
图2-2软件版本
2.串口屏硬件版本: M系列固件 >= V6.3.319.00。 版本查看: 1)查看屏幕背面版本号贴纸; 2)VisualTFT与屏幕联机成功后,右下角显示的版本号。
三、概述 本文介绍VisualTFT PC软件编译生成的‘ota.bin’工程文件,用户通过MCU用串口对屏幕升级的说明。相比之前的 对‘private’ 文件升级,区别如下所示: 文件数量:‘private’是一个文件夹,里面含有多个文件;‘ota.bin’是一个文件 数据交互:‘private’指令交互由固件处理;‘ota.bin’由lua脚本处理。
四、参考资料 1.《LUA 脚本API V1.4》可通过以下链接下载物联型开发包获取:
2.《LUA基础学习》可通过以下链接下载物联型开发包获取:
3.LUA脚本初学者可以通过下面链接进行学习。
4.AT指令,可以通过下面子连接了解
五、教程实现 本例程通过大彩协议自定义指令和用户主板通讯,指令格式为 EE B6 … FF FC FF FF,且将OTA升级部分代码封装成‘ota.lua’文件。若用户采用的是自由串口协议,可参考本例程的方法实现。 5.1 准备工程素材 在实现例程前需要作以下3个准备: 1.硬件平台; 2.软件平台; 3.UI素材。 该例程使用大彩物联型7寸串口屏DC80480M070_1111_0C为验证开发平台。如图5-1所示; 图5-1 M系列7寸串口屏
5.1.1软件平台 图5-2 下载软件 5.2 配置串口屏工程 工程配置主要介绍以下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:处理结果。
当state = 1,value 固定为0当state = 2,0-校验失败,1-校验成功
当state = 3,0-~100,解压进度
当state = 4,0-解压失败,1-解压成功
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初始化
- <font face="宋体" size="3">--------------------------------------------------------------------------
- -------------------------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</font>
复制代码
2.开始下载 当屏幕接收到用户主板发送开始下载指令(EE B6 Len 88 11 baudrate filesize down_name FF FC FF FF),先判断文件大小和文件名称是否合法,在显示下载进度部分的控件→响应主板→OTA_INIT(先清除备份区,在初始化) →提升波特率。代码如程序清单 1所示。 程序清单 2 开始下载 - <font face="宋体" size="3">--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</font>
复制代码
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写入 - <font face="宋体" size="3">--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</font>
复制代码
4.下载完成 当屏幕接收到用户主板确认升级的指令(EE B6 Len 88 33 01 FF FC FF FF),则调用ota_check_upgrade(1)开始进入校验解压过程。代码如程序清单 4所示。
程序清单 4 开始升级 - <font face="宋体" size="3">--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</font>
复制代码
5.校验解压 当屏幕进入升级过程,会自动调用on_ota_progress(status,value)进入校验、解压过程,校验中→校验结果→解压中→解压结果→恢复波特率→重启,代码程序清单 5所示。
程序清单 5 校验解压 - <font face="宋体" size="3">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</font>
复制代码
5.2.6 LUA SD升级源码 本例程中,用户还可以将ota.bin文件放在SD卡中进行升级,本例程中已将sd升级功能封装在‘ota.lua’中,用户只需要在sd插入回调函数里调用my_sd_updata OTA()即可。代码程序清单 5所示。
程序清单 6 SD卡升级源码 - <font face="宋体" size="3">--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</font>
复制代码
附录B DEMO下载链接: http://www.gz-dc.com/uploads/file/20210111/M%20OTA.zip
|