总线与接口
概述
总线(Bus)是计算机系统中连接各个组件的共享通信通道。在机器人系统中,总线连接CPU、内存、传感器和执行器,是数据流动的"高速公路"。理解总线架构对于诊断通信瓶颈和设计高效系统至关重要。
系统总线基础
三类总线
系统总线由三组信号线组成:
| 总线类型 | 功能 | 信号方向 |
|---|---|---|
| 地址总线(Address Bus) | 指定内存/外设地址 | CPU → 内存/外设 |
| 数据总线(Data Bus) | 传输数据 | 双向 |
| 控制总线(Control Bus) | 传输控制信号(读/写/中断) | 双向 |
地址总线宽度决定寻址范围:
\[
\text{可寻址空间} = 2^n \text{ 字节}
\]
其中 \(n\) 是地址总线位数。例如32位地址总线可寻址 \(2^{32} = 4\text{GB}\)。
总线带宽
\[
\text{总线带宽} = \text{数据总线宽度} \times \text{总线频率} \times \text{每周期传输次数}
\]
DDR5内存总线带宽
数据宽度 = 64位 = 8字节,频率 = 4800MHz,DDR(双倍速率):
\[\text{带宽} = 8 \times 4800 \times 10^6 \times 2 = 76.8 \text{ GB/s}\]
总线架构
传统总线架构
graph TB
CPU[CPU] --> NB[北桥<br>North Bridge]
NB --> RAM[内存 DRAM]
NB --> GPU[GPU<br>PCIe x16]
NB --> SB[南桥<br>South Bridge]
SB --> USB[USB]
SB --> SATA[SATA SSD]
SB --> ETH[以太网]
SB --> AUDIO[音频]
现代SoC总线架构
现代SoC(如ARM芯片)采用片上互连(On-Chip Interconnect):
graph TB
subgraph SoC
CPU[CPU Cluster<br>Cortex-A78] --> AXI[AXI Interconnect<br>高性能总线]
GPU[GPU] --> AXI
NPU[NPU/DLA] --> AXI
AXI --> MC[内存控制器<br>LPDDR5]
AXI --> APB[APB Bridge<br>低速外设总线]
APB --> UART[UART]
APB --> I2C[I2C]
APB --> SPI[SPI]
APB --> GPIO[GPIO]
AXI --> AHB[AHB Bridge]
AHB --> DMA[DMA控制器]
AHB --> USB_C[USB控制器]
AHB --> ETH_C[以太网控制器]
end
MC --> MEM[LPDDR5 内存]
PCIe(Peripheral Component Interconnect Express)
PCIe基础
PCIe是现代高速串行总线标准:
| 版本 | 单通道带宽 | x4带宽 | x16带宽 | 编码 |
|---|---|---|---|---|
| PCIe 3.0 | 1 GB/s | 4 GB/s | 16 GB/s | 128b/130b |
| PCIe 4.0 | 2 GB/s | 8 GB/s | 32 GB/s | 128b/130b |
| PCIe 5.0 | 4 GB/s | 16 GB/s | 64 GB/s | 128b/130b |
机器人中的PCIe应用
| 设备 | 接口 | 通道数 | 用途 |
|---|---|---|---|
| NVMe SSD | PCIe 3.0/4.0 | x4 | 数据记录 |
| GPU(桌面) | PCIe 4.0/5.0 | x16 | 深度学习训练 |
| 以太网卡 | PCIe 3.0 | x1/x4 | 高速网络通信 |
| FPGA加速卡 | PCIe 3.0/4.0 | x4/x8 | 传感器预处理 |
Jetson的PCIe
Jetson Orin拥有多条PCIe通道:
- PCIe Gen4 x8(可拆分为x4+x4)
- 用于连接NVMe SSD、以太网卡等扩展设备
USB(通用串行总线)
USB版本对比
| 版本 | 速率 | 编码 | 供电 | 机器人中的用途 |
|---|---|---|---|---|
| USB 2.0 | 480 Mbps | NRZI | 5V/0.5A | 低速相机、串口设备 |
| USB 3.0 | 5 Gbps | 8b/10b | 5V/0.9A | RGB相机、LiDAR |
| USB 3.1 | 10 Gbps | 128b/132b | 5V/3A (Type-C) | 深度相机 |
| USB 3.2 | 20 Gbps | 128b/132b | 5V/3A | 高速数据传输 |
USB在机器人中的常见问题
USB带宽共享
同一USB Host Controller下的设备共享带宽。例如:
- USB 3.0 Hub下接2个相机(各需要200MB/s)
- 总带宽500MB/s,两个相机可能出现丢帧
解决方案:使用不同的USB控制器,或使用CSI接口
# Linux下查看USB拓扑
lsusb -t
# 查看USB设备的带宽分配
cat /sys/bus/usb/devices/*/bAlternateSetting
AXI总线(ARM AMBA)
AMBA总线家族
ARM的AMBA(Advanced Microcontroller Bus Architecture)是SoC内部的标准总线协议:
| 总线 | 特点 | 带宽 | 用途 |
|---|---|---|---|
| AXI | 高性能、突发传输 | 很高 | CPU↔内存、GPU↔内存 |
| AHB | 中等性能 | 中等 | DMA、USB控制器 |
| APB | 低功耗、简单 | 低 | UART、I2C、SPI、GPIO |
AXI关键特性
- 分离的读写通道:读和写可以同时进行
- 突发传输(Burst Transfer):一次地址,连续传输多个数据
- Outstanding Transaction:不必等待前一次传输完成就可发起新传输
- 乱序完成(Out-of-Order Completion):不同ID的传输可以乱序完成
AXI 5个通道:
├── 写地址通道 (AW) : Master → Slave
├── 写数据通道 (W) : Master → Slave
├── 写响应通道 (B) : Slave → Master
├── 读地址通道 (AR) : Master → Slave
└── 读数据通道 (R) : Slave → Master
中断处理
三种I/O模式
| 模式 | 原理 | CPU占用 | 延迟 | 适用场景 |
|---|---|---|---|---|
| 轮询(Polling) | CPU不断查询设备状态 | 100% | 最低 | 超低延迟需求 |
| 中断(Interrupt) | 设备就绪时通知CPU | 低 | 中等 | 大多数场景 |
| DMA | 硬件直接传输数据 | 极低 | 较高(初始化) | 大量数据传输 |
中断处理流程
graph TD
A[外设发出中断请求] --> B[中断控制器 NVIC/GIC]
B --> C{优先级仲裁}
C --> D[保存当前上下文<br>寄存器压栈]
D --> E[跳转到中断向量表<br>执行ISR]
E --> F[清除中断标志]
F --> G[恢复上下文<br>寄存器出栈]
G --> H[返回被中断的程序]
ARM中断控制器
STM32(Cortex-M)- NVIC:
- 最多240个中断源
- 可编程优先级(0-255)
- 支持嵌套中断(高优先级可以打断低优先级ISR)
- 中断延迟:12个时钟周期(Cortex-M4)
Jetson/RPi(Cortex-A)- GIC:
- GIC-400/GIC-600
- SGI(软件生成中断)、PPI(私有外设中断)、SPI(共享外设中断)
- 支持中断路由到特定核心
中断优先级设计
对于机器人系统,典型的中断优先级分配:
| 优先级 | 中断源 | 说明 |
|---|---|---|
| 最高 | 急停按钮 | 安全相关,必须立即响应 |
| 高 | 电机编码器 | 实时控制需要 |
| 高 | IMU数据就绪 | 姿态估计 |
| 中 | 通信接收(CAN/UART) | 命令接收 |
| 低 | ADC转换完成 | 电压/温度监测 |
| 最低 | 定时器(LED闪烁) | 状态指示 |
中断服务程序(ISR)编写规则
- 尽可能短:在ISR中只做最少的工作(设置标志、拷贝数据)
- 不要阻塞:不能在ISR中调用
sleep、malloc等 - 不要使用printf:I/O操作太慢
- 使用volatile:ISR中修改的变量要声明为
volatile
// 好的ISR设计
volatile bool imu_data_ready = false;
volatile uint8_t imu_buffer[14];
void IMU_IRQHandler(void) {
// 只做数据拷贝和标志设置
memcpy((void*)imu_buffer, (void*)IMU_DATA_REG, 14);
imu_data_ready = true;
__HAL_GPIO_EXTI_CLEAR_IT(IMU_INT_PIN);
}
// 主循环中处理数据
while (1) {
if (imu_data_ready) {
imu_data_ready = false;
process_imu_data(imu_buffer);
}
}
I/O模型对比
同步 vs 异步
同步阻塞 I/O:
Thread: [===请求===][=========等待=========][==处理==]
同步非阻塞 I/O (Polling):
Thread: [请求][检查][检查][检查]...[数据就绪][处理]
异步 I/O (中断/DMA):
Thread: [请求][做其他事...][中断!][处理]
Linux I/O模型
| 模型 | 说明 | 机器人应用 |
|---|---|---|
| 阻塞I/O | read()阻塞直到数据就绪 |
简单串口读取 |
| 非阻塞I/O | read()立即返回,需轮询 |
多传感器轮询 |
| I/O多路复用 | select()/poll()/epoll() |
同时监听多个设备 |
| 异步I/O | aio_read(),内核通知完成 |
高性能数据采集 |
# Python中使用select监听多个串口
import select
sensors = [serial_imu, serial_lidar, serial_gps]
while True:
readable, _, _ = select.select(sensors, [], [], timeout=0.01)
for sensor in readable:
data = sensor.read(sensor.in_waiting)
process(data)
机器人总线架构示例
典型移动机器人
graph TB
subgraph 主控[主控 Jetson Orin]
CPU[CPU<br>Cortex-A78]
GPU_M[GPU<br>Ampere]
CSI[CSI接口]
PCIE[PCIe]
USB3[USB 3.0]
ETH[千兆以太网]
UART_M[UART]
end
subgraph 传感器
CAM[RGB-D相机] -->|CSI/USB3| CSI
LIDAR[LiDAR] -->|以太网| ETH
IMU[IMU] -->|SPI| MCU
end
subgraph MCU控制[MCU STM32H7]
MCU[Cortex-M7]
CAN_C[CAN总线]
PWM[PWM输出]
ADC_M[ADC]
end
UART_M -->|UART 115200| MCU
MCU -->|CAN| MOTOR1[电机驱动1]
MCU -->|CAN| MOTOR2[电机驱动2]
MCU -->|PWM| SERVO[舵机]
MCU -->|ADC| BATTERY[电池电压]
PCIE -->|NVMe| SSD[SSD存储]
小结
- 系统总线由地址、数据、控制三部分组成
- PCIe是高速扩展的主流标准,每代带宽翻倍
- USB方便但需注意带宽共享问题
- AXI/AHB/APB是ARM SoC内部的层次化总线
- 中断机制是实时响应的基础,ISR要尽可能短
- DMA在大数据量传输中释放CPU
参考资料
- ARM AMBA AXI Protocol Specification
- PCI Express Base Specification
- USB 3.2 Specification
- STM32 Reference Manual: NVIC and Interrupt Handling