在 STM32MP 系列微处理器中,通过 SPI 转 CAN 功能扩展 CAN 接口需要结合硬件设计(如使用 SPI 接口的 CAN 控制器芯片)和 Linux 驱动配置。以下是详细的实现步骤和关键点:


  1. 硬件选型与连接
    常用 SPI 转 CAN 芯片
  • MCP2515:经典 SPI 转 CAN 控制器,支持 CAN 2.0B。
  • MCP2517FD:支持 CAN FD(灵活数据速率)。
  • MCP2518FD:集成 CAN FD 和硬件时间戳功能。

硬件连接示例

  • SPI 接口:将 CAN 控制器芯片连接到 STM32MP 的 SPI 端口(如 SPI1)。
  • 中断引脚:配置 CAN 控制器的中断引脚(如 INT)连接到 STM32MP 的 GPIO。
  • CAN 收发器:如 TJA1050,连接 CAN 控制器与物理总线。

  1. Linux 内核驱动配置
    启用内核驱动

  2. 确认内核支持
    STM32MP 的 Linux 内核默认可能未启用 MCP251x 驱动,需手动配置:
    bash
    进入内核配置菜单
    make menuconfig

    • 启用以下选项:
      Device Drivers —>
      • Network device support —>
        <> CAN bus subsystem support —>
        CAN Device Drivers —>
        <
        > Microchip MCP251x SPI CAN controllers
  3. 编译并更新内核
    重新编译内核或模块,部署到 STM32MP 目标板。


  1. 设备树(Device Tree)配置
    在设备树中定义 SPI 控制器和 CAN 设备节点。

示例:stm32mp15xx.dtsi 或板级 DTS 文件
dts
&spi1 {
pinctrl-names = “default”;
pinctrl-0 = <&spi1_pins_a>;
status = “okay”;
cs-gpios = <&gpioa 9 GPIO_ACTIVE_LOW>; // 片选引脚(根据硬件设计调整)

can0: mcp2515@0 {
    compatible = "microchip,mcp2515";
    reg = <0>; // SPI 片选编号
    spi-max-frequency = <10000000>; // SPI 时钟频率(需与硬件匹配)
    interrupts = <&gpioa 8 IRQ_TYPE_EDGE_FALLING>; // 中断引脚配置
    vdd-supply = <&vdd_3v3>; // 电源(可选)
    oscillator-frequency = <16000000>; // CAN 控制器晶振频率
    clocks = <&can_osc>; // 若使用外部时钟源
};

};

关键配置项

  • SPI 总线速率:需与 CAN 控制器芯片的 SPI 接口速率匹配。
  • 中断引脚:确保与硬件连接一致,并配置中断触发方式(如边沿触发)。
  • 时钟源:若 CAN 控制器使用外部晶振,需指定频率。

  1. 驱动加载与接口验证
    加载驱动模块
    bash
    手动加载 MCP2515 驱动(若未编译进内核)
    modprobe mcp251x

检查 CAN 接口
bash
查看 CAN 接口是否注册成功
ip link show
输出应包含类似内容:
can0: <NOARP,ECHO> mtu 16 qdisc noop state DOWN mode DEFAULT group default qlen 10

配置 CAN 接口参数
bash
设置 CAN 总线波特率(例如 500 kbps)
ip link set can0 type can bitrate 500000
ip link set can0 up


  1. 测试 CAN 通信
    使用 can-utils 工具测试收发功能:
    bash
    安装 can-utils(需交叉编译或通过包管理器)
    sudo apt-get install can-utils

接收 CAN 数据(终端1)
candump can0

发送 CAN 数据(终端2)
cansend can0 1231122334455667788


  1. 常见问题与调试
    问题1:CAN 接口无法识别
  • 检查设备树配置:确认 SPI 和 CAN 节点无语法错误,引脚分配正确。
  • 查看内核日志:
    bash
    dmesg | grep spi
    dmesg | grep can

问题2:SPI 通信失败

  • 验证 SPI 信号:使用示波器检查 SPI 时钟(SCK)、数据线(MOSI/MISO)和片选(CS)信号。
  • 调整 SPI 速率:降低 spi-max-frequency 值(如改为 1000000)。

问题3:中断未触发

  • 检查中断引脚配置:确认 GPIO 号和触发方式(如 IRQ_TYPE_EDGE_FALLING)。
  • 测试 GPIO 中断:通过 gpiod 工具验证中断引脚是否正常工作。

  1. 集成到系统服务
    自动启动 CAN 接口
    创建 systemd 服务文件(如 /etc/systemd/system/can0.service):
    ini
    Unit
    Description=Bring up CAN0 interface

Service
Type=oneshot
ExecStart=/sbin/ip link set can0 type can bitrate 500000
ExecStartPost=/sbin/ip link set can0 up

Install
WantedBy=multi-user.target

启用服务
bash
systemctl enable can0.service
systemctl start can0.service


总结
通过 SPI 扩展 CAN 接口在 STM32MP 上的实现流程:

  1. 硬件连接:选择 CAN 控制器芯片并正确接线。
  2. 内核驱动:启用 mcp251x 驱动并编译内核。
  3. 设备树配置:定义 SPI 和 CAN 节点。
  4. 测试与调试:使用 can-utils 验证通信功能。
  5. 系统集成:配置自动启动和优化参数。

实际应用中需根据硬件设计调整设备树和驱动参数,确保 SPI 时序和中断配置正确。

更多推荐