1说明: 2本驱动完成了can控制器硬件抽象 3一 CAN Driver 注册 4 Can driver注册需要填充以下几个数据结构: 5 1、struct can_configure 6 { 7 rt_uint32_t baud_rate; 8 rt_uint32_t msgboxsz; 9 rt_uint32_t sndboxnumber; 10 rt_uint32_t mode :8; 11 rt_uint32_t privmode :8; 12 rt_uint32_t reserved :16; 13 #ifdef RT_CAN_USING_LED 14 const struct rt_can_led* rcvled; 15 const struct rt_can_led* sndled; 16 const struct rt_can_led* errled; 17 #endif /*RT_CAN_USING_LED*/ 18 rt_uint32_t ticks; 19 #ifdef RT_CAN_USING_HDR 20 rt_uint32_t maxhdr; 21 #endif 22 }; 23 struct can_configure 为can驱动的基本配置信息: 24 baud_rate : 25 enum CANBAUD 26 { 27 CAN1MBaud=0, // 1 MBit/sec 28 CAN800kBaud, // 800 kBit/sec 29 CAN500kBaud, // 500 kBit/sec 30 CAN250kBaud, // 250 kBit/sec 31 CAN125kBaud, // 125 kBit/sec 32 CAN100kBaud, // 100 kBit/sec 33 CAN50kBaud, // 50 kBit/sec 34 CAN20kBaud, // 20 kBit/sec 35 CAN10kBaud // 10 kBit/sec 36 }; 37 配置Can的波特率。 38 msgboxsz : Can接收邮箱缓冲数量,本驱动在软件层开辟msgboxsz个接收邮箱。 39 sndboxnumber : can 发送通道数量,该配置为Can控制器实际的发送通道数量。 40 mode : 41 #define RT_CAN_MODE_NORMAL 0 正常模式 42 #define RT_CAN_MODE_LISEN 1 只听模式 43 #define RT_CAN_MODE_LOOPBACK 2 自发自收模式 44 #define RT_CAN_MODE_LOOPBACKANLISEN 3 自发自收只听模式 45 配置Can 的工作状态。 46 privmode : 47 #define RT_CAN_MODE_PRIV 0x01 处于优先级模式,高优先级的消息优先发送。 48 #define RT_CAN_MODE_NOPRIV 0x00 49 配置Can driver的优先级模式。 50 #ifdef RT_CAN_USING_LED 51 const struct rt_can_led* rcvled; 52 const struct rt_can_led* sndled; 53 const struct rt_can_led* errled; 54 #endif /*RT_CAN_USING_LED*/ 55 配置can led信息, 当前can驱动的led使用了 pin驱动, 56 开启RT_CAN_USING_LED时要确保当前系统已实现pin驱动。 57 rt_uint32_t ticks : 配置Can driver timer周期。 58 #ifdef RT_CAN_USING_HDR 59 rt_uint32_t maxhdr; 60 #endif 61 如果使用硬件过滤,则开启RT_CAN_USING_HDR, maxhdr 为Can控制器过滤表的数量。 62 2、struct rt_can_ops 63 { 64 rt_err_t (*configure)(struct rt_can_device *can, struct can_configure *cfg); 65 rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg); 66 int (*sendmsg)(struct rt_can_device *can, const void* buf, rt_uint32_t boxno); 67 int (*recvmsg)(struct rt_can_device *can,void* buf, rt_uint32_t boxno); 68 }; 69 struct rt_can_ops 为要实现的特定的can控制器操作。 70 rt_err_t (*configure)(struct rt_can_device *can, struct can_configure *cfg); 71 configure根据配置信息初始化Can控制器工作模式。 72 rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg); 73 control 当前接受以下cmd参数: 74 #define RT_CAN_CMD_SET_FILTER 0x13 75 #define RT_CAN_CMD_SET_BAUD 0x14 76 #define RT_CAN_CMD_SET_MODE 0x15 77 #define RT_CAN_CMD_SET_PRIV 0x16 78 #define RT_CAN_CMD_GET_STATUS 0x17 79 #define RT_CAN_CMD_SET_STATUS_IND 0x18 80 int (*sendmsg)(struct rt_can_device *can, const void* buf, rt_uint32_t boxno); 81 sendmsg向Can控制器发送数,boxno为发送通道号。 82 int (*recvmsg)(struct rt_can_device *can,void* buf, rt_uint32_t boxno); 83 recvmsg从Can控制器接收数据,boxno为接收通道号。 84 struct rt_can_device 85 { 86 struct rt_device parent; 87 88 const struct rt_can_ops *ops; 89 struct can_configure config; 90 struct rt_can_status status; 91 rt_uint32_t timerinitflag; 92 struct rt_timer timer; 93 struct rt_can_status_ind_type status_indicate; 94 #ifdef RT_CAN_USING_HDR 95 struct rt_can_hdr* hdr; 96 #endif 97 void *can_rx; 98 void *can_tx; 99 }; 100 填充完成后,便可调用rt_hw_can_register完成can驱动的注册。 101二、 CAN Driver 的添加: 102 要添加一个新的Can驱动,至少要完成以下接口。 103 1、struct rt_can_ops 104 { 105 rt_err_t (*configure)(struct rt_can_device *can, struct can_configure *cfg); 106 rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg); 107 int (*sendmsg)(struct rt_can_device *can, const void* buf, rt_uint32_t boxno); 108 int (*recvmsg)(struct rt_can_device *can,void* buf, rt_uint32_t boxno); 109 }; 110 2、 rt_err_t (*control)(struct rt_can_device *can, int cmd, void *arg); 111 接口的 112 #define RT_CAN_CMD_SET_FILTER 0x13 113 #define RT_CAN_CMD_SET_BAUD 0x14 114 #define RT_CAN_CMD_SET_MODE 0x15 115 #define RT_CAN_CMD_SET_PRIV 0x16 116 #define RT_CAN_CMD_GET_STATUS 0x17 117 #define RT_CAN_CMD_SET_STATUS_IND 0x18 118 若干命令。 119 3、can口中断,要完接收,发送结束,以及错误中断。 120 #define RT_CAN_EVENT_RX_IND 0x01 /* Rx indication */ 121 #define RT_CAN_EVENT_TX_DONE 0x02 /* Tx complete */ 122 #define RT_CAN_EVENT_TX_FAIL 0x03 /* Tx complete */ 123 #define RT_CAN_EVENT_RX_TIMEOUT 0x05 /* Rx timeout */ 124 #define RT_CAN_EVENT_RXOF_IND 0x06 /* Rx overflow */ 125 中断产生后,调用rt_hw_can_isr(struct rt_can_device *can, int event) 126 进入相应的操作,其中接收发送中断的event,最低8位为上面的事件,16到24位为通信通道号。 127 一个作为一个例子,参见bsp/stm32f10x/driver下的bxcan.c 。 128三、CAN Driver的使用: 129 一个使用的例子,参数bsp/stm32f10x/applications下的canapp.c 130四、当前Can驱动,没有实现轮模式,采用中断模式,bxcan驱动工作在loopback模式下的时候不能读数据。 131 132五、当前Can驱动,在stm32f105上测试,暂无问题。 133