树莓派 Compute Module 4 (CM4)

元器件
开发板
库存 45

介绍

工业级核心板,BCM2711四核Cortex-A72 1.5GHz、1-8GB LPDDR4、0-32GB eMMC、双HDMI、PCIe 2.0 x1、千兆以太网PHY、WiFi 5/BT 5.0(无线版)、28GPIO、双CSI/DSI,200Pin SODIMM封装

规格参数

参数
CPUBCM2711 四核 Cortex-A72 @ 1.5GHz
GPUVideoCore VI
RAM1GB/2GB/4GB/8GB LPDDR4
GPIO28路(与Pi 4B子集兼容)
PCIePCIe 2.0 x1
eMMC0GB(Lite)/8GB/16GB/32GB
封装200Pin SODIMM (DDR2外形,电气不兼容)
尺寸55×40mm
无线可选: 802.11ac WiFi 5 + BT 5.0
电源5V
网络千兆以太网PHY(需外部MagJack)
视频双HDMI 2.0 4Kp60
CSI/DSI各2路

代码例程

树莓派 CM4 编程例程 — rpiboot 烧录 + GPIO + PCIe + 集群.md
# 树莓派 CM4 编程例程

CM4 运行 Raspberry Pi OS,GPIO 编程与 Pi 4B 完全兼容。以下聚焦 CM4 特有场景。

---

## 示例 1:rpiboot — CM4 eMMC 烧录(Linux 主机)

```bash
#!/bin/bash
# === 在 Linux 主机上执行,将 CM4 eMMC 挂载为 USB 大容量存储 ===

# 1. 安装 rpiboot
sudo apt install libusb-1.0-0-dev git
git clone --depth=1 https://github.com/raspberrypi/usbboot.git
cd usbboot
make

# 2. CM4 进入烧录模式:
#    - 断开 CM4 电源
#    - 短接 nRPIBOOT 引脚到 GND(或底板 BOOT 跳线)
#    - 用 USB 线连接 CM4 USB OTG 到主机
#    - 接通 CM4 电源

# 3. 运行 rpiboot
sudo ./rpiboot

# 成功后 CM4 eMMC 在主机上显示为 /dev/sdX
echo "CM4 eMMC 已挂载,可用 dd 或 Raspberry Pi Imager 烧录"

# 4. 烧录 Raspberry Pi OS
sudo dd if=2024-03-15-raspios-bookworm-arm64.img of=/dev/sdX bs=4M status=progress
sync

# 5. 断开 CM4 电源,移除 nRPIBOOT 短接,重新上电启动
```

## 示例 2:Python — CM4 GPIO 控制(gpiozero)

```python
#!/usr/bin/env python3
"""CM4 GPIO 控制 — 与 Pi 4B 完全相同"""
from gpiozero import LED, Button
from signal import pause

# CM4 的 28 路 GPIO 与 Pi 4B 的 BCM 编号对应
led = LED(17)       # BCM 17
btn = Button(27, pull_up=True)

btn.when_pressed = led.on
btn.when_released = led.off

print("CM4 GPIO 测试: 按键→LED")
pause()
```

## 示例 3:Shell — PCIe NVMe SSD 启用(CM4IO 底板)

```bash
#!/bin/bash
# CM4 + CM4IO 底板 PCIe 连接 NVMe SSD

# 1. 检查 PCIe 设备
lspci
# 应显示: 01:00.0 Non-Volatile memory controller: ...

# 2. 查看 NVMe 磁盘
lsblk
# 应显示: nvme0n1

# 3. 如果未识别,检查 config.txt
grep -E "dtparam=pcie|dtoverlay=pcie" /boot/config.txt

# 4. 添加 PCIe 支持(如未添加)
echo "dtparam=pciex1" | sudo tee -a /boot/config.txt
echo "dtparam=pciex1_gen=3" | sudo tee -a /boot/config.txt  # 尝试 Gen3

# 5. 格式化并挂载
sudo mkfs.ext4 /dev/nvme0n1
sudo mkdir -p /mnt/nvme
sudo mount /dev/nvme0n1 /mnt/nvme
df -h /mnt/nvme
```

## 示例 4:Python — 双路 CSI 摄像头同时采集

