天天看點

Unix 端口micropython序列槽使用Unix 端口micropython序列槽使用

目錄

  • 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全部資料收發。測試結果見下圖:

Unix 端口micropython序列槽使用Unix 端口micropython序列槽使用

測完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’)檢視有哪些模組

Unix 端口micropython序列槽使用Unix 端口micropython序列槽使用

發現裡面有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鍵補全可以檢視。

Unix 端口micropython序列槽使用Unix 端口micropython序列槽使用

這個時候就可以改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

再次執行,可以正常工作。