pub struct Eeprom {
pub header: EepromHeader,
pub vendor_info: VendorInfoAtom,
pub gpio_map_bank0: GpioMapAtom,
pub dt_blob: Option<Vec<u8>>,
pub gpio_map_bank1: Option<GpioMapAtom>,
pub custom_atoms: Vec<(u8, Vec<u8>)>,
}Fields§
§header: EepromHeader§vendor_info: VendorInfoAtom§gpio_map_bank0: GpioMapAtom§dt_blob: Option<Vec<u8>>§gpio_map_bank1: Option<GpioMapAtom>§custom_atoms: Vec<(u8, Vec<u8>)>Implementations§
Source§impl Eeprom
impl Eeprom
Sourcepub fn from_bytes(data: &[u8]) -> Result<Self, &'static str>
pub fn from_bytes(data: &[u8]) -> Result<Self, &'static str>
Parses an EEPROM image from a byte slice, validating the signature and CRC.
This variant allocates owned buffers for atoms, making it suitable for
environments where alloc is available.
pub fn add_vendor_info(&mut self, atom: VendorInfoAtom)
pub fn add_gpio_map_bank0(&mut self, atom: GpioMapAtom)
pub fn add_dt_blob(&mut self, blob: Vec<u8>)
pub fn add_gpio_map_bank1(&mut self, atom: GpioMapAtom)
pub fn add_custom_atom(&mut self, atom_type: u8, data: Vec<u8>)
Sourcepub fn update_header(&mut self)
pub fn update_header(&mut self)
Recalculate numatoms and eeplen after adding atoms
Examples found in repository?
examples/create_test.rs (line 54)
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 56)
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 60)
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 107)
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 105)
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}Sourcepub fn serialize_with_crc(&self) -> Vec<u8>
pub fn serialize_with_crc(&self) -> Vec<u8>
Serialize with CRC32 appended (4 bytes LE)
Examples found in repository?
examples/create_test.rs (line 58)
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 60)
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/create_advanced.rs (line 111)
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 109)
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}Sourcepub fn verify_crc(data: &[u8]) -> bool
pub fn verify_crc(data: &[u8]) -> bool
CRC32 check (expects last 4 bytes to be CRC32 LE)
Examples found in repository?
examples/create_test.rs (line 79)
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 81)
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/create_advanced.rs (line 156)
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 143)
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}Sourcepub fn serialize(&self) -> Vec<u8>
pub fn serialize(&self) -> Vec<u8>
Serialize EEPROM structure to Vec<u8> (without CRC)
Examples found in repository?
examples/bare_metal_example.rs (line 72)
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}Sourcepub fn serialize_to_slice_universal(
&self,
buffer: &mut [u8],
) -> Result<usize, EhatromError>
pub fn serialize_to_slice_universal( &self, buffer: &mut [u8], ) -> Result<usize, EhatromError>
Serialize EEPROM structure to buffer (universal version)
Sourcepub fn calculate_serialized_size(&self) -> usize
pub fn calculate_serialized_size(&self) -> usize
Helper method to calculate total serialized size
Examples found in repository?
examples/bare_metal_example.rs (line 63)
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}Sourcepub fn serialize_to_buffer(
&self,
buffer: &mut [u8],
offset: &mut usize,
) -> Result<(), EhatromError>
pub fn serialize_to_buffer( &self, buffer: &mut [u8], offset: &mut usize, ) -> Result<(), EhatromError>
Internal method to serialize into buffer (no_std version)
Examples found in repository?
examples/bare_metal_example.rs (line 78)
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}pub fn set_version(&mut self, version: u8)
Trait Implementations§
Auto Trait Implementations§
impl Freeze for Eeprom
impl RefUnwindSafe for Eeprom
impl Send for Eeprom
impl Sync for Eeprom
impl Unpin for Eeprom
impl UnwindSafe for Eeprom
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