控制器局域网(CAN) 是车辆中最常见的通信协议。它仅使用两根线,所有 ECU 共用 :CAN 高线(CANH)和 CAN 低线(CANL)。CAN 仅支持广播,没有内置的安全机制:任何 ECU 都可以发送任意消息,且连接到同一 CAN 总线的所有 ECU 都会接收到相同的消息。CAN 帧本质上是一串由零和一组成的比特流,具有固定的标称波特率(现代车辆中通常为 500 kbps)。
一个 CAN 帧包含:
ECU 通常被分配仲裁标识符,用于定期广播数据,且周期各不相同。例如,在 RAMN 中,ID 0x24(每 10 毫秒发送一次)表示制动踏板状态,而 ID 0x1B8(每 100 毫秒发送一次)则表示发动机钥匙状态。
较低的 ID 具有较高优先级:如果两个 ECU 同时尝试发送数据,发送高 ID 的 ECU 将让出总线,并等待下一次机会。这确保了最重要的消息总是优先发送。如果某条消息的 ID 较低,可以推断其重要性较高。
除了周期性 CAN 消息外,ECU 还可能接收和发送非周期性消息,例如诊断消息。ECU 可实现由标准文档定义的诊断接口:
由于 CAN 帧只能容纳 8 字节或更小的少量有效载荷,因此使用 CAN 传输大型数据(如 ECU 固件文件)存在挑战。XCP 协议正是基于这一限制而设计的;然而,UDS 和 KWP2000 则依赖于一个名为 ISO-TP(ISO 15765-2) 的中间传输层 。ISO-TP 层将大型有效载荷(原始版本最大可达 4095 字节,最新版本则可达 4294967295 字节)分割成多个 CAN 帧,并添加了流量控制机制,以确保接收方能够正确重组这些数据。
近年来,为实现更高带宽,CAN 协议也出现了一些新的演进:
事实上,RAMN 的 ECU 使用了 CAN FD,但默认情况下仅采用经典 CAN 帧,以保持与不兼容 CAN FD 的常用工具的兼容性。
请参阅 (略微)高级 CAN 概念部分,了解您可能会遇到但并非严格必需继续本指南的其他 CAN 概念。
要连接到 CAN 总线,只需将 CAN 接收器的 CANH 和 CANL 线缆分别连接到 CAN 总线的 CANH 和 CANL 线缆即可。在实际车辆中,这通常会通过位于仪表盘下方的车载诊断(OBD-II)数据链路连接器来实现。 在真实车辆上进行实验确实存在风险:你可能并不希望冒着损坏一辆未来多年仍打算在公共道路上行驶的车辆的风险。 RAMN 旨在用一个嵌入小型化架构中的简单四 ECU 网络来替代真实车辆,以促进汽车系统的教育与研究。
RAMN 内置了一个 USB 转 CAN 适配器。 将 RAMN 连接到你的电脑,相当于将 USB 转 CAN 适配器连接到车辆的 OBD-II 端口,但无需承担任何风险。
CAN 仅支持广播传输:所有 ECU 始终看到相同的流量。无论你在 CAN 上接收到什么,其他每个 ECU 看到的都完全一致;ECU 通常会使用 CAN 过滤器,仅处理它们所需的报文。
借助 CAN,你可以:
计算机通常没有内置的 CAN 接口,因此需要一个专用接口才能连接到 CAN 总线。
市面上有许多 USB 转 CAN 适配器可供选择。如果您拥有此类适配器,可以将其连接到 RAMN 的接线端子,并按照随附的指南开始您的实验。
本指南的其余部分将假定您使用 RAMN 内置的 USB 转 CAN 适配器。RAMN 实现了“slcan”协议,也称为“LAWICEL”或“串行”协议,该协议受到许多 CAN 分析软件工具的支持。
当您将 RAMN 用作 USB 转 CAN 适配器时,需要将接口类型指定为“slcan”,并将 RAMN 的串口作为通道(通常为 COMx 或 /dev/ttyACMx)。
请确保您的计算机上已安装 Python(参见分析环境)。将您的开发板连接到计算机,打开 Windows 的设备管理器,并在“端口(COM 和 LPT)”中查找新出现的设备。RAMN 通常会被分配一个 COM 端口号,例如“COM1”。
在 Linux 系统上,您可以通过执行命令 dmesg 并查看最后几行来找到设备名称(通常为 /dev/ttyACM0)(如果您使用的是虚拟机,请确保已将 USB 设备转发到该虚拟机)。
打开命令窗口(在 Windows 上可打开 PowerShell 或按 Windows+R),并执行以下命令,以观察每个 CAN ID 的最新 CAN 帧:

