# Serial Port 了解


## Serial Port 跟 Parallel Port

如同所見，Serial Port 就是資料以 Serial bit 順序傳輸的 Port，有順序當然也有平行的傳輸，如下不同協定例子：

* 平行傳輸：
  * LPT/IEEE 1284: 印表機用 DB-25 來同時傳輸多個資料，擁有 8 條獨立的資料線（Data 0～7），一個時脈週期同時推入 1 個 Byte。
  * PATA / IDE（Parallel ATA 硬碟排線）: 早期電腦內部的 40-pin 或 80-pin 灰色扁平寬排線，一次平行傳送 16-bit 資料。
  * DRAM 記憶體匯流排（如 DDR4 / DDR5）: 現代少數仍大量採用平行架構的領域。CPU 記憶體通道通常為 64-bit（DDR5 改為雙 32-bit 子通道），主機板上拉了幾十條等長走線同時傳送資料。
  * 早期伺服器 LPC 匯流排（Low Pin Count）: 主機板上 PCH 與 Super I/O 或 BMC 通訊的通道，採用 4-bit 平行傳輸（4 條 LAD 線）傳遞位址與資料。
* 順序傳輸：
  * UART / RS-232 / RS-485: 最經典的序列通訊，資料在單一 TX/RX 導線上逐位元（Bit-by-Bit）推出去。
  * USB（Universal Serial Bus）: 名稱直接標明是 Serial。透過一對高速差動線（D+/D- 或 USB3 的 SSTX/SSRX）依序傳輸封包位元。
  * PCIe（PCI Express）: 取代傳統 PCI 的革命性架構。雖然它支援 x4、x8、x16，但每個 Lane（通道）本質上都是一對極速的序列差動訊號線；x16 只是把 16 條獨立的序列通道做鏈結聚合（Link Aggregation），底層依然是序列架構。
  * SATA（Serial ATA）與 SAS（Serial Attached SCSI）: 取代龐大 PATA/SCSI 排線的標準，將排線從數十根接腳精簡為 7 根，改用高速序列傳輸。
  * 以太網路（Ethernet）: 不論是 100BASE-TX 還是 10G/25G/100G 光纖，單一物理通道在實體媒介上都是將位元串流以調變脈衝（NRZ、PAM4）逐個打出去。
  * 板級晶片通訊：SPI 與 I2C
    * SPI：主從式序列同步介面，資料順序透過 MOSI / MISO 傳輸。
    * I2C：單一雙向 SDA 資料線配合 SCL 時脈，以序列方式逐 bit 傳送位址與資料。
  * eSPI（Enhanced Serial Peripheral Interface）: 現代伺服器用來全面取代老舊 LPC 平行匯流排的介面，改用類似 SPI 的序列架構與 BMC / SIO 溝通。

平行傳輸因為散熱差，且可能受到干擾，又因為現在電腦頻率上升，因此很多協定都變成順序傳輸的協定。

在高頻下，平行傳輸的多條線路長度只要差了幾微米，就會發生 時脈偏斜（Clock Skew，部分 bit 先到、部分後到），且平行線路彼此會產生嚴重的電磁互串（Crosstalk）。

序列傳輸只需專注顧好單一對差動線，並透過 時脈恢復（CDR, Clock and Data Recovery） 將時脈嵌在資料流中，頻率能輕鬆拉到數 GHz 到數十 GHz，實際輸送量遠遠超越傳統平行匯流排。

![alt text](image.png)

{{< admonition type=info >}}
很特別可以看到 DB-25 竟然可以用來跑平行跟串列的協定，因為 DB-25 兩者都可以做！它本身只是一個「接頭規格（Connector）」，不是通訊協定。

在早期 PC 背板上，最容易讓人困惑的就是：同一個 DB-25 外型的接頭，既可以拿來跑「平行埠（LPT 印表機）」，也可以拿來跑「序列埠（RS-232 COM port）」。

DB-25 只定義機械結構： D-Sub 規格、外殼呈 D 型（防呆）、裡面塞了 25 根實體針腳。至於這 25 根針腳裡面走的是平行電氣訊號還是序列電氣訊號，完全由主機板接線決定。

