Mạch thời gian thực RTC DS1307/DS3231 bán ở VN giá khoảng 80k đồng, lắp vào RPi để máy có đồng hồ thời gian thực mà không cần kết nối internet.
I. Bằng cách nào?
RTC giao tiếp với RPi qua giao thức I2C nên trước hết phải bật I2C khi khởi động.
sudo raspi-config -> Advanced Options -> A6 I2C -> [Yes]
Với Wheezy
- Tạo file /etc/modules-load.d/rtc-i2c.conf
# /etc/modules-load.d/rtc-i2c.conf i2c-dev i2c_bcm2708
2. Tạo file /etc/udev/rules.d/rtc-i2c.rules để đặt giờ hệ thống từ RTC mỗi khi có RTC
# /etc/udev/rules.d/rtc-i2c.rules ACTION=="add", SUBSYSTEM=="rtc", ATTRS{hctosys}=="0", RUN+="/sbin/hwclock -s --utc"
3. Nạp các module cần thiết
sudo modprobe i2c-bcm2708 sudo modprobe i2c-dev sudo modprobe rtc-ds1307
4. Tắt RPi bằng lệnh sudo halt hay sudo shutdown -h now, sau đó lắp RTC tại đầu dãy GPIO phía trong và quay vào trong
5. Bật nguồn RPi, cài đặt i2c_tools qua lệnh
sudo apt-get install i2c-tools
sau đó kiểm tra xem RTC có được nhận biết không qua lệnh
sudo i2cdetect -y 1
68 là địa chỉ I2C của RTC
6. Tạo systemd service rtc-i2c.service. Service này gọi systemd tạo thiết bị RTC mỗi khi khởi động. Khi udev thấy thiết bị xuất hiện, nó sẽ gọi công cụ hwclock để đặt giờ hệ thống từ RTC. Ta cần tạo 2 file:
File cấu hình (tạo thư mục /etc/conf.d trước)
# /etc/conf.d/rtc-i2c CHIP="ds1307" ADDRESS="0x68" BUS="1"
Và file systemd service
# /lib/systemd/system/rtc-i2c.service
[Unit]
Description=Initialize i2c hardware RTC device driver
DefaultDependencies=no
Requires=systemd-modules-load.service
After=systemd-modules-load.service
Before=sysvinit.target
ConditionPathExists=/sys/class/i2c-adapter
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"
[Install]
WantedBy=sysinit.target
7. Cuối cùng, cho phép service vừa tạo hoạt động
sudo systemctl enable rtc-i2c.service
Chạy thử lệnh sau đây, nếu có lỗi thì tìm nguyên nhân khắc phục (thí dụ lỗi watchdog, không liên quan đến RTC)
service rtc-i2c start
8. Xóa fake-hwclock: fake-hwclock trước kia định giờ cho RPi nhưng giờ không cần nữa, giữ lại có thể gây nhiểu cho RTC
sudo apt-get remove fake-hwclock -y
update-rc.d -f fake-hwclock remove
9. Script cài đặt
#!/bin/bash
[ -e /dev/rtc0 ] && return 0
#--Load up the RTC module
#modprobe i2c-bcm2708
#modprobe i2c-dev
#modprobe rtc-ds1307
echo "Cấu hình rtc-i2c..."
cat <<'EOF' | sudo tee /etc/modules-load.d/rtc-i2c.conf &> /dev/null
# /etc/modules-load.d/rtc-i2c.conf
i2c-dev
i2c_bcm2708
EOF
echo "Thiết lập giờ hệ thống mỗi khi thấy RTC..."
cat <<'EOF' | sudo tee /etc/udev/rules.d/rtc-i2c.rules &> /dev/null
# /etc/udev/rules.d/rtc-i2c.rules
ACTION=="add", SUBSYSTEM=="rtc", ATTRS{hctosys}=="0", RUN+="/sbin/hwclock -s --utc"
EOF
echo "Tham số cho rtc-i2c service..."
[ ! -d /etc/conf.d ] && sudo mkdir /etc/conf.d
cat <<'EOF' | sudo tee /etc/conf.d/rtc-i2c &> /dev/null
# /etc/conf.d/rtc-i2c
CHIP="ds1307"
ADDRESS="0x68"
BUS="1"
EOF
echo "Tạo service rtc-i2c..."
cat <<'EOF' | sudo tee /lib/systemd/system/rtc-i2c.service &> /dev/null
[Unit]
Description=Initialize i2c hardware RTC device driver
DefaultDependencies=no
Requires=systemd-modules-load.service
After=systemd-modules-load.service
Before=sysvinit.target
ConditionPathExists=/sys/class/i2c-adapter
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"
[Install]
WantedBy=sysinit.target
EOF
echo "dtoverlay=i2c-rtc,ds3231" | sudo tee -a /boot/config.txt
echo "Chạy service rtc-i2c..."
sudo systemctl enable rtc-i2c.service
echo "Xóa fake-hwclock..."
sudo apt-get remove fake-hwclock -y
sudo update-rc.d -f fake-hwclock remove
echo -e "\nreboot và chạy thử 'hwclock -r' để kiểm tra xem RTC có hoạt động hay không?"
Với Jessie
- Thêm vào cuối file config.txt dòng
dtoverlay=i2c-rtc,ds3231
2. Mở file /lib/udev/hwclock-set, và đặt dấu # trước các dòng sau
if [ -e /run/systemd/system ] ; then
exit 0
fi
3. Gõ lệnh date, nếu ngày giờ đúng thì gõ tiếp
sudo hwclock -w
sudo hwclock -s
4. Script cài đặt
#!/bin/bash grep -qF "dtoverlay=i2c-rtc,ds3231" "/boot/config.txt" || echo "dtoverlay=i2c-rtc,ds3231" | sudo te$ sudo sed -n '/^if \[ -e \/run\/systemd\/system \]/, +2 s|^|#|' -i /lib/udev/hwclock-set sudo hwclock -w sudo hwclock -s if [ -e /lib/systemd/system/rtc-i2c.service ]; then sudo systemctl disable rtc-i2c.service sudo rm -f /lib/systemd/system/rtc-i2c.service sudo rm -R /etc/conf.d sudo rm -f /etc/udev/rules.d/rtc-i2c.rules sudo rm -f /etc/modules-load.d/rtc-i2c.conf fi
Kiểm tra
Khởi động lại RPi để các cài đặt có tác dụng. Gõ lệnh hwclock -r để xem giờ từ RTC, nếu có thông báo lỗi thì xem xét lại các bước.
II. Để làm gì?
Trước mắt, chỉ đế RPi có đồng hồ thời gian thực mà không cần kết nối internet. Các chức năng thường có với RTC như sleep, hypernate đều không có tác dụng.