Chrono Integration
Relevant source files
This document covers the optional chrono
feature integration that provides high-level DateTime operations for the ARM PL031 RTC driver. This feature extends the core Unix timestamp API with convenient date and time handling using the chrono
crate.
For information about the core driver functionality and Unix timestamp operations, see Core Driver Implementation. For details about enabling and configuring the chrono feature, see Feature Configuration.
Purpose and Scope
The chrono integration provides a type-safe, ergonomic API layer over the core RTC driver by converting between Unix timestamps and DateTime<Utc>
objects. This feature is enabled by default but can be disabled for minimal deployments that only need raw timestamp operations.
The integration handles timezone considerations by standardizing on UTC, performs bounds checking for timestamp conversions, and maintains the same interrupt and match functionality as the core API while operating on DateTime objects.
API Overview
The chrono integration extends the Rtc
struct with three additional methods that mirror the core timestamp operations but operate on DateTime<Utc>
types.
DateTime Operations
Method | Core Equivalent | Purpose |
---|---|---|
get_time() | get_unix_timestamp() | Read current time as DateTime |
set_time() | set_unix_timestamp() | Set current time from DateTime |
set_match() | set_match_timestamp() | Set match time for interrupts |
Method Implementation Details
Time Reading
The get_time()
method provides a safe conversion from the hardware's 32-bit Unix timestamp to a proper DateTime object:
flowchart TD RTC["Rtc::get_time()"] CORE["get_unix_timestamp()"] CONVERT["Utc.timestamp_opt()"] UNWRAP["unwrap()"] DATETIME["DateTime"] CONVERT --> UNWRAP CORE --> CONVERT RTC --> CORE UNWRAP --> DATETIME
Chrono DateTime Conversion Flow
The conversion uses chrono::Utc::timestamp_opt()
with nanoseconds set to 0, since the PL031 hardware only provides second-level precision. The unwrap()
is safe because valid PL031 timestamps always fall within chrono's supported range.
Sources: src/chrono.rs(L6 - L10)
Time Setting
The set_time()
method handles the reverse conversion with proper error handling for out-of-bounds timestamps:
flowchart TD INPUT["DateTime"] TIMESTAMP["time.timestamp()"] CONVERT["try_into()?"] SUCCESS["set_unix_timestamp()"] ERROR["TryFromIntError"] CONVERT --> ERROR CONVERT --> SUCCESS INPUT --> TIMESTAMP TIMESTAMP --> CONVERT
DateTime to Timestamp Conversion with Error Handling
The method returns Result<(), TryFromIntError>
to handle cases where the DateTime represents a time outside the PL031's supported range (Unix timestamps that don't fit in 32 bits).
Sources: src/chrono.rs(L12 - L18)
Match Register Integration
The set_match()
method extends the interrupt functionality to work with DateTime objects:
flowchart TD subgraph subGraph2["Hardware Layer"] PL031_MR["PL031 Match Register"] INTERRUPT_GEN["Interrupt Generation"] end subgraph subGraph1["Core Driver Layer"] SET_MATCH_TS["set_match_timestamp(u32)"] MATCH_REG["write_volatile(MR)"] end subgraph subGraph0["Chrono API Layer"] SET_MATCH["set_match(DateTime)"] CONVERT_MATCH["match_time.timestamp().try_into()?"] end CONVERT_MATCH --> SET_MATCH_TS MATCH_REG --> PL031_MR PL031_MR --> INTERRUPT_GEN SET_MATCH --> CONVERT_MATCH SET_MATCH_TS --> MATCH_REG
Match Register DateTime Integration
This allows applications to schedule interrupts using natural DateTime objects rather than calculating Unix timestamps manually.
Sources: src/chrono.rs(L20 - L26)
Error Handling and Type Safety
Conversion Error Types
The chrono integration uses TryFromIntError
to handle timestamp conversion failures. This occurs when attempting to convert a DateTime
that represents a time outside the range of a 32-bit Unix timestamp (before 1970 or after 2106).
flowchart TD DATETIME["DateTime"] TIMESTAMP["i64 timestamp"] CHECK["fits in u32?"] SUCCESS["u32 timestamp"] ERROR["TryFromIntError"] CORE_API["Core RTC API"] CHECK --> ERROR CHECK --> SUCCESS DATETIME --> TIMESTAMP SUCCESS --> CORE_API TIMESTAMP --> CHECK
Timestamp Range Validation
Applications should handle these errors appropriately, either by validating DateTime inputs or providing fallback behavior for out-of-range times.
UTC Timezone Handling
The integration standardizes on UTC timezone to avoid complex timezone conversion logic in embedded systems. This ensures consistent behavior across different deployment environments and simplifies the API surface.
Sources: src/chrono.rs(L1 - L3)
Integration with Core Functionality
The chrono methods are thin wrappers around the core driver functionality, maintaining the same safety properties and hardware access patterns while providing a more convenient interface.
flowchart TD subgraph Hardware["Hardware"] PL031["ARM PL031 RTC"] end subgraph subGraph2["Core Driver (lib.rs)"] GET_UNIX["get_unix_timestamp()"] SET_UNIX["set_unix_timestamp()"] SET_MATCH_UNIX["set_match_timestamp()"] REGISTERS["Register Operations"] end subgraph subGraph1["Chrono Feature (chrono.rs)"] GET_TIME["get_time()"] SET_TIME["set_time()"] SET_MATCH_CHRONO["set_match()"] end subgraph subGraph0["Application Code"] APP_CHRONO["DateTime Operations"] APP_CORE["Unix Timestamp Operations"] end APP_CHRONO --> GET_TIME APP_CHRONO --> SET_MATCH_CHRONO APP_CHRONO --> SET_TIME APP_CORE --> GET_UNIX APP_CORE --> SET_MATCH_UNIX APP_CORE --> SET_UNIX GET_TIME --> GET_UNIX GET_UNIX --> REGISTERS REGISTERS --> PL031 SET_MATCH_CHRONO --> SET_MATCH_UNIX SET_MATCH_UNIX --> REGISTERS SET_TIME --> SET_UNIX SET_UNIX --> REGISTERS
Chrono Integration Architecture
This design allows applications to choose the appropriate abstraction level: high-level DateTime operations for convenience, or low-level timestamp operations for performance-critical code.
Sources: src/chrono.rs(L1 - L27)