IBM 在設計個人電腦（IBM PC / PC-XT / PC-AT）時，為了防止使用者插錯，做了一個非常經典的「公母防呆」設計：

1. LPT Port 印表機，電腦端使用 DB-25 母頭（Female，有孔）
2. COM Port for RS-232，電腦端就是使用 DB-25 公頭（Male，有針）
{{< /admonition >}}

### PCIe

如同上限所述，PCIe 明明是序列，但又有多通道，感覺起來就是平行啊，實際上。

* 每一條 Lane 內部是獨立的 SerDes（序列化/解序列化器）。
* 它們不共用實體資料取樣時脈，而是利用 CDR（時脈資料恢復） 直接從自己那條線的資料邊緣抓時脈。
* Lane 0 跟 Lane 15 在實體電路上就算到達時間差了幾十個時脈週期，硬體也完全不在乎。

既然 16 條 Lane 在實體線上各自跑各自的，到達時間不同步，接收端怎麼把封包拼回來？

* PCIe 在接收端（PHY / MAC 層）為每一條 Lane 都做了一個獨立的 Elastic Buffer（彈性緩衝 FIFO）。
* 發送端在傳送資料時，會週期性地在所有 Lane 上同時打入特殊的對齊符號（如 8b/10b 的 /COM/ 或 128b/130b 的 Sync Header）。
* 接收端各自接收、各自存進 FIFO：跑得快的 Lane 先存進暫存器等著；等跑得最慢的那條 Lane 的對齊符號也到了，接收端邏輯才在內部把資料同時倒出來組裝（這個動作叫 Lane-to-Lane Deskew）。

它的「同時」，是數位邏輯層靠記憶體緩衝對齊出來的，不是物理導線上的電位同時抵達。

### CPU and Memory

電腦跟記憶體，都是用平行的傳輸，像是
CPU 處理運算時，是以「字組（Word）」為單位。8 位元 CPU 一次算 8 個 bit，32 位元 CPU 內部有 32 條並排的微型金屬導線連到暫存器，64 位元 CPU 則有 64 條。對 ALU（算術邏輯單元）來說，把這 64 個 bit 同時倒進運算器，1 個時脈週期就能出結果。

因為在矽晶片內部，導線長度是以「微米」甚至「奈米（nm）」計算，幾十條線的長度差幾乎為零，不會有嚴重的時脈偏斜（Clock Skew）；且晶片內部空間極其緊湊，拉幾十條微米導線的成本極低。

但只要離開晶片，平行傳輸就會有點問題。

## Serial Port 歷史

### 1920

非同步序列通訊（Start bit + Data bits + Stop bit）的原理，早在 1920 年代的電傳打字機（Teletypewriter）就已經成熟，當時稱為 Start-Stop 通訊機制。

### 1960s RS232 and UART

1960 年代，大型主機（Mainframe）出現，企業需要讓各分行的打字機終端或電腦透過「電話線」連回總部主機。

* RS-232 誕生（1960）：EIA（電子工業聯盟）制定了 RS-232 標準，規範終端設備（DTE）與電話數據機（DCE）之間的電氣規格（$\pm 12\text{V}$）與 DB-25 接頭。
* 硬體 UART 晶片化（1971）：威騰電子（Western Digital）創辦人 Gordon Bell 等人研發出世界上第一顆單晶片 UART（WD1402A）。自此，工程師不再需要用上百個離散邏輯閘或機械開關來做平行/序列轉換，CPU 只需把 1 個 Byte 寫入暫存器，UART 硬體晶片自動幫你轉成一串 Serial 位元。
  * 這邊特別的是 UART 的機制早就用在打字機上面摟，機械式電傳打字機確立了 Start-Stop 非同步序列協定（UART 的前身理論）

嚴格來說，UART 是「硬體控制器架構」，而大家口中說的「UART 協定」，其實是「非同步起止訊號協定（Asynchronous Start-Stop Protocol）」。UART = Universal Asynchronous Receiver / Transmitter（通用非同步收發器）。

在晶片設計中，UART 就是一組包含移位暫存器（Shift Register）、Baud Rate 產生器、控制狀態機與 FIFO 暫存器的硬體 IP 模組。

### 1980s COM Port

