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 STM32F4 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.
Additionally, if you are using Release 1.14.2 (or older) of the STM32F7 SOM BSP, apply the following patch linux-stm32f7-rtc.patch to the Linux kernel, as follows:

$ cd linux-cortexm-1.14.2/linux
$ patch -p1 < linux-stm32f7-rtc.patch

The RTC device driver is linux/drivers/rtc/rtc-stm32f2.c. To enable the RTC support in the kernel, you must enable the CONFIG_RTC_DRV_STM32F2 build time option in the kernel configuration. To do so, start the kernel configuration GUI (make kmenuconfig from the project directory) and proceed to enable the following items: Device Drivers -> Real Time Clock -> STM32F2 On-Chip RTC:

Once you have enabled CONFIG_RTC_DRV_STM32F2, go to System Type -> STM32 I/O interfaces and enable STM32 RTC (CONFIG_STM32_RTC). This will register a platform device for the STM32F4 RTC with the RTC driver:

If you would like to access the RTC using the standard Linux proc and sysfs interfaces, you need to enable the corresponding configuration options in the same menu:

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_INTF_SYSFS=y
CONFIG_RTC_INTF_PROC=y
CONFIG_RTC_INTF_DEV=y
CONFIG_RTC_DRV_STM32F2=y
CONFIG_STM32_RTC=y

There must be a device node in the target root file system for the RTC to allow accessing it using standard Linux interfaces. Add the following line into your <project>.initramfs file to create a device node for the RTC:

nod /dev/rtc0 0600 0 0 c 254 0

The hwclock Linux utility is typically used to control an RTC from an interactive shell or a shell script. In uClinux, hwclock is available as part of the multi-call busybox utility. To enable hwclock in busybox, run the busybox configuration GUI (make bmenuconfig from the project directory) and proceed to enable the following options:

CONFIG_HWCLOCK=y
CONFIG_FEATURE_HWCLOCK_ADJTIME_FHS=y

To do so, go to Linux System Utilities and enable the two items related to hwclock:

Also, you will need to add a symlink for hwlcock to the target file system. This is done by adding the following line to the <project>.initramfs file:

slink /bin/hwclock busybox 777 0 0

Having updated your project configuration as described above, build the bootable Linux image (<project>.uImage) by running make in the project directory.

The procedure described here explains how to install Linux image (uImage) to the target.

When you boot the newly installed 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:

...
rtc-stm32f2 rtc-stm32f2: rtc core: registered rtc-stm32f2 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 "2015-02-17 18:53:00"
Tue Feb 17 18:53:00 UTC 2015
~ #

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
Tue Feb 17 18:53:08 2015 0.000000 seconds
Tue Feb 17 18:53:09 UTC 2015
~ #

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:

...
rtc-stm32f2 rtc-stm32f2: setting system clock to 2015-02-17 18:54:37 UTC (1411066477)
...

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

~ # hwclock; date
Tue Feb 17 18:54:58 2015 0.000000 seconds
Tue Feb 17 18:54:57 UTC 2015
~ #