Adding a hardware clock (RTC) to the Raspberry Pi

8 May 2013 — 20 Comments

The Raspberry Pi does not have a hardware clock on board. Instead, to keep track of time during reboots and downtime the ‘fake-hwclock’ package is used. It contains scripts to save the kernel’s current clock periodically (including at shutdown) and restore it at boot so that the system clock keeps at least close to realtime. Combined with NTP this is a simple, cheap and fairly accurate setup for most use-cases.

For a project at work I wanted to test a Raspberry Pi with a Real Time Clock (RTC) connected through the GPIO pins. This hardware clock needs to be very precise. I found the RasClock, by Afterthought Software, to be precise enough (about 3ppm or ~95 seconds deviation per year) while still affordable (about 15 euro).

Hardware installation

The hardware installation is simple. Just insert the battery and place the RasClock on the last 6 GPIO ports, at the end of the board. That’s it.

This is how the RasClock GPIO module looks like

This is how the RasClock GPIO module looks like

This is the RasClock with a battery backup installed

This is the RasClock with a battery backup installed

This is the RasClock installed on the Raspberry Pi, side view

This is the RasClock installed on the Raspberry Pi, side view

This is the RasClock installed on the Raspberry Pi, top view

This is the RasClock installed on the Raspberry Pi, top view

This is the RasClock installed on my two boxed Raspberry Pi's

This is the RasClock installed on two boxed Raspberry Pi’s

Looks pretty good!

Software installation

I recommend upgrading to the latest Raspbian version. At the time of writing Raspbian runs on kernel 3.6.11. By far the easiest way to upgrade firmware, is to use rpi-update.

Unfortunately the ‘rtc-pcf2127a’ module needed to operate the RasClock, is not in the default Linux kernel provided by Raspbian. Afterthought Software provides both a binary packages and source code for their forked raspberrypi/linux repository. They added an I2C driver for NXP/Philips PCF2127A device from Eckelmann AG.

To install the binary package:

wget http://afterthoughtsoftware.com/files/linux-image-3.6.11-atsw-rtc_1.0_armhf.deb
dpkg -i linux-image-3.6.11-atsw-rtc_1.0_armhf.deb
cp /boot/vmlinuz-3.6.11-atsw-rtc+ /boot/kernel.img

The binary package is nice and quick for testing. Installing from source allows you to only build the needed kernel module, instead of a complete kernel replacement.

In the comments of the Afterthought Software site, someone posted these steps. Thanks for sharing your work!

sudo apt-get -y install build-essential gcc make cmake i2c-tools
mkdir devel
cd devel
wget https://github.com/raspberrypi/linux/archive/rpi-3.6.y.tar.gz
wget https://github.com/afterthoughtsoftware/linux/commit/fd5ff2d88f470ed70ff58393eee61110b181816a.patch
tar vxzf rpi-3.6.y.tar.gz
cd linux-rpi-3.6.y/
SUW=`pwd`
patch -p1 < ../fd5ff2d88f470ed70ff58393eee61110b181816a.patch
zcat /proc/config.gz > .config
sed -i 's/# CONFIG_RTC_DRV_PCF2127A is not set/CONFIG_RTC_DRV_PCF2127A=m/g' .config
echo m | make oldconfig
wget https://github.com/raspberrypi/firmware/raw/master/extra/Module.symvers
make modules_prepare
cd drivers/rtc
make -C $SUW M=`pwd`
sudo cp rtc-pcf2127a.ko /lib/modules/3.6.11+/kernel/drivers/rtc/
sudo depmod

It doesn’t matter if you install the binary package or compile the kernel module on your own. The steps below are the same either way.

Make sure to load the needed modules:

cat >> /etc/modules <<EOL
i2c-bcm2708
rtc-pcf2127a
EOL

Make sure the i2c-tools package is installed:

apt-get install i2c-tools

I talked about the ‘fake-hwclock’ package. Now that we have a hardware clock, we should remove this package and it’s crons.

apt-get remove fake-hwclock
rm /etc/cron.hourly/fake-hwclock
update-rc.d -f fake-hwclock remove
rm /etc/init.d/fake-hwclock

Enable the ‘hwclock.sh’ script (part of util-linux), instead:

update-rc.d hwclock.sh enable

It’s now time to boot the new kernel. When you reboot, the RasClock will be available as /dev/rtc0.

dmesg

