串列傳輸波特率不匹配
我有兩個串口,一個通過主機板 (/dev/ttyS0) 提供,一個通過牛津晶片 (/dev/ttyS1) 從 PCIE 到 RS232 卡 (Startech 2S952) 提供(有 /dev/ttyS2 但它沒有進入這個故事)。在我的情況下如何解釋波特率?
[ 1.111618] 00:03: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A [ 1.112543] 0000:08:00.0: ttyS1 at I/O 0xf010 (irq = 40, base_baud = 4000000) is a 16550A
我將邏輯分析儀連接到串列埠的 Tx/Rx 線。當我做:
stty -F /dev/ttyS0 115200 echo "ABCDEFGH" > /dev/ttyS0
然後我可以在邏輯分析儀上解碼“ABCDEFGH”字元串,後跟 0x0D 0x0A,但我必須告訴它波特率為 115200。此外,當我將筆記型電腦與 USB 串列適配器(通過空調製解調器電纜)連接並讀取關閉串口,只有當我將接收器設置為 115200 時,我才會得到有意義的輸出。據我所知,這是應該的。
現在使用 /dev/ttyS1:
stty -F /dev/ttyS1 115200 echo "ABCDEFGH" > /dev/ttyS1
我在分析的邏輯中清楚地看到,我的消息以毫秒為單位要慢得多。事實上,它慢了大約 34.7(2) 倍,40000000/115200 = 34.7(2)。特別是,接收方膝上型電腦接收到由幾個 0x00 組成的消息。當我設置為 3200 波特時,它會出現亂碼。顯然,該消息實際上是以 115200/34.6 = 3339.13…bps 傳輸的。
使用 /dev/ttyS1:
stty -F /dev/ttyS1 4000000 echo "ABCDEFGH" > /dev/ttyS1
與 /dev/ttyS1 的通信發生的位持續時間與預期的 115200 相匹配。
那麼這意味著在我的情況下:
[ 1.112543] 0000:08:00.0: ttyS1 at I/O 0xf010 (irq = 40, base_baud = 4000000) is a 16550A
應該解釋為“4000000”是一些內部振盪器的頻率,導致在現實世界中傳輸 115200。我希望這個值是硬體內部的,並且隱藏在驅動程序的深處。
我錯過了什麼?這是我第一次使用串口,所以我完全迷路了。
如果我將“console=ttyS1,4000000n8”作為核心參數傳遞,那麼我可以在筆記型電腦上設置 115200 通過串列通信。
因此,根據猜測,似乎無論出於何種原因,核心對該卡上執行的基本時鐘都有錯誤的想法。串列埠是簡單的設備,如果系統沒有標準方法從卡中找出它,我不會感到驚訝。至少在某些情況下,被配置的部分是應用於基本時鐘的除數,並且需要知道實際的基本時鐘。
(該卡確實有用於設置最大速度的跳線,因此它可能有某種方式將設置告知支持它的驅動程序。)
無論如何,
setserial
看起來有一個baud_base
選項,我猜使用它可能有助於手動解決問題:setserial /dev/ttyS1 baud_base 115200