IBM PC（1981）與 PC/AT（1984）的推出，將 Serial Port 推向大眾：

* IBM 採用了美國國家半導體的 INS8250（後續演進為帶有 16-byte FIFO 緩衝區的 16550A）UART 晶片，並將龐大的 DB-25 接頭精簡為 9 針的 DE-9。
* 作業系統將這些硬體映射為 COM1、COM2。
* 統治一切外設：在 USB 出現前，滑鼠、撥接數據機（56K Modem）、繪圖板、掌上型電腦 Palm PDA，全靠這條 9 針 Serial Port 與電腦通訊。

這時候微軟 MS-DOS / PC DOS 作業系統給序列埠起的「保留裝置名稱（Device Name）」，代表「Communication Port（通訊埠）」。

在 1981 年之前，電腦界沒有人講「COM1」、「COM2」：

* 早期大型主機與 Unix 稱呼終端序列埠為 /dev/tty（Teletypewriter）。
* 早期微電腦（跑 CP/M 系統）稱呼序列埠為 RDR:（Reader）或 PUN:（Puncher），沿用打孔卡片機的命名。

直到 1981 年微軟為 IBM PC 開發 DOS 時，為了簡化硬體存取，在系統核心設計了一組「保留裝置名稱（Reserved Device Names）」：

* LPT1、LPT2：Line Printer（平行印表機埠）
* CON：Console（鍵盤與螢幕控制台）
* PRN：預設印表機
* COM1、COM2：Communication Port（序列通訊埠，後續 MS-DOS 3.3 擴充支援到 COM3、COM4）

你可以以為 COM Port 只是一堆 DB-9 接口嗎？不是！DB-9 只是它外露給你看的「皮」，COM Port 的靈魂在於「OS 抽象 + 專屬硬體資源」。

```sh
[ 軟體應用層 ]   PuTTY / DOS 軟體開檔："COM1"
                     │
                     ▼
[ 作業系統層 ]   Windows / DOS 的虛擬裝置抽象 (驅動程式)
                     │
                     ▼ (直接控制特定硬體資源)
[ 晶片邏輯層 ]   I/O Port: 0x3F8 + IRQ: 4 ──> 實體 UART 晶片 (8250 / 16550)
                     │
                     ▼ (板上走線)
[ 實體電氣層 ]   RS-232 電平轉換晶片 (MAX232)
                     │
                     ▼
[ 實體接頭   ]   機殼背面的 DB-9 公頭
```

### COM Port 涵蓋的 I/O Port 標準

如同上面講的，COM 是一堆東西的整合，那他的 I/O Port 標準像是 0x3F8 是怎麼來的，誰定的。

在 1970 年代，每一家電腦廠商都是垂直整合的封閉帝國。

* Apple II（1977，MOS 6502 CPU）：
  * 6502 CPU 根本沒有獨立的 I/O Port 空間，所有周邊全靠 Memory-Mapped I/O（記憶體映射 I/O）。
* Commodore PET / TRS-80：
  * Commodore 用自己的位址，Tandy Radio Shack（TRS-80，Z80 CPU）又是另一套完全不同的 I/O mapping。

後果：TRS-80 上的程式，直接拿去 Apple II 或 Commodore 上跑，不管是讀鍵盤、寫螢幕還是發送 Serial 字元，位址完全不通，100% 當機。

當時各家板子的 I/O 位址與序列晶片完全不同，那軟體要怎麼寫？這就催生了現代作業系統的先驅——CP/M（Control Program for Microcomputers，由 Gary Kildall 於 1974 年開發）。

* 買 CP/M 軟體時，軟體只呼叫 BDOS 的標準函式（例如「請由序列埠讀取一個字元」）。
* 電腦製造商（如 Osborne、Kaypro、Morrow）賣電腦時，必須指派工程師寫好專屬於自家機器的 BIOS。
* 該廠商的 BIOS 知道自家的序列卡是用指撥開關設在 0x10、0x20 還是 0x80，並在 BIOS 裡寫死這段驅動邏輯。

直到在 1981 年，IBM 的 Entry Systems Division 團隊在佛羅里達州博卡拉頓（Boca Raton）秘密開發第一代 IBM PC：

