Using Kinetis On-Chip RTC in Linux Print


This application note explains how to use the Kinetis on-chip Real Time Clock (RTC) in Linux. All software tests documented below were performed on the Emcraft Kinetis K70 SOM Starter Kit, with a battery installed into the battery holder of the TWR-K70-SOM-BSB baseboard.

The RTC device driver is linux/drivers/rtc/rtc-kinetis.c. To enable the RTC support in the kernel, you must enable the CONFIG_RTC_DRV_KINETIS 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 -> Kinetis On-Chip RTC:

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_KINETIS=y
CONFIG_RTC_DRV_KINETIS_HCTOSYS=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.

Install the newly built uImage file to the Flash on the target as described in Installing Linux Images to Flash or load it to RAM via Ethernet as described in Loading Linux Images via Ethernet and TFTP.

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 "2014-04-16 12:58:00"
Wed Apr 16 12:58:00 UTC 2014
~ #

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 Kinetis Periodic Interrupt Timer (PIT), 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
Wed Apr 16 12:59:26 2014 0.000000 seconds
Wed Apr 16 12:59:26 UTC 2014
~ #

Now the RTC has the right time and date and is running so even if we disconnect the main power from the Kinetis, 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 Kinetis SOM kit for at least 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-kinetis rtc-kinetis: System time set to RTC time (seconds): 1397653409
...

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

~ # hwclock; date
Wed Apr 16 13:04:07 2014 0.000000 seconds
Wed Apr 16 13:04:07 UTC 2014
~ #