kernel/hil/
log.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Interface for a persistent log that stores distinct log entries.
6//!
7//! Log entries are appended to the end of a log and read back sequentially. Log data persists
8//! across device reboots.
9
10use crate::ErrorCode;
11
12/// An interface for reading from log storage.
13pub trait LogRead<'a> {
14    /// Unique identifier for log entries.
15    type EntryID;
16
17    /// Set the client for reading from a log. The client will be called when reading operations complete.
18    fn set_read_client(&'a self, read_client: &'a dyn LogReadClient);
19
20    /// Read the next entry from the log. The log advances to the next entry after a successful
21    /// read. State does not change in the event of a failure.
22    fn read(
23        &self,
24        buffer: &'static mut [u8],
25        length: usize,
26    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
27
28    /// Returns the entry ID at the start of the log. This is the ID of the oldest remaining entry.
29    fn log_start(&self) -> Self::EntryID;
30
31    /// Returns the entry ID at the end of the log. This is the ID of the next entry to be
32    /// appended.
33    fn log_end(&self) -> Self::EntryID;
34
35    /// Returns the ID of the next entry to be read.
36    fn next_read_entry_id(&self) -> Self::EntryID;
37
38    /// Seek to the entry with the given entry ID and begin reading from there. Fails without
39    /// modifying the read position if the given entry ID is invalid or no longer in the log.
40    fn seek(&self, entry: Self::EntryID) -> Result<(), ErrorCode>;
41
42    /// Get approximate log capacity in bytes.
43    fn get_size(&self) -> usize;
44}
45
46/// Receive callbacks from `LogRead`.
47pub trait LogReadClient {
48    /// Returns a buffer containing data read and the length of the number of bytes read or an error
49    /// code if the read failed.
50    fn read_done(&self, buffer: &'static mut [u8], length: usize, error: Result<(), ErrorCode>);
51
52    /// Returns whether the seek succeeded or failed.
53    fn seek_done(&self, error: Result<(), ErrorCode>);
54}
55
56/// An interface for writing to log storage.
57pub trait LogWrite<'a> {
58    /// Set the client for appending from a log. The client will be called when writing operations complete.
59    fn set_append_client(&'a self, append_client: &'a dyn LogWriteClient);
60
61    /// Append an entry to the end of the log. May fail if the entry is too large.
62    fn append(
63        &self,
64        buffer: &'static mut [u8],
65        length: usize,
66    ) -> Result<(), (ErrorCode, &'static mut [u8])>;
67
68    /// Sync log to storage, making all entries persistent (not including any entries that were
69    /// previously overwritten). There is no guarantee that any changes to the log are persistent
70    /// until it is synced. In the event of an error, not all pages may be synced, but the log will
71    /// remain in a valid state.
72    fn sync(&self) -> Result<(), ErrorCode>;
73
74    /// Erase the entire log. In the event of a failure, only some pages may be erased, but the log
75    /// will remain in a valid state.
76    fn erase(&self) -> Result<(), ErrorCode>;
77}
78
79/// Receive callbacks from `LogWrite`.
80pub trait LogWriteClient {
81    /// Returns the original buffer that contained the data to write, the number of bytes written,
82    /// and whether any old entries in the log were lost (due to a circular log being filled up).
83    fn append_done(
84        &self,
85        buffer: &'static mut [u8],
86        length: usize,
87        records_lost: bool,
88        error: Result<(), ErrorCode>,
89    );
90
91    /// Returns whether or not all pages were correctly synced, making all changes persistent.
92    fn sync_done(&self, error: Result<(), ErrorCode>);
93
94    /// Returns whether or not all pages of the log were erased.
95    fn erase_done(&self, error: Result<(), ErrorCode>);
96}