Adding an External Real-time Clock Module For the Beaglebone Black

The post provides rough steps for integrating a real-time clock (RTC) module with a Beaglebone Black (BBB) for the purposes of accurate date and time retention over power cycles.

Requirements

  • Beaglebone Black (BBB) Single Board Computer (SBC) Revision C
  • Ethernet cable
  • Micro-USB to USB-A cable for power
  • Adafruit DS3231 Precision RTC Breakout Kit
  • 1 CR1220 3V cell battery
  • Dupont wire connector kit
  • Crimper tool
  • Soldering iron and solder

System Description

A table with information about the BBB used in this setup:

ItemDescription
BoardBeaglebone Black (BBB) Single-board Computer (SBC)
Operating SystemDebian Linux with TI BSP, Linux 5.10.145-ti-rt-r55 #1bullseye SMP PREEMPT_RT
ProcessorTI Sitara AM3358BZCZ100 ARM Cortex-8 @ 1GHz
# of cores1
On-board Storage4GB embedded multi-media card (eMMC, disabled via uBoot at this time)
RAM512KB
ExpansionSDCard memory card slot, currently running the OS from 128GB card

Background

I desired for the BBB to always have current date and time across power cycle events. As I searched for solutions on the internet I came across forum and forum basically pointing to the integration and use of a real-time clock module. Further searching led me to the Adafruit website and their tutorial using the DS1307 Precision RTC Breakout Board product. I ordered the DS3231 unit from their online store for $17.50 on February 16th, $24.91 with tax and shipping tacked on. The unit arrived at my doorstep about 4 days later.

Hardware Setup

The Adafruit DS3231 Precision RTC Breakout kit comes with the DS3231 chip already soldered onto the PCB with pin-outs labeled. The kit also includes a single-row 8-pin 2.54mm male header that must be soldered onto the board. The first thing I did after removing the kit from its packaging was to insert the 3V CR1220 cell battery into the underside slot on the board. Next, I soldered the 8-pin header onto the board.

DS3231 and jumper cable

I used a Dupont connector kit, a 24 AWG wire kit, and the crimper tool to create a jumper cable for connecting the RTC module with the BBB. The red wire is for input voltage (Vin), black wire for ground (GND), blue wire for the I2C serial clock (SCL), and yellow wire for the I2C serial data (SDA).

The BBB was connected to the network via Ethernet and was receiving power at 5V and 500mA via the micro-USB to USB-A cable.

I needed to modify my pin setup script on the BBB to set pins 19 and 20 on header P9 from CAN RX and TX respectively; to I2C SCL and SDA; respectively. I tunneled into the BBB via SSH and made the changes to the custom setup script located in the home directory. Once that was done, I rebooted the system and checked the status of the systemd service associated with running the script at boot up and verified successful operation.

Now I was ready to connect up the hardware. First step was to remove power from the BBB. Next, I connected the female housing end of the jumper cable to the first four pins on the RTC module’s male header pins; red to pin 1 (Vin), black to pin 2 (GND), yellow to pin 3 (SDA), and blue to pin 4 (SCL). I then inserted the male end of each wire into the predetermined pin slot on the BBB’s P9 header; red to pin 7 (+5V SYS), black to pin 1 (DGND), blue to pin 19 (I2C SCL), and yellow to pin 20 (I2C SDA). With connections in place, I reapplied power to the BBB and allowed time for boot-up.

System Configuration

The following are roughly the steps I took to configure the system on the BBB to use the RTC module. Most steps were taken from the previously referenced Adafruit tutorial. However, I had to do some things different and posting the steps here serves as documentation for myself that I can easily refer to later (and by virtue of the internet others can reference this also).

Perform the following steps:

(1.) Tunnel into the BBB via ssh.

(2.) Install the ntpdate and i2ctools packages if they are not installed on the system using the system’s package manager (apt on my debian-based system):

sudo apt install nptdate i2ctools

The i2cdetect utility is a part of the i2ctools package and will be used to find the address of the RTC module on an I2C bus. The utility’s help documentation as installed and viewed on my system:

i2cdetect --help

The output:

Error: Unsupported option "--help"!
Usage: i2cdetect [-y] [-a] [-q|-r] I2CBUS [FIRST LAST]
       i2cdetect -F I2CBUS
       i2cdetect -l
  I2CBUS is an integer or an I2C bus name
  If provided, FIRST and LAST limit the probing range.

The ntpdate utility allows us to update the date and time on the system by connecting to Network Time Protocol (NTP) servers on the web. The utility’s help documentation as installed and viewed on my system was not helpful, so I refer you to documentation here.

(3.) Use the i2cdetect utility to find the address of the RTC module on the I2C bus. I found the module on I2C bus 2 on my system:

i2cdetect -y -r 2         

The output:

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

(4.) Write the device number and address to the I2C node on the system which matches the bus number where the RTC module was found (I had to login as root to perform this):

sudo su
echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-2/new_device

(5.) Get the date and time from the RTC module and make note of the output:

hwclock -r -f /dev/rtc1

Most likely the output is junk i.e. some default date and time that is not correct. For the Debian-based system running on my hardware, the /dev/rtc1 is reserved for an external clock. The hwclock utility allows one to get and set properties of the system’s hardware (HW) clocks. The help documentation as viewed on my system:

hwclock --help

The output:

Usage:
 hwclock [function] [option...]

Time clocks utility.

Functions:
 -r, --show           display the RTC time
     --get            display drift corrected RTC time
     --set            set the RTC according to --date
 -s, --hctosys        set the system time from the RTC
 -w, --systohc        set the RTC from the system time
     --systz          send timescale configurations to the kernel
 -a, --adjust         adjust the RTC to account for systematic drift
     --predict        predict the drifted RTC time according to --date

Options:
 -u, --utc            the RTC timescale is UTC
 -l, --localtime      the RTC timescale is Local
 -f, --rtc <file>     use an alternate file to /dev/rtc0
     --directisa      use the ISA bus instead of /dev/rtc0 access
     --date <time>    date/time input for --set and --predict
     --delay <sec>    delay used when set new RTC time
     --update-drift   update the RTC drift factor
     --noadjfile      do not use /etc/adjtime
     --adjfile <file> use an alternate file to /etc/adjtime
     --test           dry run; implies --verbose
 -v, --verbose        display more details

 -h, --help           display this help
 -V, --version        display version

For more details see hwclock(8).

(6.) Update the system’s date and time via the NTP servers:

ntpdate -b -s -u pool.ntp.org

(7.) Write the up-to-date date and time information into the external RTC module:

hwclock -w -f /dev/rtc1

Using systemd for Time Setup Automation on Boot Up

I followed the steps from the Adafruit tutorial to create a service to update the system date and time from the RTC module shortly after the BBB boots up with some modifications.

(1.) The Bash script:

#!/bin/bash
sleep 15
echo ds3231 0x68 /sys/class/ic2-adapter/i2c-2/new_device
hwclock -s -f /dev/rtc1
hwclock -w

(2.) Setting the permissions on the script:

sudo chmod 755 rtc_init.sh

(3.) A systemd unit file was created in the /etc/systemd/system directory to call the Bash script as a part of a service to update the system date and time shortly after boot up:

[Unit]
Description=DS3231 RTC Service

[Service]
Type=simple
User=root
Group=root
ExecStart=/bin/bash /home/debian/rtc_init.sh
SyslogIdentifier=rtc_ds3231

[Install]
WantedBy=multi-user.target

(4.) Setting permissions on the unit file, enabling the service, and rebooting the BBB:

sudo chmod 777 rtc-ds3231.service
sudo systemctl enable rtc-ds3231.service
sudo reboot

References