广州大彩串口屏论坛_大彩开发者交流论坛

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 10585|回复: 0

大彩串口屏M系列OTA升级

[复制链接]

106

主题

139

帖子

9850

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
9850
发表于 2021-1-12 17:51:30 | 显示全部楼层 |阅读模式
本帖最后由 卡米拉 于 2021-1-13 17:48 编辑

串口升级ota.bin演示(升级后,屏幕显示彩色圆圈)
一、适合范围
本文档适合医用级的串口屏产品使用。

二、开发环境版本
1.VisualTFT软件版本:V3.0.1.1137及以上的版本。
版本查看:
1)打开VisualTFT软件启动页面如图21软件版本,右上角会显示的软件版本号;
图2-1软件版本

2)打开VisualTFT,在软件右下角可以查看软件版本图22软件版本,最新版本可登录http://www.gz-dc.com/进行下载。
图2-2软件版本

2.串口屏硬件版本: M系列固件 >= V6.3.319.00。
版本查看:
1)查看屏幕背面版本号贴纸;
2)VisualTFT与屏幕联机成功后,右下角显示的版本号。


三、概述
本文介绍VisualTFT PC软件编译生成的‘ota.bin’工程文件,用户通过MCU用串口对屏幕升级的说明。相比之前的 对‘private’ 文件升级,区别如下所示:
文件数量:‘private’是一个文件夹,里面含有多个文件;‘ota.bin’是一个文件
升级协议:‘private’升级的协议是固定,可参考http://www.gz-dc.com/uploads/file/;‘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寸串口屏
其他尺寸M型的串口屏均可借鉴此教程。

5.1.1软件平台
使用大彩自主研发的上位机软件VisualTFT配置工程,登录http://www.gz-dc.com/下载。如图5-2所示;
图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进行先校验在解压,解压成功后即已经升级完成,屏幕自动重启。
  • state:1,进入升级状态。


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’处理以下关键点:
  • 全局变量:修改升级页面对应的画面ID

注意:ota.lua文件里面也需要更改画面ID以及控件ID

  • 初始化:加载ota.lua文件
  • 初始化:初始化隐藏ota 升级的进度
  • 串口回调:判断是否是B6指令
    代码如程序清单 1所示。
    程序清单 1  main.lua初始化

  1. <font face="宋体" size="3">--------------------------------------------------------------------------
  2. -------------------------screen id define strat----------------------------
  3. --------------------------------------------------------------------------
  4. --screen id variant: define rule 'sc_' + name

  5. sc_Lock = 0                   --升级画面的ID
  6. --------------------------------------------------------------------------
  7. --------------------------- screen id define end ---------------------------
  8. --------------------------------------------------------------------------

  9. function on_init()
  10.    
  11.     dofile('ota.lua')  --加载ota.lua文件
  12.     my_assecc_ota(0)   --隐藏ota升级进度
  13. end

  14. function on_uart_recv_data(packet)
  15.    
  16.     collectgarbage("collect")
  17.     local isOTA = packet[1]
  18.    
  19.     print('> funcode = '..string.format('%02X', packet[2]))
  20.    
  21.     if isOTA == 0xB6
  22.     then
  23.         ota_operating(packet)  --ota处理流程
  24.     end
  25. end</font>
复制代码

