mirror of
https://github.com/espressif/esp-idf.git
synced 2026-08-18 06:35:35 +03:00
feat(esp_libc): refactored POSIX timers get/set functions
- Added sys/timex.h and clock_adjtime API
This commit is contained in:
60
components/esp_libc/platform_include/esp_libc_clock.h
Normal file
60
components/esp_libc/platform_include/esp_libc_clock.h
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "sdkconfig.h"
|
||||
#include <time.h>
|
||||
#include <sys/timex.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief Operations for a clock source
|
||||
*
|
||||
* Callbacks return 0 on success, -1 on error (with errno set).
|
||||
*/
|
||||
typedef struct {
|
||||
int (*gettime)(struct timespec *tp, void *ctx); /*!< Get current time (required) */
|
||||
int (*settime)(const struct timespec *tp, void *ctx); /*!< Set current time (optional, may be NULL) */
|
||||
int (*adjtime)(struct timex *buf, void *ctx); /*!< Adjust clock via struct timex (optional, may be NULL) */
|
||||
int (*getres)(struct timespec *res, void *ctx); /*!< Get clock resolution (required) */
|
||||
} esp_libc_clock_ops_t;
|
||||
|
||||
/**
|
||||
* @brief Link-time clock descriptor (placed in .esp_libc_clock_desc)
|
||||
*/
|
||||
typedef struct {
|
||||
clockid_t clk_id;
|
||||
esp_libc_clock_ops_t ops;
|
||||
void *ctx;
|
||||
} esp_libc_clock_desc_t;
|
||||
|
||||
/**
|
||||
* @brief Register a clock at link time
|
||||
*
|
||||
* Place this macro at file scope after defining the clock operation functions.
|
||||
* The linker collects all descriptors into a contiguous array; clock_gettime(),
|
||||
* clock_settime(), clock_getres(), and clock_adjtime() dispatch by clock ID.
|
||||
*
|
||||
* @note The entity registering the clock is responsible for ensuring the
|
||||
* clock operations functions are thread safe.
|
||||
*
|
||||
* @param name_token Unique C identifier token for the static descriptor symbol
|
||||
* @param clk_id_val Clock ID (e.g. CLOCK_REALTIME or a custom clockid_t)
|
||||
* @param ops_symbol lvalue of type esp_libc_clock_ops_t (e.g. s_my_ops)
|
||||
* @param ctx_val Context pointer passed to callbacks (may be NULL)
|
||||
*/
|
||||
#define ESP_LIBC_CLOCK_REGISTER(name_token, clk_id_val, ops_symbol, ctx_val) \
|
||||
static const esp_libc_clock_desc_t _esp_libc_clock_desc_##name_token \
|
||||
__attribute__((used, section(".esp_libc_clock_desc"))) = { \
|
||||
.clk_id = (clk_id_val), .ops = (ops_symbol), .ctx = (ctx_val) }
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
62
components/esp_libc/platform_include/sys/timex.h
Normal file
62
components/esp_libc/platform_include/sys/timex.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Minimal subset of <sys/timex.h> for clock_adjtime() support.
|
||||
* Original struct timex and ADJ_* constants by David L. Mills (1993).
|
||||
*
|
||||
* Only the modes, offset, and freq fields are implemented.
|
||||
* freq uses ppb (parts per billion) units instead of Linux's scaled ppm.
|
||||
*/
|
||||
|
||||
#define ADJ_OFFSET 0x0001 /* time offset; microseconds by default, nanoseconds with ADJ_NANO */
|
||||
#define ADJ_FREQUENCY 0x0002 /* frequency offset in ppb (parts per billion) */
|
||||
#define ADJ_MICRO 0x1000 /* select microsecond resolution */
|
||||
#define ADJ_NANO 0x2000 /* select nanosecond resolution */
|
||||
#define ADJ_OFFSET_SINGLESHOT 0x8001 /* old-fashioned adjtime (offset in microseconds)*/
|
||||
#define ADJ_OFFSET_SS_READ 0xa001 /* read-only adjtime (remaining offset in microseconds) */
|
||||
|
||||
struct timex {
|
||||
int modes; /*!< Mode selector (ADJ_OFFSET, ADJ_FREQUENCY, etc.) */
|
||||
long offset; /*!< Time offset: microseconds by default, nanoseconds when ADJ_NANO is set */
|
||||
long freq; /*!< Frequency offset in ppb (parts per billion) */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Adjust a clock identified by clk_id
|
||||
*
|
||||
* Uses struct timex.modes to select which fields to apply:
|
||||
* - ADJ_OFFSET: gradually slew by buf->offset
|
||||
* - ADJ_FREQUENCY: set frequency trim to buf->freq ppb
|
||||
* - ADJ_OFFSET_SINGLESHOT: old-style adjtime(), buf->offset
|
||||
* - ADJ_OFFSET_SS_READ: read remaining adjtime() correction into buf->offset
|
||||
*
|
||||
* buf->offset uses microseconds by default. Set ADJ_NANO in modes to use
|
||||
* nanoseconds instead. ADJ_MICRO may be used to explicitly select the default.
|
||||
*
|
||||
* ADJ_OFFSET and ADJ_FREQUENCY are mutually exclusive; do not OR them together.
|
||||
*
|
||||
* @param clk_id Clock identifier (CLOCK_REALTIME, or a custom registered clock)
|
||||
* @param buf Pointer to struct timex with modes and values to apply.
|
||||
* On return, buf->offset may be updated (e.g. ADJ_OFFSET_SS_READ).
|
||||
*
|
||||
* @return
|
||||
* - 0: Success
|
||||
* - -1: Failure (errno is set)
|
||||
*/
|
||||
int clock_adjtime(clockid_t clk_id, struct timex *buf);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
Reference in New Issue
Block a user