This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

RTC data not persistent across reboots

Hi,

We have NXP PCF8523 RTC sitting on i2c bus of AM335x.

And we are writing to RTC using 'RTC_SET_TIME' ioctl on RTC device(/dev/rtc0). 

If we read back the data from RTC before reboot, it shows proper data, that we have written. But after reboot, the data is reset to old data that was present before we wrote.

But if we do a 'settimeofday' or 'hwclock --hctosys' before reboot in above scenario, after reboot, it shows proper data that we have written.

Please let us know, if we are missing anything.

Thanks

  • In your system there are probably two RTC timers - an internal one in the Sitara processor (rtc0) and the external one that you really use (rtc1). The issue is due to the fact that rtc0 is used by the system by default. Here is what needs to be done:

    1. Update the system file /etc/udev/rukes.d/localextra.rules

        This is the file contents (if you made modifications to the system there may be additional lines):
        --------------------------------------------------------------
        # There are a number of modifiers that are allowed to be used in some
        # of the different fields. They provide the following subsitutions:
        #
        # %n the "kernel number" of the device.
        #    For example, 'sda3' has a "kernel number" of '3'
        # %e the smallest number for that name which does not matches an existing node
        # %k the kernel name for the device
        # %M the kernel major number for the device
        # %m the kernel minor number for the device
        # %b the bus id for the device
        # %c the string returned by the PROGRAM
        # %s{filename} the content of a sysfs attribute
        # %% the '%' char itself
        #

        # The first rtc device is symlinked to /dev/rtc
        KERNEL=="rtc0", SYMLINK+="rtc"

        #The first framebuffer is symlinked to /dev/fb
        KERNEL=="fb0",  SYMLINK+="fb"
        --------------------------------------------------------------
        The line:
        KERNEL=="rtc0", SYMLINK+="rtc"

        must be replaced with the line:
        KERNEL=="rtc1", SYMLINK+="rtc"

    The file must be saved in the original location. Reboot the system.

    2. At kernel prompt set the system date and time:
        date MMDDhhmmYYYY

    3. Update the RTC:
        hwclock -w

    4. For verification you can read the RTC with:
        hwclock -r

    After this timekeeping should be OK.

  • If you disabled the processor internal RTC already, you can skip step 1.
  • Thanks for replying.

    I already have processor internal RTC disabled.
    And we are writing to RTC registers directly using 'RTC_SET_TIME' ioctl on RTC device(/dev/rtc0).

    Why do, we need below step?
    3. Update the RTC:
    hwclock -w

    Thanks
  • Because this performs the actual hardware write to the RTC.
  • But, the actual hardware write to RTC is happening as part of below:

    ioctl(nI2Cfd, RTC_SET_TIME, &rt))
    |
    rtc_dev_ioctl
    |
    rtc_set_time(rtc, &tm);
    |
    rtc->ops->set_time(rtc->dev.parent, tm);
    pcf8523_rtc_set_time(...)
    |
    err = i2c_transfer(client->adapter, &msg, 1);

    Please correct me, if I am wrong.

    Thanks
  • Hi,

    hwclock communicates with the rtc kernel driver through /dev/rtc/. So when you use the hwclock it handles the specified parameters to the rtc driver and performs hw write using the set_time, i2c_transfer etc.

    Best Regards,
    Yordan