dockerraspberry-pihardwarereal-time-clockbalena

BalenaOS use Raspberry Pi Compute Module 4 IO board's Real-Time Clock inside container


I'm trying to use the CM4 IO board's Real-Time Clock (RTC) to persist datetime changes from within a docker container, so whenever the device reboots, it remembers the newly set datetime. (By default it syncs via chrony.) I can update the system's datetime using the date --set="<datetime string>", but upon reboot it re-syncs and overrides the previously set datetime.

To enable the OI board's RTC, you need to set BALENA_HOST_CONFIG_dtparam="i2c_vc=on" according to the IO board's datasheet: I've done that (added fleet-wide configuration), after that I've also added i2c-tools to the container I want to use it in, which allows the usage of the i2cdetect command. It can detect the RTC (with battery inserted off course) using the following command: i2cdetect -y 10 (RTC is on i2c-10) which shows the RTC device on address 0x51 as stated by the datasheet:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:                         -- -- -- -- 0c -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 2f 
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- 51 -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

Although to me this looks like it's on 1x51, so maybe there's an issue there? However, the address does seem to be correct, since I get the following result when running i2cget -y 10 0x51: 0x00. Whereas when I run i2cget -y 10 1x51, I get: Error: Chip address is not a number!. Just to be complete, this is what I get when I run (other i2c addresses in use, don't know what for):

This is what I get when running i2cdetect -l:

i2c-10  i2c         i2c-22-mux (chan_id 1)              I2C adapter
i2c-0   i2c         i2c-22-mux (chan_id 0)              I2C adapter
i2c-22  i2c         bcm2835 (i2c@7e205000)              I2C adapter

This is also reflected when running ls -hal /dev/i2c* (same result inside container and on host OS):

crw-rw---- 1 root i2c 89,  0 Apr  5 12:49 /dev/i2c-0
crw-rw---- 1 root i2c 89, 10 Apr  5 12:49 /dev/i2c-10
crw-rw---- 1 root i2c 89, 22 Apr  5 12:49 /dev/i2c-22

This is the output when I run dmesg | grep -E '(i2c|rtc)' | head -50 (same result inside container and on host OS):

[    6.492981] i2c i2c-22: Added multiplexed i2c bus 0
[    6.493115] i2c i2c-22: Added multiplexed i2c bus 10
[    9.378968] i2c /dev entries driver

So far so good, it seems.

According to this post on Raspberry Pi's forum, you also need to:

  1. echo pcf85063 0x51 >/sys/class/i2c-adapter/i2c-10/new_device
  2. modprobe rtc-pcf85063

I've added both these things to my docker setup (and also tried a few variations listed in that same post), however I don't think I even need this, since I can detect it right away after setting the _dtparam. Having done this or not doesn't seem to make any difference.

Normally, when everything is working correctly, you should be able to set, update, ... the RTC using the hwclock commands, but whenever I run that, I get the following message:

hwclock: Cannot access the Hardware Clock via any known method.
hwclock: Use the --verbose option to see the details of our search for an access method.

This is the output when I run hwclock --verbose:

hwclock from util-linux 2.36.1
System Time: 1649177573.560553
Trying to open: /dev/rtc0
Trying to open: /dev/rtc
Trying to open: /dev/misc/rtc
No usable clock interface found.
hwclock: Cannot access the Hardware Clock via any known method.

When I run timedatectl on the host OS I get:

               Local time: Tue 2022-04-05 17:04:37 UTC
           Universal time: Tue 2022-04-05 17:04:37 UTC
                 RTC time: n/a
                Time zone: n/a (UTC, +0000)
System clock synchronized: yes
              NTP service: n/a
          RTC in local TZ: no

This seems to indicate the RTC is not working.

When running this command inside the container itself, I get:

System has not been booted with systemd as init system (PID 1). Can't operate.
Failed to connect to bus: Host is down

What am I missing or doing wrong here? Is this a permission/usergroup issue (since I'm trying to do this from inside a container)? Is it some wrong configuration? Am I missing some extra setup?


Solution

  • I'd also posted the same question on the balena forum and what I had to do was simply set BALENA_HOST_CONFIG_dtoverlay to "i2c-rtc,pcf85063a,i2c_csi_dsi,addr=0x51".

    Extra info: in the CM4 IO board datasheet (Section 2.13) it indicates you only need to set BALENA_HOST_CONFIG_dtparam to "i2c_vc=on", but this is not needed when setting the dtoverlay from above. I've tested with and without this and have found no difference.