```python
#!/usr/bin/env python3
"""CM4 双路 CSI 摄像头同时拍照(需两条 CSI 排线)"""
import subprocess
import time

# CM4 支持两路 CSI (camera0, camera1)
print("拍照 CAM0...")
subprocess.run(["libcamera-still", "-o", "cam0.jpg",
                "--camera", "0", "-t", "100", "--width", "1920",
                "--height", "1080"])

time.sleep(0.5)

print("拍照 CAM1...")
subprocess.run(["libcamera-still", "-o", "cam1.jpg",
                "--camera", "1", "-t", "100", "--width", "1920",
                "--height", "1080"])

print("双路拍照完成: cam0.jpg, cam1.jpg")
```

## 示例 5:Shell — CM4 集群(K3s 轻量 Kubernetes)

```bash
#!/bin/bash
# CM4 集群 — 在 CM4IO 底板上运行 K3s

# === 所有节点 ===
# 禁用 swap
sudo dphys-swapfile swapoff
sudo dphys-swapfile uninstall
sudo update-rc.d dphys-swapfile remove

# 启用 cgroups
echo "cgroup_memory=1 cgroup_enable=memory" | sudo tee -a /boot/cmdline.txt
sudo reboot

# === Master 节点 ===
curl -sfL https://get.k3s.io | sh -
TOKEN=$(sudo cat /var/lib/rancher/k3s/server/node-token)
MASTER_IP=$(hostname -I | awk '{print $1}')
echo "Token: $TOKEN"
echo "Master IP: $MASTER_IP"

# === Worker 节点 (每台CM4) ===
# curl -sfL https://get.k3s.io | K3S_URL=https://$MASTER_IP:6443 \
#   K3S_TOKEN=$TOKEN sh -

# 验证集群
sudo kubectl get nodes
```

## 示例 6:C — 直接寄存器操作 GPIO(CM4 BCM2711)

```c
/*
 * CM4 GPIO 直接寄存器操作(高频率翻转)
 * 编译: gcc -o fast_gpio fast_gpio.c
 * 运行: sudo ./fast_gpio
 */
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

#define BCM2711_PERI_BASE 0xFE000000
#define GPIO_BASE         (BCM2711_PERI_BASE + 0x200000)
#define BLOCK_SIZE        4096

#define GPFSEL0  0x00
#define GPSET0   0x1C
#define GPCLR0   0x28

volatile unsigned int *gpio;

#define INP_GPIO(g)  *(gpio + ((g)/10)) &= ~(7 << (((g)%10)*3))
#define OUT_GPIO(g)  *(gpio + ((g)/10)) |=  (1 << (((g)%10)*3))
#define SET_GPIO(g)  *(gpio + 7) = 1 << (g)  // GPSET0
#define CLR_GPIO(g)  *(gpio + 10) = 1 << (g) // GPCLR0

int main() {
    int fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd < 0) { perror("open /dev/mem"); return 1; }

    gpio = (unsigned int*) mmap(NULL, BLOCK_SIZE,
        PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
    if (gpio == MAP_FAILED) { perror("mmap"); return 1; }

    int pin = 17;
    OUT_GPIO(pin);

    printf("GPIO%d 高速翻转 1000000 次...\n", pin);
    for (int i = 0; i < 1000000; i++) {
        SET_GPIO(pin);
        CLR_GPIO(pin);
    }
    printf("完成\n");

    munmap((void*)gpio, BLOCK_SIZE);
    close(fd);
    return 0;
}
```

---

## ⚠️ CM4 编程特别注意

1. **eMMC 编程必须用 rpiboot**:不能像 Pi 4B 那样拔 SD 卡烧录,Lite 版通过 SD 卡、eMMC 版必须 USB OTG 模式。
2. **GPIO 与 Pi 4B 子集**:CM4 仅 28 路 GPIO,缺失的部分(如 GPIO16/19/20/21 的某些功能)需查阅 CM4 数据手册确认。
3. **PCIe 需要配置**:默认未启用,需在 config.txt 添加 `dtparam=pciex1`。
4. **USB OTG 仅 1 路**:如需多路 USB,底板必须使用 USB Hub 芯片。
5. **万不可与 DDR2 SODIMM 插槽混淆**:物理外形相同但电气完全不同,插错会烧毁!
6. **CM4IO 底板**:官方 CM4IO 提供标准接口,适合原型验证和开发。

参考资料

暂无参考文献