2.开始下载
当屏幕接收到用户主板发送开始下载指令(EE B6 Len 88 11 baudrate filesize down_name FF FC FF FF),先判断文件大小和文件名称是否合法,在显示下载进度部分的控件→响应主板→OTA_INIT(先清除备份区,在初始化) →提升波特率。代码如程序清单 1所示。
程序清单 2  开始下载
  1. <font face="宋体" size="3">--uart ota transmission operation
  2. function ota_operating(packet)

  3.     local datalen = (packet[2] << 8) | packet[3]
  4.     local funcode = packet[4]
  5.     local cur_screen = get_current_screen()
  6.    
  7.     if funcode == ota_code
  8.     then
  9.         local child_code = packet[5]
  10.         local down_name  = ''
  11.             
  12.         if child_code == _start_down
  13.         then
  14.             baudrate = uart_get_baudrate()
  15.             
  16.             local baudrateTemp = 115200
  17.             
  18.             baudrateTemp = (packet[6] << 24) |
  19.                               (packet[7] << 16) |
  20.                               (packet[8] <<  8) |
  21.                               (packet[9] <<  0)

  22.             filesize = (packet[10] << 24) |
  23.                          (packet[11] << 16) |
  24.                          (packet[12] <<  8) |
  25.                          (packet[13] <<  0)
  26.                     
  27.             for i = 14, (#(packet) - 4)
  28.             do
  29.                 down_name = down_name..string.char(packet[i])
  30.             end
  31.          
  32.             if down_name == filename and filesize > 0
  33.             then
  34.                 my_assecc_ota(1)
  35.                 down_state = 1
  36.                 change_screen(sc_Lock)
  37.                
  38.                 my_uartsend_ota(child_code, ota_suc)
  39.                
  40.                 if en_ota_SD == 1
  41.                 then
  42.                     ......
  43.                 else
  44.                     pre_sn         = -1
  45.                     ota_cnt        = 0
  46.                     ota_writeTb    = {}
  47.                     ota_writeByte  = 0
  48.                     TransferSize   = 0
  49.                     set_value(sc_Lock,  88, 0)
  50.                             set_text(sc_Lock,
  51.                                        188,
  52.                                        'Downloading : 0 %   
  53.                                        [ '..math.ceil(TransferSize)..' byte / '..
  54.                                         math.ceil(filesize)..' byte ]')
  55.                     ota_destroy()
  56.                     ota_addr = ota_init('0123456789abcdef', filesize, 0x800000)
  57.                 end        
  58.                 uart_set_baudrate(baudrateTemp)
  59.             else
  60.                 my_uartsend_ota(child_code, ota_nodown)
  61.             end
  62.         ......
  63.         end
  64.     end
  65. 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写入
  1. <font face="宋体" size="3">--uart ota transmission operation
  2. function ota_operating(packet)

  3.     local datalen = (packet[2] << 8) | packet[3]
  4.     local funcode = packet[4]
  5.     local cur_screen = get_current_screen()
  6.    
  7.     if funcode == ota_code
  8.     then
  9.     --EE B6 LEN(2BYTE) 88 11 FILESIZE(4byte) FILENAME FF FC FF FF
  10.         local child_code = packet[5]
  11.         local down_name  = ''

  12.         if child_code == _start_down
  13.         then
  14.            ......
  15.       
  16.         elseif child_code == _dwoning
  17.         then
  18.         --EE B6 LEN(2BYTE) 88 22 01 00 00 11 11 check_H check_L FF FC FF FF
  19.             local sn = packet[6]
  20.             if pre_sn == 255
  21.             then
  22.                 pre_sn = -1
  23.             end
  24.             print(' > pre_sn = '..pre_sn..' / sn = '..sn)

  25.             if pre_sn + 1 == sn
  26.             then
  27.                 local packsize = #(packet) - 13 + 1
  28.                 if packsize > 0 and packsize <= otaUartPacketSize
  29.                 then
  30.                     if ((packsize + 13) == (#(packet) + 1)) and
  31.                         (((#(packet) + 1) - 13) > 0)
  32.                     then
  33.                         local isCheckTure = my_checkSum(packet)
  34.                         if isCheckTure == 1
  35.                         then
  36.                             TransferSize = packsize + TransferSize
  37.                             local prg = string.format ('%.1f', ((TransferSize *
  38.                                           100) / filesize))
  39.                             set_value(sc_Lock,  88, math.ceil((TransferSize *
  40.                                           1000) / filesize))
  41.                             set_text(sc_Lock, 188, 'Downloading : '..prg..' %
  42.    [ '..math.ceil(TransferSize)..' byte / '..math.ceil(filesize)..' byte ]')
  43.                            
  44.                             for i = 7, (#(packet) - 6)
  45.                             do
  46.                                 ota_writeTb[ota_writeByte] = packet[i]
  47.                                 ota_writeByte = ota_writeByte + 1
  48.                             end
  49.                            
  50.                             if #(ota_writeTb) >= 0
  51.                             then
  52.                            
  53.                                 local isOtaWrite = 0
  54.                                 
  55.                                 ota_cnt = ota_cnt + 1
  56.                                 if ota_cnt == 4
  57.                                 then
  58.                                     isOtaWrite = 1
  59.                                     
  60.                                 elseif ota_cnt < 4 and TransferSize == filesize
  61.                                 then
  62.                                     isOtaWrite = 1
  63.                                 end
  64.                                 
  65.                                 if isOtaWrite == 1
  66.                                 then
  67.                                     
  68.                                     if #(ota_writeTb) <= 2047
  69.                                     then
  70.                                         for i = (#(ota_writeTb) + 1), 2047
  71.                                         do
  72.                                             ota_writeTb[ota_writeByte] = 0x00
  73.                                             ota_writeByte = ota_writeByte + 1
  74.                                         end
  75.                                     end
  76.                                     ......
  77.                                     local _write =  ota_write(ota_writeTb)
  78.                                     
  79.                                     ota_cnt = 0
  80.                                     ota_writeByte = 0
  81.                                     ota_writeTb   = {}
  82.                                 end
  83.                                 
  84.                                 pre_sn = sn
  85.                                 my_uartsend_ota(child_code, ota_suc, pre_sn)
  86.                             end   
  87.                         end
  88.                     else
  89.                         --check sum error
  90.                         my_uartsend_ota(child_code,
  91.                                            ota_packet_checkfail, (pre_sn + 1))
  92.                     end
  93.                 else
  94.                     --size > 512byte error
  95.                     print(' > packet size > '..otaUartPacketSize..' ERROR !')
  96.                 end
  97.             else
  98.                 --sn error
  99.                 my_uartsend_ota(child_code, ota_snfail, (pre_sn + 1))
  100.             end     
  101.             ......
  102.         end
  103.     end
  104. end</font>
复制代码

4.下载完成
当屏幕接收到用户主板确认升级的指令(EE B6 Len 88 33 01 FF FC FF FF),则调用ota_check_upgrade(1)开始进入校验解压过程。代码如程序清单 4所示。

程序清单 4  开始升级
  1. <font face="宋体" size="3">--uart ota transmission operation
  2. function ota_operating(packet)

  3.     local datalen = (packet[2] << 8) | packet[3]
  4.     local funcode = packet[4]
  5.     local cur_screen = get_current_screen()
  6.    
  7.     if funcode == ota_code
  8.     then
  9.         --EE B6 LEN(2BYTE) 88 11 FILESIZE(4byte) FILENAME FF FC FF FF
  10.         local child_code = packet[5]
  11.         local down_name  = ''
  12.         
  13.         if child_code == _start_down
  14.         then
  15.             ......

  16.         elseif child_code == _dwoning
  17.         then
  18.             ......
  19.         elseif child_code == _end_down and down_state == 1
  20.         then
  21.             local isUpdata = packet[6]
  22.             if isUpdata == 0x01
  23.             then
  24.                 my_uartsend_ota(child_code, ota_suc)
  25.                
  26.                 ......
  27.                 ota_check_upgrade(1)
  28.                
  29.             end
  30.         ......
  31.         end
  32.     end
  33. end</font>
复制代码

5.校验解压
当屏幕进入升级过程,会自动调用on_ota_progress(status,value)进入校验、解压过程,校验中→校验结果→解压中→解压结果→恢复波特率→重启,代码程序清单 5所示。

程序清单 5  校验解压
  1. <font face="宋体" size="3">function on_ota_progress(status,value)
  2.    
  3.     --Checking
  4.     if status == 1 and value == 0
  5.     then
  6.         set_value(sc_Lock, 88, value)
  7.         set_text(sc_Lock, 188, '')
  8.         refresh_screen()
  9.    
  10.     --Check result
  11.     elseif status == 2
  12.     then
  13.         my_uartsend_ota(_file_check, value)
  14.    
  15.     --Unpacking
  16.     elseif status == 3
  17.     then
  18.         set_value(sc_Lock, 88, value*10)
  19.         set_text(sc_Lock, 188, 'flash_updatesects : '..value..' %')
  20.         refresh_screen()
  21.         
  22.     --Unpacking result   
  23.     elseif status == 4
  24.     then
  25.         
  26.         my_uartsend_ota(_unzip, value)
  27.         print('> baudrate = '..baudrate)
  28.         uart_set_baudrate(baudrate)   
  29.         delay_ms(100)
  30.     end
  31. end</font>
复制代码

5.2.6 LUA SD升级源码
本例程中,用户还可以将ota.bin文件放在SD卡中进行升级,本例程中已将sd升级功能封装在‘ota.lua’中,用户只需要在sd插入回调函数里调用my_sd_updata OTA()即可。代码程序清单 5所示。

程序清单 6  SD卡升级源码
  1. <font face="宋体" size="3">--main.lua
  2. function on_sd_inserted(dir)
  3.     my_sd_updataOTA()
  4. end


  5. --ota.lua
  6. --sd update ota
  7. function my_sd_updataOTA()
  8.    
  9.     local finish = 0
  10.    
  11.     if file_open(sd_path, 1) == true
  12.     then
  13.         size = file_size()
  14.         ota_destroy()
  15.         
  16.         local sdota_addr = ota_init('0123456789abcdef', size, 0x800000)

  17.         --ota resume
  18.         if sdota_addr > 0
  19.         then
  20.             file_seek(sdota_addr)
  21.         end
  22.         
  23.         while(true)
  24.         do
  25.             local rddata = file_read(2048)
  26.             if #(rddata) < 2047
  27.             then
  28.                 for i = (#(rddata) + 1), 2047
  29.                 do
  30.                     rddata[i] = 0x00

  31.                 end
  32.                 finish=1
  33.             end

  34.             ota_write(rddata)      
  35.             print('> finish = '..finish)
  36.             if finish == 1 then
  37.                 break
  38.             end
  39.         end

  40.         file_close()
  41.         my_assecc_ota(1)
  42.         ota_check_upgrade(1)
  43.     end
  44. end</font>
复制代码

附录A
MCU 发送给屏幕的指令如下所示:
屏幕应答或通知MCU屏幕的指令如下所示:

附录B
DEMO下载链接:
http://www.gz-dc.com/uploads/file/20210111/M%20OTA.zip



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
销售与技术支持:(020)82186683-601
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|广州大彩串口屏论坛_大彩开发者交流论坛

GMT+8, 2024-12-27 23:36 , Processed in 0.050847 second(s), 20 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表