1. CPU 限制（Intel 8088）：
   1. Intel x86 架構有一套獨立於記憶體的位址空間，叫做 I/O Port 空間（共 64KB，位址 0x0000 到 0xFFFF），專門用 IN / OUT 組合語言指令存取。
2. 硬體位址劃分（Address Decoding）：
   1. IBM 工程師把這塊空間切片分配給不同周邊（計時器、中斷控制器、鍵盤、軟碟機、顯示卡）。
   2. 他們設計了一張選購擴充卡——「非同步通訊介面卡（Asynchronous Communications Adapter）」。
   3. 卡上焊了一顆 INS8250 UART 晶片。
   4. 8250 晶片內部需要 8 個暫存器（接收/發送、除數鎖存、中斷控制等），需要佔用連續的 8 個 I/O Byte 位址。
   5. IBM 工程師挑選了 0x3F8 作為基底位址（Base Address），範圍涵蓋 0x3F8 到 0x3FF，並拉了一根跳線接到 8259A 中斷控制器的 IRQ 4。
   6. 為了支援第二張卡，他們又規劃了基底位址 0x2F8（涵蓋 0x2F8 到 0x2FF），接在 IRQ 3。

因為 IBM 當時出版了極其詳盡的《IBM PC Technical Reference Manual》（硬體參考手冊），裡面把主機板線路圖、BIOS 原始碼完整印了出來。

### TTY

Windows 叫做 COM Port，「COM Port」這個名稱是微軟體系（DOS / Windows）專屬的命名習慣；但在 Unix-like（Linux、FreeBSD、OpenBSD、macOS）體系中，完全對應的整套子系統被稱為「TTY（Teletypewriter）子系統」。

兩者的底層硬體（I/O Port、IRQ、UART 晶片、RS-232 電平）完全一樣，但在作業系統核心架構與軟體暴露方式上，Unix-like 發展出了一套更強大、更具歷史厚度的抽象模型。

![alt text](image-1.png)

## RS-232

RS-232 是 1960 年美國電子工業聯盟（EIA）發布的 RS-232 標準，純粹屬於 OSI 模型中的 實體層（Physical Layer）。它整份規範只關注四件事：

1. 電氣特性（Electrical Characteristics）
   1. 邏輯 1（Marking）：$-3\text{V} \sim -15\text{V}$（典型為 $-12\text{V}$）
   2. 邏輯 0（Spacing）：$+3\text{V} \sim +15\text{V}$（典型為 $+12\text{V}$）
   3. 壓降與迴轉率（Slew Rate）：限制信號上升與下降的最大斜率（不超過 $30\text{V}/\mu\text{s}$），防止電磁輻射干擾周圍電路。
   4. 最大負載阻抗：規定接收端負載電阻應在 $3\text{k}\Omega \sim 7\text{k}\Omega$ 之間。
2. 定義了 DB-25（以及後續 DE-9）接頭的物理尺寸、公母頭形狀，以及每一根針腳的固定功能（哪一根是 TX、哪一根是 RX、哪一根是 GND）。
3. 功能性訊號定義（Functional Descriptions of Circuits）: 明確定義各控制腳的語意：DTR 代表終端開機就緒、DSR 代表數據機就緒、RTS/CTS 代表請求/允許發送等。
4. 互連角色模型（Procedural Exchange）: 定義連線的兩端必須分為 DTE（終端設備，如電腦） 與 DCE（通訊設備，如數據機）。

### RS-232 + UART

只靠 RS-232 無法傳輸資料，因為他只定義 Physical Layer，CPU 是平行傳輸資料，所以 UART 就是用來把平行轉成順序。

1. 沒有時鐘線，對端怎麼知道哪裡是開頭？
   1. 是 UART 的狀態機規範：發送時強行插入一個「0」（Start bit）把電位拉高（以 RS-232 來說是變成正電壓），通知對端的 UART 晶片「醒醒，準備收資料了！」。
2. 誰來掌控節奏（Baud Rate）？
   RS-232 的導線只是一根金屬線，它不知道什麼叫「9600 bps」或「115200 bps」。必須由 UART 的分頻計時器，精準算出每 $8.68\,\mu\text{s}$（115200 速率下）在 TX 線上推一個 bit，並讓對端 UART 以相同的節奏在線路正中間取樣。

