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:
Schermafdruk van 2022-04-05 18-43-55
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):

  • i2cget -y 10 0x0c: 0x5f
  • i2cget -y 10 0x2f: 0x00

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?

1 Like

Hello @VromansN thank you for your message.

Asking for help internally i have found a dt-overlay that maybe you can test. Did you try this?

BALENA_HOST_CONFIG_dtoverlay to "i2c-rtc,ds1307"

On the other hand, find here the information about the balena Time Management

Hi @mpous , I don’t believe I’ve tried "i2c-rtc,ds1307" (although I have seen ds1307 pop up a few times, so I’m not sure). I have tried "i2c-rtc,pcf85063" since the CM4 uses an PCF85063AT RTC. I’ll try this config and let you know. Also: I’ve already looked through the Time Management documentation, but didn’t really find anything regarding using the RTC instead of (or in combination with) chrony.

@VromansN let us know if that works!

@VromansN The DS1307 I2C RTC uses I2C addr 0x68 (which is not changeable) and your CM4 IO board is detected @0x51:
This means, your RTC is cannot be an DS1307: Therefore, there is no need to try with ds1307 at all:
Example: Set RTC Time | Adding a Real Time Clock to Raspberry Pi | Adafruit Learning System
In theory, it could be DS1307-look-alike, but not the usual DS1307 using 0x68.

The DS1307 is often used for as an add-on RTC for the Pi4, not the CM4:

Indeed the CM4 IO board uses the pcf85063AT, but more devicetree options should be set than described in the spec sheet:

dtparam=i2c_vc=on
dtoverlay=i2c-rtc,pcf85063a,i2c_csi_dsi,addr=0x51

You can set both, but the BALENA_HOST_CONFIG_dtoverlay might be sufficient:

BALENA_HOST_CONFIG_dtparam="i2c_vc=on"`
BALENA_HOST_CONFIG_dtoverlay=i2c-rtc,pcf85063a,i2c_csi_dsi,addr=0x51

addr=0x51 the I²C address without using echo to probe for 0x51: bcm2711_defconfig: include CONFIG_RTC_HCTOSYS=y to automatically set system time from rtc on cm4io · Issue #4205 · raspberrypi/linux · GitHub

In case you need multiple dtoverlay lines in config.txt (e.g. to enable USB host mode) you need to set use quotes like here inside the variable: Advanced boot settings - Balena Documentation
Example:

BALENA_HOST_CONFIG_dtoverlay = "i2c-rtc,pcf85063a,i2c_csi_dsi,addr=0x51","dwc2,dr_mode=host"

PPS: Another link: Raspberry Pi Compute Module 4 Board RTC (pcf85063a) - device - snapcraft.io

2 Likes

@bkaindl thanks so much! Here’s what ended up working for me: on the fleet Configuration set BALENA_HOST_CONFIG_dtoverlay to "i2c-rtc,pcf85063a,i2c_csi_dsi,addr=0x51".
I’ve tested with both the BALENA_HOST_CONFIG_dtparam (set to "i2c_vc=on") and not setting it, as you suspected, this one is indeed not needed.
This was very similar to what I already had, apart from the addr=0x51, that one was missing. I had also put them separately between quotes, so I had "i2c-rtc","pcf85063a","i2c_csi_dsi" instead of "i2c-rtc,pcf85063a,i2c_csi_dsi,addr=0x51". Now it works flawlessly.

Again, thanks so much!

2 Likes

Thank you @bkaindl and @VromansN for sharing this! You rock!

1 Like