Slackware ARM on a Raspberry Pi
Install a DS3231 RTC for Slackware ARM on the Raspberry Pi
This SARPi project will enable you to connect and install a ChronoDot (DS3231) real time clock (RTC) using Slackware ARM 14.2 or -current on a Raspberry Pi 1, 2, or 3. The project would suit those who do not wish to depend on NTP servers for time information, or where no Internet connection is available, and accurate time is a factor. There may be other reasons why you might want to rely on an onboard RTC for time keeping purposes but, alas, the Raspberry Pi 1, 2, and 3, doesn't come with one. So we thought it would be cool and interesting, as well as educational and fun, to give our Slackware ARM system its own RTC module.
What you will need for this project
• A Raspberry Pi 1, 2, or 3 running Slackware ARM 14.2 or -current.
• An understanding of whether your Slackware ARM system requires Device Tree overlays or not. *IMPORTANT!*
• A ChronoDot RTC (or other DS3231 based real time clock). You can use DS1307 RTCs too.
• Suitable cables to connect the ChronoDot to your RPi (other RTCs may connect directly to the GPIO without cables).
• The i2c-tools package; i2c-tools-3.1.2-arm-1_slack14.2_fd0.txz for Slackware ARM 14.2 , or the Slackware ARM -current package; i2c-tools-3.1.2-armv7-1_slackcurrent_fd0.txz, (for pre-DT systems).
Note for Slackware ARM packages: Make sure to only install package(s) for the Slackware ARM version you're running. Packages that are built for -current hard float port will not work with 14.2 soft float port (and vice versa).
Connecting the ChronoDot RTC module to a Raspberry Pi
First of all you're going to connect the ChronoDot RTC to your Raspberry Pi.
The RTC module we're using in this project is the ChronoDot v2.1 [DS3231SN]. One reason why we chose this particular RTC is because it comes as a complete unit and we don't need to do any soldering. Another reason was because it's already supported by the rtc-ds1307 module under Slackware Linux. The extreme accuracy of the ChronoDot's Maxim DS3231 controller was also a major factor in selecting this RTC module.
This tutorial also works for other DS3231 based real time clocks, such as the extremely popular DS3231 MINI RTC Module which plugs directly in to the Raspberry Pi GPIO without the need for any cables. The RTC device may be different but the code required to use it is exactly the same.
You can also use this tutorial for DS1307 based RTCs, substituting 'ds3231' for 'ds1307' where applicable.
With everything powered off, follow the diagram below and connect the ChronoDot to your Raspberry Pi GPIO header. One easy way to do this is by using solderless female-female breadboard jumper cables which simply "plug-in". You can of course make your own connections and cables by using old CD/DVD ROM audio cables, etc. The only important thing is that you ensure the wiring is correct and insulated.
• ChronoDot VCC Raspberry Pi GPIO Pin 1 (3v3)
• ChronoDot SDA Raspberry Pi GPIO Pin 3 (SDA)
• ChronoDot SCL Raspberry Pi GPIO Pin 5 (SCL)
• ChronoDot GND Raspberry Pi GPIO Pin 9 (Ground) - can also be connected to GPIO Pin 6 (Ground)
NB: Make sure you connect the ChronoDot to the 3.3v power supply and NOT the 5v power. Although the ChronoDot is designed to operate on anywhere between 2.3v and 5.5v, on the Raspberry Pi we need to be powering it from the (3v3) 3.3 volts supply using GPIO Pin 1.
The first 26 pins of the 40-pin GPIO on a Raspberry Pi Model A+, Raspberry Pi Model B+, Raspberry Pi 2, and Raspberry Pi 3, are exactly the same as the Raspberry Pi Model B (rev.2).
Connect the 3v Lithium CR1632 coin cell battery to the ChronoDot RTC (which comes supplied). Make sure the polarity is correct! Plug the ChronoDot into your Raspberry Pi and do a final check of the connections before powering it on, just to be sure. At this point you can power on your Raspberry Pi and boot your Slackware ARM system.
Next you're going to need to know whether to use the Device Tree (DT) or non-Device Tree (pre-DT) method to install the ChronoDot RTC...
To be, or not to be, Device Tree, that is the question. So, what is it?
Device Tree (DT) is the recommended way to describe hardware on Linux platforms (although it's OS-independent). By default, on the Raspberry Pi, Device Tree is always on and you have to disable it if it's not required. The latest Raspberry Pi kernels and firmware use Device Tree to manage hardware resource allocation and load some supported modules (not all) at boot. This has supplanted the previous method of loading modules in rc.modules and/or rc.local on start-up. The two methods each work perfectly but they are very different in the way they work. So, it's important that you know which method your system is using.
So, it's either; a Device Tree (DT) system, or a non-Device Tree (commonly referred to as pre-DT) system, but it can't be both.
How do you know if you are using Device Tree or not?
If you've been following the SARPi tutorial and have upgraded the Raspberry Pi kernel and firmware (using rpi-update) then you will most certainly be using a Device Tree (DT) system. If you haven't already done so it's recommended that you update your Slackware ARM system using slackpkg and rpi-update to ensure your system is fully up-to-date before continuing.
For those who do not wish to use Device Tree there is the pre-DT method. However, it's not known how long this will be available and, "Be aware that this option may not be supported indefinitely.", said one of the Raspberry Pi engineers on 21 Jan 2015.
Why has the previous method of loading modules changed to Device Tree?
Raspberry Pi's latest kernels and firmware now use Device Tree (DT) to manage some resource allocation and module loading. This change is to alleviate the problem of multiple drivers contending for system resources, and to allow HAT modules to be auto-configured. With Device Tree it's easy for users to control which devices are enabled at boot time. It also makes it easier to change the configuration of the system without having to recompile source code. This means new hardware can easily be added and supported with minor changes to the Device Tree. For example, if you have a new peripheral hardware it can be included in the Device Tree using 'overlays' (i.e. *.dtb* files) so that, when the Raspberry Pi boots, the start.elf (bootloader) will combine overlays with an appropriate base device tree, and then pass a fully resolved Device Tree to the kernel. This selection is automatic, based on the RPi model you are booting from. So, it means that the same overlays can be used on different Raspberry Pi versions. With Device Tree it's much simpler and easier to manage/maintain/add/remove/modify hardware settings, throughout the whole range of RPI devices, than the pre-DT method. Some might even refer to it as 'progress'. :-p
What's the main difference(s) between a Device Tree and non-Device Tree system?
With Device Tree all the RPI's external interfaces (I2C, I2S, SPI) are turned off by default. They must be activated by adding settings in the /boot/config.txt file and any hardware connected to them must be represented by a Device Tree Blob (DTB) which is passed to the kernel by the start.elf bootloader and then used by the system. There's no need to load modules via this method IF the hardware is instantiated using a DTB.
Note: If the hardware you're using is not supported by the Device Tree you have the option to create your own DTB.
On a non-Device Tree system all the RPi's external interfaces are turned on by default without the need to explicitly load or blacklist kernel modules or rely on module blacklisting to manage contention. There's no requirement to specify I2C, I2S, SPI hardware settings in the /boot/config.txt file via this method.
How do you disable Device Tree?
If Device Tree isn't to your liking, or if you're having issues with the new way of working, or if you'd prefer to continue using the pre-DT way of working, it can be disabled very easily in Slackware ARM on the Raspberry Pi. To achieve this, log in as 'root' user and type the following:
You need to add 'device_tree=' on a line by itself in the /boot/config.txt file. See the example screenshot below.
Exit and save the /boot/config.txt file ['CTRL' & 'X' keys together]. After the system reboots, Device Tree should now be disabled.
Be aware that the option to disable Device Tree may not be supported indefinitely. It's recommended that you use Device Tree because it's now supported by default in the current official Raspberry Pi kernel and firmware.
So, now you should at least know if your Slackware ARM system requires Device Tree overlays, or not.
• If you have a Device Tree (DT) system then continue with the Device Tree Overlay Method section below.
• If you have a non-Device Tree (pre-DT) system then go to the Non-Device Tree Overlay Method section of this tutorial.
Device Tree Overlay Method
Installing & configuring the ChronoDot RTC on Slackware ARM with Device Tree overlays
You'll need to follow this section of the RTC tutorial if your system uses Device Tree overlays to load hardware at boot time. For the purpose of this section of the tutorial we have given the name "koor" to our Slackware ARM system.
Log in and change to the 'root' user. The first thing you're going to do is edit the '/boot/config.txt' file and add some settings to enable the I2C interface and instruct the system that you're are using a DS3231 RTC (a.k.a the ChronoDot). To do this you need to type 'nano -w /boot/config.txt' at the command prompt.
Scroll down to the section you see in the screenshot below, titled "uncomment to enable the I2C interface".
Remove the hash '#' from the beginning of the 'dtparam=i2c=on' line as shown in the screenshot below.
To tell the system to use the ChronoDot RTC [DS3231] you'll need to add the following code to the '/boot/config.txt' file:
This code can be put anywhere in the '/boot/config.txt' file after the line you have just uncommented (removed the '#' from). In the example screenshot below we have put it directly under that line, with its own comment (which is only for our own reference). You are not required to add a comment.
Exit and save the /boot/config.txt file ['CTRL' & 'X' keys together].
So, type 'reboot' at the command prompt and allow the system to restart. Then log in with your normal user account when prompted.
After logging in, change to 'root' user and at the command prompt type 'hwclock -r && date'. This will instruct the system to read the ChronoDot RTC's date/time setting (i.e. hardware clock) and display it and also display the current system date/time. The '&&' just means 'do this next' so you're telling the system to run one command and then another command straight after it. You'll need to do this in order to check the current status of the hardware clock and the system time. You should see something similar to the example screenshot below.
If you receive any error notifications go back and check your settings in the /boot/config.txt file. If you find any mistakes correct them and reboot your system once more. Your /boot/config.txt file should pretty much match what's displayed in this tutorial in order to work successfully.
As you can see from our example, the system time and ChronoDot RTC are not in sync. The first output is the hardware clock (the ChronoDot RTC) and beneath it is the output from the system date/time. Your own results will be completely different but the point is to check if the system time and hardware clock are accurate. For us they are not. For you they are probably not too, especially if you are configuring the ChronoDot RTC for the first time.
So now we need to accurately set the system and hardware clock date/time and we're going to use a ntp server to achieve this. You are probably going to need to do the same and if you want to use a ntp server you will require an internet connection.
If you don't have an internet connection you can set the system time by using the 'date MMDDHHmmYYYY.SS' command.
MM = 2 digit month (00-12)
DD = 2 digit date (01-31)
HH = 2 digit hours (00-23) [24 hour format]
mm = 2 digit minutes (00-59)
YYYY = 4 digit year
SS = 2 digit seconds (00-59)
So, for example, 07:44:13 PM on 09 April 2016 would be: 'date 040919442016.13'
Incidentally, you can also set the date/time from a ntp server connected to your local network if you have one available.
So, to set the system date/time you'll use the 'ntpdate' command, followed by a ntp server address. The ntp server we are using as an example is 'pool.ntp.org' but you can select your own here if you prefer. To set the hardware clock date/time you can get it from the system once you know it is relatively accurate. You can achieve this with one simple command.
At the command prompt type: 'ntpdate pool.ntp.org && hwclock -w'
What you've effectively done is set the system date/time with the 'ntpdate pool.ntp.org' part of this command and subsequently taken that setting and written it to the hardware clock (ChronoDot RTC) with the 'hwclock -w' part of this command.
Now you can use the 'hwclock -r && date' command again to check that the system and hardware clock date/time matches.
If the output of the system date/time and hardware clock date/time are identical then you have successfully installed and configured the ChronoDot RTC on your Slackware ARM system. Well done!
Seeing as you now have a fully working and installed, highly accurate, real time clock there's no need to rely on a ntp server at boot time. You can configure the system so that the date/time is set by the hardware clock (i.e. the ChronoDot RTC). Type the following command:
Your /etc/rc.d/rc.local file should look like the screenshot below.
This file grabs the date/time from a ntp server at boot time. You can easily change it so that the system date/time is set by your ChronoDot RTC instead.
All you need to do is comment out the ntpdate line (i.e. put a hash '#' at the start of the line) so it doesn't run the command and then put 'hwclock -s' on a line by itself at the end of the /etc/rc.d/rc.local file. In the example below we have done just that, and also added a comment for our own reference.
Exit and save the /etc/rc.d/rc.local file ['CTRL' & 'X' keys together]
After rebooting log in again and 'su -' to root user. At the command prompt type 'hwclock -r && date'. What you should see is that your Slackware ARM system date/time and ChronoDot RTC date/time are identical.
Now you can be sure whenever you boot your Slackware ARM system it will grab the date/time from your ChronoDot RTC. It won't matter if you don't have an Internet connection anymore as far as system time is concerned.
If, for whatever reason, you need to set the date/time accurately again on your ChronoDot RTC then you can use the same 'ntpdate pool.ntp.org && hwclock -w' command to achieve this. Always remember that in order to use this command you must be logged in as the 'root' user.
As far as this tutorial goes, for installing and configuring the ChronoDot RTC on your Slackware ARM (DT) system on a Raspberry Pi, you are done! Contratulations are in order if you have successfully managed to complete this fun little project. :-D
Non-Device Tree Overlay Method
Installing & configuring the ChronoDot RTC on Slackware ARM without Device Tree overlays
You need to follow this section of the tutorial only if your system does not rely on Device Tree overlays to load and configure hardware at boot time. For the purpose of this section of the tutorial, we have given the name "myrasbox" to our Slackware ARM system.
Remember, if you want to use a non-Device Tree (pre-DT) system to install and configure your ChronoDot RTC, you'll need to disable Device Tree in the /boot/config.txt file by adding 'device_tree=' on a line by itself.
Log in as (or change to) the 'root' user. If the date is not already set to current time you should now set it manually, or use the 'ntpdate' command. It's a good idea to make sure your Slackware ARM software and Raspberry Pi kernel and firmware are fully up to date. Running slackpkg and rpi-update at this point will achieve this and, depending on the number of updates available, may take a while to complete. A reboot may also be required.
As 'root' user, you're going to 'cd' to the /tmp directory and download the i2c-tools package. There's two choices; Slackware ARM 14.2, and -current.
Note for Slackware ARM packages: Make sure to only install package(s) for the Slackware ARM version you're running. Packages that are built for -current hard float port will not work with 14.2 soft float port (and vice versa).
• To download and install i2c-tools-3.1.2 for Slackware ARM -current type the following:
root@myrasbox:/tmp# wget http://sarpi.fatdog.eu/files/pkg/i2c-tools-3.1.2-armv7-1_slackcurrent_fd0.txz
root@myrasbox:/tmp# installpkg i2c-tools-3.1.2-armv7-1_slackcurrent_fd0.txz
• To download and install i2c-tools-3.1.2 for Slackware ARM 14.2 type the following:
root@myrasbox:/tmp# wget http://sarpi.fatdog.eu/files/pkg/i2c-tools-3.1.2-arm-1_slack14.2_fd0.txz
root@myrasbox:/tmp# installpkg i2c-tools-3.1.2-arm-1_slack14.2_fd0.txz
This i2c-tools Slackware ARM package was created specifically for this project using the i2c-tools.SlackBuild script available from SlackBuilds.org because it didn't seem to be already available for download on the Internet. It goes without saying that i2c-tools for linux is useful for more than just setting up RTCs on a Raspberry Pi.
Once this has completed you should see something similar to the following output.
After installing the i2c-tools package, you're going to edit the rc.local file and instruct the Slackware ARM system to load the required modules and perform commands at boot time in order to communicate with the ChronoDot RTC. Do this with 'nano' by typing:
You will hopefully see something similar to the screenshot below.
You need to tell the system to load some specific modules. These will be explained later. Enter the following code into the rc.local file below any existing text:
Pay attention to the next section because it is important (only) for Raspberry Pi 1 Model B owners. Whether you are using a Raspberry Pi 1 Model B rev.1 or rev.2 board depends on the code you need to enter and this is crucial towards success. Raspberry Pi 1 Model A+ and Model B+, Raspberry Pi 2, and Raspberry Pi 3, users do not have to bother checking their hardware version(s). If you're unsure which revision you're currently using see this page: Identifying Your Model of Raspberry Pi. Once you have determined which version of Raspberry Pi you are using, you can proceed.
• For Raspberry Pi 1 Model B rev.1 boards you need to enter the following code into the rc.local file below the text you have just entered:
• For Raspberry Pi 3, Raspberry Pi 2, Raspberry Pi 1 Model B rev.2, Model A/A+/B+ boards you need to enter the following code into the rc.local file below the text you have just entered:
The last thing you need to do before saving the rc.local file is to comment out the sntp line by putting a #hash in front of it. This stops the system from attempting to grab the current time from a NTP server over the Internet at boot time. It would be a little pointless to get a time reference from a NTP server when there's a highly accurate real time clock available! :-D
Now you should have a rc.local file looking very similar to the one below.
Once you've finished editing the rc.local file press CTRL+X keys to exit, press "Y" (yes) when asked if you wish to save any changes and then press Enter to save the file.
The i2c-bcm2708 module is the low level i2c subsystem driver. The i2c-dev module allows access to devices through the /dev interface. The rtc-ds1307 module contains the drivers for many RTC controllers, such as the DS1337 and MCP79410. Using the 'modinfo rtc-ds1307' command shows you that the DS3231 (i.e. the ChronoDot) is supported within the rtc-ds1307 module, and that's why it's needed at boot time.
The 'echo ds3231 0x68 > /sys/class/i2c-adapter/i2c-1/new_device' command is telling the i2c subsystem that there's a new 'ds3231' device available (the ChronoDot) and where it is on the bus. It's worth noting that this command only works the first time you use it. Any repeated usage will result in an error message.
The '/sbin/hwclock -s' command is asking the real time clock (the ChronoDot) for a time reference and subsequently writing that date and time to the Slackware ARM Linux system.
It's time to get it all working
So now your rc.local file should be configured to initialise the ChronoDot RTC and use it at boot time. You could 'reboot' at this point to test your setup but there's no real need to do so.
Instead of rebooting your Raspberry Pi, you can simply run the rc.local file to load the modules and perform the commands required to get the ChronoDot RTC working with the system. Type the following code to run the rc.local file:
After running the rc.local file you need to make sure the ChronoDot RTC is being recognised by the system and, most importantly, set the correct time and date on it. So, depending on whether your Raspberry Pi is a rev.1 or rev.2 board (check it with this link), type the following:
• For Raspberry Pi 1 Model B rev.1 boards use this command:
• For Raspberry Pi 3, Raspberry Pi 2, Raspberry Pi 1 Model B rev.2, Model A/A+/B+ boards use this command:
The screenshot below is the result you're looking for. It shows that the device has been detected and recognised.
Instead of '68' being displayed you might see 'UU' in its place. This is perfectly fine because it just means that a software driver (the rtc-ds1307 module) has been loaded and is currently using the 0x68 address. In both cases it indicates the ChronoDot RTC has been detected.
So you can go right ahead and find out what time and date is set to on your ChronoDot RTC. If this is the first time you have used it don't expect the current settings to be anywhere near accurate. Type the following command:
The result should be something similar to what you see below. Notice that in our screenshot the current date and time is years out on the ChronoDot. Yours may also be the same. However, this is just a transient error because it's the first time the ChronoDot RTC has been powered on. ;-)
Setting the ChronoDot RTC to the correct time & date
This can be achieved in two ways: manually using the 'date' command, or by utilising a NTP server on the Internet with the 'ntpdate' command. The latter is preferred for accuracy reasons alone.
• Set the time and date on the ChronoDot RTC manually by using the following command (pay attention to the date format):
The month (MM), day (DD), hour (HH), and minute (mm) values are always specified in 2 digits and have a leading zero '0' when applicable. The time is always specified as the 24 hour clock. The year (YYYY) value is always specified by 4 digits.
Example: if the time is 9:17pm on September 11, 2016 then the command would be as follows:
In our example above the 'date 091121172016' command sets the time and date on our Slackware ARM Linux system and the 'hwclock -w' command which follows then writes that date and time to the hardware clock (the ChronoDot RTC).
• Set the time and date on the ChronoDot RTC using a NTP server with the following command:
The 'ntpdate pool.ntp.org' command grabs the current date and time from a NTP server and writes it to our Slackware ARM Linux system. The 'hwclock -w' command which follows then writes that date and time to the hardware clock (the ChronoDot RTC). The NTP server you use does not have to be the same one as in our example.
NB: The above 'date' and/or 'ntpdate' command(s) can be used at any time (as 'root' user) to set the time & date on the ChronoDot RTC.
Now type 'hwclock -r' (i.e. READ the hardware clock) to see if you have successfully set the ChronoDot RTC to the correct date and time. You should check the output to make sure it's accurate.
After you have set the date and time the ChronoDot RTC will retain it, even when your Raspberry Pi is turned off, because of the 3v Lithium CR1632 coin cell battery. The ChronoDot real time clock is the most accurate RTC module that we've ever come across and it's really impressed us with ease of use, cost effectiveness, and a totally cool design!
countdown reboot? (optional)
As final confirmation that you've done everything right you can power off your Raspberry Pi (disconnecting any Ethernet cable or wireless Internet device) and power it back on, booting into your Slackware ARM Linux system. Once again, login as 'root' and type the 'hwclock -r' or 'date' command, or both. If the result is accurate to current time then it's perfect.
When we rebooted our Raspberry Pi, and disconnected it from any Internet connection, a few minutes later we logged in as 'root' and typed the following:
The section of output above from the 'dmesg' command tells us that the i2c modules have been loaded successfully and are working, and that our ChronoDot RTC (ds3231) has been recognised and is configured correctly for use by our Slackware ARM Linux system. We also checked that the date and time was still current and accurate by typing:
The date and time were spot on! If you found the same results, WELL DONE! 100% success. Happy days once again. :-D
Thanks & Credits!
Thank you for reading and taking part in this fun little project. We hope others find it as interesting and educational as we did.
Credit and a massive thank you to Matteo Bernardini for his i2c-tools.SlackBuild script which allowed us to build the i2c-tools-3.1.2 packages for Slackware ARM and, as always, Stuart Winter for his ceaseless efforts towards Slackware ARM. Without you all this project would not have been successful, or even possible. <3