Linux 硬件时间戳引擎 (HTE)

作者:

Dipen Patel

简介

某些设备具有内置的硬件时间戳引擎,可以实时监控系统信号、线路、总线等的状态变化;检测到变化时,它们可以自动存储发生时刻的时间戳。与使用软件对应项(例如 ktime 及其变体)相比,这种功能可能有助于在获取时间戳时实现更高的准确性。

本文档描述了希望使用硬件时间戳引擎 (HTE) 框架的硬件时间戳引擎提供程序和使用者驱动程序可以使用的 API。使用者和提供程序都必须包含 #include <linux/hte.h>

提供程序的 HTE 框架 API

int hte_push_ts_ns(const struct hte_chip *chip, u32 xlated_id, struct hte_ts_data *data)

推送纳秒级时间戳数据。

参数

const struct hte_chip *chip

HTE 芯片,在注册期间使用。

u32 xlated_id

子系统和提供程序都理解的实体 ID,这是从请求 API 期间的 xlate 回调获得的。

struct hte_ts_data *data

时间戳数据。

描述

它被提供程序用于推送时间戳数据。

返回值

成功时返回 0,失败时返回负错误代码。

int devm_hte_register_chip(struct hte_chip *chip)

资源管理 API,用于注册 HTE 芯片。

参数

struct hte_chip *chip

要添加到子系统的 HTE 芯片。

描述

它被提供程序用于向 HTE 子系统注册自身。当提供程序退出时,将自动完成注销。

返回值

成功时返回 0,失败时返回负错误代码。

消费者的 HTE 框架 API

int hte_ts_put(struct hte_ts_desc *desc)

释放并禁用给定描述符的时间戳。

参数

struct hte_ts_desc *desc

时间戳描述符。

上下文

debugfs_remove_recursive() 函数调用可能使用睡眠锁,不适合在原子上下文中调用。

返回值

成功时返回 0,失败时返回负错误代码。

int hte_disable_ts(struct hte_ts_desc *desc)

在给定描述符上禁用时间戳。

参数

struct hte_ts_desc *desc

时间戳描述符,与请求 API 返回的相同。

描述

该 API 不会释放与 desc 关联的任何资源。

上下文

持有互斥锁,不适合在原子上下文中调用。

返回值

成功时返回 0,失败时返回负错误代码。

int hte_enable_ts(struct hte_ts_desc *desc)

在给定描述符上启用时间戳。

参数

struct hte_ts_desc *desc

时间戳描述符,与请求 API 返回的相同。

上下文

持有互斥锁,不适合在原子上下文中调用。

返回值

成功时返回 0,失败时返回负错误代码。

int of_hte_req_count(struct device *dev)

返回要添加时间戳的实体数量。

参数

struct device *dev

HTE 消费者。

描述

该函数通过解析设备树返回请求添加时间戳的实体总数。

返回值

成功时返回正数,如果不存在条目则返回 -ENOENT,其他错误返回 -EINVAL。

int hte_ts_get(struct device *dev, struct hte_ts_desc *desc, int index)

初始化并获取 HTE 描述符的函数。

参数

struct device *dev

HTE 消费者/客户端设备,用于解析设备树节点的情况。

struct hte_ts_desc *desc

预分配的时间戳描述符。

int index

如果存在节点,该索引将用作解析设备树节点中 line_id 的索引。

描述

该函数初始化消费者提供的 HTE 描述符。如果消费者具有设备树节点,则 index 用于解析行 ID 和其他详细信息。在使用任何请求 API 之前,需要调用该函数。

上下文

持有互斥锁。

返回值

成功时返回 0,失败时返回负错误代码。

int hte_request_ts_ns(struct hte_ts_desc *desc, hte_ts_cb_t cb, hte_ts_sec_cb_t tcb, void *data)

请求并启用纳秒级硬件时间戳的 API。

参数

struct hte_ts_desc *desc

预分配和初始化的时间戳描述符。

hte_ts_cb_t cb

回调以将时间戳数据推送到消费者。

hte_ts_sec_cb_t tcb

可选回调。如果提供,子系统将初始化工作队列。当 cb 返回 HTE_RUN_SECOND_CB 时调用。

void *data

客户端数据,在 cb 和 tcb 回调期间使用。

描述

实体是提供程序特定的,例如,GPIO 线、信号、总线等。该 API 分配必要的资源并启用时间戳。

上下文

持有互斥锁。

返回值

