Using STM32F7 On-Chip RTC in Linux Print


This application note explains how to use the STM32F7 on-chip Real Time Clock (RTC) in Linux.

All software tests documented below were performed on the Emcraft STM32F7 System-On-Module (SOM), plugged into a special development baseboard referred to as the "TWR-SOM-BSB baseboard". That baseboard provides a battery holder for a coin battery providing back-up power for the STM32F7 RTC. Note that the TWR-SOM-BSB is a special baseboard developed by Emcraft in a certain project and differs from the SOM-BSB-EXT baseboard included with the STM32F7 SOM Starter Kit. Use the TWR-SOM-BSB schematics to understand the hardware connections between the SOM RTC interface and the battery holder on the baseboard.

Note: Earlier builds of the STM32F7 SOM have the C10 and C11 capacitors not installed. This affects functionality of the RTC clock. To ensure correct operation of the RTC clock, please install 16 pF capacitors to C10 and C11.

The RTC device driver is linux/drivers/rtc/rtc-stm32.c. The RTC support is controlled by the CONFIG_RTC_DRV_STM32F2 build time option in the kernel configuration. In the kernel configuration GUI (make kmenuconfig from the project directory) this is: Device Drivers -> Real Time Clock -> STM32F2 On-Chip RTC:

User-space interface to the RTC using the Linux proc and sysfs interfaces is enabled by the following menu in the kernel configuration GUI:

For the sake of completeness, here is a full list of the relevant kernel configuration options enabled in the Linux project used by the tests shown below in this application note:

CONFIG_RTC_LIB=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_HCTOSYS=y
CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
CONFIG_RTC_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_STM32=y

For the run-time configuration of the kernel, RTC should be enabled in rootfs.dts.STM32F7 in projects/rootfs as follows:

/*
* Real time clock
*/
&rtc {
status = "okay";
};

There must be a device node (/dev/rtc0) in the target root file system for the RTC to allow accessing it using standard Linux interfaces. In the rootfs project, this device node is created automatically.

The hwclock Linux utility is typically used to control an RTC from an interactive shell or a shell script. hwclock is available as part of the multi-call busybox utility and is already enabled in the rootfs project using the following options:

CONFIG_HWCLOCK=y
CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS=y

Here is where these options are defined in the busybox configuration GUI (make bmenuconfig from the project directory). Proceed to Linux System Utilities.

When you boot the Linux image on the target, there will be the following message in the kernel bootstrap print-out indicating that the RTC driver is available and has registered a platform device for the on-chip RTC:

...
stm32-rtc 40002800.rtc: rtc core: registered 40002800.rtc as rtc0
...

Here is what you should be able to do with the RTC on the target.

First thing to do is to set the system time and date to the right values. The most obvious way to do that is use the date command, for instance:

~ # date -s "2016-09-19 14:40:00"
Mon Sep 19 14:40:00 UTC 2016
~ #

Another possibility is to use the Internet connectivity (which assumes a configuration with an Ethernet link and TCP/IP stack enabled) in order to get the current time and date from a public Internet server. Refer to Running TCP/IP stack in Linux for information on how to do that.

It is important to understand that the system time is maintained using the STM32F7 TIM Timer, which resets itself on each power / reset cycle. It is therefore important to write the system time into the RTC. This is done as follows:

~ # hwclock -w
~ #

Let's read the RTC and the system time back and make sure that they both show the correct time and date:

~ # hwclock; date
Mon Sep 19 14:43:00 UTC 2016 0.000000 seconds
Mon Sep 19 14:43:00 UTC 2016
~ #

Now the RTC has the right time and date and is running so even if we disconnect the main power from the STM32F7, we will still maintain the time in the RTC, as long as the RTC is powered from a battery or similar. To test that, disconnect the main power from the STM32F7 SOM kit for several minutes and then power the kit up again.

As Linux boots up, the RTC device driver copies the up-to-date time and date in the RTC to the system time. This is reflected as follows in the kernel boot messages:

...
stm32-rtc 40002800.rtc: setting system clock to 2016-09-19 14:43:09 UTC (1463496189)
...

Let's validate that the system clock matches the RTC clock and they both match the wall clock:

~ # hwclock; date
Mon Sep 19 14:43:20 UTC 2016 0.000000 seconds
Mon Sep 19 14:43:20 UTC 2016
~ #