这可能需要您使用命令 python -m pip install "python-can[viewer]" 安装 Python 模块。按 Q 键退出。从这里开始,您应该能够直接在 RAMN 中使用 python-can 脚本 。如果遇到问题,请参阅 USB 不稳定。
如果您不习惯使用命令行,可以尝试使用带有图形界面的替代工具 SavvyCAN。只需下载最新的 SavvyCAN 二进制文件并进行安装。(在 Linux 上,下载 .AppImage 文件,并通过输入 chmod +x file.AppImage 命令使其可执行,然后通过输入 ./file.AppImage 来运行)

务必选择正确的 CAN 总线速率(切勿与串口速率混淆)。之后您可以关闭窗口,并应能够观察到 CAN 消息。

有关如何使用该软件,请参阅 SavvyCAN 文档 。
在本指南的剩余部分,我们将重点介绍 Linux 和常被汽车爱好者使用的 can-utils 软件包 。Linux 将 CAN 作为标准接口支持,这意味着您可以像使用任何其他 Linux 接口一样使用它。
您可以通过输入 dmesg 并查找最近添加的设备来确定 RAMN 的 slcan(串口)被赋予了哪个名称,该设备应以“/dev/ttyACM”开头。如果您未看到任何设备,请确保您的 RAMN 已通过 USB 连接,并且 USB 设备已转发到您的虚拟机(如适用)。
某些工具,例如 wireshark,可能不直接支持 slcan,但可能支持 socketCAN 等接口。对于这些工具,您可以执行以下命令,将 slcan 接口(例如 /dev/ttyACM0)转换为 socketCAN 接口(例如 can0):
执行此命令后,您应该能够通过 ifconfig 命令看到一个新的“can0”接口。这将使您能够使用 can-utils 软件包中的工具,这些工具在下一节中有详细说明。在某些环境中,您可能会遇到上述命令的问题。如果出现这种情况,请尝试为 CAN 接口指定一个不同的名称,例如,在所有后续命令中使用“slcan0”代替“can0”。
在 Linux 系统中,同一时间只能有一个程序打开串行设备,但多个程序可以同时打开 CAN 接口。这意味着,如果你直接使用 slcan,每次只能执行一条 CAN 命令;而如果使用 socketCAN,则可以并行执行多条命令。通常情况下,如果某个工具同时支持 socketCAN 和 slcan,你应该优先选择 socketCAN。
当通过 slcan 使用串口时,系统可能会要求你输入两个波特率/比特率:一个是串口的波特率,另一个是 CAN 总线的波特率。串口的波特率并不重要,因为它只是虚拟的;然而,CAN 总线的波特率却至关重要,必须正确设置(默认为 500000 bps)。
在启动 slcand 之前,请确保没有其他程序正在使用 RAMN 的串口。一旦你运行 slcand,该串口将一直处于占用状态,其他程序(例如 TeraTerm)将无法访问它。你可以通过以下命令关闭 slcand 并释放串口:
您可以使用 -s 选项更改 slcan 适配器的 CAN 波特率,该选项接受一个整数,对应于以下波特率:
例如, sudo slcand -o -c -s8 /dev/ttyACM0 将以 1000000 bps 的 CAN 波特率打开 RAMN。 请注意,这仅适用于适配器(ECU A),而不适用于其他 ECU,因此默认情况下这里应仅显示 CAN 错误。 如果您想使用不同于默认 500000 bps 的波特率,您必须重新刷新所有 ECU,或者使用 UDS 链接控制服务(参见与 UDS 交互)。
slcand 命令存在两个缺点:
您可以使用 RAMN 的 vcand 脚本来创建虚拟的额外串行接口,并将串行接口转换为 CAN FD socketCAN 接口。
有关使用方法,请参阅 vcand。
请注意,截至 2024 年,这些脚本是用 Python 实现的,并未针对低 CPU 占用率进行优化。
cansniffer 可能是你在新网络上首先想要尝试的命令。它允许你观察每个 CAN 标识符的最新帧
你可以使用以下命令启动它:

要退出,请按“q”键后按回车键,或按“Control+C”。
如果您希望以二进制格式查看 CAN 消息,可以使用-B(或-b)选项:

一旦启动 cansniffer,您仍然可以输入命令,这些命令列于 cansniffer 的帮助页面中(直接在 cansniffer 窗口中输入命令并按 ENTER 键)。
在现代汽车网络中,你很可能会被大量信息淹没,因为即使车辆处于空闲状态,也应存在许多带有多个字节变化的 CAN 报文。这是因为 CAN 报文可能实现了复杂的算法,并包含诸如报文计数器、循环冗余校验(CRC)和消息认证码(MAC)等易变字段。
一个用于过滤易变字段的实用命令是“#”(井号)命令,它允许 cansniffer 停止高亮显示那些已经观察到的字节变化。这样,在后续操作中(例如移动 RAMN 控件时),新的变化会更加明显。
尝试连续多次输入“#”命令,期间不要触碰任何控制装置。你应该会发现,被彩色高亮显示的位数逐渐减少。接下来,移动 RAMN 板上的制动控制装置,并观察 cansniffer:由 ECU B 发送的制动消息的 2 字节有效载荷应会被高亮显示,便于你快速识别。此外,当你在 0%到 100%之间踩动制动踏板时,还应注意到另一条 CAN 消息中的某个位也在翻转;该位对应于 ECU D 的制动 LED 状态(如果未出现此现象,请确认手刹处于底部位置)。由于各 ECU 之间存在交互作用,你不能假定单一控制仅影响一条 CAN 消息,因此识别 CAN 消息的具体用途可能会比较棘手。
如果您想从 cansniffer 中过滤掉某些报文,可以使用“-”命令(例如,“-024”用于隐藏 0x024 报文)。您也可以使用“n”命令来过滤所有报文,然后通过“+”命令添加特定报文以进行观察(例如,“+024”仅显示 0x024 报文)。再次使用“a”命令即可显示所有报文。
尽管 cansniffer 是一个用于概览 CAN 总线流量的优秀工具,但它仅显示每个标识符的最新帧。若要按出现顺序观察所有 CAN 帧,可以改用 candump。
按 Control+C 退出。您可以使用 -tz 选项添加时间戳,使用 -a 选项添加 ASCII 输出。

并非所有消息都具有相同的周期,因此你会更频繁地观察到某些消息,而其他消息则较少。candump 的主要用例有两个:
要将 CAN 流量记录到文件中,可以使用-l 选项:
这会将 CAN 流量记录到一个自动生成名称的文件中。如果你希望指定文件名,可以改用-f <文件名>(此功能可能仅在较新版本中可用)。
在实际网络中,你可能会观察到大量的帧,导致 candump 的输出过多而难以处理。通常情况下,你会希望先使用 cansniffer 识别出感兴趣的标识符,然后再通过 candump 结合过滤器对这些标识符进行进一步分析。有关过滤器的更多信息,请参阅 CAN 过滤器 章节。
您可以在 candump 中通过在接口名称后添加 ,<value>:<mask> ,并以十六进制形式指定值来应用过滤器。例如:
您应该在 RAMN 上观察到,尽管 candump 的输出非常庞大,但上述命令的输出却并非如此。您可以为 candump 添加多个过滤器,例如,要观察 ID 为 0x1BB 和 ID 为 0x1D3 的消息,可以使用以下命令:
这有助于识别 CAN 报文之间的关系,例如:将制动踏板置于零位,同时将手刹置于底部位置。这样应确保制动指示灯处于关闭状态。当您拨动手刹开关时,您应该会看到制动指示灯亮起。在 cansniffer 中,您可以看到两个 CAN ID(0x1BB 和 0x1D3)的有效载荷随之发生变化。由于指示灯和开关分别位于不同的 ECU 上,您可以推断其中一条 CAN 报文可能指示了制动指示灯的状态,而另一条则指示了开关的状态,但您无法确定哪条对应哪个状态,因为在 cansniffer 中它们似乎同时发生变化。
如果你在拨动开关的同时使用上述命令,会发现 0x1D3 的值会在 0x1BB 之前发生变化,由此可以推断出 0x1D3 代表开关的值,而 0x1BB 则代表 LED 的状态(该状态会因接收到 0x1D3 消息而改变)。