成功时返回 0,失败时返回负错误代码。

int devm_hte_request_ts_ns(struct device *dev, struct hte_ts_desc *desc, hte_ts_cb_t cb, hte_ts_sec_cb_t tcb, void *data)

资源管理 API,用于请求并启用纳秒级硬件时间戳。

参数

struct device *dev

HTE 消费者/客户端设备。

struct hte_ts_desc *desc

预分配和初始化的时间戳描述符。

hte_ts_cb_t cb

回调以将时间戳数据推送到消费者。

hte_ts_sec_cb_t tcb

可选回调。如果提供,子系统将初始化工作队列。当 cb 返回 HTE_RUN_SECOND_CB 时调用。

void *data

客户端数据,在 cb 和 tcb 回调期间使用。

描述

实体是提供程序特定的,例如,GPIO 线、信号、总线等。该 API 分配必要的资源并启用时间戳。当消费者退出时,它会自动释放和禁用资源。

上下文

持有互斥锁。

返回值

成功时返回 0,失败时返回负错误代码。

int hte_init_line_attr(struct hte_ts_desc *desc, u32 line_id, unsigned long edge_flags, const char *name, void *data)

初始化线路属性。

参数

struct hte_ts_desc *desc

预分配的时间戳描述符。

u32 line_id

线路 ID。

unsigned long edge_flags

与 line_id 相关的边沿标志。

const char *name

线路名称。

void *data

与 line_id 相关的线路数据。

描述

清除线路属性并使用提供的参数进行初始化。在调用任何面向消费者的函数之前,需要调用该函数。

上下文

任何。

返回值

成功时返回 0,失败时返回负错误代码。

int hte_get_clk_src_info(const struct hte_ts_desc *desc, struct hte_clk_info *ci)

获取时间戳描述符的时钟源信息。

参数

const struct hte_ts_desc *desc

时间戳描述符,与请求 API 返回的相同。

struct hte_clk_info *ci

API 使用时钟信息数据填充此结构。

上下文

任何上下文。

返回值

成功时返回 0,失败时返回负错误代码。

HTE 框架公共结构

enum hte_edge

HTE 线路边沿标志。

常量

HTE_EDGE_NO_SETUP

无边沿设置。在这种情况下,消费者将设置边沿,例如在请求 irq 调用期间。

HTE_RISING_EDGE_TS

上升沿。

HTE_FALLING_EDGE_TS

下降沿。

enum hte_return

在回调期间使用的 HTE 子系统返回值。

常量

HTE_CB_HANDLED

消费者处理了数据。

HTE_RUN_SECOND_CB

消费者需要进一步处理,在这种情况下,HTE 子系统调用消费者提供的辅助回调,允许在其中睡眠。

struct hte_ts_data

HTE 时间戳数据。

定义:

struct hte_ts_data {
    u64 tsc;
    u64 seq;
    int raw_level;
};

成员

tsc

时间戳值。

seq

时间戳的序列计数器。

raw_level

如果提供程序支持,则在时间戳处的线路电平,否则为 -1。

struct hte_clk_info

HTE 提供者用于时间戳的时钟源信息。

定义:

struct hte_clk_info {
    u64 hz;
    clockid_t type;
};

成员

hz

支持的时钟频率,单位为赫兹 (HZ),例如 1KHz 时钟 = 1000。

type

支持的时钟类型。

hte_ts_cb_t

Typedef:HTE 时间戳数据处理的主要回调函数。

语法

enum hte_return hte_ts_cb_t (struct hte_ts_data *ts, void *data)

参数

struct hte_ts_data *ts

硬件时间戳数据。

void *data

客户端提供的数据。

描述

此回调函数用于将时间戳数据推送给客户端,不允许睡眠。

hte_ts_sec_cb_t

Typedef:HTE 时间戳数据处理的次要回调函数。

语法

enum hte_return hte_ts_sec_cb_t (void *data)

参数

void *data

客户端提供的数据。

描述

当客户端需要进一步处理并且允许睡眠时使用此回调函数。

struct hte_line_attr

线路属性。

定义:

struct hte_line_attr {
    u32 line_id;
    void *line_data;
    unsigned long edge_flags;
    const char *name;
};

成员

line_id

消费者和提供者都理解的逻辑 ID。

line_data

与 line_id 相关的线路数据。

edge_flags

边沿设置标志。

name

被监控以进行硬件时间戳的实体的描述性名称。 如果为空,HTE 核心将构造名称。