The kernel ring buffer should list something like this:

[ 32.737903] rtc-pcf2127a 1-0051: chip found
[ 32.739712] rtc-pcf2127a 1-0051: rtc core: registered rtc-pcf2127a as rtc0
[ 32.739775] i2c i2c-1: new_device: Instantiated device pcf2127a at 0x51

Because this is a new device, we need to set the time in the hardware clock. Do this by copying the system time to the RasClock.

hwclock --systohc --utc

Using the ‘hwclock’ command, you can read the RasClock:

hwclock --show --utc

Output:

Wed 08 May 2013 21:59:49 CEST -0.862324 seconds

Adding the ‘–debug’ flag adds some more interesting output, especially if you want to know exactly what goes on. Example output:

hwclock from util-linux 2.20.1
Using /dev interface to clock.
Assuming hardware clock is kept in UTC time.
Waiting for clock tick...
/dev/rtc0 does not have interrupt functions. Waiting in loop for time from /dev/rtc0 to change
...got clock tick
Time read from Hardware Clock: 2013/05/08 19:56:20
Hw clock time : 2013/05/08 19:56:20 = 1368042980 seconds since 1969
Wed 08 May 2013 21:56:20 CEST -0.752934 seconds

You can also access the hardware clock through the /sys pseudo filesystem like this:

cat /sys/class/rtc/rtc0/date
cat /sys/class/rtc/rtc0/name

The first command returns the date, the second command the name of the chip which is ‘rtc-pcf2127a’.

Using the clock

In my current setup, the RasClock keeps time during reboot and when the Raspberry Pi is turned off. My goal is to build a NTP server that is capable of keeping time also when no NTP peers are available to prevent time drifts. I assume the hardware clock that I have now available is more accurate than the clocksource that drives the system time. I need to experiment to see how the two clocks compare. I’ll come back on the subject in a follow-up post.