Cansend 允许你通过指定 CAN ID 和有效载荷(以十六进制表示)来发送 CAN 消息。
例如,要发送一个 CAN ID 为 0x123 且有效载荷为单字节 0xFF 的消息,可以使用以下命令:
利用 cansend,你可以验证这样一个假设:0x1BB 代表 LED 状态,而 0x1D3 代表手刹开关状态。首先,在手刹处于 ON 位置(顶部位置)时记录来自 1BB 的消息,然后将手刹拨至 OFF 位置(底部位置)。请确保制动踏板处于 0%位置,且不会对刹车 LED 产生干扰。
你可以使用 cansend 重放一条 CAN 消息(在本示例中,负载为 07008A756501D87F):
通过发送这条消息,你是在告诉所有 ECU“刹车指示灯已亮”,但仅凭这一点并不会使指示灯真正点亮。然而,如果你在手刹处于开启状态时记录了一条 CAN ID 为 0x1D3 的消息,并在手刹关闭时再次发送该消息,你应该会观察到刹车指示灯会短暂地亮起:
这是因为该消息显示“手刹开关已开启”,这本身会导致 ECU D 点亮刹车 LED 指示灯。然而,这种点亮只是暂时的,因为 ECU B 仍在持续发送消息(告知各 ECU 手刹开关处于关闭状态),从而立即覆盖你所发送的任何数值。
你可以使用简单的 bash 脚本自动化某些传输任务,例如,如果你想连续发送一条消息 100 次:
或者,如果你想以相同的消息向 CAN 总线持续发送 2 秒钟:
如果你发送的 CAN 消息通常由另一个 ECU 正常传输,而该 ECU 仍在主动发送数据,你可能会产生 CAN 错误。如果错误次数过多,可能会导致 ECU 被迫与 CAN 总线断开连接(参见 错误帧与总线关闭 )。默认情况下,只有通过电源复位才能使 ECU 重新连接,但你可以配置 RAMN 的 ECU 使其自动重新连接。
您还可以使用 cansend 发送设置了 RTR 位标志的消息,其参数为 <can id>#R<dlc> 。RAMN 的 ECU B、C 和 D 将分别使用其硬件序列号响应 ID 为 0x701、0x702 和 0x703 的 CAN RTR 帧。
您可以在 candump 中显示这些消息,方法如下:
此外,在另一个终端中,你可以发送 RTR 帧:
这应该会产生以下结果:

您可以使用 canplayer“重放文件”(即发送日志文件中捕获的所有 CAN 消息),这些文件是由 candump 生成的。您需要指定两个接口作为参数:一个是用于读取文件中消息的接口,另一个是用于发送相同消息的接口。通常情况下,您会希望使用相同的接口:
如果遇到错误,请尝试执行 sudo ifconfig can0 txqueuelen 10000 。
在这里,我们指定 can0=can0,因为我们希望从接口 can0(在文件中)读取消息,并在 can0(实际硬件)上进行重放。
当您需要重复特定的 CAN 消息序列时,Canplayer 非常有用,例如重复一个被分割成多个 CAN 消息的 UDS 命令。此外,当您希望将某个 ECU 与它通常连接的 CAN 总线隔离时,Canplayer 也非常实用。许多 ECU 在未检测到正常 CAN 通信时会进入睡眠状态,因此通过 canplayer 以无限循环方式运行(使用“-l i”选项)可以避免这种情况:
现代 ECU 可能无法很好地应对 canplayer,因为它们具备消息认证机制,可防止 ECU 接受重放的消息。
如果你熟悉 Wireshark,可以直接启动它,并直接观察你的 socketCAN 接口(例如,你可以直接打开 can0)。你应该能够应用常规的 Wireshark 过滤器,并且 Wireshark 应该能够解析复杂的 CAN 流量,比如 UDS 命令。