### RS-232 and TTL

CPU、UART 晶片內部使用的是 TTL（Transistor-Transistor Logic，電晶體-電晶體邏輯） 或現代的 CMOS 邏輯，而外部纜線跑的是 RS-232。

因此還會需要一個叫做 EIA 收發器（EIA Transceiver）來轉換。

1. 發送端（Driver）：升壓 ＋ 邏輯反向
   1. 當 UART 的 TX 腳位輸出 3.3V（邏輯 1） 時，收發器將其翻轉並拉大為 $-12\text{V}$。
   2. 當 UART 的 TX 腳位輸出 0V（邏輯 0） 時，收發器將其翻轉並拉大為 $+12\text{V}$。
2. 接收端（Receiver）：降壓 ＋ 邏輯反向 ＋ 雜訊消除
3. 電氣隔離與防護（ESD）
   1. 人體插拔線材時常有數千伏特的靜電放電（ESD），收發器內部帶有鉗位二極體（Clamping Diodes），直接把高壓突波導入機殼地線（Chassis GND），保護主板 CPU 與南橋 PCH。

### 序列傳輸全鏈路：從 CPU 到實體纜線（以發送字元 'A' / 0x41 為例）

#### 第一階段：軟體與 CPU 發起傳輸（平行數位域）

* **應用層與 OS 核心**：終端軟體呼叫 `write(fd, "A", 1)`，經由 OS 核心（Linux TTY 驅動或 Windows Serial 驅動）排入傳輸隊列。
* **CPU 匯流排推進**：CPU 執行 I/O 寫入指令（如 x86 的 `out dx, al`，其中 `AL = 0x41`，`DX = 0x3F8`）。
* **平行傳遞**：主機板內部匯流排（PCH / eSPI / LPC）上的 8 條資料線（D0～D7）同時並排通電，將二進位 `01000001` 在單一週期內寫入位於 `0x3F8` 的 UART 暫存器。

#### 第二階段：UART 控制器晶片（平行轉序列 ＋ 成框包裝）

* **暫存緩衝**：位元組進入發送 FIFO（Transmit FIFO），等待移位暫存器（Shift Register）就緒後載入。
* **成框邏輯（Framing, 以 8N1 為例）**：
  * **Start bit**：TX 引腳由閒置的高電位（3.3V）強行拉低至 0V，維持 1 個 bit 時間，通知對端取樣。
  * **Data bits**：依約定 Baud rate（如 115200 bps，每 bit 約 8.68 µs），採 LSB（最低有效位元）優先原則，逐位元在 TX 腳位推動 TTL 電位（`1` $\rightarrow$ 3.3V，`0` $\rightarrow$ 0V）：
    `bit0(1) → bit1(0) → bit2(0) → bit3(0) → bit4(0) → bit5(0) → bit6(1) → bit7(0)`
  * **Stop bit**：發送結束後強制拉回高電位（3.3V），維持至少 1 個 bit 時間做為訊框結尾。
* **物理狀態**：此時資料已完成序列化，但仍為微弱的 0V / 3.3V TTL 板級訊號，驅動電流僅數 mA，無法直接出機殼長距傳輸。

#### 第三階段：EIA 收發器（電平轉換與驅動放大）

* **高壓產生**：緊鄰連接埠的收發器晶片（如 MAX3232 / GD75232）藉由內部電荷泵（Charge Pump）與外接電容，將主機板 3.3V 升壓並反轉為 $\pm 12\text{V}$。
* **邏輯反向與電壓匹配**：依照 RS-232 負邏輯規範完成硬體電平轉換：
  * 數位 `0`（0V TTL）$\rightarrow$ 轉換為 **$+12\text{V}$（Space）**
  * 數位 `1`（3.3V TTL）$\rightarrow$ 轉換為 **$-12\text{V}$（Mark）**
* **驅動加強**：將弱信號轉換為具備數十 mA 輸出能力的大電流訊號，足以克服外部長線纜的寄生電容與衰減。

#### 第四階段：實體接頭與纜線（離開主機對外傳輸）

