#[repr(C, packed(1))]pub struct EepromHeader {
pub signature: [u8; 4],
pub version: u8,
pub reserved: u8,
pub numatoms: u16,
pub eeplen: u32,
}Expand description
EEPROM header structure for Raspberry Pi The header is always 12 bytes long and follows the packed representation.
Fields§
§signature: [u8; 4]Always 0x52 0x2D 0x50 0x69 (“R-Pi”)
version: u8Format version (0x01 for first version)
reserved: u8Reserved byte (0x00)
numatoms: u16Number of atoms (Little Endian)
eeplen: u32Total length of EEPROM data (Little Endian)
Implementations§
Source§impl EepromHeader
impl EepromHeader
Sourcepub const fn new() -> Self
pub const fn new() -> Self
Creates a new EepromHeader with default values
Examples found in repository?
examples/create_test.rs (line 35)
12fn main() {
13 // Create a vendor info atom
14 let vendor_atom = VendorInfoAtom::new(
15 0x4D4F, // vendor_id (example: "MO")
16 0x1234, // product_id
17 1, // product_ver
18 "TestVendor",
19 "TestProduct",
20 [
21 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC,
22 0xDE, 0xF0,
23 ], // UUID
24 );
25
26 // Create GPIO map for bank 0
27 let gpio_atom = GpioMapAtom {
28 flags: 0x0000,
29 pins: [0u8; 28], // All pins as inputs
30 };
31
32 // Create EEPROM structure
33 #[cfg(feature = "alloc")]
34 let mut eeprom = Eeprom {
35 header: EepromHeader::new(),
36 vendor_info: vendor_atom,
37 gpio_map_bank0: gpio_atom,
38 dt_blob: None,
39 gpio_map_bank1: None,
40 custom_atoms: Vec::new(),
41 };
42
43 #[cfg(not(feature = "alloc"))]
44 let mut eeprom = Eeprom {
45 header: EepromHeader::new(),
46 vendor_info: vendor_atom,
47 gpio_map_bank0: gpio_atom,
48 dt_blob: None,
49 gpio_map_bank1: None,
50 custom_atoms: &[],
51 };
52
53 // Update header with correct counts and length
54 eeprom.update_header();
55
56 // Serialize with CRC
57 #[cfg(feature = "alloc")]
58 let serialized = eeprom.serialize_with_crc();
59
60 #[cfg(not(feature = "alloc"))]
61 let serialized = {
62 let mut buffer = [0u8; 1024]; // Буфер достаточного размера
63 let size = eeprom
64 .serialize_with_crc_to_slice(&mut buffer)
65 .expect("Failed to serialize EEPROM");
66 &buffer[..size]
67 };
68
69 // Create output directory if it doesn't exist
70 if std::fs::metadata("tests/data").is_err() {
71 std::fs::create_dir_all("tests/data").expect("Failed to create tests/data directory");
72 }
73
74 std::fs::write("tests/data/test.bin", &serialized).expect("Failed to write test file");
75
76 println!("Created tests/data/test.bin ({} bytes)", serialized.len());
77
78 // Verify the created file
79 if Eeprom::verify_crc(&serialized) {
80 println!("✅ CRC verification passed");
81 } else {
82 println!("❌ CRC verification failed");
83 }
84}More examples
examples/create_simple.rs (line 37)
12fn main() {
13 println!("📝 Creating minimal EEPROM with basic vendor info...");
14
15 // Create a minimal vendor info atom
16 let vendor_atom = VendorInfoAtom::new(
17 0x5349, // vendor_id (example: "SI" for Simple)
18 0x4D50, // product_id (example: "MP" for MiniProduct)
19 1, // product_ver
20 "Simple",
21 "MinimalHAT",
22 [
23 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
24 0xEE, 0xFF,
25 ], // Simple UUID
26 );
27
28 // Create minimal GPIO map
29 let gpio_atom = GpioMapAtom {
30 flags: 0x0000,
31 pins: [0u8; 28], // All pins unused
32 };
33
34 // Create EEPROM structure
35 #[cfg(feature = "alloc")]
36 let mut eeprom = Eeprom {
37 header: EepromHeader::new(),
38 vendor_info: vendor_atom,
39 gpio_map_bank0: gpio_atom,
40 dt_blob: None,
41 gpio_map_bank1: None,
42 custom_atoms: Vec::new(),
43 };
44
45 #[cfg(not(feature = "alloc"))]
46 let mut eeprom = Eeprom {
47 header: EepromHeader::new(),
48 vendor_info: vendor_atom,
49 gpio_map_bank0: gpio_atom,
50 dt_blob: None,
51 gpio_map_bank1: None,
52 custom_atoms: &[],
53 };
54
55 // Update header with correct counts and length
56 eeprom.update_header();
57
58 // Serialize with CRC
59 #[cfg(feature = "alloc")]
60 let serialized = eeprom.serialize_with_crc();
61
62 #[cfg(not(feature = "alloc"))]
63 let serialized = {
64 let mut buffer = [0u8; 1024]; // Буфер достаточного размера
65 let size = eeprom
66 .serialize_with_crc_to_slice(&mut buffer)
67 .expect("Failed to serialize EEPROM");
68 &buffer[..size]
69 };
70
71 // Create output directory if it doesn't exist
72 if std::fs::metadata("tests/data").is_err() {
73 std::fs::create_dir_all("tests/data").expect("Failed to create tests/data directory");
74 }
75
76 std::fs::write("tests/data/simple.bin", &serialized).expect("Failed to write simple file");
77
78 println!("Created tests/data/simple.bin ({} bytes)", serialized.len());
79
80 // Verify the created file
81 if Eeprom::verify_crc(&serialized) {
82 println!("✅ CRC verification passed");
83 } else {
84 println!("❌ CRC verification failed");
85 }
86}examples/bare_metal_example.rs (line 49)
16fn main() {
17 // This example demonstrates how to use ehatrom in a bare-metal environment
18 // without heap allocation
19
20 // Create EEPROM structure with static data
21 let vendor_info = VendorInfoAtom::new(
22 0x0001, // vendor_id
23 0x0002, // product_id
24 0x0001, // product_ver
25 "Acme Corp",
26 "Test HAT",
27 [
28 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
29 0x77, 0x88,
30 ],
31 );
32
33 let gpio_map = GpioMapAtom {
34 flags: 0x0001,
35 pins: [0; 28], // All pins disabled
36 };
37
38 // Custom atoms with static data
39 static CUSTOM_DATA: &[u8] = b"Hello, Bare Metal!";
40
41 // In no_std environment, custom_atoms would be a static slice
42 #[cfg(not(feature = "alloc"))]
43 static CUSTOM_ATOMS: &[(u8, &[u8])] = &[(0x80, CUSTOM_DATA)];
44
45 #[cfg(feature = "alloc")]
46 let custom_atoms = vec![(0x80u8, CUSTOM_DATA.to_vec())];
47
48 let mut eeprom = Eeprom {
49 header: EepromHeader::new(),
50 vendor_info,
51 gpio_map_bank0: gpio_map,
52 dt_blob: None,
53 gpio_map_bank1: None,
54 #[cfg(feature = "alloc")]
55 custom_atoms,
56 #[cfg(not(feature = "alloc"))]
57 custom_atoms: CUSTOM_ATOMS,
58 };
59
60 eeprom.update_header();
61
62 // Calculate required buffer size
63 let buffer_size = eeprom.calculate_serialized_size();
64 println!("Required buffer size: {buffer_size} bytes");
65
66 // Serialize to fixed buffer (demonstrates no heap allocation approach)
67 let mut buffer = vec![0u8; 512]; // In real no_std, this would be a static array
68
69 #[cfg(feature = "alloc")]
70 {
71 // Standard allocation-based serialization
72 let serialized = eeprom.serialize();
73 println!("Serialized {} bytes using Vec", serialized.len());
74 }
75
76 // Demonstrate no-allocation serialization (available in both std and no_std)
77 let mut offset = 0;
78 match eeprom.serialize_to_buffer(&mut buffer, &mut offset) {
79 Ok(()) => {
80 println!("Successfully serialized {offset} bytes to buffer");
81 println!("First 16 bytes: {:02X?}", &buffer[..16.min(offset)]);
82 }
83 Err(e) => {
84 println!("Serialization failed: {e:?}");
85 }
86 }
87
88 println!("EEPROM structure:\n{eeprom}");
89}examples/create_advanced.rs (line 82)
13fn main() {
14 println!("🚀 Creating advanced EEPROM with Device Tree support...");
15
16 // Create a vendor info atom with detailed information
17 let vendor_atom = VendorInfoAtom::new(
18 0x414C, // vendor_id (example: "AL" for AleksejZaharčenko)
19 0x2024, // product_id (year)
20 1, // product_ver
21 "4STM4 Ocultum",
22 "Advanced HAT Demo",
23 [
24 // UUID for this specific HAT
25 0x12, 0x34, 0x56, 0x78, 0x9A, 0xBC, 0xDE, 0xF0, 0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54,
26 0x32, 0x10,
27 ],
28 );
29
30 // Create GPIO map for bank 0 with specific pin configurations
31 let mut gpio_pins = [0u8; 28];
32
33 // Configure some pins as outputs (value 1)
34 gpio_pins[18] = 1; // GPIO 18 as output
35 gpio_pins[19] = 1; // GPIO 19 as output
36 gpio_pins[20] = 1; // GPIO 20 as output
37 gpio_pins[21] = 1; // GPIO 21 as output
38
39 // Other pins remain as inputs (value 0)
40
41 let gpio_atom = GpioMapAtom {
42 flags: 0x0001, // Set some flags
43 pins: gpio_pins,
44 };
45
46 // Create a simple Device Tree blob (minimal example)
47 // In real use, this would be a proper compiled device tree
48 let dt_blob_data = b"# Simple Device Tree overlay for demo HAT
49/dts-v1/;
50/plugin/;
51
52/ {
53 compatible = \"brcm,bcm2835\";
54
55 fragment@0 {
56 target = <&gpio>;
57 __overlay__ {
58 demo_pins: demo_pins {
59 brcm,pins = <18 19 20 21>;
60 brcm,function = <1>; /* GPIO_OUT */
61 };
62 };
63 };
64
65 fragment@1 {
66 target-path = \"/\";
67 __overlay__ {
68 demo_hat {
69 compatible = \"4stm4,demo-hat\";
70 pinctrl-names = \"default\";
71 pinctrl-0 = <&demo_pins>;
72 status = \"okay\";
73 };
74 };
75 };
76};"
77 .to_vec();
78
79 // Create EEPROM structure with all components
80 #[cfg(feature = "alloc")]
81 let mut eeprom = Eeprom {
82 header: EepromHeader::new(),
83 vendor_info: vendor_atom,
84 gpio_map_bank0: gpio_atom,
85 dt_blob: Some(dt_blob_data), // dt_blob is Option<Vec<u8>>
86 gpio_map_bank1: None, // Not used in this example
87 custom_atoms: Vec::new(),
88 };
89
90 #[cfg(not(feature = "alloc"))]
91 // Для no_std режима создаем статические данные
92 let mut eeprom = {
93 // Для no_std нам нужны статические данные, это просто заглушка
94 static DT_BLOB_DATA: [u8; 1] = [0];
95 static CUSTOM_ATOMS: [(u8, &[u8]); 0] = [];
96 Eeprom {
97 header: EepromHeader::new(),
98 vendor_info: vendor_atom,
99 gpio_map_bank0: gpio_atom,
100 dt_blob: Some(&DT_BLOB_DATA), // dt_blob is Option<&[u8]> в no_std
101 gpio_map_bank1: None,
102 custom_atoms: &CUSTOM_ATOMS,
103 }
104 };
105
106 // Update header with correct counts and length
107 eeprom.update_header();
108
109 // Serialize with CRC
110 #[cfg(feature = "alloc")]
111 let serialized = eeprom.serialize_with_crc();
112
113 #[cfg(not(feature = "alloc"))]
114 // Создаем буфер и вектор для копирования данных
115 let serialized = {
116 let mut buffer = [0u8; 4096]; // Больший буфер для DT blob
117 let size = eeprom
118 .serialize_with_crc_to_slice(&mut buffer)
119 .expect("Failed to serialize EEPROM");
120 // Копируем данные в новый вектор
121 buffer[..size].to_vec()
122 };
123 let filename = "tests/data/advanced.bin";
124
125 // Create output directory if it doesn't exist
126 if std::fs::metadata("tests/data").is_err() {
127 std::fs::create_dir_all("tests/data").expect("Failed to create tests/data directory");
128 }
129
130 std::fs::write(filename, &serialized).expect("Failed to write advanced EEPROM file");
131
132 println!("✅ Created {} ({} bytes)", filename, serialized.len());
133 println!("📊 EEPROM structure:");
134 println!(" • Header: 12 bytes");
135 println!(
136 " • Vendor Info: {} bytes",
137 std::mem::size_of::<VendorInfoAtom>() + "4STM4 Ocultum".len() + "Advanced HAT Demo".len()
138 );
139 println!(
140 " • GPIO Map Bank 0: {} bytes",
141 std::mem::size_of::<GpioMapAtom>()
142 );
143 println!(
144 " • Device Tree Blob: {} bytes",
145 serialized.len()
146 - 12
147 - std::mem::size_of::<VendorInfoAtom>()
148 - "4STM4 Ocultum".len()
149 - "Advanced HAT Demo".len()
150 - std::mem::size_of::<GpioMapAtom>()
151 - 4
152 );
153 println!(" • CRC32: 4 bytes");
154
155 // Verify the created file
156 if Eeprom::verify_crc(&serialized) {
157 println!("✅ CRC32 verification passed");
158 } else {
159 println!("❌ CRC32 verification failed");
160 }
161
162 println!("🎯 Use './target/release/ehatrom show {filename}' to analyze the created EEPROM");
163}examples/create_custom_atoms.rs (line 81)
12fn main() {
13 println!("📝 Creating EEPROM with custom atoms...");
14
15 // Create a list to hold our custom atoms
16 let mut custom_atoms = Vec::new();
17
18 // Create vendor info atom
19 let vendor_atom = VendorInfoAtom::new(
20 0x4143, // vendor_id "AC" (example)
21 0x0001, // product_id
22 2, // product_ver
23 "ACME Custom HATs",
24 "SensorBoard Plus",
25 [
26 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
27 0xEE, 0xFF,
28 ], // UUID
29 );
30
31 // Create GPIO map for bank 0 - more complex pin assignments
32 let mut pins = [0u8; 28];
33 pins[4] = 0x01; // GPIO4 - Input
34 pins[17] = 0x02; // GPIO17 - Output
35 pins[18] = 0x02; // GPIO18 - Output
36 pins[22] = 0x01; // GPIO22 - Input
37 pins[23] = 0x01; // GPIO23 - Input
38 pins[24] = 0x02; // GPIO24 - Output
39 pins[25] = 0x02; // GPIO25 - Output
40 let gpio_atom = GpioMapAtom {
41 flags: 0x0000,
42 pins,
43 };
44
45 // Custom atom 1: Configuration string
46 let config_str = "MODE=SENSORS,INTERVAL=250,UNITS=METRIC".to_string();
47 custom_atoms.push((0x81, config_str.into_bytes())); // Using tuple format (type, data)
48
49 // Custom atom 2: Sensor calibration data (example of binary data)
50 let mut sensor_cal = Vec::new();
51 // Temperature offset and gain
52 sensor_cal.extend_from_slice(&((-2.5f32).to_be_bytes()));
53 sensor_cal.extend_from_slice(&(1.03f32.to_be_bytes()));
54 // Humidity offset and gain
55 sensor_cal.extend_from_slice(&(1.2f32.to_be_bytes()));
56 sensor_cal.extend_from_slice(&(0.98f32.to_be_bytes()));
57 // Pressure offset and gain
58 sensor_cal.extend_from_slice(&(15.0f32.to_be_bytes()));
59 sensor_cal.extend_from_slice(&(1.0f32.to_be_bytes()));
60 custom_atoms.push((0x82, sensor_cal)); // Using tuple format (type, data)
61
62 // Custom atom 3: Hardware version info as string
63 let hw_info = format!(
64 "HW_VERSION={}.{}.{},PCB_REV=C,ASSEMBLY_DATE=2024-12-20",
65 env!("CARGO_PKG_VERSION_MAJOR"),
66 env!("CARGO_PKG_VERSION_MINOR"),
67 env!("CARGO_PKG_VERSION_PATCH")
68 );
69 custom_atoms.push((0x83, hw_info.into_bytes())); // Using tuple format (type, data)
70
71 // Custom atom 4: Binary data (e.g., lookup table)
72 let mut lookup_table = Vec::new();
73 for i in 0..32 {
74 lookup_table.push((i * i) as u8); // Simple quadratic lookup table
75 }
76 custom_atoms.push((0x84, lookup_table)); // Using tuple format (type, data)
77
78 // Create EEPROM structure
79 #[cfg(feature = "alloc")]
80 let mut eeprom = Eeprom {
81 header: EepromHeader::new(),
82 vendor_info: vendor_atom,
83 gpio_map_bank0: gpio_atom,
84 dt_blob: None,
85 gpio_map_bank1: None,
86 custom_atoms,
87 };
88
89 #[cfg(not(feature = "alloc"))]
90 // Для no_std режима создаем статические данные
91 let mut eeprom = {
92 // Для no_std нам нужны статические данные, это просто заглушка
93 static CUSTOM_ATOMS: [(u8, &[u8]); 0] = [];
94 Eeprom {
95 header: EepromHeader::new(),
96 vendor_info: vendor_atom,
97 gpio_map_bank0: gpio_atom,
98 dt_blob: None,
99 gpio_map_bank1: None,
100 custom_atoms: &CUSTOM_ATOMS,
101 }
102 };
103
104 // Update header with correct counts and length
105 eeprom.update_header();
106
107 // Serialize with CRC
108 #[cfg(feature = "alloc")]
109 let serialized = eeprom.serialize_with_crc();
110
111 #[cfg(not(feature = "alloc"))]
112 // Создаем буфер и вектор для копирования данных
113 let serialized = {
114 let mut buffer = [0u8; 1024]; // Буфер достаточного размера
115 let size = eeprom
116 .serialize_with_crc_to_slice(&mut buffer)
117 .expect("Failed to serialize EEPROM");
118 // Копируем данные в новый вектор
119 buffer[..size].to_vec()
120 };
121
122 let filename = "tests/data/custom_atoms.bin";
123
124 // Create output directory if it doesn't exist
125 if std::fs::metadata("tests/data").is_err() {
126 std::fs::create_dir_all("tests/data").expect("Failed to create tests/data directory");
127 }
128
129 std::fs::write(filename, &serialized).expect("Failed to write custom atoms EEPROM file");
130
131 println!("✅ Created {} ({} bytes)", filename, serialized.len());
132 println!("📊 EEPROM contains:");
133 println!(" • Standard HAT header");
134 println!(" • Vendor info atom");
135 println!(" • GPIO map atom");
136 println!(" • 4 custom atoms:");
137 println!(" - 0x81: Configuration string");
138 println!(" - 0x82: Sensor calibration data");
139 println!(" - 0x83: Hardware version info");
140 println!(" - 0x84: Lookup table (32 bytes)");
141
142 // Verify the created file
143 if Eeprom::verify_crc(&serialized) {
144 println!("✅ CRC32 verification passed");
145 } else {
146 println!("❌ CRC32 verification failed");
147 }
148
149 println!("💡 This demonstrates how to embed custom application-specific data in HAT EEPROM");
150}Trait Implementations§
Source§impl Clone for EepromHeader
impl Clone for EepromHeader
Source§fn clone(&self) -> EepromHeader
fn clone(&self) -> EepromHeader
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreSource§impl Debug for EepromHeader
impl Debug for EepromHeader
Source§impl Default for EepromHeader
impl Default for EepromHeader
Source§fn default() -> EepromHeader
fn default() -> EepromHeader
Returns the “default value” for a type. Read more
Source§impl Display for EepromHeader
impl Display for EepromHeader
impl Copy for EepromHeader
Auto Trait Implementations§
impl Freeze for EepromHeader
impl RefUnwindSafe for EepromHeader
impl Send for EepromHeader
impl Sync for EepromHeader
impl Unpin for EepromHeader
impl UnwindSafe for EepromHeader
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more