API GUIDE / CAN / OVERVIEW

G32S10 CAN API 概述

模块概述:本文档描述 G32S10 SDK 当前提供的 CAN 硬件驱动层:

1. 文档范围

本文档描述 G32S10 SDK 当前提供的 CAN 硬件驱动层:

层级职责
LL直接访问 CAN 寄存器和位域,不维护软件状态
HAL管理 CPM 时钟/复位、原始位时序和 filter 配置、帧寄存器访问、控制器状态、外设中断源、callback 以及 CAN 寄存器窗口 DMA 地址

CAN 帧协议语义、DLC 转换、bitrate 查表、SoC IRQ 所有权、DMA 通道申请、waiter、 队列、超时、恢复策略和统计信息属于可选的 CAN middleware,详见code/middleware/can/example/README.md。

HAL 会检查寄存器访问所需的前置条件,包括句柄、实例、filter index 和控制器状态 是否合法。HAL 可以在逻辑帧字段与 TFIR/RFIR/RXID 原始字段之间转换,但不负责 DLC/应用长度换算、完整 CAN 帧语义校验或 im_can_frame_t 转换,也不维护完整的 收发策略。

2. 编译配置与文件

直接使用 HAL/LL 时需要使能:

CONFIG_DRIVER_CAN=y

DRIVER_CAN 会选择 CAN HAL 及其 CPM 依赖,不会自动选择 OS、DMA 驱动或 CAN middleware。

可选的寄存器 dump helper 还需要同时使能:

CONFIG_SDK_ENABLE_DEBUG_HELPERS=y
CONFIG_CAN_ENABLE_DEBUG_HELPERS=y

未同时使能这两个选项时,hal_can_regs_dump() 保留公开符号,但返回IM_ERR_UNSUPPORTED,不会读取或打印寄存器。

相关源文件如下:

文件职责
code/include/drivers/g32s10/can/hal_can.hHAL 公开类型和函数
code/drivers/g32s10/can/hal_can.cHAL 实现及 CPM 集成
code/include/drivers/g32s10/can/ll_can.hLL 寄存器和位域辅助接口
code/include/drivers/g32s10/can/can_regs.h寄存器布局、实例和 PM 位定义
code/drivers/g32s10/can/KconfigDRIVER_CAN 配置
code/drivers/g32s10/can/CMakeLists.txtHAL 源文件注册

当前支持 CAN0 和 CAN1 两个寄存器块实例。板级 pinmux 和外部 CAN 收发器 配置仍由 BSP 和硬件设计负责。

3. 位时序字段

HAL 接收已经编码的寄存器字段,不根据目标 bitrate 自动计算时序:

typedef struct {
    uint32_t tseg1;
    uint32_t tseg2;
    uint32_t sjw;
    uint32_t divider;
} hal_can_bit_timing_t;

实际值计算如下:

TSEG1 = tseg1 + 1
TSEG2 = tseg2 + 1
SJW   = sjw + 1
BRP   = divider + 1

bitrate = CANCLK / (BRP * (1 + TSEG1 + TSEG2))

PM 定义的编码字段范围如下:

字段编码范围
tseg10..15
tseg20..7
sjw0..3,同时受 PM 中与 tseg2 的关系约束
divider0..63

HAL 在写寄存器前校验每个字段是否位于上述编码范围,但不会根据物理 bitrate 选择 timing profile,也不校验 sjw <= tseg2 等协议层时序关系。hal_can_set_timing() 仅可在控制器处于 reset 时调用。

4. 原始帧镜像与 Filter

HAL 对外提供控制器原始 TX/RX 寄存器窗口镜像:

typedef struct {
    uint32_t frame_info;
    uint32_t id;
    uint32_t data[HAL_CAN_DATA_REG_COUNT];
} hal_can_frame_image_t;

镜像共 18 个 word,即 72 byte。frame_info、id 和 data 保存 PM 定义的原始 寄存器值。HAL 还提供不暴露寄存器 bit 位置的逻辑字段结构:

typedef struct {
    uint32_t dlc;
    uint32_t filter_match;
    bool is_extended;
    bool is_remote;
    bool is_fd;
    bool brs;
    bool esi;
} hal_can_frame_info_t;

dlc、帧格式、remote、FD 和 BRS 可用于 TX 编码及 RX 解码;filter_match 和esi 来自 RX 帧信息。该结构描述寄存器字段的逻辑值,不等同于应用层 CAN 帧。 HAL 仍然不负责:

  • 根据 payload byte 长度计算 DLC;

  • 校验标准标识符或扩展标识符范围;

  • 校验 remote、FD、BRS 与 payload 长度组合;

  • 判断 data 窗口中有多少 byte 有效。

hal_can_tx_frame_info_encode() 把逻辑字段编码为原始 TFIR,hal_can_rx_frame_info_decode() 解码原始 RFIR,hal_can_rx_id_decode() 从原始 RXID 中提取有效标识符。寄存器 bit 位置和 RXID mask 因而由 HAL 维护。

hal_can_tx_image_write() 将镜像复制到 TX 寄存器窗口。hal_can_tx_header_get() 在不修改窗口的情况下读回原始 TFIR/TXID header,使 DMA owner 可以通过 HAL 验证写入可见性。hal_can_tx_request() 请求发送,hal_can_tx_abort() 取消当前发送请求。hal_can_rx_image_read() 复制一个可用 RX 镜像,调用方随后必须调用 hal_can_rx_release() 释放硬件 RX buffer。 这些接口均为立即操作,不实现软件 timeout 或 retry loop。

Acceptance filter 使用:

typedef struct {
    uint32_t id;
    uint32_t mask;
} hal_can_filter_t;

mask bit 为 0 时比较对应标识符 bit,为 1 时忽略该 bit。id 和 mask 均为 29 位硬件字段,HAL 会拒绝超过 0x1FFFFFFF 的值。HAL_CAN_FILTER_ACCEPT_ALL 表示全部 bit 均忽略。配置、使能或关闭 filter 时, 控制器必须处于 reset。

5. 已移除的旧版策略接口

重构后的 HAL 不再提供:

  • 内置模块时钟或 baud-rate 查找表;

  • hal_can_set_baud();

  • 独立的 hal_can_set_module_clock();

  • hal_can_config_t.bus_rate 或 manual_timing_enable;

  • HAL_CAN_DMA_REQUEST_TX;

  • HAL 所有的 hal_can_frame_t 和帧/DLC 校验 helper;

  • 独立的 hal_can_frame.c 或 im_can_timing.c 源文件。

应用需要基于 bitrate 配置和应用级 im_can_frame_t 收发时,应使用可选的 CAN middleware。应用自行管理原始硬件 timing、帧镜像编码、IRQ 路由和传输策略时, 可以直接使用 HAL。