Skip to content

sys: realtime: Add native real-time library and API #72173

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
1 change: 1 addition & 0 deletions drivers/rtc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ zephyr_library_sources_ifdef(CONFIG_RTC_SMARTBOND rtc_smartbond.c)
zephyr_library_sources_ifdef(CONFIG_RTC_ATMEL_SAM rtc_sam.c)
zephyr_library_sources_ifdef(CONFIG_RTC_RPI_PICO rtc_rpi_pico.c)
zephyr_library_sources_ifdef(CONFIG_RTC_NUMAKER rtc_numaker.c)
zephyr_library_sources_ifdef(CONFIG_RTC_HWCLOCK rtc_hwclock.c)
1 change: 1 addition & 0 deletions drivers/rtc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -53,5 +53,6 @@ source "drivers/rtc/Kconfig.sam"
source "drivers/rtc/Kconfig.smartbond"
source "drivers/rtc/Kconfig.stm32"
source "drivers/rtc/Kconfig.numaker"
source "drivers/rtc/Kconfig.hwclock"

endif # RTC
25 changes: 25 additions & 0 deletions drivers/rtc/Kconfig.hwclock
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (c) 2024 Bjarki Arge Andreasen
# SPDX-License-Identifier: Apache-2.0

DT_CHOSEN_RTC := zephyr,rtc

config RTC_HWCLOCK
bool "Hardware clock"
default y
depends on $(dt_chosen_enabled,$(DT_CHOSEN_RTC))
depends on SYS_REALTIME
help
The hardware clock is used to set the system
real-time clock on boot.

if RTC_HWCLOCK

config RTC_HWCLOCK_INIT_PRIORITY
int "Initialization priority of hardware clock"
default 51
help
The initialization priority of the hardware clock
must be higher than the initialization priority of
the chosen RTC device driver.

endif # RTC_HWCLOCK
44 changes: 44 additions & 0 deletions drivers/rtc/rtc_hwclock.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2024 Bjarki Arge Andreasen
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/init.h>
#include <zephyr/drivers/rtc.h>
#include <zephyr/sys/realtime.h>

BUILD_ASSERT(
CONFIG_RTC_HWCLOCK_INIT_PRIORITY > CONFIG_RTC_INIT_PRIORITY,
"Hardware clock init prio must be higher than the RTC device driver"
);

static const struct device *rtc = DEVICE_DT_GET(DT_CHOSEN(zephyr_rtc));

static const struct sys_datetime *rtc_time_to_sys_datetime(const struct rtc_time *timeptr)
{
return (const struct sys_datetime *)timeptr;
}

static int rtc_hwclock_init(void)
{
int ret;
struct rtc_time rtctime;
const struct sys_datetime *datetime;

if (!device_is_ready(rtc)) {
return -ENODEV;
}

ret = rtc_get_time(rtc, &rtctime);
if (ret == -ENODATA) {
return 0;
} else if (ret < 0) {
return ret;
}

datetime = rtc_time_to_sys_datetime(&rtctime);
return sys_realtime_set_datetime(datetime);
}

SYS_INIT(rtc_hwclock_init, POST_KERNEL, CONFIG_RTC_HWCLOCK_INIT_PRIORITY);
58 changes: 53 additions & 5 deletions drivers/rtc/rtc_shell.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <zephyr/kernel.h>
#include <zephyr/shell/shell.h>
#include <zephyr/drivers/rtc.h>
#include <zephyr/sys/realtime.h>
#include <time.h>
#include <stdlib.h>

Expand Down Expand Up @@ -227,6 +228,43 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry)
entry->subcmd = NULL;
}

#if CONFIG_SYS_REALTIME
static int cmd_sync(const struct shell *sh, size_t argc, char **argv)
{
const struct device *dev = device_get_binding(argv[1]);

if (!device_is_ready(dev)) {
shell_error(sh, "device %s not %s", argv[1], "ready");
return -ENODEV;
}

ARG_UNUSED(argc);
ARG_UNUSED(argv);

struct rtc_time rtctime;

int res = rtc_get_time(dev, &rtctime);

if (res == -ENODATA) {
shell_error(sh, "device %s not %s", argv[1], "set");
return 0;
}
if (res < 0) {
return res;
}

struct sys_datetime *datetime = (struct sys_datetime *)(&rtctime);

res = sys_realtime_set_datetime(datetime);

if (res < 0) {
shell_error(sh, "failed to set system realtime from %s", argv[1]);
}

return res;
}
#endif /* CONFIG_SYS_REALTIME */

#define RTC_GET_HELP \
("Get current time (UTC)\n" \
"Usage: rtc get <device>")
Expand All @@ -235,12 +273,22 @@ static void device_name_get(size_t idx, struct shell_static_entry *entry)
("Set UTC time\n" \
"Usage: rtc set <device> <YYYY-MM-DDThh:mm:ss> | <YYYY-MM-DD> | <hh:mm:ss>")

#if CONFIG_SYS_REALTIME
#define RTC_SYNC_HELP \
("Set system realtime from RTC time\n" \
"Usage: rtc sync <device>")
#endif /* CONFIG_SYS_REALTIME */

SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);

