Calendar API for Zephyr RTOS.
-
Ability to set and receive calendar time through a generic API where the backend is hidden from the user level. If a battery backed RTC is used, the calendar time will be retained through power cycles.
-
Supports access from user threads via system calls so it operates the same with or without
CONFIG_USERSPACE=y
- STM32 RTC
- Maxim DS3231
- Micro Crystal RV8263, RV3032
zcalendar is fully compatible with the west build system, and is designed to be easily integrated into any Zephyr project through the project's west manifest. It is configured through the project conf file, and depending on the backend, it may also need to be configured with the device tree.
Enable with
CONFIG_CALENDAR=y
Enable the desired backend such as
CONFIG_STM32_RTC_CALENDAR=y
Refer to the Kconfig files to learn about optional configurations which can be used as well.
Some backends need specific device tree configurations. This is something I would like to address in the future to make configuration clearer, but for now examples for configuration of each backend are included.
The Maxim DS3231 backend leverages the existing driver implementation in the counter API. In this case, you must select the appropriate device in the device tree for zcal to use internally. This can be done using the included device tree bindings
&i2c0 {
calendar_rtc: ds3231@68 {
compatible = "maxim,ds3231";
reg = <0x68>;
label = "DS3231";
isw-gpios = <&gpio0 0 (GPIO_PULL_UP | GPIO_ACTIVE_LOW)>;
};
};
/ {
calendar{
compatible = "calendar";
label = "CALENDAR";
rtc = <&calendar_rtc>;
};
};
Or by using a chosen node
/ {
chosen{
zcal,rtc = &calendar_rtc;
}
}
The Micro Crystal RV is independent of all zephyr drivers and APIs, and so includes its own device tree binding.
&i2c0 {
calendar_rtc: rv@51 {
compatible = "microcrystal,rv-calendar";
reg = <0x51>;
label = "RV8263";
};
};
The STM32 implementation is independent of the counter API and does not rely on other devices like i2c, so it does not need any device tree configuration.
Here is an example west manifest file. Modify according to your project needs
manifest:
remotes:
- name: zephyrproject-rtos
url-base: https://github.com/zephyrproject-rtos
- name: zcal
url-base: https://github.com/bpbradley
projects:
- name: zephyr
remote: zephyrproject-rtos
revision: main
import:
path-prefix: rtos
- name: zcalendar
remote: zcal
revision: zephyr-v2.7.3
path: modules/zcalendar
self:
path: app
Here is everthing needed for basic usage of the calendar API with the Micro Crystal RV8263 backend
CONFIG_CALENDAR=y
CONFIG_RV8263_RTC_CALENDAR=y
&i2c0 {
calendar_rtc: rv@51 {
compatible = "microcrystal,rv-calendar";
reg = <0x51>;
label = "RV8263";
};
};
#include <zephyr.h>
#include <zcal/calendar.h>
int main(){
/* Get the device handle */
const struct device * calendar = \
device_get_binding(DT_LABEL(DT_NODELABEL(calendar_rtc)));
if (calendar){
/* Set the calendar time by epoch */
struct tm * time;
const time_t epoch = 1669843527;
time = gmtime(&epoch);
calendar_settime(calendar, time);
/* Wait */
k_sleep(K_SECONDS(5));
/* Check the calendar time */
int rc = calendar_gettime(calendar, time);
/* Convert the time to a human readable string */
if (!rc){
char timestr[120] = {0};
strftime(timestr,120,
"%A %B %d %Y %H:%M:%S", time);
printk("%s", timestr);
}
}
return 0;
}
If the application is configured in User Mode, where the api must interact with the kernel only via system calls, there will be additional configuration required since from from zephyrs perspective, the application is trying to make system calls.
In this case, the following configuration is needed
CONFIG_APPLICATION_DEFINED_SYSCALL=y
and the SYSCALL_INCLUDE_DIRS
environment variable needs to include
the path to zcalendar. This can be done in CMakeLists.txt
like so, before the boilerplate is loaded
list (APPEND SYSCALL_INCLUDE_DIRS
path/to/zcalendar
)