The Real Time Clock (RTC) serves two real purposes: keep accurate time/date information and provide wake up alarms (both during runtime and while sleeping).
Since the RTC is externally powered and clocked independent of the processor, it can remain running even when the rest of the system is turned off. This way the clock continues to keep accurate information and it can be used to wake up the processor from power savings modes (such as hibernate or standby).
This document highlights most of the issues that software developers need to be concerned with. It is not intended to be a replacement for the HRM, so if you are working heavily on the RTC, please consult that primarily.
Normally, RTC precision is a requirement in most embedded applications, but due to the external environment – temperature change, frequency variation of the crystal that clocks the RTC – the RTC precision may not be as accurate as expected. While Quartz oscillators provide an accuracy far superior to that of other conventional oscillator designs, they are not perfect. Very low cost crystals may cause the RTC to drift by several minutes each day. To maintain a more accurate timebase (if necessary), you should check out Network Time protocol.
There is no “year” field as it is up to the host software to represent the stored time according to its own native format and timezone rules. The “days” field has a granularity of 2^15 days which should provide for a life time of ~90 years.
The figure below provides a block diagram of the RTC as updated externally. The external crystal clocks in at 32.768kHz which is normalized by the prescaler counter into a 1 Hz tick. This cascades down into the seconds/minutes/hours/days counters (according to normal time rules obviously), triggering any enabled events as are enabled by the RTC configuration registers.
The figure below provides a block diagram which shows how reads and writes of RTC registers are handled. Since the registers are externally powered, there is a transition domain to keep the on-chip System RTC MMRs in sync with the registers in the RTC peripheral. The biggest issue to keep in mind is that writes are synced once per tick (the frequency of which is determined by the prescale bit), and that successive writes to the same register inbetween syncs are discarded (you can write to multiple registers simultaneously).
The Blackfin RTC driver can be found in the kernel configuration menu under the RTC framework.
Device Drivers ---> <*> Real Time Clock ---> --- Real Time Clock [*] Set system time from RTC on startup and resume (rtc0) RTC used to set the system time --- RTC interfaces [*] /sys/class/rtc/rtcN (sysfs) [*] /proc/driver/rtc (procfs for rtc0) [*] /dev/rtcN (character devices) --- on-CPU RTC drivers <*> Blackfin On-Chip RTC
You need not enable the
Set system time from RTC on startup and resume option, but many people find it much more convenient to automatically sync the RTC hwclock to the Linux system clock before executing userspace (and by executing hwclock in userspace).
You may also disable any RTC interfaces that your system does not need. Often times that means you can disable the proc interface. The sysfs and dev interfaces tend to be used by userspace applications for interacting with the RTC directly. Feel free to review your setup to see what may actually be utilized.
Since Linux provides a nice extensible common RTC framework for integrating a diverse set of RTC devices, there should be no need for end users to actually dive into the driver. For the curious, the code should be sufficiently documented for you to find your way around. It is stored at linux-2.6.x/drivers/rtc/rtc-bfin.c.
There should also be no in-kernel consumers of direct RTC devices, so let's just move on to userspace.
If you are creating your own board port, make sure to include the simplistic platform resources for the on-chip RTC. Otherwise, your system may not actually load the RTC platform driver.
The RTC framework exposes RTC devices as
/dev/rtc#. Since typically there is only one RTC on a Blackfin system, the
/dev/rtc0 device node should represent the on-chip device. If you have more than one RTC setup on your system, you will have to consult the kernel boot log to figure out what RTC is being configured as which device node.
In order to use the RTC, you need to open the device node using the standard filesystem functions. All operations (such as get the time, set an alarm, etc…) are performed using ioctl()'s. You can use the read() function to put your process to sleep while it waits for an operation that involves a delay to complete; e.g. setting an alarm and then waiting for it to go off.
For the exact ioctl API and a complete example application, consult the file linux-2.6.x/Documentation/rtc.txt.
Please note that the Blackfin RTC cannot support the IRQP function. This is because the Linux framework expects to be able to set the frequency to 2^N Hz while the fastest the Blackfin hardware supports is 1 Hz. No, the prescale bit cannot be sanely used to increase this frequency as it affects all of the time fields, not just the alarms.
Often times people will want to use the RTC to wake the process up from a power savings mode. The common steps to take are:
Since these are common operations, there is an applet that is part of busybox called
rtcwake that automates this process. Consult the rtcwake(8) man page for more information on how to use it.
Have a look at hwclock if you wish to keep the Linux system clock and the hardware (RTC) clock in sync.