【问题标题】:Set the hardware clock in Python?在 Python 中设置硬件时钟?
【发布时间】:2011-01-12 17:33:44
【问题描述】:

如何在嵌入式 Linux 系统上使用 Python 设置硬件时钟?

【问题讨论】:

    标签: python linux hwclock


    【解决方案1】:

    除了调用 os.system() 之外,可能没有简单的方法。

    import os
    os.system('hwclock --set %s' % date_str)
    

    或使用“日期”命令

    import os
    os.system('date -s %s' % date_str)
    

    或者如果你渴望做一些 c 编码,用 swig 包装系统调用......但我认为这将比它的价值更多。

    【讨论】:

    • 应该可以做到——只要 rtc 或 rtcN 驱动程序存在——通过 ioctl,在 fcntl 中,docs.python.org/library/fcntl.html 和 rtc(4)(或内核的 D​​ocumentation/rtc.txt) -- 但是,如果您在系统上安装了 Python,那么 hwclock 应该很适合。
    • Zdav,感谢您的帮助。请注意:我正在使用busybox,首先需要使用“os.system('date -s %s'% date_str)”更改系统时钟,然后使用os.system从系统时钟设置硬件时钟('hwclock -w)。问候
    【解决方案2】:

    Ubuntu 16.04 上的更新版本:

    import subprocess
    import shlex
    
    subprocess.call(shlex.split("timedatectl set-ntp false"))  # May be necessary
    subprocess.call(shlex.split("sudo date -s '2 OCT 2006 18:00:00'"))
    subprocess.call(shlex.split("sudo hwclock -w"))
    

    重要提示:您可能需要将时间/日期设置更改为手动设置 (set-ntp false),否则它会立即将其更改回当前时间。

    hwclock -w根据当前系统时间设置硬件时钟(date设置)

    要求date & hwclock 也以sudo 运行。

    【讨论】:

      【解决方案3】:

      使用 Python 的os.system 函数调用hwclock 命令。

      【讨论】:

        【解决方案4】:

        这使用ioctl 来根据请求设置硬件时钟(但不是系统时钟)。它避免了额外的过程,但涉及更多。我正在使用pytzdateutil 来处理本地/UTC 转换。随意使用代码(3 条款 BSD 许可证)。使用get_hwclock() 获取时钟并使用set_hwclock() 设置它...

        from collections import namedtuple
        from datetime import datetime
        from fcntl import ioctl
        import struct
        from dateutil.tz import tzutc
        from pytz import timezone
        
        
        # From `uapi/asm-generic/ioctl.h`
        _IOC_NRBITS = 8
        _IOC_TYPEBITS = 8
        _IOC_SIZEBITS = 14
        _IOC_DIRBITS = 2
        
        _IOC_NRMASK = (1 << _IOC_NRBITS) - 1
        _IOC_TYPEMASK = (1 << _IOC_TYPEBITS) - 1
        _IOC_SIZEMASK = (1 << _IOC_SIZEBITS) - 1
        _IOC_DIRMASK = (1 << _IOC_DIRBITS) - 1
        
        _IOC_NRSHIFT = 0
        _IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS
        _IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS
        _IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS
        
        _IOC_NONE = 0
        _IOC_WRITE = 1
        _IOC_READ = 2
        
        
        def _IOC(dir, type, nr, size):
            return ((dir << _IOC_DIRSHIFT) |
                    (type << _IOC_TYPESHIFT) |
                    (nr << _IOC_NRSHIFT) |
                    (size << _IOC_SIZESHIFT))
        
        
        def _IOC_TYPECHECK(t):
            return len(t)
        
        
        def _IO(type, nr):
            return _IOC(_IOC_NONE, type, nr, 0)
        
        
        def _IOR(type, nr, size):
            return _IOC(_IOC_READ, type, nr, _IOC_TYPECHECK(size))
        
        
        def _IOW(type, nr, size):
            return _IOC(_IOC_WRITE, type, nr, _IOC_TYPECHECK(size))
        
        
        def to_utc(dtobj):
            if dtobj.tzinfo is None:
                dtobj = timezone("UTC").localize(
                    dtobj.replace(tzinfo=None) - tzlocal().utcoffset(dtobj))
            return dtobj.astimezone(timezone("UTC"))
        
        
        class RtcTime(namedtuple(
            # man(4) rtc
            "RtcTime",
            "tm_sec tm_min tm_hour "
            "tm_mday tm_mon tm_year "
            "tm_wday tm_yday tm_isdst"  # Last row is unused.
        )):
        
            _fmt = 9 * "i"
        
            def __new__(cls, tm_sec=0, tm_min=0, tm_hour=0,
                        tm_mday=0, tm_mon=0, tm_year=0,
                        tm_wday=0, tm_yday=0, tm_isdst=0):
                return super(RtcTime, cls).__new__(cls, tm_sec, tm_min, tm_hour,
                                                    tm_mday, tm_mon, tm_year,
                                                    tm_wday, tm_yday, tm_isdst)
        
            def __str__(self):
                return self.to_datetime().isoformat()
        
            @classmethod
            def from_datetime(cls, dtobj):
                dt = to_utc(dtobj)
                return cls(tm_sec=dt.second, tm_min=dt.minute, tm_hour=dt.hour,
                           tm_mday=dt.day, tm_mon=dt.month - 1, tm_year=dt.year - 1900)
        
            def to_datetime(self):
                # From `hwclock.c`.
                return datetime(
                    year=self.tm_year + 1900, month=self.tm_mon + 1, day=self.tm_mday,
                    hour=self.tm_hour, minute=self.tm_min, second=self.tm_sec,
                    tzinfo=tzutc())
        
            def pack(self):
                return struct.pack(self._fmt, *self)
        
            @classmethod
            def unpack(cls, buffer):
                return cls._make(struct.unpack(cls._fmt, buffer))
        
        
        # From `uapi/linux/rtc.h`
        rtc_time = RtcTime().pack()
        RTC_RD_TIME = _IOR(ord("p"), 0x09, rtc_time)   # 0x80247009
        RTC_SET_TIME = _IOW(ord("p"), 0x0a, rtc_time)  # 0x4024700a
        del rtc_time
        
        
        def get_hwclock(devrtc="/dev/rtc"):
            with open(devrtc) as rtc:
                ret = ioctl(rtc, RTC_RD_TIME, RtcTime().pack())
            return RtcTime.unpack(ret).to_datetime()
        
        
        def set_hwclock(dt, devrtc="/dev/rtc"):
            with open(devrtc) as rtc:
                ioctl(rtc, RTC_SET_TIME, RtcTime.from_datetime(dt).pack())
        

        【讨论】:

        • 非常感谢。这也可以作为图书馆使用吗?有人告诉我复制和粘贴是一种不好的模式。
        • @guettli:图书馆:我不知道。就我而言,我认为在代码库中复制和粘贴 是一种不好的模式。但是复制第三方代码,将其保存到具有适当许可的文件中,并在生产代码中使用是另一回事:它仍然像你会得到的一样干燥......
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-09-17
        • 1970-01-01
        • 2021-05-29
        • 2014-12-09
        • 1970-01-01
        • 2019-01-30
        • 1970-01-01
        相关资源
        最近更新 更多