20 responses to Adding a hardware clock (RTC) to the Raspberry Pi

  1. 

    A personal computer has a battery driven hardware clock. The battery ensures that the clock will work even if the rest of the computer is without electricity. The hardware clock can be set from the BIOS setup screen or from whatever operating system is running.

  2. 

    Do you know if the build instructions still work? I am running a 3.6.11+ kernel and I cannot get your instructions to produce the required module. Has something changed in the patch or kernel? I am following your instructions exactly and I get “cp: cannot stat `rtc-pcf2127a.ko’: No such file or directory” at the end.

    • 

      Hi Gerald,

      Thanks for your reply. I tried again following the above instructions, and then found I missed a critical step. You see, the .config is used from the current running kernel. But that one hasn’t the rtc-pcf2127a module enabled yet if you start from scratch. I’ve now added a step (line 11) to toggle on ‘CONFIG_RTC_DRV_PCF2127A’.

      Just start from line 11 and on and you’ll probably be allright!

      Sorry for the inconvenience and let me know if it now works 🙂

      Take care,
      Remi

      • 

        Hello!

        Thanks for the reply – your line 12, where you used sed to enable the module does not work for me. On my untouched kernel, “# CONFIG_RTC_DRV_PCF2127A is not set” does not exist, so your sed will not work. I tried adding “CONFIG_RTC_DRV_PCF2127A=m”, which worked and created the module. It doesn’t seem to work, though. Modules load, but there’s nothing to indicate it’s working – shouldn’t the modules have some sort of dependency? below?

        rtc_pcf2127a 2491 0
        i2c_bcm2708 3759 0

        Also, nothing in dmesg. I’ll continue looking. If you have any ideas it would be much appreciated.

      • 

        Hi Gerard,

        When I find the time, I’ll try building it from scratch myself and see if I can reproduce the problem.

        On a working pi a ‘lsmod’ shows:

        Module Size Used by
        rtc_pcf2127a 2487 0
        snd_bcm2835 15846 0
        snd_pcm 77560 1 snd_bcm2835
        snd_page_alloc 5145 1 snd_pcm
        snd_seq 53329 0
        snd_seq_device 6438 1 snd_seq
        snd_timer 19998 2 snd_pcm,snd_seq
        snd 58447 5 snd_bcm2835,snd_timer,snd_pcm,snd_seq,snd_seq_device
        leds_gpio 2235 0
        led_class 3562 1 leds_gpio
        i2c_bcm2708 3759 0

        So, the 0’s should be OK.

        I’ll come back to you!

  3. 

    I am using 3.2.7+ kernel (debian/wheezy, armel). How can I build rtc-pcf2127a module?

  4. 

    This guide was great. The only change I made was the following pulled from teh ModMyPi blog…

    After the first reboot, open /etc/rc.local for editing.

    sudo vi /etc/rc.local

    For Rev 1. Raspberry Pi Boards Add the following text:
    echo pcf2127a 0×51 > /sys/class/i2c-adapter/i2c-0/new_device
    ( sleep 2; hwclock -s ) &

    For Rev 2. Raspberry Pi Boards Add the following text:
    echo pcf2127a 0×51 > /sys/class/i2c-adapter/i2c-1/new_device
    ( sleep 2; hwclock -s ) &

    Then reboot again. This allowed me to see the hwclock using dmesg.

  5. 

    Hi

    Im using a DS1307 RCT chip so I didn’t need to compile extra kernel module. I didn’t realise I have to disable fake-hwclock and enable hwclock.sh. Many thanks for this article!

    My RasPI now acts as stratum 1 NTP time server using a Rockwell Jupiter GPS & PPS module, the DS1307 as RTC and a 20×4 LCD display to print information returned from ntpq.

  6. 

    Sorry for dropping in but I have a question about the use of the NXP PCF2127AT. It looks like you’re communicating via the I2C bus. We’re encountering weird effects with this circuit although the I2C bus seems to function properly (according to our logic analyzer and after timing analysis with our scope). It worked well for a while, then we began to have problems such as static time readings and unexpected data. The RAM doesn’t seem to be accessible. Have you encountered such things?

    • 

      Hi Pieter, No I haven’t seen anything like it. My RTC is working just fine, even after a power-loss. Good luck on this issue, I’d try to see if another unit has the same problem?

  7. 

    All our test boards have the same problem. We’ve checked hard- and software but can’t really solve the problem. I’ve sent the issue to NXP but they definitely need their time also to find a cause. Thank you for the reply!

  8. 

    Good hint, thanks! However, as long as there is any other Linux device in the LAN with a built-in RTC and sshd, you may completely obey fake-hwclock and replace it with an ssh call to just that other device which retrieves the current date from there and uses the result to set it locally.

    A Linux device with sshd could be:

    Your NAS,
    your router,
    another server not being a Pi,
    sky is the limit.

    However, there remain of course many cases where you may really want and need a true RTC even in a Pi.

    HTH,
    dave

  9. 

    Hi Remi, congratulations for your blog, I found it looking for information after installing an expansión board on my raspberry.
    That is:
    http://www.suptronics.com/RPI.html
    I think it brings powerful facilities to Raspberry.
    My main interest was to use the HDMI to VGA converter on it. As in the same board came a RTC I followed the installation procedure from the provider and from your blog, and it came up an old keyboard problem that I had with a previous version of Raspbian. My keyboard is a wireless Microsoft 800. The problem is that when I type any key in the keyboard the key typed is repeated for ever….It worked fine just before to boot with the new updated RTC kernel. Coming back to the former kernel the keyboard worked fine again.
    I would like some help about what is happening, you said that rtc-pcf2127a module is only added to the working kernel. Then what is the relation with the keyboard for its malfunction???..

    I appreciate your comments.

    Thank you very much.

  10. 

    Sorry to resurrect an old thread, but I tried to run this but get a fail on

    patch -p1 .config

    with the error
    patch **** Only garbage was found in the patch input.
    and .config contains
    patch unexpectedly ends in middle of line
    Any thoughts, since I’m a bit stumped.
    Thanks 🙂

  11. 

    Nice article. It helped me to jump into kernel module compilation.
    A short update, kernel 3.12.20+ includes rtc-pcf2127.ko, so the custom kernel/additional rtc-pcf2127a.ko module might not be necesary.
    I got hwclock to work by using “rtc-pcf2127” on etc/modules and “echo pcf2127 0×51 > /sys/class/i2c-adapter/i2c-1/new_device” on /etc/rc.local.

Trackbacks and Pingbacks:

  1. How accurately can the Raspberry Pi keep time? « Remi Bergsma's blog - May 12, 2013

    […] Just like virtual hardware, the Raspberry Pi has no hardware clock. But it is fairly simple to add a hardware clock using the GPIO ports. In a previous blog post, I explained how to set this up. […]

Leave a reply to Pieter Cancel reply