大彩串口屏m系列ota升级-龙8客户端下载

串口升级ota.bin演示(升级后,屏幕显示彩色圆圈)


一、适用范围


本文档适合大彩医用级的串口屏产品使用。




二、开发环境版本


1. visualtft软件版本:v3.0.1.1137及以上的版本。

版本查看:

1) 打开visualtft软件启动页面如图2-1软件版本,右上角会显示的软件版本号;

图片

图2-1软件版本


2) 打开visualtft,在软件右下角可以查看软件版本图2-2软件版本,最新版本可登录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》可通过以下链接下载物联型开发包获取:

http:/www.gz-dc.com/index.php?s=/list/index/cid/19.html

2



《lua基础学习》可通过以下链接下载物联型开发包获取:

http:/www.gz-dc.com/index.php?s=/list/index/cid/19.html

3



lua脚本初学者可以通过下面链接进行学习。

http://www.runoob.com/lua/lua-arrays.html

4



at指令,可以通过下面链接了解

http://www.openluat.com/




五、教程实现


本例程通过大彩协议自定义指令和用户主板通讯,指令格式为 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 画面配置

本例程,只配置下载部分的画面及控件,在龙8客户端下载主页面(画面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初始化

--------------------------------------------------------------------------
-------------------------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

▲下滑查看





附录a


mcu 发送给屏幕的指令如下所示:

图片

 

屏幕应答或通知mcu屏幕的指令如下所示:

图片




附录b


demo下载链接:

http://www.gz-dc.com/uploads/file/20210111/m ota.zip