Skip to content

Commit 4ce425e

Browse files
committed
add blank_check command
Add a command to perform a blank check on a device. This is an alternate method for devices that have ECC, where a blank device doesn't necessarily have a predetermined or homogenous bit pattern. Signed-off-by: Sean Cross <[email protected]>
1 parent be44533 commit 4ce425e

File tree

2 files changed

+97
-38
lines changed

2 files changed

+97
-38
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ description = "A crate to write CMSIS-DAP flash algorithms for flashing embedded
1212

1313
[features]
1414
default = ["erase-chip", "panic-handler"]
15+
blank-check = []
1516
erase-chip = []
1617
panic-handler = []
1718
read-flash = []

src/lib.rs

Lines changed: 96 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
3030
pub const FUNCTION_ERASE: u32 = 1;
3131
pub const FUNCTION_PROGRAM: u32 = 2;
3232
pub const FUNCTION_VERIFY: u32 = 3;
33+
pub const FUNCTION_BLANKCHECK: u32 = 4;
3334

3435
pub type ErrorCode = core::num::NonZeroU32;
3536

@@ -84,13 +85,23 @@ pub trait FlashAlgorithm: Sized + 'static {
8485
/// * `data` - The data.
8586
#[cfg(feature = "read-flash")]
8687
fn read_flash(&mut self, address: u32, data: &mut [u8]) -> Result<(), ErrorCode>;
88+
89+
/// Verify that flash is blank.
90+
///
91+
/// # Arguments
92+
///
93+
/// * `address` - The start address of the flash to check.
94+
/// * `size` - The length of the area to check.
95+
#[cfg(feature = "blank-check")]
96+
fn blank_check(&mut self, address: u32, size: u32) -> Result<(), ErrorCode>;
8797
}
8898

8999
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
90100
pub enum Function {
91101
Erase = 1,
92102
Program = 2,
93103
Verify = 3,
104+
BlankCheck = 4,
94105
}
95106