为了实现阻抗匹配 ,CAN 要求在 CANH 和 CANL 线路的每一端各连接一个 120 欧姆的电阻(这些线路对所有 ECU 都是共用的)。RAMN 上已经内置了这些电阻,因此如果你使用外部工具,请确保该工具没有自带终端电阻(通常可以通过移除跳线或拨动开关来实现)。
CAN 仅需两根线:CANH 和 CANL,所有 ECU 共用。要传输“零”位,CAN 收发器会在 CANH 和 CANL 之间产生 2V 的电压差( 显性位 )。要传输“一”位,CAN 收发器则不作任何操作( 隐性位 ),此时 CANH 和 CANL 之间的电压差为 0V。
如果两个收发器同时尝试发送不同的位,则该位的值将取显性位的值,即0。
CAN ID 和有效载荷是 CAN 帧中最重要的字段,但还存在其他字段:
这些字段周围有时会存在分隔符和保留位。
CAN 帧以比特流形式传输,具有标称比特率。为确保 CAN 总线上观察到足够多的电压跳变,以实现时钟同步,CAN 采用了位填充机制:
例如,如果 CAN 控制器要发送标识符 0x3E0(二进制为 0001111100000),则该标识符的比特流将为 000111110000001。
位填充和去填充是在硬件中完成的,因此除非您使用逻辑分析仪观察 CAN 电压,否则您将无法察觉到位填充的存在。位填充不适用于 CRC 之后的字段。
如果 CAN 帧出现异常(例如位填充错误、CRC 错误等),总线上的 ECU 会检测到该问题。
ECU 的默认行为是假设“我正确,而 CAN 总线有错”,并为所有节点破坏当前的 CAN 帧(“错误主动”状态)。具体来说,当 ECU 检测到错误时,它会立即通过发送一个错误帧来通知其他节点,该错误帧由六个连续的显性位(零)组成。由于这些位是显性的,它们必然会覆盖正在进行的任何传输;同时,六个连续的零违反了位填充规则,从而确保所有其他可能未察觉到错误的 ECU 也能检测到该错误。
ECU 内部设有计数器,当检测到错误时会递增,而检测到有效帧时则会递减。如果这些计数器达到某个阈值,它们便会开始认为“我可能是导致 CAN 错误的原因”,并停止使用主动错误帧来破坏帧(此时它们会变为“错误被动”状态)。
如果错误持续发生,ECU 将判定自身应进入“总线关闭”状态,并与 CAN 总线断开连接。如果你为 CAN 接收器设置了错误的波特率,就会遇到总线关闭的问题。
点击此链接以了解更多关于 CAN 错误的信息。CAN 协议定义的错误包括:
与错误帧类似的还有过载帧 。它们的形式与错误帧相同,但不会增加错误计数器。过载帧只能在 IFS 字段(即“间隔期”)传输期间发送,原因可能是某个 ECU 需要额外时间来处理帧,或者某个 ECU 检测到其他 ECU 违反了间隔期规定。
默认情况下,RAMN ECU 启用了“自动重传”CAN 设置。这意味着当出现故障(例如短路)时,ECU 会迅速进入总线关闭模式,因为它们会在发生错误后立即尝试重新传输,并很快达到计数器限制。您可以通过将 hfdcan1.Init.AutoRetransmission = ENABLE; 更改为 hfdcan1.Init.AutoRetransmission = DISABLE; (在 main.c 中)并重新编译固件来更改此行为。此外,您也可以使用 AUTO_RECOVER_BUSOFF 配置标志,以自动从总线关闭事件中恢复。
CAN 帧包含一个“ACK”位,该位始终为显性电平,并且必须由所有接收方发送,以确认它们已正确接收到该帧。需要注意的是,这一位(且仅这一位)是由多个接收方发送的,而非帧的发送方。
ACK 位必须始终由接收方发送,即使它们已激活过滤器且对接收到的帧并不感兴趣。
一些 CAN 控制器具有仅监听模式,通常不会对帧进行应答。这种应答机制的一个后果是,CAN 总线必须始终拥有至少两个活动的 ECU。
由于 CAN 协议仅允许广播帧,ECU 会接收到大量它们并不需要的消息,从而造成过载。因此,CAN 控制器通常提供多种选项来设置各种 CAN 过滤器,以便仅接收它们关心的标识符对应的消息。
现代微控制器支持多种类型的过滤器,但传统上,一个过滤器由一个值和一个掩码定义。诸如 candump 之类的工具接受以下格式的过滤器:
我们以标准标识符的接收过滤器为例,此类标识符长度为11位。掩码和值的长度均与标识符相同。
掩码 0x7FF 对应的二进制为 11111111111,表示您关心标识符中的所有位 。因此,CAN 滤波器将仅接受标识符与该值完全一致的消息。例如,与 candump 配合使用的滤波器“1BB:7FF”将仅显示 ID 为 0x1BB 的 CAN 消息。
掩码 0x000 对应的二进制为 00000000000,表示您不关心标识符中的任何一位 。这意味着 CAN 滤波器将接受所有标识符(CAN 控制器可能对扩展和标准标识符需要不同的滤波器,因此您仍可能拒绝扩展标识符)。
如果您使用滤波器“1BB:000”启动 candump,它将显示所有 ID——这里的 1BB 没有任何影响,因为掩码表明所有位都不重要。此掩码与“000:000”和“FFF:000”是等效的。
掩码不必非得是 0x000 或 0x7FF,你也可以使用它们来指定更高级的条件。
例如,你可以使用001:001(仅关注最低位,且该位应为1)来仅显示奇数标识符,或者使用000:001(仅关注最低位,且该位应为0)来仅显示偶数标识符。
要指定一个范围,可以使用以 1 开头、以 0 结尾的掩码。一个常见的过滤器是你需要记住的 7e0:7F0。此过滤器表示你希望显示从 0x7e0 到 0x7ef 范围内的 CAN ID,这些 ID 对应于 RAMN 中的 UDS 诊断消息。
CAN 总线具有单一固定的标称波特率,在现代车辆中通常为 500 kbps。大多数 CAN 工具会允许你直接指定 CAN 总线的波特率,但有些工具可能会要求你提供具体的位定时参数。
CAN 协议将单个比特划分为若干个时间量子 。一个时间量子对应于 CAN 控制器时钟的周期 。RAMN 的 CAN 控制器采用 40 MHz 的时钟,因此相应的时间量子为 25 ns。
CAN 控制器认为一个位由四个段组成,每个段由若干时间量子构成:
ECU 均依赖于不同的时钟,这些时钟并不完美,存在轻微的同步偏差。CAN 控制器可以通过动态调整相位缓冲段 1 和相位缓冲段 2 的长度来调节 CAN 帧位的长度。同步跳转宽度(SJW)参数指定了这些调整的最大范围。
采样点对应于相位缓冲段 1 的末端和相位缓冲段 2 的起始位置,是 CAN 接收器实际观测 CAN 信号电压的时间点。如果采样点过早,可能会在电压尚未稳定时就进行读取(例如由于振铃现象)。如果采样点过晚,则可能读取到下一个位的信息。通常建议将采样点设置在 75%到 90%之间。
同步段始终为一个时间量子长度。在实际应用中,传播段和相位缓冲段 1 经常被合并为一个单独的段。因此,STM32 CAN 控制器(以及一般的 CAN 控制器)会要求您提供两个用于决定波特率的值:
您需要选择 TSEG1 和 TSEG2,以满足以下条件:
其中,乘数为您的 CAN 位时间与 CAN 控制器时间量子之间的比率。
例如,如果您的 CAN 控制器时钟为 40 MHz(时间量子为 25 纳秒),而您希望 CAN 波特率为 500 kbps(位时间为 2 微秒),则您的乘数为:
因此,只要满足以下条件,您可以任意选择 TSEG1 和 TSEG2:
RAMN 使用 TSEG1 = 60 和 TSEG2 = 19,因此采样点位于 76%(即 (60 + 1) / 80)。然而,它也可以使用其他组合,例如 TSEG1 = 69 和 TSEG2 = 10,此时仍会得到完全相同的波特率。
对于 SJW 值,应从最低值开始,如果遇到 CAN 错误,则将其调高。
具有灵活数据速率的控制器局域网(CAN FD) 是 CAN 的最新演进版本,支持更高的带宽。RAMN 与 CAN FD 兼容。本节总结了在使用 CAN FD 替代 CAN 时您应了解的最低要求。
尽管 CAN FD 控制器能够理解和传输经典 CAN 帧,但经典 CAN 控制器无法识别 CAN FD 帧,因此会破坏这些帧 。如果您希望传输 CAN FD 帧,需确保总线上的所有 ECU 均与 CAN FD 兼容(默认情况下,RAMN 即为此情况)。
CAN FD 允许的最大有效载荷为 64 字节。DLC 字段大小(4 位)保持不变,而大于 8 的 DLC 代表特定的尺寸:
CAN FD 引入了“比特率切换”功能:CAN 控制器在传输数据时可以提高波特率(即缩短比特时间)。当设置比特率切换(BRS)标志时,就会发生比特率切换。因此,CAN FD 控制器会请求两组不同的比特定时参数:“标称”和“数据”。
CAN FD 在 CAN FD 帧中增加了一个“错误状态指示器”位标志,用于指定该帧的发送方当前处于主动错误模式还是被动错误模式(参见 错误帧与总线关闭 )。
CAN FD 中不存在 RTR 标志。
实际上存在 CAN FD 的两个版本 :“ISO CAN FD”和“非 ISO CAN FD”,由于存在细微的协议差异,两者互不兼容。