EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
凭借实时性、抗干扰性和安全性等优点,CAN2.0在工业及汽车行业得到了广泛应用,但其最高速率仅为1Mbit/s,每帧最多只能传输8字节的有效数据,报文中只有约50%的带宽用于有效数据传输。然而随着产业的发展,各种传感器和控制器数量的增多,总线上的数据量也激增,这使得CAN2.0总线在传输速率和带宽方面的缺点暴露的更加明显,于是就诞生了CAN-FD。
3 v5 t1 y) I2 w. @- {! r2 r; v3 @ aCAN-FD在传输速率和带宽方面有了明显的提升,波特率可高达8Mbit/s,每帧可多达64字节有效数据,传输效率可提高至约80%,能够进一步提高总线的实时性,拓宽总线的数据带宽,提升总线的传输效率。
+ [: x; t' M7 c1 `6 H# o4 e在飞凌嵌入式OKMX8MP-C开发板上有两路CAN-FD,小编今天就基于这款开发板以处理器的M核与A核各控制一路CAN-FD互相通信为例,从应用角度讲述M核和A核如何控制CAN-FD高速通信。 ![]()
4 b5 j5 J3 S6 o8 h$ b$ N9 v) }+ _+ Q1 a) m+ \& r; o0 G( c
0 V* n% L" t: M) m& {飞凌嵌入式OKMX8MP-C开发板所搭载的NXP i.MX8M Plus处理器具备强悍的性能,集成4个主频最高可达1.8GHz (工业级主频为1.6GHz)的ARM Cortex-A53多任务核和1个Cortex-M7实时核,不管是对数据的高速吞吐、处理,还是复杂的人机交互界面处理,都能从容应对。
( W7 k7 ^8 G# Z" w4 H0 x01 M核CAN-FD 1. CAN-FD初始化 CAN-FD初始化主要包括总线时钟,管脚和相应寄存器的初始化。具体如下: 0 G) z7 J5 q( R, z$ q9 |1 g; ], l
(1)CAN总线时钟: 现将CAN总线倍频到800MHz,再10分频到80MHz。 CLOCK_SetRootMux(kCLOCK_RootFlexCan1, kCLOCK_FlexCanRootmuxSysPll1); // 设置CAN1总线时钟为800MHz CLOCK_SetRootDivider(kCLOCK_RootFlexCan1, 2U, 5U); // 分频因子为2*5=10,设置CAN1总线时钟为80MHz
2 W. W4 s7 t; Z* I- i. i(2)管脚配置: 选择CAN1的发送管脚为32脚,接收管脚为34脚。 IOMUXC_SetPinMux(IOMUXC_SAI2_TXC_CAN1_RX, 0U); // CAN1 RX IOMUXC_SetPinMux(IOMUXC_SAI2_RXC_CAN1_TX, 0U); // CAN1 TX
7 e3 ?3 O: @$ Q: O(3)CAN波特率: CAN-FD支持可变速率,即控制区和数据区的波特率可以不一致,控制区最大为1Mbit/s;数据区最大为8Mbit/s。后续程序根据总线时钟和设置的波特率,分配时段设置的seg1,seg2等数值。 pConfig->bitRate = 1000000U; // CAN-FD控制区波特率为1Mbit/s pConfig->bitRateFD = 8000000U; // CAN-FD数据区波特率为8Mbit/s# S. r1 p1 f5 R1 R% L+ _+ J
(4)CAN-FD使能: 除了使能CAN-FD,可变波特率也需要使能,否则数据区的最大速率和控制区的速率一样,最大为1Mbit/s。 base->MCR |= CAN_MCR_FDEN_MASK; // CAN-FD使能 fdctrl |= CAN_FDCTRL_FDRATE_MASK; // 可变波特率使能
" d' G: \6 s* u) A; S+ U" p(5)关闭自回环: 如果开启了自回环,那么CAN1数据会在芯片内回环,不会到外部管脚,在程序调试时可以排除外部端子的干扰,但真实应用时,需要关闭自回环,从外部管脚收发数据。 pConfig->enableLoopBack = false; // 不回环,使用外部管脚
" w4 [8 O8 L4 U0 _4 b5 {7 y. R(6)帧格式: 本次我们使用11位标准数据帧,小伙伴也在后续试试扩展帧。需要设置自己的ID,便于总线上其他设备识别。 mbConfig.format = kFLEXCAN_FrameFormatStandard; // 11位标准帧,非扩展帧 mbConfig.type = kFLEXCAN_FrameTypeData; // 数据帧 非远程帧 mbConfig.id = FLEXCAN_ID_STD(rxIdentifier); // 帧ID 用于区别总线中不同的设备
6 f' _7 F `- G% u(7)接收过滤: 用户可设置接收过滤规则,这样就可以只接收特定帧ID的数据,减少应用处理的数据量。 rxIdentifier = 0;FLEXCAN_SetRxMbGlobalMask(EXAMPLE_CAN, FLEXCAN_RX_MB_STD_MASK(rxIdentifier, 0, 0));//接收所有ID数据3 G! t2 M# V* n( w' _' Q
2. CAN-FD收发流程 本次测试M核做主站,CAN1先发送一帧包含64字节数据,A核CAN2收到,将64字节数据再次发送,M核CAN1接收。对比发送和接收的64字节数据是否一致。重复100次。 : A1 K" @6 [ c4 l; m- k m1 K
(1)CAN-FD发送数据: EXAMPLE_CAN表示为CAN1,flexcanHandle为CAN实例,包含了发送接收回调函数,txXfer为要发送的64字节数据。 FLEXCAN_TransfeRFDSendNonBlocking(EXAMPLE_CAN, &flexcanHandle, &txXfer); // CAN-FD发送数据
4 J& v d( k4 B! ^. U2 E5 G% R(2)CAN-FD接收数据: EXAMPLE_CAN表示为CAN1,flexcanHandle为CAN实例,包含了发送接收回调函数,rxXfer为接收的64字节数据。 FLEXCAN_TransferFDReceiveNonBlocking(EXAMPLE_CAN, &flexcanHandle, &rxXfer); // CAN-FD接收函数
6 J2 ?1 b' [4 J% s/ [( s( A(3)接收和发送数据对比: for (j = 0U; j <= DLC; j++) // 对比收发数据,不一致打印 { if(txXfer.framefd->dataWord[j] != rxXfer.framefd->dataWord[j]) { LOG_INFO("Data mismatch !!! j=%d \r\n",j); } }, b% s( e4 |+ y$ r" w! }$ `
02 A核CAN-FD A核设备树中保留CAN2,内核解析设备树在 /dev下生成can0。设置波特率后使能can0节点,应用程序中open函数打开接口,write函数发送数据,read函数接收数据。我们把CAN接口的示例已经作为一个跨平台的综合演示程序,小伙伴们可以直接加参数调用即可。 8 _+ l9 n5 _& c7 f5 [
1. 分配节点 (1)M核独享CAN1,A核独享CAN2,修改设备树,在设备树OK8MP-C.dts中,删除CAN1设备节点,保留CAN2设备节点。编译新的设备树;
$ |$ l$ f1 ~" X6 R) G9 i6 I- n(2)将生成的OK8MP-C.dtb和Image拷贝至开发板的 /run/media/mmcblk2p1/ 目录下,输入sync命令同步后重启开发板;
, Y+ w$ R/ f" m. ^2 J [$ F(3)通过A核串口输入命令uname -r ,显示内核版本,将 /lib/modbule目录下文件夹名称改为内核版本,这样才能自动加载模块生成can0节点,重启开发板。 ![]()
7 _ G% a6 h8 B% q% Z& |( H5 l; j+ q* ]% s' t
2 F6 B# J3 r* m% ] 6 l4 N2 D3 t- s+ o0 x4 u
' Q5 \- c% e4 m3 \, X
$ h9 L5 i8 s/ Z- ]2. 演示Demo 进程名:can_demo
4 R4 J2 @: g9 t3 G: }; {% j使用方法:./can_demo设备名 [参数选项]… … . `1 y: |/ I9 `, V( Z7 |+ b1 [
2 x5 w' r2 K4 [, j5 o2 B! |. q( A' ~- y" k* z y6 C
本次测试接口为can0(对应开发板CAN2),控制区波特率为1Mbit/s,数据区最大为8Mbit/s,11位标准帧,不过滤帧ID,不主动发数据,不回环。因此命令为:
. _6 E! g4 b2 g2 Q; n' V
7 f9 G& ?: z) m) ]6 N# e ./can_demo can0-b 1000 -fd 8000。* k: t1 C" f7 Q; ^7 S- j/ `+ q
03 程序验证 1. 硬件连接 使用杜邦线将CAN1和CAN2的can-H短接,同时将can-L短接,注意不要接反。 ![]()
! d! B% [6 B( I5 z+ _ }4 F% ~# i, p! ]: G5 ?
9 u6 q+ I/ U& V. U% [" I% P2. M核程序 修改uboot环境变量设置M核自启动,同时将M核程序forlinx_m7_tcm_firmware.bin; 放到/run/media/mmcblk2p1/目录下。详细操作可看上篇文章《【玩转多核异构】M核程序的启动、编写和仿真》。
2 d( j8 v3 b2 @# e3. A核程序 (1)使用串口Xmodem,网络FTP,SCP,U盘,TF卡等多种方式,将can_demo从电脑拷贝至核心板默认目录下,输入以下命令修改权限; - 3 Q4 x8 f! a" b% T9 V
1 Y6 p: |0 M4 w3 I4 l9 S' |# d0 Q chmod 777 can_demo( s& R% a8 p2 B' T% T3 v4 q/ y
(2)输入以下命令,A核应用程序can_demo将设置波特率后打开can0节点,等待M核发送的数据,再将接收的数据通过CAN2发送给M核。 - 4 G, X2 {( H: X2 @) J- C6 E" H
( K# {4 S& G1 {$ `4 {( S# J0 E ./can_demo can0 -b 1000 -fd 8000
$ Z( @* g. R) w# d4. 实际测试 (1)OKMX8MP-C开发板重新上电后,M核程序启动,完成CAN1初始化后,在M核调试串口输出信息,等待按键;
* E& M- L; @* i k7 A o(2)在A核调试串口输入以下命令,CAN2将处于接收的状态: - - t" `+ _1 d; H- H j
1 g: E* E+ Z" B4 v
./can_demo can0 -b 1000 -fd 80000 F& M- I( X8 U
(3)在M核串口按下键A或a,M核CAN1发送64字节数据,A核CAN2接收数据,并将接收的数据再次发送,M核CAN1接收后和发送数据对比,输出结果。循环100次;
2 b$ _8 N, z, f4 C(4)通过测试可以看到,依托i.MX8M Plus强大的性能,双核都以8Mbit/s的高速率发送大量数据,均没有出现异常。 ![]()
5 i5 _/ D; W5 e* x- `1 l4 {) b: l
7 X$ X0 t5 D; D8 @; [6 l
$ W M+ [: }! `+ w2 S/ C1 C9 n. w0 r* E) ]
|