Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Initialize an external I2C RTC module on raspberry using udev and systemd

Description

Enable i2c RTC using systemd. A udev rules triggers an I2C systemd service on I2C kernel module adding. Service then loads I2C driver adding a new I2C device to /sys Then kernel loads I2C RTC driver and adds an RTC device It triggers a udev rules that updates hardware clock

Application on raspberry pi

Enable I2C

  • enable I2C in config.txt, adding device_tree_param=i2c1=on

  • enable I2C driver loading at boot, refer i2c.conf

  • reboot raspberry

  • check an I2C bus is found :

    i2cdetect -l
    i2c-1   unknown         bcm2835 I2C adapter                     N/A
    
  • check I2C rtc is detected :

    i2cdetect -y 1
    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: -- -- -- -- -- -- -- --          
    

Enable I2C RTC

  • create /etc/udev/rules.d/50-i2c_start.rules

  • create /etc/conf.d/rtc-i2c

  • create /etc/systemd/system/i2c_rtc.service

  • create /etc/udev/rules.d//etc/udev/rules.d/60-rtc-i2c.rules

  • test it:

    hwclock -r
    2000-01-02 01:25:04.301281+01:00
    
  • when an NTP service is started, it should set hwclock to a valid time, if not you must set a valid system clock and then set hwclock to system clock

    hwclock --systohc
    
  • reboot

  • system clock should be fine, even if system is not connected to outside world

# /etc/udev/rules.d/50-i2c_start.rules
#
#
#I2C hardware device driver
ACTION=="add", KERNEL=="i2c_bcm2708", SUBSYSTEM=="module", TAG+="systemd"
# /etc/udev/rules.d/60-rtc-i2c.rules
#
#
ACTION=="add", SUBSYSTEM=="rtc", ATTRS{hctosys}=="0", RUN+="/usr/bin/hwclock -s --utc"
#/etc/conf.d/rtc-i2c
# configure there your RTC chip and address
CHIP="ds1307"
ADDRESS="0x68"
BUS="1"
# /etc/modules.load.d/i2c.conf
i2c-bcm2708
i2c-dev
# /etc/systemd/system/i2c_rtc.service
[Unit]
Description=Initialize i2c hardware RTC device driver
DefaultDependencies=no
Requires=sys-module-i2c_bcm2708.device
After=sys-module-i2c_bcm2708.device
Conflicts=shutdown.target
[Service]
Type=oneshot
RemainAfterExit=yes
EnvironmentFile=/etc/conf.d/rtc-i2c
ExecStart=/bin/sh -c "echo ${CHIP} ${ADDRESS} > /sys/class/i2c-adapter/i2c-${BUS}/new_device"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.