快速设计UI版的blhost给LPC55S69更新固件

对于恩智浦的MCU来讲,目前官方用的blhost固件更新工具是命令行版的上位机。在工程师实际应用的过程中,有些朋友可能会觉得命令行版本的上位机不符合个人的使用习惯或者不好发布给自己的终端用户,我们需要的是一个简单易用的GUI版本的上位机。这里给大家安利一个利用python和QT5的组件PySide2使用python脚本快速调用blhost.exe实现简单上位机操作的方法,最后会有打包成exe文件方便发布给终端客户的。

建立开发环境

在使用python开发前,我个人是用Anaconda3和文本编辑器开发的,所以推荐先安装Anaconda3
,文本编辑器推荐使用Sublime

和Visual Studio Code。

安装好开发环境后,进入python的执行环境


快速设计UI版的blhost给LPC55S69更新固件_第1张图片
Anaconda3 命令行

安装插件

安装PySide2

使用pip wheel为Python包安装Qt。从CMD运行以下命令进行安装:

pip install PySide2

或者:

pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.12/latest pyside2 --trusted-host download.qt.io

个人推荐国内的客户用第二种安装方法,第一种我经常安装超时。

安装QT5的开发工具Designer

pip install PyQt5-tools

或者:

pip install PyQt5-tools -i http://pypi.douban.com/simple --trusted-host=pypi.douban.com

安装打包exe的工具pyinstaller

pip install pyinstaller

如果你要开发基于串口的升级工具,还需要安装pyserial

pip install pyserial

这篇文章会以USB HID接口升级为主,串口玩法暂且不表

使用QT Designer设计UI

利用Everything工具搜索到QtDesigner

一般来将通过Windows搜索QtDesigner比较麻烦,建议安装Everything

快速设计UI版的blhost给LPC55S69更新固件_第2张图片
Everything查找Designer.exe

在Everything里搜索designer.exe,找到anaconda3\Lib\site-packages\pyqt5_tools\Qt\bin下的designer.exe并运行。
快速设计UI版的blhost给LPC55S69更新固件_第3张图片
QtDesigner

创建界面

选择QVGA landscape(320x240)然后点击Create按钮,创建一个新的界面

快速设计UI版的blhost给LPC55S69更新固件_第4张图片
创建一个新的QT界面

添加按键和对话框

为新的界面添加3个按键Push Button以及2个对话框Text Browser

快速设计UI版的blhost给LPC55S69更新固件_第5张图片
添加按键和对话框

修改2个对话框的Object名字为Text_Path/Text_Result
Text_Path会用来显示烧录目标HEX文件的路径
Text_Reset会用来提示连接的状态和烧录的结果
修改3个按键的Object名字为But_Conn/But_Open/But_Prog
But_Conn按键用来测试是否与ISP状态的MCU连接正常
But_Open按键用来打开要烧录的HEX文件
But_Prog按键用来烧录But_Open选择的HEX文件
再修改3个按键的名字为Connect?/OpenBinary/Programm

快速设计UI版的blhost给LPC55S69更新固件_第6张图片
修改按键名称

设定好后保存UI界面


快速设计UI版的blhost给LPC55S69更新固件_第7张图片
保存UI

将UI文件转换成python脚本

在Anaconda3的命令行界面里进入UI保存的文件夹,然后输入以下命令

pyuic5 ui.ui >blhost_gui.py

快速设计UI版的blhost给LPC55S69更新固件_第8张图片
UI文件转成python脚本

转换好后,
在blhost_gui.py开头import的位置加入如下引用
注意,这里要看好PySide2而不是PyQt5

import sys
import os
import subprocess

from PySide2 import QtCore, QtGui, QtWidgets

from PySide2.QtWidgets import *
from PySide2.QtCore import *

在blhost_gui.py最后一行加入如下代码

