NXP MCU 技术论坛
直播中

张鑫

8年用户 1131经验值
私信 关注
[问答]

使用CAN以及CANIF配置了S32K310的CAN驱动模块,如何进行报文的接收呢?

我使用CAN以及CANIF配置了S32K310的CAN驱动模块。我知道调用CAN_Write()函数进行报文的发送,但我存有以下的一些问题:
1.我该如何进行报文的接收呢?我看到有一些文章说能够通过CanIf_RxIndication()函数进行接收。但是这个函数在静态代码中的逻辑应当是自动调用,而不是由我在外部主程序中调用。或者说这个函数在触发中断自动执行后将数据进行了存储,那我该如何将这些数据读取出来呢?我是否能用自己编写的回调函数去替换他?(我在MCAL的例程中没有找到使用中断的CAN例程,似乎只有POLLING模式的例程)
2.为什么CAN的接收一定要通过CANIF而发送却可以直接由CAN驱动发出?这是否有一些规范限制我必须这样做。

回帖(1)

张丽

2025-3-26 17:58:21

在S32K310的AUTOSAR MCAL架构中,CAN报文接收的设计遵循分层机制(CAN Driver → CAN Interface → CAN Transport Layer),以下是关键问题解答和实现指南:




1. CAN接收机制详解


(1)接收流程与回调机制



  • CanIf_RxIndication() 是AUTOSAR标准中定义的回调函数,由CAN Driver在接收中断触发时自动调用(无需手动调用)。

  • 触发条件:当CAN控制器接收FIFO或MB(Message Buffer)中有报文到达且匹配ID过滤规则时,硬件触发中断。

  • 数据存储:接收的报文会通过CanIf_RxIndication()传递给上层(如COM模块或应用层),需在CanIf层配置接收缓冲区。


(2)实现接收的步骤


a. 硬件中断配置


  • S32K3配置工具(如S32DS/S32 Configuration Tool):

    • 启用CAN控制器的接收中断(CAN_IRQ_RX)。

    • 配置NVIC中断优先级并启用全局中断。


  • 代码示例(中断服务函数):
    void CAN0_ORED_0_IRQHandler(void)
    {
      if (CAN_GetStatusFlag(CAN0, CAN_IFLAG_RXF)) // 检查RXF标志
      {
          CanIf_RxIndication(CAN0, CAN_RX_MB_IDX); // 传递硬件句柄和MB索引
          CAN_ClearStatusFlag(CAN0, CAN_IFLAG_RXF); // 清除中断标志
      }
    }


b. CanIf层配置


  • 接收缓冲区映射

    • 在CanIf配置中定义CanIfHwFilterCanIfRxPduCfg,将物理邮箱(MB)映射到逻辑接收PDU。



  • 回调注册



    • 若需要自定义处理,在应用层注册回调函数(非替换CanIf_RxIndication):

      void My_RxCallback(uint8_t ControllerId, Can_HwHandleType Hth, const PduInfoType* PduInfo)
      {
      // 解析PduInfo->SduDataPtr获取数据
      }


    // 在CanIf初始化后注册回调
    CanIf_SetRxIndication(My_RxCallback);





c. 应用层读取数据


  • 轮询方式(不推荐,仅调试用):
    Can_PduType rxPdu;
    if (CAN_Read(CAN0, CAN_RX_MB_IDX, &rxPdu) == CAN_OK)
    {
      // 处理rxPdu.data[]
    }

  • 中断方式

    • 数据在回调函数My_RxCallback中实时处理,无需主动读取。





2. 为何必须通过CANIF模块?


AUTOSAR架构要求严格分层:



  • CAN Driver:直接操作硬件(如MB配置、中断标志管理)。

  • CANIF:提供硬件抽象,管理PDU路由、DLC校验、唤醒事件等。

  • 优势:模块解耦、支持多CAN控制器、统一接口(如CanIf_Transmit()CanIf_RxIndication)。


若需绕过CANIF,需直接操作CAN Driver的接收MB,但会破坏AUTOSAR兼容性。




3. 配置工具关键步骤



  1. S32 Configuration Tool

    • CAN Controller → 启用Rx Interrupt,配置ID过滤器。

    • CanIf模块 → 添加Rx Hardware Object,关联到对应的CAN控制器和MB。


  2. 生成代码

    • 检查CanIf_Cfg.c中生成的CanIf_RxIndication调用链。

    • 确保中断向量表包含CANx_ORED_y_IRQHandler





4. 完整接收代码示例


// can_cfg.c (自动生成)
const CanIf_ConfigType CanIf_Config = {
    .RxPduCfgs = {
        {
            .CanIfRxPduHrhId = 0, // 硬件接收句柄索引
            .CanIfRxPduId = 0,    // 应用层PDU ID
            .CanIfRxPduCanId = 0x123 // 标准ID
        }
    }
};

// app_can.c
void My_RxCallback(uint8_t ControllerId, Can_HwHandleType Hth, const PduInfoType* PduInfo)
{
    uint8_t* data = PduInfo->SduDataPtr;
    uint32_t id = CanIf_GetRxPduId(ControllerId, Hth);
    printf("Received ID: 0x%X, Data: %02X %02Xn", id, data[0], data[1]);
}

int main(void)
{
    CAN_Init(CAN0); // 初始化CAN控制器
    CanIf_Init(&CanIf_Config); // 初始化CAN Interface
    CanIf_SetRxIndication(My_RxCallback); // 注册应用层回调

    while(1)
    {
        // 主循环可处理其他任务
    }
}



5. 常见问题排查



  • 无接收中断:检查CAN控制器时钟是否使能、NVIC优先级配置、ID过滤器设置。

  • 数据未更新:确认接收MB在中断后是否被正确释放(CAN_ClearStatusFlag)。

  • 回调未触发:确保CanIf_SetRxIndication在初始化后调用,且PDU ID匹配。


通过上述步骤,您可以在S32K310上实现基于中断的高效CAN报文接收,同时遵循AUTOSAR分层规范。

举报

更多回帖

发帖
×
20
完善资料,
赚取积分