瑞芯微Rockchip开发者社区
登录
直播中
杨勇
7年用户
1173经验值
私信
关注
[问答]
MCP2515是什么?MCP2515协议控制器有哪些功能呢
开启该帖子的消息推送
MCP2515
控制器
SPI
MCP2515是什么?MCP2515协议控制器有哪些功能呢?
回帖
(1)
谢芳芳
2022-3-7 16:29:49
【RK3399】【Linux】Rockchip3399 Can驱动分析 mcp2515
MCP2515介绍
Microchip 的MCP2515 是一款独立控制器局域网络(Controller Area Network, CAN)协议控制器,完全支持CAN V2.0B 技术规范。该器件能发送和接收标准和扩展
数据帧
以及远程帧。MCP2515 自带的两个验收屏蔽
寄存器
和六个验收滤波寄存器可以过滤掉不想要的报文,因此减少了主
单片机
(MCU)的开销。MCP2515与MCU 的连接是通过业界标准
串行外设接口
(Serial Peripheral Interface, SPI)来实现的。
SPI协议模块:
TXCAN:连接到CAN总线的发送输出引脚
RXCAN:连接到CAN总线的接收输入引脚
CLKOUT:带可编程预分频器的时钟输出引脚
mcp251x.c驱动分析
在驱动的probe函数中mcp251x_can_probe进行spi资源的获取,设备的注册
1035 const struct of_device_id *of_id = of_match_device(mcp251x_of_match,
1036 &spi->dev);
1037 struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
1038 struct net_device *net;
1039 struct mcp251x_priv *priv;
1040 struct clk *clk;
1041 int freq, ret;
1042
1043 clk = devm_clk_get(&spi->dev, NULL);
1044 if (IS_ERR(clk)) {
1045 if (pdata)
1046 freq = pdata->oscillator_frequency;
1047 else
1048 return PTR_ERR(clk);
1049 } else {
1050 freq = clk_get_rate(clk);
1051 }
1052
1053 /* Sanity check */
1054 if (freq < 1000000 || freq > 25000000)
1055 return -ERANGE;
1035:从设备树中获取spi设备资源
1043~1051:获取设备树中设定的时钟
1057 /* Allocate can/net device */
1058 net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
1059 if (!net)
1060 return -ENOMEM;
1061
1062 if (!IS_ERR(clk)) {
1063 ret = clk_prepare_enable(clk);
1064 if (ret)
1065 goto out_free;
1066 }
分配can/net设备
struct mcp251x_priv结构如下:
244 struct mcp251x_priv {
245 struct can_priv can;
246 struct net_device *net;
247 struct spi_device *spi;
248 enum mcp251x_model model;
249
250 struct mutex mcp_lock; /* SPI device lock */
251
252 u8 *spi_tx_buf;
253 u8 *spi_rx_buf;
254 dma_addr_t spi_tx_dma;
255 dma_addr_t spi_rx_dma;
256
257 struct sk_buff *tx_skb;
258 int tx_len;
259
260 struct workqueue_struct *wq;
261 struct work_struct tx_work;
262 struct work_struct restart_work;
263
264 int force_quit;
265 int after_suspend;
266 #define AFTER_SUSPEND_UP 1
267 #define AFTER_SUSPEND_DOWN 2
268 #define AFTER_SUSPEND_POWER 4
269 #define AFTER_SUSPEND_RESTART 8
270 int restart_tx;
271 struct regulator *power;
272 struct regulator *transceiver;
273 struct clk *clk;
274 };
对上述结构体进行赋值,并写入到spi驱动中
1068 net->netdev_ops = &mcp251x_netdev_ops;
1069 net->flags |= IFF_ECHO;
1070
1071 priv = netdev_priv(net);
1072 priv->can.bittiming_const = &mcp251x_bittiming_const;
1073 priv->can.do_set_mode = mcp251x_do_set_mode;
1074 priv->can.clock.freq = freq / 2;
1075 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
1076 CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
1077 if (of_id)
1078 priv->model = (enum mcp251x_model)of_id->data;
1079 else
1080 priv->model = spi_get_device_id(spi)->driver_data;
1081 priv->net = net;
1082 priv->clk = clk;
1083
1084 spi_set_drvdata(spi, priv);
1068 net->netdev_ops = &mcp251x_netdev_ops;对Can操作函数进行赋值
mcp251x_netdev_ops:
992 static const struct net_device_ops mcp251x_netdev_ops = {
993 .ndo_open = mcp251x_open,
994 .ndo_stop = mcp251x_stop,
995 .ndo_start_xmit = mcp251x_hard_start_xmit,
996 .ndo_change_mtu = can_change_mtu,
997 };
1071 priv = netdev_priv(net);访问net_device网络设备的私有数据
1072 priv->can.bittiming_const = &mcp251x_bittiming_const;设置can设备的时序参数
220 #define DEVICE_NAME "mcp251x"
226 static const struct can_bittiming_const mcp251x_bittiming_const = {
227 .name = DEVICE_NAME,
228 .tseg1_min = 3,
229 .tseg1_max = 16,
230 .tseg2_min = 2,
231 .tseg2_max = 8,
232 .sjw_max = 4,
233 .brp_min = 1,
234 .brp_max = 64,
235 .brp_inc = 1,
236 };
can_bittiming_const定义如下
46 struct can_bittiming_const {
47 char name[16]; /* Name of the CAN controller hardware */
48 __u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */
49 __u32 tseg1_max;
50 __u32 tseg2_min; /* Time segement 2 = phase_seg2 */
51 __u32 tseg2_max;
52 __u32 sjw_max; /* Synchronisation jump width */
53 __u32 brp_min; /* Bit-rate prescaler */
54 __u32 brp_max;
55 __u32 brp_inc;
56 };
CAN位时间
CAN 总线上的所有器件都必须使用相同的比特率。然而,并非所有器件都要求具有相同的主振荡器时钟频率。对于采用不同时钟频率的器件,应通过适当设置波特率预分频比以及每一时间段中的时间份额的数量来对比特率进行调整。CAN 位时间由互不重叠的时间段组成。 每个时间段又由时间份额 (TQ)组成,在 CAN 规范中,标称比特率 (NominalBit Rate, NBR)定义为在不需要再同步的情况下,理想发送器每秒发送的位数,它可用下面的公式来表示:
标称位时间
标称位时间 (Nominal Bit Time, NBT)(tbit)由互不重叠的段时间段组成(图 5-1) 。因此 NBT 为下列时间段之和:
与 NBT 相关的参数是采样点、同步跳转宽度(Synchronization Jump Width, SJW)和信息处理时间(Information Processing Time, IPT)
同步段
同步段 (SyncSeg)为 NBT 中的首段,用于同步 CAN总线上的各个节点。输入信号的跳变沿就发生在同步段,该段持续时间为 1 TQ。
传播段(PropSeg)用于补偿各节点之间的物理传输延迟时间。传输延迟时
间为信号在总线上传播时间的两倍,包括总线驱动器延迟时间。传播段的长度可编程设定为 1 – 8 TQ。
相位缓冲段 1 (PS1)和相位缓冲段 2 (PS2)两个相位缓冲段 PS1 和 PS2 用于补偿总线上的边沿相位误差。通过再同步,可以延长 PS1 (或缩短 PS2) 。PS1 可编程设定为 1–8 TQ, 而 PS2 可编程设定为 2–8 TQ。
采样点
采样点是位时间内的一个时间点。在该时间点,读取总线电平并进行分析。采样点位于相位缓冲段 PS1 的终点。但当采样模式设置为每位采样 3 次时例外。这种情况下,在 PS1 的终点仍然对某一位进行采样时,前两次的采样时间间隔为TQ/2,而该位的值将根据三个采样值中至少两次采样的相同值决定。
信息处理时间
信息处理时间 (IPT)是确定采样点的位电平值所需要的时间。 IPT 从采样点开始,以 TQ 计量, MicrochipCAN 模块将该时间长度定义为 2 TQ。 PS2 同样开始于采样点,且为位时间的最后一个时间段,因此 PS2 的最小值不能小于 IPT
同步跳转宽度
同步跳转宽度(SJW)可通过编程设定为 1 – 4 TQ,它可对位时钟进行必要的调整来保持与发送报文同步。
时间份额
组成位时间的每个段都由时间份额 (TQ)组成。每个时间份额的长度取决于振荡器周期 (tOSC)。通常 TQ为两个振荡器周期。图 5-2 显示了如何从 TOSC 和 TQ推导出位周期。 TQ 的长度等于一个 TQ 时钟周期(tBRPCLK),利用称为波特率预分频器(BRP)的可编程预分频器对它进行编程设置。以下公式对此进行了阐
述:
【RK3399】【Linux】Rockchip3399 Can驱动分析 mcp2515
MCP2515介绍
Microchip 的MCP2515 是一款独立控制器局域网络(Controller Area Network, CAN)协议控制器,完全支持CAN V2.0B 技术规范。该器件能发送和接收标准和扩展
数据帧
以及远程帧。MCP2515 自带的两个验收屏蔽
寄存器
和六个验收滤波寄存器可以过滤掉不想要的报文,因此减少了主
单片机
(MCU)的开销。MCP2515与MCU 的连接是通过业界标准
串行外设接口
(Serial Peripheral Interface, SPI)来实现的。
SPI协议模块:
TXCAN:连接到CAN总线的发送输出引脚
RXCAN:连接到CAN总线的接收输入引脚
CLKOUT:带可编程预分频器的时钟输出引脚
mcp251x.c驱动分析
在驱动的probe函数中mcp251x_can_probe进行spi资源的获取,设备的注册
1035 const struct of_device_id *of_id = of_match_device(mcp251x_of_match,
1036 &spi->dev);
1037 struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
1038 struct net_device *net;
1039 struct mcp251x_priv *priv;
1040 struct clk *clk;
1041 int freq, ret;
1042
1043 clk = devm_clk_get(&spi->dev, NULL);
1044 if (IS_ERR(clk)) {
1045 if (pdata)
1046 freq = pdata->oscillator_frequency;
1047 else
1048 return PTR_ERR(clk);
1049 } else {
1050 freq = clk_get_rate(clk);
1051 }
1052
1053 /* Sanity check */
1054 if (freq < 1000000 || freq > 25000000)
1055 return -ERANGE;
1035:从设备树中获取spi设备资源
1043~1051:获取设备树中设定的时钟
1057 /* Allocate can/net device */
1058 net = alloc_candev(sizeof(struct mcp251x_priv), TX_ECHO_SKB_MAX);
1059 if (!net)
1060 return -ENOMEM;
1061
1062 if (!IS_ERR(clk)) {
1063 ret = clk_prepare_enable(clk);
1064 if (ret)
1065 goto out_free;
1066 }
分配can/net设备
struct mcp251x_priv结构如下:
244 struct mcp251x_priv {
245 struct can_priv can;
246 struct net_device *net;
247 struct spi_device *spi;
248 enum mcp251x_model model;
249
250 struct mutex mcp_lock; /* SPI device lock */
251
252 u8 *spi_tx_buf;
253 u8 *spi_rx_buf;
254 dma_addr_t spi_tx_dma;
255 dma_addr_t spi_rx_dma;
256
257 struct sk_buff *tx_skb;
258 int tx_len;
259
260 struct workqueue_struct *wq;
261 struct work_struct tx_work;
262 struct work_struct restart_work;
263
264 int force_quit;
265 int after_suspend;
266 #define AFTER_SUSPEND_UP 1
267 #define AFTER_SUSPEND_DOWN 2
268 #define AFTER_SUSPEND_POWER 4
269 #define AFTER_SUSPEND_RESTART 8
270 int restart_tx;
271 struct regulator *power;
272 struct regulator *transceiver;
273 struct clk *clk;
274 };
对上述结构体进行赋值,并写入到spi驱动中
1068 net->netdev_ops = &mcp251x_netdev_ops;
1069 net->flags |= IFF_ECHO;
1070
1071 priv = netdev_priv(net);
1072 priv->can.bittiming_const = &mcp251x_bittiming_const;
1073 priv->can.do_set_mode = mcp251x_do_set_mode;
1074 priv->can.clock.freq = freq / 2;
1075 priv->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES |
1076 CAN_CTRLMODE_LOOPBACK | CAN_CTRLMODE_LISTENONLY;
1077 if (of_id)
1078 priv->model = (enum mcp251x_model)of_id->data;
1079 else
1080 priv->model = spi_get_device_id(spi)->driver_data;
1081 priv->net = net;
1082 priv->clk = clk;
1083
1084 spi_set_drvdata(spi, priv);
1068 net->netdev_ops = &mcp251x_netdev_ops;对Can操作函数进行赋值
mcp251x_netdev_ops:
992 static const struct net_device_ops mcp251x_netdev_ops = {
993 .ndo_open = mcp251x_open,
994 .ndo_stop = mcp251x_stop,
995 .ndo_start_xmit = mcp251x_hard_start_xmit,
996 .ndo_change_mtu = can_change_mtu,
997 };
1071 priv = netdev_priv(net);访问net_device网络设备的私有数据
1072 priv->can.bittiming_const = &mcp251x_bittiming_const;设置can设备的时序参数
220 #define DEVICE_NAME "mcp251x"
226 static const struct can_bittiming_const mcp251x_bittiming_const = {
227 .name = DEVICE_NAME,
228 .tseg1_min = 3,
229 .tseg1_max = 16,
230 .tseg2_min = 2,
231 .tseg2_max = 8,
232 .sjw_max = 4,
233 .brp_min = 1,
234 .brp_max = 64,
235 .brp_inc = 1,
236 };
can_bittiming_const定义如下
46 struct can_bittiming_const {
47 char name[16]; /* Name of the CAN controller hardware */
48 __u32 tseg1_min; /* Time segement 1 = prop_seg + phase_seg1 */
49 __u32 tseg1_max;
50 __u32 tseg2_min; /* Time segement 2 = phase_seg2 */
51 __u32 tseg2_max;
52 __u32 sjw_max; /* Synchronisation jump width */
53 __u32 brp_min; /* Bit-rate prescaler */
54 __u32 brp_max;
55 __u32 brp_inc;
56 };
CAN位时间
CAN 总线上的所有器件都必须使用相同的比特率。然而,并非所有器件都要求具有相同的主振荡器时钟频率。对于采用不同时钟频率的器件,应通过适当设置波特率预分频比以及每一时间段中的时间份额的数量来对比特率进行调整。CAN 位时间由互不重叠的时间段组成。 每个时间段又由时间份额 (TQ)组成,在 CAN 规范中,标称比特率 (NominalBit Rate, NBR)定义为在不需要再同步的情况下,理想发送器每秒发送的位数,它可用下面的公式来表示:
标称位时间
标称位时间 (Nominal Bit Time, NBT)(tbit)由互不重叠的段时间段组成(图 5-1) 。因此 NBT 为下列时间段之和:
与 NBT 相关的参数是采样点、同步跳转宽度(Synchronization Jump Width, SJW)和信息处理时间(Information Processing Time, IPT)
同步段
同步段 (SyncSeg)为 NBT 中的首段,用于同步 CAN总线上的各个节点。输入信号的跳变沿就发生在同步段,该段持续时间为 1 TQ。
传播段(PropSeg)用于补偿各节点之间的物理传输延迟时间。传输延迟时
间为信号在总线上传播时间的两倍,包括总线驱动器延迟时间。传播段的长度可编程设定为 1 – 8 TQ。
相位缓冲段 1 (PS1)和相位缓冲段 2 (PS2)两个相位缓冲段 PS1 和 PS2 用于补偿总线上的边沿相位误差。通过再同步,可以延长 PS1 (或缩短 PS2) 。PS1 可编程设定为 1–8 TQ, 而 PS2 可编程设定为 2–8 TQ。
采样点
采样点是位时间内的一个时间点。在该时间点,读取总线电平并进行分析。采样点位于相位缓冲段 PS1 的终点。但当采样模式设置为每位采样 3 次时例外。这种情况下,在 PS1 的终点仍然对某一位进行采样时,前两次的采样时间间隔为TQ/2,而该位的值将根据三个采样值中至少两次采样的相同值决定。
信息处理时间
信息处理时间 (IPT)是确定采样点的位电平值所需要的时间。 IPT 从采样点开始,以 TQ 计量, MicrochipCAN 模块将该时间长度定义为 2 TQ。 PS2 同样开始于采样点,且为位时间的最后一个时间段,因此 PS2 的最小值不能小于 IPT
同步跳转宽度
同步跳转宽度(SJW)可通过编程设定为 1 – 4 TQ,它可对位时钟进行必要的调整来保持与发送报文同步。
时间份额
组成位时间的每个段都由时间份额 (TQ)组成。每个时间份额的长度取决于振荡器周期 (tOSC)。通常 TQ为两个振荡器周期。图 5-2 显示了如何从 TOSC 和 TQ推导出位周期。 TQ 的长度等于一个 TQ 时钟周期(tBRPCLK),利用称为波特率预分频器(BRP)的可编程预分频器对它进行编程设置。以下公式对此进行了阐
述:
举报
更多回帖
rotate(-90deg);
回复
相关问答
MCP2515
控制器
SPI
MCP2515
协议
控制器
与MCU的连接是如何实现的
2022-02-11
1576
MCP2515
错误帧
2018-11-27
4044
MCP2515
资料表存疑
2019-09-30
3621
pic16的j1939/
mcp2515
库文件
有
吗?
2018-10-30
1486
如何解决扩展CAN芯片
MCP2515
的驱动移植问题?
2022-01-04
1704
MCP2515
收发数据过程中,不触发中断
2022-12-23
1402
基于stm32f103c8t6的
有
mcp2515
的can例程
2014-05-27
13402
MCP2515
通信问题
2019-05-17
4019
与PIC16F877A的CAN接口如何连接
MCP2515
?
2019-10-28
1013
请问RK3399
有
飞凌
mcp2515
模块的驱动么?
2021-12-30
1095
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
首页
论坛版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分