struct hte_ts_desc

HTE 时间戳描述符。

定义:

struct hte_ts_desc {
    struct hte_line_attr attr;
    void *hte_data;
};

成员

attr

线路属性。

hte_data

子系统的私有数据,由 HTE 子系统设置。

描述

此结构是消费者与子系统以及子系统与提供者之间的通信令牌。

struct hte_ops

由提供者设置的 HTE 操作集。

定义:

struct hte_ops {
    int (*request)(struct hte_chip *chip, struct hte_ts_desc *desc, u32 xlated_id);
    int (*release)(struct hte_chip *chip, struct hte_ts_desc *desc, u32 xlated_id);
    int (*enable)(struct hte_chip *chip, u32 xlated_id);
    int (*disable)(struct hte_chip *chip, u32 xlated_id);
    int (*get_clk_src_info)(struct hte_chip *chip, struct hte_clk_info *ci);
};

成员

request

用于请求 HTE 时间戳的钩子。 成功时返回 0,失败时返回非零值。

release

用于释放 HTE 时间戳的钩子。 成功时返回 0,失败时返回非零值。

enable

用于启用指定时间戳的钩子。 成功时返回 0,失败时返回非零值。

disable

用于禁用指定时间戳的钩子。 成功时返回 0,失败时返回非零值。

get_clk_src_info

用于获取提供者用于时间戳的时钟信息的钩子。 成功时返回 0,失败时返回负错误代码。 成功后,HTE 子系统将填充提供的 struct hte_clk_info

描述

xlated_id 参数用于 HTE 子系统和提供者之间的通信,并由提供者翻译。

struct hte_chip

抽象 HTE 芯片。

定义:

struct hte_chip {
    const char *name;
    struct device *dev;
    const struct hte_ops *ops;
    u32 nlines;
    int (*xlate_of)(struct hte_chip *gc,const struct of_phandle_args *args, struct hte_ts_desc *desc, u32 *xlated_id);
    int (*xlate_plat)(struct hte_chip *gc, struct hte_ts_desc *desc, u32 *xlated_id);
    bool (*match_from_linedata)(const struct hte_chip *chip, const struct hte_ts_desc *hdesc);
    u8 of_hte_n_cells;
    struct hte_device *gdev;
    void *data;
};

成员

name

HTE IP 块的功能名称。

dev

提供 HTE 的设备。

ops

此 HTE 的回调函数。

nlines

此芯片支持的线路/信号数量。

xlate_of

回调函数,用于将消费者提供的逻辑 ID 转换为物理 ID,成功时返回 0,失败时返回负值。 成功时,它将(0 到 nlines 之间)存储在 xlated_id 参数中。

xlate_plat

与上述相同,但适用于没有 DT 节点的消费者。

match_from_linedata

使用 line_data 匹配 HTE 设备。

of_hte_n_cells

用于形成 HTE 说明符的单元格数。

gdev

HTE 子系统抽象设备,HTE 子系统内部使用。

data

芯片特定的私有数据。

关于 HTE 时间戳数据的更多信息

struct hte_ts_data 用于在消费者和提供者之间传递时间戳详细信息。它以 u64 纳秒为单位表示时间戳数据。例如,GPIO 线路的典型时间戳数据生命周期如下:

- Monitors GPIO line change.
- Detects the state change on GPIO line.
- Converts timestamps in nanoseconds.
- Stores GPIO raw level in raw_level variable if the provider has that
hardware capability.
- Pushes this hte_ts_data object to HTE subsystem.
- HTE subsystem increments seq counter and invokes consumer provided callback.
Based on callback return value, the HTE core invokes secondary callback in
the thread context.

HTE 子系统 debugfs 属性

HTE 子系统在 /sys/kernel/debug/hte/ 创建 debugfs 属性。 它还在 /sys/kernel/debug/hte/<provider>/<label or line id>/ 创建与线路/信号相关的 debugfs 属性。 请注意,这些属性是只读的。

ts_requested

从给定提供者请求的实体总数,其中实体由提供者指定,并且可以代表线路、GPIO、芯片信号、总线等。该属性将在 /sys/kernel/debug/hte/<provider>/ 中可用。

total_ts

提供者支持的实体总数。 该属性将在 /sys/kernel/debug/hte/<provider>/ 中可用。

dropped_timestamps

给定线路的丢弃的时间戳。 该属性将在 /sys/kernel/debug/hte/<provider>/<label or line id>/ 中可用。