Skip to content

Commit 72b0bea

Browse files
authored
Merge pull request #172 from JanekGraff/flash
Implement interface to internal flash storage
2 parents c7a7350 + 41c761d commit 72b0bea

File tree

6 files changed

+625
-0
lines changed

6 files changed

+625
-0
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
1616
- Provide getters to serial status flags idle/txe/rxne/tc.
1717
- Provide ability to reset timer UIF interrupt flag
1818
- PWM complementary output capability for TIM1 with new example to demonstrate
19+
- Implement interface for reading and writing to the internal flash memory and an example for demonstration.
1920
- PWM output on complementary channels only for single channel timers (TIM16 + TIM17)
2021

2122
### Fixed

Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ nb = "1"
3939
void = { version = "1.0", default-features = false }
4040
stm32-usbd = { version = "0.6", optional = true }
4141
bxcan = "0.6.0"
42+
embedded-storage = "0.3.0"
4243

4344
[dev-dependencies]
4445
cortex-m-rt = "0.7"

examples/flash_read_write.rs

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#![no_main]
2+
#![no_std]
3+
4+
use panic_halt as _;
5+
use stm32f0xx_hal as hal;
6+
7+
use crate::hal::{
8+
flash::{FlashExt, LockedFlash},
9+
pac,
10+
prelude::*,
11+
};
12+
13+
use cortex_m_rt::entry;
14+
use embedded_storage::nor_flash::{NorFlash, ReadNorFlash};
15+
16+
/// # NOTE
17+
/// This example assumes a flash size of more than 16K. If your MCU has less or equal than 16K Bytes
18+
/// of flash memory, adjust the `memory.x` file and `OFFSET_START` + `OFFSET_END` constants accordingly.
19+
#[entry]
20+
fn main() -> ! {
21+
if let Some(mut p) = pac::Peripherals::take() {
22+
let _ = p.RCC.configure().freeze(&mut p.FLASH);
23+
24+
// Check that flash is big enough for this example
25+
assert!(p.FLASH.len() > 16 * 1024);
26+
27+
// All examples use the first 16K of flash for the program so we use the first page after that
28+
const OFFSET_START: u32 = 16 * 1024;
29+
const OFFSET_END: u32 = OFFSET_START + 1024;
30+
// Unlock flash before writing
31+
let mut unlocked_flash = p.FLASH.unlocked();
32+
33+
NorFlash::erase(&mut unlocked_flash, OFFSET_START, OFFSET_END).unwrap();
34+
35+
// Write some data to the start of that page
36+
let write_data = [0xC0_u8, 0xFF_u8, 0xEE_u8, 0x00_u8];
37+
match NorFlash::write(&mut unlocked_flash, OFFSET_START, &write_data) {
38+
Err(_) => panic!(),
39+
Ok(_) => (),
40+
}
41+
42+
// Read back the written data from flash
43+
let mut read_buffer: [u8; 4] = [0; 4];
44+
unlocked_flash.read(OFFSET_START, &mut read_buffer).unwrap();
45+
assert_eq!(write_data, read_buffer);
46+
47+
// Lock flash by dropping it
48+
drop(unlocked_flash);
49+
50+
// It is also possible to read "manually" using core functions
51+
let read_data = unsafe {
52+
core::slice::from_raw_parts(
53+
(p.FLASH.address() + OFFSET_START as usize) as *const u8,
54+
write_data.len(),
55+
)
56+
};
57+
for (i, d) in read_data.iter().enumerate() {
58+
read_buffer[i] = *d;
59+
}
60+
61+
assert_eq!(write_data, read_buffer);
62+
63+
// Reading is also possible on locked flash
64+
let mut locked_flash = LockedFlash::new(p.FLASH);
65+
locked_flash.read(OFFSET_START, &mut read_buffer).unwrap();
66+
67+
assert_eq!(write_data, read_buffer);
68+
}
69+
loop {
70+
continue;
71+
}
72+
}

0 commit comments

Comments
 (0)