目錄
- Unix 端口micropython序列槽使用
-
- 1.安裝序列槽模組
- 2.編寫代碼測試
- 3.增加序列槽波特率以及逾時時間的優化
-
- 3.1增加波特率
- 3.2優化逾時時間
Unix 端口micropython序列槽使用
unix端口上mpy作為序列槽測試工具還是很友善的,前兩章我們已經移植好了arm闆的linux系統上運作的mpy,沒有看過的同學點選下面連結檢視,現在來繼續學習序列槽的使用。
連結:支援LVGL的micropython固件編譯(二)arm闆移植
1.安裝序列槽模組
在python中我們首先會想到安裝pyserial,mpy同樣也可以安裝,在python中我們是通過pip install 來安裝管理三方模組包的。而在mpy中我們可以使用upip(mpy的很多模組前面帶u是以同标準py區分開),可以執行如下指令安裝:
安裝指令:
./micropython-lvgl -m upip install micropython-serial
mpy預設的mod加載路徑為
~/.micropython/lib
或
/usr/lib/micropython
,而我們剛剛執行安裝後的模組代碼就放在~/.micropython/lib路徑裡, 這個下載下傳的序列槽模組是可以直接引用的。但是有點小問題,後面會講到,以及如何修改。
2.編寫代碼測試
import serial
import time
def bytesToHexString(bytes):
hex_list = ['%02X ' % b for b in bytes]
str = ''
for i in range(len(hex_list)):
str += hex_list[i]
if ((i+1) % 16) == 0:
str +='\r\n'
return str
# 序列槽自收發測試 0x00-0XFF
def uart_test(ser):
list1 = []
for i in range(0, 256):
list1.append(i)
ser.write(bytes(list1))
print("send: 0x00...0xFF")
print("等待接收序列槽資料...")
while ser.inWaiting() == 0:
time.sleep(0.3)
s = ser.read(ser.inWaiting())
print(bytesToHexString(s))
# 初始化序列槽,入參:序列槽節點,波特率,逾時時間
ser=serial.Serial("/dev/ttyS5",9600,timeout=1)
ser.open()
uart_test(ser)
ser.close()
以上代碼用于序列槽回環測試,測試時需要短接序列槽的TX與RX。以9600的波特率測試0x00到0XFF全部資料收發。測試結果見下圖:
測完9600你可能還想測一下其他所有波特率是否都能正常工作,波特率傳輸上限在哪,測試發現隻有9600,19200,57600,115200等波特率可以帶入,想來arm闆不可能隻支援這點波特率,那一定是我們的serial模組限制了。另外逾時時間機關應該是s,但帶入小數比如0.1又會報錯,提示該參數需要整數而不是小數,這應當是一個bug了序列槽逾時設定應當可以做到ms機關。下面我們就來分析下serial模組代碼解決問題。
3.增加序列槽波特率以及逾時時間的優化
3.1增加波特率
在
~/.micropython/lib
目錄下找到serial.py打開
看到如下代碼:
BAUD_MAP = {
9600: termios.B9600,
# From Linux asm-generic/termbits.h
19200: 14,
57600: termios.B57600,
115200: termios.B115200
}
說明波特率可設範圍是在這裡添加的,而這個波特率值來自termios模組提供,termios模組提供的值本質上來自 Linux核心中 asm-generic/termbits.h檔案。讓我們找一下termios模組在哪裡,./micropython-lvgl進入repl,鍵入help(‘modules’)檢視有哪些模組
發現裡面有termios,是一個内置到mpy固件裡的模組,隻能去mpy源碼裡找了。
打開mpy源碼工程找到ports\unix\modtermios.c檔案,裡面有這樣一段代碼:
#define C(name) { MP_ROM_QSTR(MP_QSTR_##name), MP_ROM_INT(name) }
C(TCSANOW),
C(B9600),
#ifdef B57600
C(B57600),
#endif
#ifdef B115200
C(B115200),
#endif
這裡可以看出termios隻提供了三個波特率 9600,57600,115200,跟我們serial.py裡引用的一緻,那麼隻需要在這裡添加自己需要的波特率就好了,但可以供我們選擇的波特率在哪裡找呢,這時候就需要找到你arm闆的核心代碼了,找到include\uapi\asm-generic\termbits.h檔案裡面已經定義好了很多波特率(arm跟mips這裡可能會有些許差别),從其中添加我們需要的即可,下面是我添加的波特率:
#define C(name) { MP_ROM_QSTR(MP_QSTR_##name), MP_ROM_INT(name) }
C(TCSANOW),
C(B9600),
#ifdef B57600
C(B57600),
#endif
#ifdef B115200
C(B115200),
#endif
#ifdef B460800
C(B460800),
#endif
#ifdef B921600
C(B921600),
#endif
#ifdef B1152000
C(B1152000),
#endif
#ifdef B1500000
C(B1500000),
#endif
#ifdef B2000000
C(B2000000),
#endif
#ifdef B2500000
C(B2500000),
#endif
#ifdef B3000000
C(B3000000),
#endif
#undef C
};
重新編譯mpy固件,在repl裡可以檢視我們新增的波特率是否加進來了,鍵入termios. 按tab鍵補全可以檢視。
這個時候就可以改serial.py增加更多波特率了
BAUD_MAP = {
9600: termios.B9600,
# From Linux asm-generic/termbits.h
19200: 14,
57600: termios.B57600,
115200: termios.B115200,
460800: termios.B460800,
921600: termios.B921600,
1152000: termios.B1152000,
1500000: termios.B1500000,
2000000: termios.B2000000,
2500000: termios.B2500000,
3000000: termios.B3000000,
}
3.2優化逾時時間
前面測試時已經提到,timeout入參機關為S,隻有帶入小數才能設為ms級别逾時,但入參隻能接受整數。
檢視serial.py代碼,找到如下代碼:
def __init__(self, port, baudrate, timeout=None, **kwargs):
self.port = port
self.baudrate = baudrate
self.timeout = -1 if timeout is None else timeout * 1000
self.open()
這裡會發現timeout入參不為空時乘了1000,意味着送給底層接口的timeout是ms機關的,小數應該允許被傳入,我們自己在強轉為int傳給下面接口即可,修改該部分代碼為:
def __init__(self, port, baudrate, timeout=None, **kwargs):
self.port = port
self.baudrate = baudrate
self.timeout = -1 if timeout is None else int(timeout * 1000)#強轉為int
self.open()
可以修改下我們的序列槽測試代碼timeout
再次執行,可以正常工作。