SHELL_STATIC_SUBCMD_SET_CREATE(sub_rtc,
/* Alphabetically sorted */
SHELL_CMD_ARG(set, &dsub_device_name, RTC_SET_HELP, cmd_set, 3, 0),
SHELL_CMD_ARG(get, &dsub_device_name, RTC_GET_HELP, cmd_get, 2, 0),
SHELL_SUBCMD_SET_END);
SHELL_STATIC_SUBCMD_SET_CREATE(
sub_rtc,
SHELL_CMD_ARG(set, &dsub_device_name, RTC_SET_HELP, cmd_set, 3, 0),
SHELL_CMD_ARG(get, &dsub_device_name, RTC_GET_HELP, cmd_get, 2, 0),
#if CONFIG_SYS_REALTIME
SHELL_CMD_ARG(sync, &dsub_device_name, RTC_SYNC_HELP, cmd_sync, 2, 0),
#endif /* CONFIG_SYS_REALTIME */
SHELL_SUBCMD_SET_END
);

SHELL_CMD_REGISTER(rtc, &sub_rtc, "RTC commands", NULL);
19 changes: 19 additions & 0 deletions include/zephyr/sys/internal/realtime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/*
* Copyright (c) 2024 Bjarki Arge Andreasen
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_SYS_INTERNAL_REALTIME_H_
#define ZEPHYR_INCLUDE_SYS_INTERNAL_REALTIME_H_

#include <zephyr/kernel.h>
#include <zephyr/sys/realtime.h>

/** Validate timestamp */
bool sys_realtime_validate_timestamp(const int64_t *timestamp_ms);

/** Validate datetime */
bool sys_realtime_validate_datetime(const struct sys_datetime *datetime);

#endif /* ZEPHYR_INCLUDE_SYS_INTERNAL_REALTIME_H_ */
42 changes: 42 additions & 0 deletions include/zephyr/sys/realtime.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2024 Bjarki Arge Andreasen
*
* SPDX-License-Identifier: Apache-2.0
*/

#ifndef ZEPHYR_INCLUDE_SYS_REALTIME_H_
#define ZEPHYR_INCLUDE_SYS_REALTIME_H_

#include <zephyr/kernel.h>

struct sys_datetime {
int tm_sec; /**< Seconds [0, 59] */
int tm_min; /**< Minutes [0, 59] */
int tm_hour; /**< Hours [0, 23] */
int tm_mday; /**< Day of the month [1, 31] */
int tm_mon; /**< Month [0, 11] */
int tm_year; /**< Year - 1900 */
int tm_wday; /**< Day of the week [0, 6] (Sunday = 0) (Unknown = -1) */
int tm_yday; /**< Day of the year [0, 365] (Unknown = -1) */
int tm_isdst; /**< Daylight saving time flag [-1] (Unknown = -1) */
int tm_nsec; /**< Nanoseconds [0, 999999999] (Unknown = 0) */
};

/** Get universal coordinated time unix timestamp in milliseconds */
__syscall int sys_realtime_get_timestamp(int64_t *timestamp_ms);
/** Set universal coordinated time unix timestamp in milliseconds */
__syscall int sys_realtime_set_timestamp(const int64_t *timestamp_ms);

/** Get universal coordinated time datetime */
__syscall int sys_realtime_get_datetime(struct sys_datetime *datetime);
/** Set universal coordinated time datetime */
__syscall int sys_realtime_set_datetime(const struct sys_datetime *datetime);

/** Convert universal coordinated time datetime to unix timestamp in milliseconds */
int sys_realtime_datetime_to_timestamp(int64_t *timestamp_ms, const struct sys_datetime *datetime);
/** Convert universal coordinated time unix timestamp in milliseconds to datetime */
int sys_realtime_timestamp_to_datetime(struct sys_datetime *datetime, const int64_t *timestamp_ms);

#include <zephyr/syscalls/realtime.h>

#endif /* ZEPHYR_INCLUDE_SYS_REALTIME_H_ */
1 change: 1 addition & 0 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ add_subdirectory(heap)
add_subdirectory(mem_blocks)
add_subdirectory(os)
add_subdirectory(utils)
add_subdirectory(realtime)
add_subdirectory_ifdef(CONFIG_SMF smf)
add_subdirectory_ifdef(CONFIG_OPENAMP open-amp)
add_subdirectory_ifdef(CONFIG_ACPI acpi)
3 changes: 3 additions & 0 deletions lib/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ source "lib/acpi/Kconfig"
source "lib/runtime/Kconfig"

source "lib/utils/Kconfig"

source "lib/realtime/Kconfig"

endmenu
4 changes: 0 additions & 4 deletions lib/posix/options/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,6 @@

set(GEN_DIR ${ZEPHYR_BINARY_DIR}/include/generated)

zephyr_syscall_header(
posix_clock.h
)

if(CONFIG_POSIX_API)
zephyr_include_directories(${ZEPHYR_BASE}/include/zephyr/posix)
endif()
Expand Down
1 change: 1 addition & 0 deletions lib/posix/options/Kconfig.timer
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

menuconfig POSIX_TIMERS
bool "POSIX timers, clocks, and sleep functions"
select SYS_REALTIME
help
Select 'y' here and Zephyr will provide implementations of clock_getres(), clock_gettime(),
clock_settime(), nanosleep(), timer_create(), timer_delete(), timer_getoverrun(),
Expand Down
Loading
Loading