對(duì)于恩智浦的MCU來講或杠,目前官方用的blhost固件更新工具是命令行版的上位機(jī)。在工程師實(shí)際應(yīng)用的過程中,有些朋友可能會(huì)覺得命令行版本的上位機(jī)不符合個(gè)人的使用習(xí)慣或者不好發(fā)布給自己的終端用戶,我們需要的是一個(gè)簡(jiǎn)單易用的GUI版本的上位機(jī)疾掰。這里給大家安利一個(gè)利用python和QT5的組件PySide2使用python腳本快速調(diào)用blhost.exe實(shí)現(xiàn)簡(jiǎn)單上位機(jī)操作的方法,最后會(huì)有打包成exe文件方便發(fā)布給終端客戶的徐紧。
建立開發(fā)環(huán)境
在使用python開發(fā)前静檬,我個(gè)人是用Anaconda3和文本編輯器開發(fā)的,所以推薦先安裝Anaconda3
浪汪,文本編輯器推薦使用Sublime
安裝好開發(fā)環(huán)境后,進(jìn)入python的執(zhí)行環(huán)境
安裝插件
安裝PySide2
使用pip wheel為Python包安裝Qt死遭。從CMD運(yùn)行以下命令進(jìn)行安裝:
pip install PySide2
或者:
pip install --index-url=http://download.qt.io/snapshots/ci/pyside/5.12/latest pyside2 --trusted-host download.qt.io
個(gè)人推薦國(guó)內(nèi)的客戶用第二種安裝方法,第一種我經(jīng)常安裝超時(shí)凯旋。
安裝QT5的開發(fā)工具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
如果你要開發(fā)基于串口的升級(jí)工具呀潭,還需要安裝pyserial
pip install pyserial
這篇文章會(huì)以USB HID接口升級(jí)為主,串口玩法暫且不表
使用QT Designer設(shè)計(jì)UI
利用Everything工具搜索到QtDesigner
一般來將通過Windows搜索QtDesigner比較麻煩至非,建議安裝Everything
在Everything里搜索designer.exe钠署,找到anaconda3\Lib\site-packages\pyqt5_tools\Qt\bin下的designer.exe并運(yùn)行。
創(chuàng)建界面
選擇QVGA landscape(320x240)然后點(diǎn)擊Create按鈕荒椭,創(chuàng)建一個(gè)新的界面
添加按鍵和對(duì)話框
為新的界面添加3個(gè)按鍵Push Button以及2個(gè)對(duì)話框Text Browser
修改2個(gè)對(duì)話框的Object名字為Text_Path/Text_Result
Text_Path會(huì)用來顯示燒錄目標(biāo)HEX文件的路徑
Text_Reset會(huì)用來提示連接的狀態(tài)和燒錄的結(jié)果
修改3個(gè)按鍵的Object名字為But_Conn/But_Open/But_Prog
But_Conn按鍵用來測(cè)試是否與ISP狀態(tài)的MCU連接正常
But_Open按鍵用來打開要燒錄的HEX文件
But_Prog按鍵用來燒錄But_Open選擇的HEX文件
再修改3個(gè)按鍵的名字為Connect?/OpenBinary/Programm
設(shè)定好后保存UI界面
將UI文件轉(zhuǎn)換成python腳本
在Anaconda3的命令行界面里進(jìn)入U(xiǎn)I保存的文件夾谐鼎,然后輸入以下命令
pyuic5 ui.ui >blhost_gui.py
轉(zhuǎn)換好后,
在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_())
嘗試運(yùn)行下GUI
轉(zhuǎn)換好后狸棍,我們可以嘗試運(yùn)行下界面身害,在命令行里輸入
python blhost_gui.py
這時(shí)候會(huì)彈出我們?cè)赒tDesigner里設(shè)計(jì)好的UI界面,并且在命令行終端里會(huì)顯示blhost application start
OK草戈,接下來我們就可以添加實(shí)際的控制邏輯的代碼了
加入blhost的功能
為了引用blhost.exe的功能塌鸯,我們直接通過python的subprocess方法,還記的我們添加的那行import代碼么唐片?
import subprocess
這里我們直接把bhost.exe復(fù)制到blhost_gui.py的文件夾下丙猬,blhost.exe在SDK包里,具體路徑為SDK_2.7.0_LPC55S69\middleware\mcu-boot\bin\Tools\blhost\win
在def retranslateUi(self, MainWindow) 函數(shù)結(jié)尾的地方费韭,加入按鍵響應(yīng)(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功能需要調(diào)用openfile/program/connectwUSB三個(gè)函數(shù)來實(shí)現(xiàn)打開HEX文件茧球,對(duì)芯片變成以及檢查USB連接的狀態(tài)。所以我們要在retranslateUi函數(shù)后加入3個(gè)新的函數(shù)星持。
首先我們先加入打開文件的函數(shù)
openfile_name在這里代表了選擇的目標(biāo)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連接的函數(shù)
檢查USB是否和開發(fā)板上進(jìn)入ISP模式的MCU連接正常,我們使用blhost.exe的get-property的功能钉汗,通過python的subprocess.Popen調(diào)用羹令,所以我們要把blhost.exe放在該腳本同一的文件夾下。
0x1FC9,0x0021是MCU USB ISP時(shí)的VID和PID损痰,這里是LPC55S69的不同的恩智浦MCU該VID和PID可能不同福侈,隨時(shí)可以修改。
get-property 1是獲取當(dāng)前BOOT ROM的版本卢未,如果獲取的版本是2.2.0的則芯片是0A的版本肪凛,如果是3.0.0的則是1B的版本,如果是其他數(shù)字則需要根據(jù)KBOOT的版本號(hào)來確定芯片的版本辽社。
獲取到正確的KBOOT的版本號(hào)后悔在Text_Result對(duì)話框里顯示出來信息伟墙,如果不正確則提示連接異常或者提示是未知的芯片版本滴铅。
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")
最后我們加入燒錄芯片的函數(shù)
同檢查芯片連接狀況的函數(shù)差不多戳葵,這里燒錄我們調(diào)用的是blhost的 flash-image功能,需要注意的是USB的VID和PID號(hào)要對(duì)汉匙,其他無礙拱烁。
正確的燒錄blhost.exe會(huì)返回“Success”,燒錄失敗會(huì)返回其他信息噩翠。
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")
運(yùn)行blhost_gui.py
當(dāng)我們補(bǔ)充完以上提到的代碼后戏自,在Anaconda3的命令行里輸入
python blhost_gui.py
就可以正常運(yùn)行該UI,如果還沒有連接開發(fā)板或者開發(fā)板上MCU的狀態(tài)不對(duì)
開發(fā)板設(shè)置
LPC55S69-EVK配置為USB ISP模式需要注意以下幾點(diǎn)
- J7斷開
- J11斷開
- J6選擇HS
- 短接J10(上電進(jìn)入ISP模式)
- 使用USB接口P9進(jìn)行USB ISP操作
正常連接和燒錄
如果USB連接正常伤锚,則按下Connect按鈕會(huì)顯示連接芯片的版本號(hào)擅笔。
接下來我們可以按下按鈕OpenBinary選擇一個(gè)我們要燒錄的hex文件
再點(diǎn)擊燒錄按鈕Program,就可以正常燒錄了
打包成exe文件
為了便于我們發(fā)布該軟件給其他沒有建立python執(zhí)行環(huán)境的客戶,我們可以用pyinstaller猛们。
為了把整個(gè)執(zhí)行環(huán)境達(dá)成一個(gè)exe念脯,我們需要在pyinstaller命令后加入-F使blhost_gui.py打包后只生成一個(gè)exe文件
pyinstaller.exe blhost_gui.py -F
最后會(huì)在文件夾dist下邊找到blhost_gui
直接執(zhí)行該exe文件,當(dāng)按下功能按鈕的時(shí)候會(huì)發(fā)現(xiàn)找不到blhost
原因是需要把blhost.exe和blhost_gui.exe放在同一文件夾下阅懦,復(fù)制blhost.exe過來就可以解決和二。
這里有個(gè)問題留給高手們,有誰(shuí)知道如何把blhost.exe一起打包進(jìn)來的么耳胎?歡迎高手們指點(diǎn)一二惯吕。