* **介面引腳**：高壓序列脈衝導向機殼後方的實體接頭（DB-9 Pin 3 為 TXD，Pin 5 為參考地 GND；或 RJ-45 Console 腳位）。
* **波形輸出**：在實體銅線上，字元 `'A'` 表現為由 $-12\text{V}$ 跳至 $+12\text{V}$ 的雙極性高壓脈衝串流，經由外部電纜長距離（最長可達 15 公尺以上）傳遞至遠端設備的接收端。

## RJ-45 and RS-232

早期的 RS-232 普遍使用龐大的 DB-9 或 DB-25 金屬接頭。1990 年代 Cisco 等網通大廠發現：1U 伺服器與 Switch 面板空間太小，塞不下 DB-9，於是將 RS-232 的訊號直接映射進 8P8C（RJ-45） 的針腳中。

中間使用現才主要為

1. Cat5e / Cat6 雙絞網路線（搭配 RJ-45 轉 DB-9 轉接頭）：直接拿現成的普通雙絞線。雖然 RS-232 是單端訊號（無法使用差動抗噪），但引腳設計刻意把 Pin 4/5 接地線 安排在中間，把 TXD（Pin 3）與 RXD（Pin 6）隔開，藉此抑制高低壓跳變產生的電磁串擾（Crosstalk）。
2. 藍色扁平 Rollover 線 / USB-Console 扁平線：裡面是 8 芯平行的無遮罩軟銅線（Flat Ribbon Wire），完全不扭絞，直通兩端的水晶頭。

而維運工程師那邊就會接 USB-to-RJ45 轉接頭 / 介面卡，上面有 RS-232 Transceiver 晶片以及 USB 轉 UART 橋接晶片。

## 相關新的協定

![alt text](image-2.png)

* USB:
  * 1996 年 USB 推出（USB 1.1 的 12 Mbps、USB 2.0 的 480 Mbps），頻寬暴增幾千倍。
  * 提供內建 5V 供電，接頭小巧且支援熱插拔。
  * 透過 USB CDC-ACM（通訊裝置類別） 或 FTDI/CH340 晶片，軟體依然可以將 USB 當成虛擬 COM Port 使用，兼顧相容性與高速需求。
* 工業與長距離控制領域的繼承者：RS-422 與 RS-485
  * 差動訊號（Differential Signaling）：改用一對絞線（$A$ 與 $B$ 兩條線的電壓差）傳輸，具備極強的共模雜訊抑制能力。
  * 距離暴增：傳輸距離一舉拉長至 1200 公尺（1.2 公里）。
  * 多點匯流排（Multi-drop / Multi-point）：RS-485 可以在同一對線上掛載 32 到 256 個節點，這直接催生了工業界最龐大的現場匯流排——Modbus RTU over RS-485。
* 機房伺服器與網管領域：Ethernet（以太網）與 SOL
  * 過去網管工程師去機房，必須隨身帶一條「藍色 Console 線（RJ-45 轉 DB-9）」插在 Switch 或伺服器背後。
  * RS-232 瓶頸：必須人到現場，或拉昂貴的專用 Terminal Server（終端伺服器）硬體去轉接。
  * 帶內管理：作業系統啟動後，直接走 Ethernet 跑 SSH。
  * 帶外管理（OOBM）：伺服器的 BMC（如 Dell iDRAC、HPE iLO）透過 Dedicated NIC（專用網孔）執行 IPMI / Redfish。原本的序列文字被打包成 SOL（Serial Over LAN） 透過網路傳輸，工程師坐在冷氣房就能看見 BIOS POST Code。
* 在主機板內部，晶片與晶片之間（例如 CPU 讀取溫度感測器、讀寫 EEPROM / SPI Flash）：
  * 不需要 RS-232 複雜的負高壓（$\pm 12\text{V}$）與額外收發器。
  * 直接改用純低壓（1.8V / 3.3V）同步介面：
    * SPI：跑極速同步序列（帶 SCLK 時脈線，可達數十 MHz）。
    * I2C / I3C：極簡兩線式開漏匯流排（SDA/SCL），省走線面積。

## Reference

* [帶你認識物聯網基礎 Serial 通訊（ㄧ）](https://vocus.cc/article/65379246fd89780001a6a170)