96107
/// A macro to define a new flash algoritm.
@@ -115,26 +126,29 @@ macro_rules! algorithm {
115126
}) => {
116127
static mut _IS_INIT: bool = false;
117128
static mut _ALGO_INSTANCE: core::mem::MaybeUninit<$type> = core::mem::MaybeUninit::uninit();
118-
129+
119130
core::arch::global_asm!(".section .PrgData, \"aw\"");
120-
131+
121132
#[no_mangle]
122133
#[link_section = ".entry"]
123134
pub unsafe extern "C" fn Init(addr: u32, clock: u32, function: u32) -> u32 {
124-
if _IS_INIT {
125-
UnInit();
135+
unsafe {
136+
if _IS_INIT {
137+
UnInit();
138+
}
139+
_IS_INIT = true;
126140
}
127-
_IS_INIT = true;
128141
let function = match function {
129142
1 => $crate::Function::Erase,
130143
2 => $crate::Function::Program,
131144
3 => $crate::Function::Verify,
145+
4 => $crate::Function::BlankCheck,
132146
_ => core::panic!("This branch can only be reached if the host library sent an unknown function code.")
133147
};
134148
match <$type as $crate::FlashAlgorithm>::new(addr, clock, function) {
135149
Ok(inst) => {
136-
_ALGO_INSTANCE.as_mut_ptr().write(inst);
137-
_IS_INIT = true;
150+
unsafe { _ALGO_INSTANCE.as_mut_ptr().write(inst) };
151+
unsafe { _IS_INIT = true };
138152
0
139153
}
140154
Err(e) => e.get(),
@@ -143,20 +157,24 @@ macro_rules! algorithm {
143157
#[no_mangle]
144158
#[link_section = ".entry"]
145159
pub unsafe extern "C" fn UnInit() -> u32 {
146-
if !_IS_INIT {
147-
return 1;
160+
unsafe {
161+
if !_IS_INIT {
162+
return 1;
163+
}
164+
_ALGO_INSTANCE.as_mut_ptr().drop_in_place();
165+
_IS_INIT = false;
148166
}
149-
_ALGO_INSTANCE.as_mut_ptr().drop_in_place();
150-
_IS_INIT = false;
151167
0
152168
}
153169
#[no_mangle]
154170
#[link_section = ".entry"]
155171
pub unsafe extern "C" fn EraseSector(addr: u32) -> u32 {
156-
if !_IS_INIT {
157-
return 1;
158-
}
159-
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
172+
let this = unsafe {
173+
if !unsafe { _IS_INIT } {
174+
return 1;
175+
}
176+
&mut *_ALGO_INSTANCE.as_mut_ptr()
177+
};
160178
match <$type as $crate::FlashAlgorithm>::erase_sector(this, addr) {
161179
Ok(()) => 0,
162180
Err(e) => e.get(),
@@ -165,11 +183,14 @@ macro_rules! algorithm {
165183
#[no_mangle]
166184
#[link_section = ".entry"]
167185
pub unsafe extern "C" fn ProgramPage(addr: u32, size: u32, data: *const u8) -> u32 {
168-
if !_IS_INIT {
169-
return 1;
170-
}
171-
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
172-
let data_slice: &[u8] = unsafe { core::slice::from_raw_parts(data, size as usize) };
186+
let (this, data_slice) = unsafe {
187+
if !_IS_INIT {
188+
return 1;
189+
}
190+
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
191+
let data_slice: &[u8] = core::slice::from_raw_parts(data, size as usize);
192+
(this, data_slice)
193+
};
173194
match <$type as $crate::FlashAlgorithm>::program_page(this, addr, data_slice) {
174195
Ok(()) => 0,
175196
Err(e) => e.get(),
@@ -178,7 +199,8 @@ macro_rules! algorithm {
178199
$crate::erase_chip!($type);
179200
$crate::read_flash!($type);
180201
$crate::verify!($type);
181-
202+
$crate::blank_check!($type);
203+
182204
#[allow(non_upper_case_globals)]
183205
#[no_mangle]
184206
#[used]
@@ -217,7 +239,7 @@ macro_rules! algorithm {
217239
}
218240
],
219241
};
220-
242+
221243
#[repr(C)]
222244
pub struct FlashDeviceDescription {
223245
vers: u16,
@@ -230,17 +252,17 @@ macro_rules! algorithm {
230252
empty: u8,
231253
program_time_out: u32,
232254
erase_time_out: u32,
233-
255+
234256
flash_sectors: [FlashSector; $crate::count!($($size)*) + 1],
235257
}
236-
258+
237259
#[repr(C)]
238260
#[derive(Copy, Clone)]
239261
pub struct FlashSector {
240262
size: u32,
241263
address: u32,
242264
}
243-
265+
244266
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
245267
#[repr(u16)]
246268
pub enum DeviceType {
@@ -268,10 +290,12 @@ macro_rules! erase_chip {
268290
#[no_mangle]
269291
#[link_section = ".entry"]
270292
pub unsafe extern "C" fn EraseChip() -> u32 {
271-
if !_IS_INIT {
272-
return 1;
273-
}
274-
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
293+
let this = unsafe {
294+
if !_IS_INIT {
295+
return 1;
296+
}
297+
&mut *_ALGO_INSTANCE.as_mut_ptr()
298+
};
275299
match <$type as $crate::FlashAlgorithm>::erase_all(this) {
276300
Ok(()) => 0,
277301
Err(e) => e.get(),
@@ -294,11 +318,15 @@ macro_rules! read_flash {
294318
#[no_mangle]
295319
#[link_section = ".entry"]
296320
pub unsafe extern "C" fn ReadFlash(addr: u32, size: u32, data: *mut u8) -> u32 {
297-
if !_IS_INIT {
298-
return 1;
299-
}
300-
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
301-
let data_slice: &mut [u8] = unsafe { core::slice::from_raw_parts_mut(data, size as usize) };
321+
let (this, data_slice) = unsafe {
322+
if !_IS_INIT {
323+
return 1;
324+
}
325+
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
326+
let data_slice: &mut [u8] =
327+
core::slice::from_raw_parts_mut(data, size as usize);
328+
(this, data_slice)
329+
};
302330
match <$type as $crate::FlashAlgorithm>::read_flash(this, addr, data_slice) {
303331
Ok(()) => 0,
304332
Err(e) => e.get(),
@@ -321,10 +349,12 @@ macro_rules! verify {
321349
#[no_mangle]
322350
#[link_section = ".entry"]
323351
pub unsafe extern "C" fn Verify(addr: u32, size: u32, data: *const u8) -> u32 {
324-
if !_IS_INIT {
325-
return 1;
326-
}
327-
let this = &mut *_ALGO_INSTANCE.as_mut_ptr();
352+
let this = unsafe {
353+
if !_IS_INIT {
354+
return 1;
355+
}
356+
&mut *_ALGO_INSTANCE.as_mut_ptr()
357+
};
328358

329359
if data.is_null() {
330360
match <$type as $crate::FlashAlgorithm>::verify(this, addr, size, None) {
@@ -343,6 +373,34 @@ macro_rules! verify {
343373
};
344374
}
345375

376+
#[doc(hidden)]
377+
#[macro_export]
378+
#[cfg(not(feature = "blank-check"))]
379+
macro_rules! blank_check {
380+
($type:ty) => {};
381+
}
382+
#[doc(hidden)]
383+
#[macro_export]
384+
#[cfg(feature = "blank-check")]
385+
macro_rules! blank_check {
386+
($type:ty) => {
387+
#[no_mangle]
388+
#[link_section = ".entry"]
389+
pub unsafe extern "C" fn BlankCheck(addr: u32, size: u32) -> u32 {
390+
let this = unsafe {
391+
if !_IS_INIT {
392+
return 1;
393+
}
394+
&mut *_ALGO_INSTANCE.as_mut_ptr()
395+
};
396+
match <$type as $crate::FlashAlgorithm>::blank_check(this, addr, size) {
397+
Ok(()) => 0,
398+
Err(e) => e.get(),
399+
}
400+
}
401+
};
402+
}
403+
346404
#[doc(hidden)]
347405
#[macro_export]
348406
macro_rules! count {

0 commit comments

Comments
 (0)