__author__ = "Magicoe.Niu"
__version__ = "v1.0"
class mainWin(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(mainWin, self).__init__(parent)
        self.setupUi(self)
if __name__ == '__main__':
    print("blhost application start")
    app = QApplication(sys.argv)
    main_win = mainWin()
    main_win.show()
    sys.exit(app.exec_())

尝试运行下GUI

转换好后,我们可以尝试运行下界面,在命令行里输入

python blhost_gui.py

这时候会弹出我们在QtDesigner里设计好的UI界面,并且在命令行终端里会显示blhost application start

快速设计UI版的blhost给LPC55S69更新固件_第9张图片
首次运行GUI界面

OK,接下来我们就可以添加实际的控制逻辑的代码了

加入blhost的功能

为了引用blhost.exe的功能,我们直接通过python的subprocess方法,还记的我们添加的那行import代码么?

import subprocess

这里我们直接把bhost.exe复制到blhost_gui.py的文件夹下,blhost.exe在SDK包里,具体路径为SDK_2.7.0_LPC55S69\middleware\mcu-boot\bin\Tools\blhost\win

快速设计UI版的blhost给LPC55S69更新固件_第10张图片
复制blhost.exe到blhost_gui.py的文件夹下

在def retranslateUi(self, MainWindow) 函数结尾的地方,加入按键响应(clicked.connect())的代码

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.But_Open.setText(_translate("MainWindow", "OpenBinary"))
        self.But_Conn.setText(_translate("MainWindow", "Connect?"))
        self.But_Prog.setText(_translate("MainWindow", "Program"))

        self.But_Open.clicked.connect(self.openfile)
        self.But_Prog.clicked.connect(self.program)
        self.But_Conn.clicked.connect(self.connectwUSB)

新加入的3行clicked.connect功能需要调用openfile/program/connectwUSB三个函数来实现打开HEX文件,对芯片变成以及检查USB连接的状态。所以我们要在retranslateUi函数后加入3个新的函数。

首先我们先加入打开文件的函数

openfile_name在这里代表了选择的目标HEX文件的路径,我们把它显示在文本框“Text_Path”中

    def openfile(self):
        openfile_name = QFileDialog.getOpenFileName(self,'选择文件','','Hex File(*.hex)')
        print(openfile_name)
        self.Text_Path.setText(openfile_name[0])

接下来我们加入检查USB连接的函数

检查USB是否和开发板上进入ISP模式的MCU连接正常,我们使用blhost.exe的get-property的功能,通过python的subprocess.Popen调用,所以我们要把blhost.exe放在该脚本同一的文件夹下。
0x1FC9,0x0021是MCU USB ISP时的VID和PID,这里是LPC55S69的不同的恩智浦MCU该VID和PID可能不同,随时可以修改。
get-property 1是获取当前BOOT ROM的版本,如果获取的版本是2.2.0的则芯片是0A的版本,如果是3.0.0的则是1B的版本,如果是其他数字则需要根据KBOOT的版本号来确定芯片的版本。
获取到正确的KBOOT的版本号后悔在Text_Result对话框里显示出来信息,如果不正确则提示连接异常或者提示是未知的芯片版本。

    def connectwUSB(self):
        print("blhost programming connect")
        blhost_main = "blhost.exe"
        ret = subprocess.Popen(blhost_main + " -u 0x1FC9,0x0021 -- get-property 1", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        RetText = ret.communicate()
        print (RetText)
        if "Current Version" in str(RetText):
            if "Current Version = K2.2.0" in str(RetText):
                self.Text_Result.setText("Connected Silicon 0A Success")
            elif "Current Version = K3.0.0" in str(RetText):
                self.Text_Result.setText("Connected Silicon 1B Success")
            else:
                self.Text_Result.setText("Connected Silicon Success, unknown Silicon version")
        else:
            self.Text_Result.setText("Connected with USB Failed")

最后我们加入烧录芯片的函数

同检查芯片连接状况的函数差不多,这里烧录我们调用的是blhost的 flash-image功能,需要注意的是USB的VID和PID号要对,其他无碍。
正确的烧录blhost.exe会返回“Success”,烧录失败会返回其他信息。

    def program(self):
        target_bin = self.Text_Path.toPlainText()
        print(target_bin)
        print("blhost programming start")
        blhost_main = "blhost.exe"
        ret = subprocess.Popen(blhost_main + " -u 0x1FC9,0x0021 -- flash-image "+ target_bin +" erase", shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        RetText = ret.communicate()
        print (RetText)
        if "Success" in str(RetText):
            self.Text_Result.setText("Program Success")
        else:
            self.Text_Result.setText("Program Failed")

运行blhost_gui.py

当我们补充完以上提到的代码后,在Anaconda3的命令行里输入

python blhost_gui.py

就可以正常运行该UI,如果还没有连接开发板或者开发板上MCU的状态不对


快速设计UI版的blhost给LPC55S69更新固件_第11张图片
检查USB连接状态

开发板设置

LPC55S69-EVK配置为USB ISP模式需要注意以下几点

  1. J7断开
  2. J11断开
  3. J6选择HS
  4. 短接J10(上电进入ISP模式)
  5. 使用USB接口P9进行USB ISP操作
LPC55S69-EVK USB ISP设置

正常连接和烧录

如果USB连接正常,则按下Connect按钮会显示连接芯片的版本号。


快速设计UI版的blhost给LPC55S69更新固件_第12张图片
USB连接正常

接下来我们可以按下按钮OpenBinary选择一个我们要烧录的hex文件


快速设计UI版的blhost给LPC55S69更新固件_第13张图片
选择HEX文件

再点击烧录按钮Program,就可以正常烧录了
快速设计UI版的blhost给LPC55S69更新固件_第14张图片
正常烧录

打包成exe文件

为了便于我们发布该软件给其他没有建立python执行环境的客户,我们可以用pyinstaller。
为了把整个执行环境达成一个exe,我们需要在pyinstaller命令后加入-F使blhost_gui.py打包后只生成一个exe文件

pyinstaller.exe blhost_gui.py -F

最后会在文件夹dist下边找到blhost_gui


快速设计UI版的blhost给LPC55S69更新固件_第15张图片
最终生成的exe文件

直接执行该exe文件,当按下功能按钮的时候会发现找不到blhost
原因是需要把blhost.exe和blhost_gui.exe放在同一文件夹下,复制blhost.exe过来就可以解决。


快速设计UI版的blhost给LPC55S69更新固件_第16张图片
执行exe失败

这里有个问题留给高手们,有谁知道如何把blhost.exe一起打包进来的么?欢迎高手们指点一二。

你可能感兴趣的:(快速设计UI版的blhost给LPC55S69更新固件)