双线汽车接口 (TWAI)
本文介绍了 ESP-IDF 中的双线汽车接口(Two-Wire Automotive Interface)控制器驱动的功能,章节目录如下:
概述
TWAI 是一种适用于汽车和工业应用的高可靠性的多主机实时串行异步通信协议。它兼容 ISO11898-1 标准定义的帧结构,可以支持 11 位 ID 的标准帧和 29 位 ID 的扩展帧。支持报文优先级和无损仲裁,支持自动重传和故障自动隔离机制。ESP32-C3 包含 1 个 TWAI 控制器,可以创建 1 个驱动实例。
ESP32-C3 TWAI 控制器 不兼容 ISO11898-1 FD 格式帧,并会将这些帧解析为错误。
基于硬件的高容错、多主机特性,该驱动的主要应用场景包括:
- 作为复杂干扰环境的通信总线,为设备提供可靠通信 
- 作为远距离多传感器/执行器总线,单节点故障不影响总线运行 
- 搭建去中心化分布式局域网络,避免单一主节点机制的不确定性 
- 配合其他通信协议作为桥接设备 
快速入门
本节将带你快速了解如何使用 TWAI 驱动。通过简单的示例,展示如何创建一个 TWAI 节点实例,如何发送和接收总线上的报文,以及如何安全停止和删除驱动。一般的使用流程如下:
硬件连接
ESP32-C3 内部没有集成 TWAI 收发器。因此你需要外接一个收发器才能加入 TWAI 总线。外部收发器的型号取决于具体应用遵循的物理层规范。例如,使用 TJA105x 收发器以兼容 ISO 11898-2 标准。
其中:
- 在做单节点测试时,可以直接短接 TX 和 RX 引脚以省略收发器。 
- BUS_OFF (可选),在 TWAI 控制器进入离线状态时为低逻辑电平 (0 V)。否则为高逻辑电平 (3.3 V)。 
- CLK_OUT (可选),输出控制器时间量子时钟,即源时钟的分频时钟。 
创建和启动 TWAI 节点
首先,我们需要创建一个 TWAI 实例。以下代码展示了如何创建一个波特率为 200kHz 的 TWAI 节点:
#include "esp_twai.h"
#include "esp_twai_onchip.h"
twai_node_handle_t node_hdl = NULL;
twai_onchip_node_config_t node_config = {
    .io_cfg.tx = 4,     // twai tx GPIO
    .io_cfg.rx = 5,     // twai rx GPIO
    .bit_timing.bitrate = 200000,   // 200k 波特率
    .tx_queue_depth = 5,// 发送队列深度为5
};
// 创建 TWAI 控制器驱动实例
ESP_ERROR_CHECK(twai_new_node_onchip(&node_config, &node_hdl));
// 启动 TWAI 控制器
ESP_ERROR_CHECK(twai_node_enable(node_hdl));
当创建 TWAI 实例时,我们需要通过 twai_onchip_node_config_t 配置 GPIO 引脚、波特率等参数。这些参数将决定 TWAI 的工作方式。然后调用 twai_new_node_onchip() 函数创建一个新的 TWAI 实例,该函数将返回一个指向新实例的句柄。 TWAI 的句柄实际上是一个指向 TWAI 内存对象的指针,类型为 twai_node_handle_t。
以下是 twai_onchip_node_config_t 结构体的其他配置参数及其解释:
- twai_onchip_node_config_t::clk_src指定控制器使用的时钟源,支持的时钟源列表见- twai_clock_source_t
- twai_onchip_node_config_t::bit_timing::sp_permill指定采样点位置,ssp_permill 指定二次采样点位置,可用于低信噪比下的时序微调。
- twai_onchip_node_config_t::data_timing指定 FD 格式时数据段的波特率及采样点,如果控制器不兼容 FD 格式,此配置无效。
- twai_onchip_node_config_t::fail_retry_cnt失败重传次数,-1 表示无限重传直到成功或 BUS_OFF; 0 表示失败后重传 0 次,即单次模式; 1 :重传 1 次,以此类推。
- twai_onchip_node_config_t::intr_priority中断优先级,范围 [0:3],值越大优先级越高。
- twai_onchip_node_config_t::flags通常用来微调驱动的一些行为,包括以下选项:- twai_onchip_node_config_t::flags::enable_self_test使能自测模式,发送报文时不检查ACK接收,可用于单节点测试。
- twai_onchip_node_config_t::flags::enable_loopback使能自收发模式,节点会收到自己发送的报文(如果配置了过滤器则还需要符合过滤规则),同时也会发送到总线。
- twai_onchip_node_config_t::flags::enable_listen_only配置为监听模式,节点只接收,不发送任何显性位,包括 ACK 和错误帧。
- twai_onchip_node_config_t::flags::no_receive_rtr使用过滤器时是否同时过滤掉符合 ID 规则的远程帧。
 
