Edit online

设计说明

4 Dec 2024
Read time: 3 minute(s)

源码说明

CAN 模块的源码位于:
  • bsp/artinchip/drv/can/drv_can.c,CAN 模块 driver 层源码

  • bsp/artinchip/hal/can/aic_hal_can.c,CAN 模块 hal 层源码

  • bsp/artinchip/include/hal/aic_hal_can.h,CAN 模块 hal 层头文件

模块架构


can_arch

关键流程设计

初始化流程

CAN 模块的初始化流程如下:

  1. 释放 reset 和 clock 信号

  2. 设置为复位模式

  3. 设置默认接收所有帧数据

  4. 设置为 normal 模式

中断处理流程

在驱动中,利用中断进行数据的接收和总线错误的检测。由于 CAN 每帧数据量较小,所以发送时采用了轮询的方式,直到发送完所有数据。但是为了统计发送信息,也使能了发送中断,接收到发送中断后,只更新 CAN 的发送状态信息。


interrupt_flow

数据发送流程

由于 CAN 每帧的数据量只有 8byte,所以发送数据时没有采用 DMA 或中断方式,而是直接调用发送函数将数据发送出去。CAN 模块驱动的数据发送流程如下:


start_xmit

数据结构设计

typedef struct can_handle can_handle;
struct can_handle {
    unsigned long can_base;
    uint32_t irq_num;
    uint32_t clk_id;
    uint32_t idx;
    void (*callback)(can_handle * phandle, void *arg);
    void *arg;
    uint32_t baudrate;
    can_msg_t msg;
    can_status_t status;
};

接口设计

driver 层接口设计
1. aic_can_control
函数原型 static rt_err_t aic_can_control(struct rt_can_device *can, int cmd, void *arg)
功能说明 CAN 模块 control 接口,用于设置波特率,获取状态等
参数定义
can: 指向 rt_can_device 设备的指针
cmd: CAN 命令
arg: 命令参数
返回值 RT_EOK:执行成功
注意事项 -
2. aic_can_send
函数原型 static int aic_can_send(struct rt_can_device *can, const void *buf, rt_uint32_t boxno)
功能说明 CAN 发送接口
参数定义
can: 指向 rt_can_device 设备的指针
buf: 指向要发送的 can message 的指针
boxno: 发送的邮箱号
返回值 0:执行成功
注意事项 -
3. aic_can_recv
函数原型 static int aic_can_recv(struct rt_can_device *can, void *buf, rt_uint32_t boxno)
功能说明 CAN 接收接口
参数定义
can: 指向 rt_can_device 设备的指针
buf: 指向存储接收的 can message 的指针
boxno: 接收的邮箱号
返回值 0:执行成功
注意事项 -
hal 层接口设计
4. hal_can_init
函数原型 int hal_can_init(can_handle *phandle, uint32_t can_idx);
功能说明 CAN 模块初始化
参数定义
phandle: 指向 can_handle 结构体的指针
can_idx: 需要初始化的 CAN 模块索引号
返回值
0:执行成功
-EINVAL:执行失败
注意事项 -
5. hal_can_uninit
函数原型 void hal_can_uninit(can_handle *phandle);
功能说明 CAN 模块去初始化
参数定义
phandle: 指向 can_handle 结构体的指针
返回值
注意事项 -
6. hal_can_tx_frame
函数原型 void hal_can_tx_frame(can_handle *phandle, can_msg_t * msg, can_op_req_t req);
功能说明 CAN 模块去初始化
参数定义
phandle: 指向 can_handle 结构体的指针
msg: 指向要发送的 CAN message 的指针
req: 发送请求,用于指示是正常发送/自发自收/终止发送
返回值
注意事项 -
7. hal_can_ioctl
函数原型 int hal_can_ioctl(can_handle *phandle, int cmd, void *arg);
功能说明 CAN 模块去初始化
参数定义
phandle: 指向 can_handle 结构体的指针
cmd: CAN 命令
arg: 命令参数
返回值
注意事项 -