双线汽车接口 (TWAI)

[English]

本文介绍了 ESP-IDF 中的双线汽车接口(Two-Wire Automotive Interface)控制器驱动的功能,章节目录如下:

概述

TWAI 是一种适用于汽车和工业应用的高可靠性的多主机实时串行异步通信协议。它兼容 ISO11898-1 标准定义的帧结构,可以支持 11 位 ID 的标准帧和 29 位 ID 的扩展帧。支持报文优先级和无损仲裁,支持自动重传和故障自动隔离机制。ESP32-P4 包含 3 个 TWAI 控制器,可以创建 3 个驱动实例。

ESP32-P4 TWAI 控制器 不兼容 ISO11898-1 FD 格式帧,并会将这些帧解析为错误。

基于硬件的高容错、多主机特性,该驱动的主要应用场景包括:

  • 作为复杂干扰环境的通信总线,为设备提供可靠通信

  • 作为远距离多传感器/执行器总线,单节点故障不影响总线运行

  • 搭建去中心化分布式局域网络,避免单一主节点机制的不确定性

  • 配合其他通信协议作为桥接设备

快速入门

本节将带你快速了解如何使用 TWAI 驱动。通过简单的示例,展示如何创建一个 TWAI 节点实例,如何发送和接收总线上的报文,以及如何安全停止和删除驱动。一般的使用流程如下:

../../_images/base_flow.drawio.svg

硬件连接

ESP32-P4 内部没有集成 TWAI 收发器。因此你需要外接一个收发器才能加入 TWAI 总线。外部收发器的型号取决于具体应用遵循的物理层规范。例如,使用 TJA105x 收发器以兼容 ISO 11898-2 标准。

ESP32 to Transceiver Wiring

其中:

  • 在做单节点测试时,可以直接短接 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 报文有多种类型,由报头指定。一个典型的数据帧报文主要包括报头和数据,大概结构如下:

../../_images/frame_struct.svg

为减少拷贝带来的性能损失,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,队列满则直接返回超时

其中 twai_frame_t::header::id 指示了该文的 ID 为 0x01。报文的 ID 通常用于表示报文在应用中的类型,并在发送过程中起到总线竞争仲裁的作用,其数值越小,在总线上的优先级越高。twai_frame_t::buffer 则指向要发送数据所在的内存地址,并由 twai_frame_t::buffer_len 给出数据长度。

需要注意的是 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 驱动的更多玩法。驱动支持更详细的控制器配置和错误反馈功能,完整的驱动功能图如下:

../../_images/full_flow.drawio.svg

位时序自定义

和其他异步通信不同的是,TWAI 控制器在一个位时间里实际上在进行以 时间量子(Tq) 为单位的计数 / 采样,一个位里的时间量子的数量决定了最终的波特率以及采样点位置。在信号质量较低时时,可以手动更加精准的配置这些时序段以满足要求。位时间里的时间量子分为不同的段,如图所示:

Bit timing configuration

其中同步段 sync 固定为 1 ,采样点位于 tseg1 和 tseg2 中间,同步跳变宽度 sjw 确定单个位时间可以为了同步而延长/缩短的最大时间量子数,范围为 [1:tseg2]。时钟源除以预分频 BRP 即为时间量子,所有段的时间总和即为一个位时间。故有如下公式:

  • 波特率:

\[\text{bitrate} = \frac{f_{\text{src}}}{\text{brp} \cdot (1 + \text{prop_seg} + \text{tseg}_1 + \text{tseg}_2)}\]
  • 采样点:

\[\text{sample_point} = \frac{1 + \text{prop_seg} + \text{tseg}_1}{1 + \text{prop_seg} + \text{tseg}_1 + \text{tseg}_2}\]

以下代码展示了在时钟源 80M 时,配置波特率为 500Kbit/s ,采样点为 75% 的具体配置。

twai_timing_advanced_config_t timing_cfg = {
    .brp = 8,  // 预分频为 8,时间量子 80M/8=1M
    .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 二次采样点相对同步段偏移的时间量子数。

备注

brpprop_segtseg_1tseg_2sjw 的不同组合可以实现相同波特率。用户应考虑 传播延迟、节点信息处理时间和相位误差 等因素,根据总线的物理特性进行调整。

过滤器配置

掩码过滤器

TWAI 控制器硬件可以根据 ID 对报文进行过滤,从而减少软硬件开销使节点更加高效。过滤掉报文的节点 不会接收到该报文,但仍会应答

ESP32-P4 包含 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-P4 支持双过滤器模式,可将硬件配置为并列的两个独立的 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 加载指令带来的延迟。

备注

但是,中断处理程序调用的用户回调函数和用户上下文数据仍然可能位于 Flash 中,延迟问题还是会存在,这需要用户自己将回调函数和数据放入内部 RAM 中,比如使用 IRAM_ATTRDRAM_ATTR

关于资源消耗

使用 IDF Size 工具可以查看 TWAI 驱动的 Flash 和内存空间消耗。以下是测试条件(以 ESP32-C6 为例):

  • 编译器优化等级设置为 -Os,以确保代码尺寸最小化。

  • 默认日志等级设置为 ESP_LOG_INFO,以平衡调试信息和性能。

  • 关闭以下驱动优化选项:

注意,以下数据仅供参考,不是精确值,在不同芯片上会有所出入。

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 驱动的所有调试日志,无论全局日志级别设置如何。启用此选项可以帮助开发人员在调试过程中获取更详细的日志信息,从而更容易定位和解决问题。

应用示例

  • 暂无

API 参考

Header File

  • components/esp_driver_twai/include/esp_twai_onchip.h

  • 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_twai component. 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(uint16_t id1, uint16_t mask1, uint16_t id2, uint16_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 eache filter.

参数:
  • id1 -- First ID to filter.

  • mask1 -- Mask for first ID.

  • id2 -- Second 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

Header File

  • components/esp_driver_twai/include/esp_twai.h

  • 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_twai component. 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_change callback or twai_node_get_info to 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_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_cb callback, you can't call it from a task.

备注

Please also provide buffer and buffer_len inside 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

  • components/esp_driver_twai/include/esp_twai_types.h

  • 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_twai component. 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.

Public Members

uint32_t bitrate

Expected TWAI bus baud_rate/bitrate in bits/second

uint16_t sp_permill

Optional, sampling point in permill (1/1000) of the entire bit time

uint16_t ssp_permill

Optional, secondary sample point(ssp) in permill (1/1000) of the entire bit time

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.

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

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

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_error callback for fail reason if send failed

const twai_frame_t *done_tx_frame

Pointer to the frame that has been transmitted

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

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

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

Type Definitions

typedef struct twai_node_base *twai_node_handle_t

ESP TWAI controller handle.

Header File

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

Structures

struct twai_timing_config_t

TWAI bitrate timing config advanced mode.

备注

Setting one of quanta_resolution_hz and brp is enough, otherwise, brp is 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, clock_source_freq / brp = quanta_resolution_hz

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

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 id instead 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

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)

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

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_hz is 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)


此文档对您有帮助吗?