函数 twai_node_enable() 将启动 TWAI 控制器,此时 TWAI 控制器就连接到了总线,可以向总线发送报文。如果收到了总线上其他节点发送的报文,或者检测到了总线错误,也将产生相应事件。
与之对应的函数是 twai_node_disable(),该函数将立即停止节点工作并与总线断开,正在进行的传输将被中止。当下次重新启动时,如果发送队列中有未完成的任务,驱动将立即发起新的传输。
发送报文
TWAI 报文有多种类型,由报头指定。一个典型的数据帧报文主要包括报头和数据,大概结构如下:
为减少拷贝带来的性能损失,TWAI 驱动使用指针进行传递。以下代码展示了如何发送一条典型的数据帧报文:
uint8_t send_buff[8] = {0};
twai_frame_t tx_msg = {
    .header.id = 0x1,       // 报文ID
    .header.ide = true,     // 29 位扩展ID格式
    .buffer = send_buff,    // 发送数据的地址
    .buffer_len = sizeof(send_buff),    // 发送数据的长度
};
ESP_ERROR_CHECK(twai_node_transmit(node_hdl, &tx_msg, 0));  // 超时为0,队列满则直接返回超时
ESP_ERROR_CHECK(twai_node_transmit_wait_all_done(node_hdl, -1));  // 等待发送完成
其中 twai_frame_t::header::id 指示了该文的 ID 为 0x01。报文的 ID 通常用于表示报文在应用中的类型,并在发送过程中起到总线竞争仲裁的作用,其数值越小,在总线上的优先级越高。twai_frame_t::buffer 则指向要发送数据所在的内存地址,并由 twai_frame_t::buffer_len 给出数据长度。twai_node_transmit() 函数是线程安全的,并且也可以在 ISR 中调用。当从 ISR 调用时,timeout 参数将被忽略,函数不会阻塞。
需要注意的是 twai_frame_t::header::dlc 同样可以指定一个数据帧中数据的长度,dlc(data length code) 与具体长度的对应兼容 ISO11898-1 规定。可使用 twaifd_dlc2len() / twaifd_len2dlc() 进行转换,选择其一即可,如果 dlc 和 buffer_len 都不为 0 ,那他们所代表的长度必须一致。
报文类型 twai_frame_t 中还包括其他的配置参数,如下:
- twai_frame_t::dlc数据长度代码,经典帧 [0:8] 代表长度 [0:8];FD 格式 [0:15] 代表长度 [0:64]。
- twai_frame_t::header::ide使用 29 位扩展ID格式。
- twai_frame_t::header::rtr报文为远程帧,不包含数据段。
- twai_frame_t::header::fdf报文为 FD 格式,支持最大数据长度 64 字节。
- twai_frame_t::header::brs发送报文时在数据段使用独立的波特率。
- twai_frame_t::header::esi对于收到的报文,指示发送节点的错误状态。
接收报文
接收报文必须在接收事件回调中进行,因此,要接收报文需要在控制器启动前注册接收事件回调 twai_event_callbacks_t::on_rx_done ,从而在事件发生时接收报文。以下代码分别展示了如何注册接收事件回调,以及如何在回调中接收报文:
注册接收事件回调(在控制器启动前):
twai_event_callbacks_t user_cbs = {
    .on_rx_done = twai_rx_cb,
};
ESP_ERROR_CHECK(twai_node_register_event_callbacks(node_hdl, &user_cbs, NULL));
在事件中接收报文:
static bool twai_rx_cb(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
{
    uint8_t recv_buff[8];
    twai_frame_t rx_frame = {
        .buffer = recv_buff,
        .buffer_len = sizeof(recv_buff),
    };
    if (ESP_OK == twai_node_receive_from_isr(handle, &rx_frame)) {
        // receive ok, do something here
    }
    return false;
}
同样,驱动使用指针进行传递,因此需要在接收前配置 twai_frame_t::buffer 的指针及其内存长度 twai_frame_t::buffer_len
停止和删除节点
当不再需要使用 TWAI 时,应该调用 twai_node_delete() 函数来释放软硬件资源。删除前请确保 TWAI 已经处于停止状态。
进阶功能
在了解了基本用法后,我们可以进一步探索 TWAI 驱动的更多玩法。驱动支持更详细的控制器配置和错误反馈功能,完整的驱动功能图如下:
在 ISR 中发送
TWAI 驱动支持在中断服务程序 (ISR) 中发送报文。这对于需要低延迟响应或由硬件定时器触发的周期性传输的应用特别有用。例如,你可以在 on_tx_done 回调中触发一次新的传输,该回调在 ISR 上下文中执行。
static bool twai_tx_done_cb(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx)
{
    // 一帧已成功发送。排队另一帧。
    // 帧及其数据缓冲区必须在传输完成之前保持有效。
    static const uint8_t data_buffer[] = {1, 2, 3, 4};
    static const twai_frame_t tx_frame = {
        .header.id = 0x2,
        .buffer = (uint8_t *)data_buffer,
        .buffer_len = sizeof(data_buffer),
    };
    // `twai_node_transmit` 在 ISR 上下文中调用是安全的
    twai_node_transmit(handle, &tx_frame, 0);
    return false;
}
备注
在 ISR 中调用 twai_node_transmit() 时,timeout 参数将被忽略,函数不会阻塞。如果发送队列已满,函数将立即返回错误。应用程序需要自行处理队列已满的情况。
位时序自定义
和其他异步通信不同的是,TWAI 控制器在一个位时间里实际上在进行以 时间量子(Tq) 为单位的计数 / 采样,一个位里的时间量子的数量决定了最终的波特率以及采样点位置。在信号质量较低时时,可以手动更加精准的配置这些时序段以满足要求。位时间里的时间量子分为不同的段,如图所示:
其中同步段 sync 固定为 1 ,采样点位于 tseg1 和 tseg2 中间,同步跳变宽度 sjw 确定单个位时间可以为了同步而延长/缩短的最大时间量子数,范围为 [1:tseg2]。时钟源除以预分频 BRP 即为时间量子,所有段的时间总和即为一个位时间。故有如下公式:
- 波特率: 
- 采样点: 
以下代码展示了在时钟源 80M 时,配置波特率为 500Kbit/s ,采样点为 75% 的具体配置。
twai_timing_advanced_config_t timing_cfg = {
    .brp = 8,  // 预分频为 8,时间量子 80M/8=10M
    .prop_seg = 10,
    .tseg_1 = 4,
    .tseg_2 = 5,
    .sjw = 3,
};
ESP_ERROR_CHECK(twai_node_reconfig_timing(node_hdl, &timing_cfg, NULL)); // 配置仲裁段波特率,NULL 表示不配置 FD 数据段波特率
当手动配置这些段时,需要根据具体硬件留意每个段所支持的范围大小。时序配置函数 twai_node_reconfig_timing() 可以同时或单独对仲裁段和 FD 数据段时序进行配置,当控制器不支持 FD 格式时,对数据段的配置无效。时序参数 twai_timing_advanced_config_t 中还有一些别的配置参数:
- twai_timing_advanced_config_t::clk_src时钟源。
- twai_timing_advanced_config_t::ssp_offset二次采样点相对同步段偏移的时间量子数。
备注
brp、prop_seg、tseg_1、tseg_2 和 sjw 的不同组合可以实现相同波特率。用户应考虑 传播延迟、节点信息处理时间和相位误差 等因素,根据总线的物理特性进行调整。
过滤器配置
掩码过滤器
TWAI 控制器硬件可以根据 ID 对报文进行过滤,从而减少软硬件开销使节点更加高效。过滤掉报文的节点 不会接收到该报文,但仍会应答。
ESP32-C3 包含 1 个掩码过滤器,报文通过任意一个过滤器即能收到该报文。典型的 TWAI 掩码过滤器通过 ID 和 MASK 配置,其中:
- ID 表示期望接收的报文的标准11位或扩展29位ID。 
- MASK 表示对ID的过滤规则: - '0' 表示该位忽略,任意值都通过。 
- '1' 表示该位需要相等才能通过。 
- ID 和 MASK 都为 0 时,即忽略所有位,过滤器接收所有的帧。 
- ID 和 MASK 都为最大值 0xFFFFFFFF 表示不接收任何帧。 
 
下面代码展示了如何计算 MASK 和配置过滤器:
twai_mask_filter_config_t mfilter_cfg = {
    .id = 0x10,         // 0b 000 0001 0000
    .mask = 0x7f0,      // 0b 111 1111 0000 表示高7位严格匹配,低4位忽略,接收ID为
                        // 0b 000 0001 xxxx (16进制0x01x)
    .is_ext = false,    // 不接收扩展ID,只接收标准ID
};
ESP_ERROR_CHECK(twai_node_config_mask_filter(node_hdl, 0, &mfilter_cfg));   //配置过滤器0
双过滤器模式
ESP32-C3 支持双过滤器模式,可将硬件配置为并列的两个独立的 16 位掩码过滤器,支持接收更多 ID。但注意,使用双过滤器模式过滤 29 位扩展ID时,每个过滤器只能过滤其ID的高 16 位,剩余13位不做过滤。以下代码展示了如何借助 twai_make_dual_filter() 配置双过滤器模式。
// filter 1 id/mask 0x020, 0x7f0, receive only std id 0x02x
// filter 2 id/mask 0x013, 0x7f8, receive only std id 0x010~0x017
twai_mask_filter_config_t dual_config = twai_make_dual_filter(0x020, 0x7f0, 0x013, 0x7f8, false); // id1, mask1, id2, mask2, 不接收扩展ID
ESP_ERROR_CHECK(twai_node_config_mask_filter(node_hdl, 0, &dual_config));
总线错误和恢复
TWAI控制器能够检测由于总线干扰产生的/损坏的不符合帧格式的错误,并规定了一套由发送/接收错误计数器(TEC/REC)实现的故障隔离机制。计数器值决定节点的错误状态,即主动错误、错误警告、被动错误和离线,它可以使持续存在错误的节点最终自行断开与总线的连接。
- 主动错误: 当 TEC 和 REC 都小于 96 时,节点处于主动错误状态,表示正常运行。可以参与总线通信,检测到错误时发送 主动错误标志,主动报告检测到的错误。 
- 错误警告: 当 TEC 或 REC 中的一个大于或等于 96 时,且两个都小于 128 ,节点处于错误警告状态,表示可能存在错误,但行为不变。 
- 被动错误: 当 TEC 或 REC 中的一个大于或等于 128 时,节点处于被动错误状态。仍可以参与总线通信,但在检测到错误时,只能发送一次 被动错误标志。 
- 离线: 当 TEC 大于或等于 256 时,节点进入离线状态。离线的节点相当于断开连接,不会对总线产生任何影响。节点将保持离线状态,直到软件触发恢复操作。 
软件可随时使用函数 twai_node_get_info() 获取节点状态。或当控制器检测到错误时,会产生 twai_event_callbacks_t::on_error 回调,可通过传参中的错误数据查看错误原因。
当错误导致节点状态变化时,会进入 twai_event_callbacks_t::on_state_change 回调,可在回调中查看节点的状态变化。若节点已经离线且需要恢复,需要在task中调用 twai_node_recover()。 但注意,控制器不会立即恢复 ,需要在检测到 129 次连续 11 个隐性位后才会自动重新连接到总线。
节点恢复完成时同样进入 twai_event_callbacks_t::on_state_change 回调,状态由 TWAI_ERROR_BUS_OFF 变为 TWAI_ERROR_ACTIVE。恢复完成的节点可以立即进行传输,如果发送队列中有未完成的任务,驱动将立即发起新的传输。
关于低功耗
当启用电源管理 CONFIG_PM_ENABLE 时,系统在进入睡眠模式前可能会调整或关闭时钟源,从而导致 TWAI 出错。为了防止这种情况发生,驱动内部使用电源锁管理。当调用 twai_node_enable() 函数后,该锁将被激活,确保系统不会进入睡眠模式,从而保持 TWAI 功能正常。如果需要降低功耗,可以调用 twai_node_disable() 函数来释放电源管理锁,使系统能够进入睡眠模式,睡眠期间 TWAI 控制器也将停止工作。
关于 Cache 安全
在进行 Flash 写操作时,为了避免 Cache 从 Flash 加载指令和数据时出现错误,系统会暂时禁用 Cache 功能。这会导致存放在 Flash 上的中断处理程序在此期间无法响应。如果希望在 Cache 被禁用期间,中断处理程序仍能正常运行,可以启用 CONFIG_TWAI_ISR_CACHE_SAFE 选项。
备注
请注意,在启用该选项后,所有的中断回调函数及其上下文数据 必须存放在内部存储空间 中。因为在 Cache 被禁用时,系统无法从 Flash 中加载数据和指令。
关于线程安全
驱动程序可保证所有公开的 TWAI API 的线程安全,使用时,可以直接从不同的 RTOS 任务中调用此类 API,无需额外锁保护。
关于性能
为了提升中断处理的实时响应能力, 驱动提供了 CONFIG_TWAI_ISR_IN_IRAM 选项。启用该选项后,中断处理程序和接收操作将被放置在内部 RAM 中运行,从而减少了从 Flash 加载指令带来的延迟。
对于需要高性能发送操作的应用,驱动还提供了 CONFIG_TWAI_IO_FUNC_IN_IRAM 选项,用于将发送函数放置在 IRAM 中。这对于在用户任务中频繁调用 twai_node_transmit() 的时间关键应用特别有效。
备注
但是,中断处理程序调用的用户回调函数和用户上下文数据仍然可能位于 Flash 中,延迟问题还是会存在,这需要用户自己将回调函数和数据放入内部 RAM 中,比如使用 IRAM_ATTR 和 DRAM_ATTR。
关于资源消耗
使用 IDF Size 工具可以查看 TWAI 驱动的 Flash 和内存空间消耗。以下是测试条件(以 ESP32-C6 为例):
- 编译器优化等级设置为 - -Os,以确保代码尺寸最小化。
- 默认日志等级设置为 - ESP_LOG_INFO,以平衡调试信息和性能。
- 关闭以下驱动优化选项: - CONFIG_TWAI_ISR_IN_IRAM - 中断处理程序不放入 IRAM。 
- CONFIG_TWAI_ISR_CACHE_SAFE - 不启用 Cache 安全选项。 
 
注意,以下数据仅供参考,不是精确值,在不同芯片上会有所出入。
| Component Layer | Total Size | DIRAM | .bss | .data | .text | Flash | .rodata | .text | 
|---|---|---|---|---|---|---|---|---|
| driver | 7262 | 12 | 12 | 0 | 0 | 7250 | 506 | 6744 | 
| hal | 1952 | 0 | 0 | 0 | 0 | 0 | 0 | 1952 | 
| soc | 64 | 0 | 0 | 0 | 0 | 64 | 64 | 0 | 
打开 CONFIG_TWAI_ISR_IN_IRAM 优化选项的消耗情况:
| Component Layer | Total Size | DIRAM | .bss | .data | .text | Flash | .rodata | .text | 
|---|---|---|---|---|---|---|---|---|
| driver | 7248 | 692 | 12 | 0 | 680 | 6556 | 506 | 6050 | 
| hal | 1952 | 1030 | 0 | 0 | 1030 | 922 | 0 | 922 | 
| soc | 64 | 0 | 0 | 0 | 0 | 0 | 64 | 0 | 
此外,每一个 TWAI 句柄会从 heap 中动态申请约 168 + 4 * twai_onchip_node_config_t::tx_queue_depth 字节的内存。
其他 Kconfig 选项
- CONFIG_TWAI_ENABLE_DEBUG_LOG 选项允许强制启用 TWAI 驱动的所有调试日志,无论全局日志级别设置如何。启用此选项可以帮助开发人员在调试过程中获取更详细的日志信息,从而更容易定位和解决问题。 
应用示例
- peripherals/twai/twai_utils 演示了如何使用 TWAI(Two-Wire Automotive Interface,双线汽车接口)API 创建一个命令行工具,用于 TWAI 总线通信,支持帧的发送/接收、过滤、监控,以及经典和 FD 格式,以便测试和调试 TWAI 网络。 
- peripherals/twai/twai_error_recovery 演示了总线错误上报,节点状态变化等事件信息,以及如何从离线状态恢复节点并重新进行通信。 
- peripherals/twai/twai_network 通过发送、监听, 2 个不同角色的节点,演示了如何使用驱动程序进行单次的和大量的数据发送,以及配置过滤器以接收这些数据。 
- peripherals/twai/cybergear 演示了如何通过 TWAI 接口控制 XiaoMi CyberGear 电机。 
API 参考
Header File
- This header file can be included with: - #include "esp_twai_onchip.h" 
- This header file is a part of the API provided by the - esp_driver_twaicomponent. To declare that your component depends on- esp_driver_twai, add the following to your CMakeLists.txt:- REQUIRES esp_driver_twai - or - PRIV_REQUIRES esp_driver_twai 
Functions
- 
esp_err_t twai_new_node_onchip(const twai_onchip_node_config_t *node_config, twai_node_handle_t *node_ret)
- Allocate a TWAI hardware node by specific init config structure To delete/free the TWAI, call - twai_node_delete()- 参数:
- node_config -- [in] Init config structure 
- node_ret -- [out] Return driver handle 
 
- 返回:
- ESP_OK Allocate success ESP_ERR_NO_MEM No enough free memory ESP_ERR_NOT_FOUND No free hardware controller ESP_ERR_INVALID_ARG Config argument not available ESP_ERR_INVALID_STATE State error, including hardware state error and driver state error ESP_FAIL Other reasons 
 
- 
static inline twai_mask_filter_config_t twai_make_dual_filter(uint32_t id1, uint32_t mask1, uint32_t id2, uint32_t mask2, bool is_ext)
- Helper function to configure a dual 16-bit acceptance filter. - 备注 - For 29bits Extended IDs, ONLY high 16bits id/mask is used for each filter. - 参数:
- id1 -- First full 11/29 bits ID to filter. 
- mask1 -- Mask for first ID. 
- id2 -- Second full 11/29 bits ID to filter. 
- mask2 -- Mask for second ID. 
- is_ext -- True if using Extended (29-bit) IDs, false for Standard (11-bit) IDs. 
 
- 返回:
- twai_mask_filter_config_t A filled filter configuration structure for dual filtering. 
 
Structures
- 
struct twai_onchip_node_config_t
- TWAI on-chip node initialization configuration structure. - Public Members - 
gpio_num_t tx
- GPIO pin for twai TX 
 - 
gpio_num_t rx
- GPIO pin for twai RX 
 - 
gpio_num_t quanta_clk_out
- GPIO pin for quanta clock output, Set -1 to not use 
 - 
gpio_num_t bus_off_indicator
- GPIO pin for bus-off indicator, Set -1 to not use 
 - 
struct twai_onchip_node_config_t io_cfg
- I/O configuration 
 - 
twai_clock_source_t clk_src
- Optional, clock source, remain 0 to using TWAI_CLK_SRC_DEFAULT by default 
 - 
twai_timing_basic_config_t bit_timing
- Timing configuration for classic twai and FD arbitration stage 
 - 
twai_timing_basic_config_t data_timing
- Optional, timing configuration for FD data stage 
 - 
int8_t fail_retry_cnt
- Hardware retry limit if failed, range [-1:15], -1 for re-trans forever 
 - 
uint32_t tx_queue_depth
- Depth of the transmit queue 
 - 
int intr_priority
- Interrupt priority, [0:3] 
 - 
uint32_t enable_self_test
- Transmission does not require acknowledgment. Use this mode for self testing 
 - 
uint32_t enable_loopback
- The TWAI controller receive back frames what it send out 
 - 
uint32_t enable_listen_only
- The TWAI controller will not influence the bus (No transmissions or acknowledgments) but can receive messages 
 - 
uint32_t no_receive_rtr
- Don't receive remote frames 
 - 
struct twai_onchip_node_config_t flags
- Misc configuration flags 
 
- 
gpio_num_t tx
Header File
- This header file can be included with: - #include "esp_twai.h" 
- This header file is a part of the API provided by the - esp_driver_twaicomponent. To declare that your component depends on- esp_driver_twai, add the following to your CMakeLists.txt:- REQUIRES esp_driver_twai - or - PRIV_REQUIRES esp_driver_twai 
Functions
- 
esp_err_t twai_node_enable(twai_node_handle_t node)
- Enable the TWAI node. - 参数:
- node -- Handle to the TWAI node 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_disable(twai_node_handle_t node)
- Disable the TWAI node. - 参数:
- node -- Handle to the TWAI node 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_recover(twai_node_handle_t node)
- Init the recover process for TWAI node which in bus-off. - 备注 - Follow - on_state_changecallback or- twai_node_get_infoto know recover finish or not- 参数:
- node -- Handle to the TWAI node 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_delete(twai_node_handle_t node)
- Delete the TWAI node and release resources. - 参数:
- node -- Handle to the TWAI node 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_register_event_callbacks(twai_node_handle_t node, const twai_event_callbacks_t *cbs, void *user_data)
- Register event callbacks for the TWAI node. - 参数:
- node -- Handle to the TWAI node 
- cbs -- Pointer to a structure of event callback functions 
- user_data -- User-defined data passed to callback functions 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_reconfig_timing(twai_node_handle_t node, const twai_timing_advanced_config_t *bit_timing, const twai_timing_advanced_config_t *data_timing)
- Reconfigure the timing settings of the TWAI node. - 备注 - You can reconfigure the timing for the arbitration and data phase, separately or together. - 参数:
- node -- Handle to the TWAI node 
- bit_timing -- Optional,pointer to new twai cc(classic) or arbitration phase of twai fd timing configuration 
- data_timing -- Optional, pointer to new twai fd timing configuration 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_config_mask_filter(twai_node_handle_t node, uint8_t filter_id, const twai_mask_filter_config_t *mask_cfg)
- Configure the mask filter of the TWAI node. - 参数:
- node -- Handle to the TWAI node 
- filter_id -- Index of the filter to configure 
- mask_cfg -- Pointer to the mask filter configuration 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_config_range_filter(twai_node_handle_t node, uint8_t filter_id, const twai_range_filter_config_t *range_cfg)
- Configure the range filter of the TWAI node. - 参数:
- node -- Handle to the TWAI node 
- filter_id -- Index of the filter to configure 
- range_cfg -- Pointer to the range filter configuration 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_get_info(twai_node_handle_t node, twai_node_status_t *status_ret, twai_node_record_t *statistics_ret)
- Get information about the TWAI node. - 参数:
- node -- Handle to the TWAI node 
- status_ret -- Pointer to store the current node status 
- statistics_ret -- Pointer to store node statistics 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_transmit(twai_node_handle_t node, const twai_frame_t *frame, int timeout_ms)
- Transmit a TWAI frame. - 参数:
- node -- [in] Handle to the TWAI node 
- frame -- [in] Pointer to the frame to transmit 
- timeout_ms -- [in] Maximum wait time if the transmission queue is full (milliseconds), -1 to wait forever 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_transmit_wait_all_done(twai_node_handle_t node, int timeout_ms)
- Wait for all pending transfers to finish, if bus-off happens during waiting, wait until node recovered and tx is finished, or timeout. - 参数:
- node -- [in] Handle to the TWAI node 
- timeout_ms -- [in] Maximum wait time for all pending transfers to finish (milliseconds), -1 to wait forever 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
- 
esp_err_t twai_node_receive_from_isr(twai_node_handle_t node, twai_frame_t *rx_frame)
- Receive a TWAI frame from 'rx_done_cb'. - 备注 - This function can only be called from the - rx_done_cbcallback, you can't call it from a task.- 备注 - Please also provide - bufferand- buffer_leninside the rx_frame- 备注 - Can get original data length from - twaifd_dlc2len(rx_frame.header.dlc)- 参数:
- node -- [in] Handle to the TWAI node 
- rx_frame -- [out] Pointer to the frame store rx content 
 
- 返回:
- ESP_OK on success, error code otherwise 
 
Header File
- This header file can be included with: - #include "esp_twai_types.h" 
- This header file is a part of the API provided by the - esp_driver_twaicomponent. To declare that your component depends on- esp_driver_twai, add the following to your CMakeLists.txt:- REQUIRES esp_driver_twai - or - PRIV_REQUIRES esp_driver_twai 
Structures
- 
struct twai_timing_basic_config_t
- TWAI bitrate timing config basic (simple) mode. 
- 
struct twai_frame_t
- TWAI transaction frame param type. - Public Members - 
twai_frame_header_t header
- message attribute/metadata, exclude data buffer 
 - 
uint8_t *buffer
- buffer address for tx and rx message data 
 - 
size_t buffer_len
- buffer length of provided data buffer pointer, in bytes. 
 
- 
twai_frame_header_t header
- 
struct twai_node_status_t
- TWAI node's status. - Public Members - 
twai_error_state_t state
- Node's error state 
 - 
uint16_t tx_error_count
- Node's TX error count 
 - 
uint16_t rx_error_count
- Node's RX error count 
 
- 
twai_error_state_t state
- 
struct twai_node_record_t
- TWAI node's statistics/record type. - This structure contains some statistics regarding a node's communication on the TWAI bus - Public Members - 
uint32_t bus_err_num
- Cumulative number (since - twai_node_enable()) of bus errors
 
- 
uint32_t bus_err_num
- 
struct twai_tx_done_event_data_t
- TWAI "TX done" event data. - Public Members - 
bool is_tx_success
- Indicate if frame send successful, refer - on_errorcallback for fail reason if send failed
 - 
const twai_frame_t *done_tx_frame
- Pointer to the frame that has been transmitted 
 
- 
bool is_tx_success
- 
struct twai_rx_done_event_data_t
- TWAI "RX done" event data. 
- 
struct twai_state_change_event_data_t
- TWAI "state change" event data. - Public Members - 
twai_error_state_t old_sta
- Previous error state 
 - 
twai_error_state_t new_sta
- New error state after the change 
 
- 
twai_error_state_t old_sta
- 
struct twai_error_event_data_t
- TWAI "error" event data. - Public Members - 
twai_error_flags_t err_flags
- Error flags indicating the type of the error 
 
- 
twai_error_flags_t err_flags
- 
struct twai_event_callbacks_t
- Group of supported TWAI callbacks. - 备注 - All of these callbacks is invoked from ISR context. Thus, the implementation of the callback function must adhere to the ISR restrictions such as not calling any blocking APIs. - 备注 - Set the particular event callback's entry to NULL to unregister it if not required. - 备注 - When TWAI_ISR_CACHE_SAFE is enabled, the callbacks must be placed in IRAM. - Public Members - 
bool (*on_tx_done)(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx)
- TWAI "TX done" event callback prototype. - Param handle:
- TWAI node handle 
- Param edata:
- "TX done" event data (passed by the driver) 
- Param user_ctx:
- User data, passed from - twai_node_register_event_callbacks()
- Return:
- Whether a higher priority task has been unblocked by this function 
 
 - 
bool (*on_rx_done)(twai_node_handle_t handle, const twai_rx_done_event_data_t *edata, void *user_ctx)
- TWAI "RX done" event callback prototype. - Param handle:
- TWAI node handle 
- Param edata:
- "RX done" event data (passed by the driver) 
- Param user_ctx:
- User data, passed from - twai_node_register_event_callbacks()
- Return:
- Whether a higher priority task has been unblocked by this function 
 
 - 
bool (*on_state_change)(twai_node_handle_t handle, const twai_state_change_event_data_t *edata, void *user_ctx)
- TWAI "state change" event callback prototype. - Param handle:
- TWAI node handle 
- Param edata:
- "state change" event data (passed by the driver) 
- Param user_ctx:
- User data, passed from - twai_node_register_event_callbacks()
- Return:
- Whether a higher priority task has been unblocked by this function 
 
 - 
bool (*on_error)(twai_node_handle_t handle, const twai_error_event_data_t *edata, void *user_ctx)
- TWAI "error" event callback prototype. - Param handle:
- [in] TWAI node handle 
- Param edata:
- [in] "error" event data (passed by the driver) 
- Param user_ctx:
- [in] User data, passed from - twai_node_register_event_callbacks()
- Return:
- Whether a higher priority task has been unblocked by this function 
 
 
- 
bool (*on_tx_done)(twai_node_handle_t handle, const twai_tx_done_event_data_t *edata, void *user_ctx)
Type Definitions
- 
typedef struct twai_node_base *twai_node_handle_t
- ESP TWAI controller handle. 
Header File
- This header file can be included with: - #include "hal/twai_types.h" 
Functions
- 
static inline uint16_t twaifd_dlc2len(uint16_t dlc)
- Translate TWAIFD format DLC code to bytes length. - 参数:
- dlc -- [in] The frame DLC code follow the FD spec 
- 返回:
- The byte length of DLC stand for 
 
- 
static inline uint16_t twaifd_len2dlc(uint16_t byte_len)
- Translate TWAIFD format bytes length to DLC code. - 参数:
- byte_len -- [in] The byte length of the message 
- 返回:
- The FD adopted frame DLC code 
 
Unions
- 
union twai_error_flags_t
- #include <twai_types.h>TWAI transmit error type structure. Public Members - 
uint32_t arb_lost
- Arbitration lost error (lost arbitration during transmission) 
 - 
uint32_t bit_err
- Bit error detected (dominant/recessive mismatch during transmission) 
 - 
uint32_t form_err
- Form error detected (frame fixed-form bit violation) 
 - 
uint32_t stuff_err
- Stuff error detected (e.g. dominant error frame received) 
 - 
uint32_t ack_err
- ACK error (no ack), transmission without acknowledge received 
 - struct twai_error_flags_t
 - 
uint32_t val
- Integrated error flags 
 
- 
uint32_t arb_lost
Structures
- 
struct twai_timing_config_t
- TWAI bitrate timing config advanced mode. - 备注 - Setting one of - quanta_resolution_hzand- brpis enough, otherwise,- brpis not used.- Public Members - 
twai_clock_source_t clk_src
- Optional, clock source, remain 0 to using TWAI_CLK_SRC_DEFAULT by default 
 - 
uint32_t quanta_resolution_hz
- The resolution of one timing quanta, in Hz. If setting, brp will be ignored 
 - 
uint32_t brp
- Bit rate pre-divider, f(clk_src) / brp = quanta_resolution_hz, f(clk_src) can be obtained using esp_clk_tree_src_get_freq_hz(clk_src,,) 
 - 
uint8_t prop_seg
- Prop_seg length, in quanta time 
 - 
uint8_t tseg_1
- Seg_1 length, in quanta time 
 - 
uint8_t tseg_2
- Seg_2 length, in quanta time 
 - 
uint8_t sjw
- Sync jump width, in quanta time 
 - 
uint8_t ssp_offset
- Secondary sample point offset refet to Sync seg, in quanta time, set 0 to disable ssp 
 - 
bool triple_sampling
- Deprecated, in favor of - ssp_offset
 
- 
twai_clock_source_t clk_src
- 
struct twai_mask_filter_config_t
- Configuration for TWAI mask filter. - Public Members - 
uint32_t id
- Single base ID for filtering 
 - 
uint32_t *id_list
- Base ID list array for filtering, which share the same - mask
 - 
uint32_t num_of_ids
- List length of - id_list, remain empty to using single- idinstead of- id_list
 - 
uint32_t mask
- Mask to determine the matching bits (1 = match bit, 0 = any bit) 
 - 
uint32_t is_ext
- True for extended ID filtering, false for standard ID 
 - 
uint32_t no_classic
- If true, Classic TWAI frames are excluded (only TWAI FD allowed) 
 - 
uint32_t no_fd
- If true, TWAI FD frames are excluded (only Classic TWAI allowed) 
 - 
uint32_t dual_filter
- Set filter as dual-16bits filter mode, see - twai_make_dual_filter()for easy config
 
- 
uint32_t id
- 
struct twai_range_filter_config_t
- Range-based filter configuration structure. - Public Members - 
uint32_t range_low
- Lower bound of the filtering range 
 - 
uint32_t range_high
- Upper bound of the filtering range 
 - 
uint32_t is_ext
- True for extended ID filtering, false for standard ID 
 - 
uint32_t no_classic
- If true, Classic TWAI frames are excluded (only TWAI FD allowed) 
 - 
uint32_t no_fd
- If true, TWAI FD frames are excluded (only Classic TWAI allowed) 
 
- 
uint32_t range_low
- 
struct twai_frame_header_t
- TWAI frame header/format struct type. - Public Members - 
uint32_t id
- message arbitration identification 
 - 
uint16_t dlc
- message data length code 
 - 
uint32_t ide
- Extended Frame Format (29bit ID) 
 - 
uint32_t rtr
- Message is a Remote Frame 
 - 
uint32_t fdf
- Message is FD format, allow max 64 byte of data 
 - 
uint32_t brs
- Transmit message with Bit Rate Shift. 
 - 
uint32_t esi
- Transmit side error indicator for received frame 
 - 
uint64_t timestamp
- Timestamp for received message 
 - 
uint64_t trigger_time
- Trigger time for transmitting message 
 
- 
uint32_t id
Macros
- 
TWAI_STD_ID_MASK
- Mask of the ID fields in a standard frame 
- 
TWAI_EXT_ID_MASK
- Mask of the ID fields in an extended frame 
- 
TWAI_FRAME_MAX_DLC
- 
TWAI_FRAME_MAX_LEN
- 
TWAIFD_FRAME_MAX_DLC
- 
TWAIFD_FRAME_MAX_LEN
Type Definitions
- 
typedef soc_periph_twai_clk_src_t twai_clock_source_t
- TWAI group clock source. - 备注 - User should select the clock source based on the power and resolution requirement 
- 
typedef twai_timing_config_t twai_timing_advanced_config_t
- TWAI bitrate timing config advanced mode for esp_driver_twai. - 备注 - quanta_resolution_hzis not supported in this driver
Enumerations
- 
enum twai_error_state_t
- TWAI node error fsm states. - Values: - 
enumerator TWAI_ERROR_ACTIVE
- Error active state: TEC/REC < 96 
 - 
enumerator TWAI_ERROR_WARNING
- Error warning state: TEC/REC >= 96 and < 128 
 - 
enumerator TWAI_ERROR_PASSIVE
- Error passive state: TEC/REC >= 128 and < 256 
 - 
enumerator TWAI_ERROR_BUS_OFF
- Bus-off state: TEC >= 256 (node offline) 
 
- 
enumerator TWAI_ERROR_ACTIVE