Skip to content

Commit eb629a3

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 <sean@xobs.io>
1 parent be44533 commit eb629a3

File tree

2 files changed

+89
-31
lines changed

2 files changed

+89
-31
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: 88 additions & 31 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.
@@ -121,20 +132,23 @@ macro_rules! algorithm {
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,6 +199,7 @@ macro_rules! algorithm {
178199
$crate::erase_chip!($type);
179200
$crate::read_flash!($type);
180201
$crate::verify!($type);
202+
$crate::blank_check!($type);
181203

182204
#[allow(non_upper_case_globals)]
183205
#[no_mangle]
@@ -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,14 @@ 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] = core::slice::from_raw_parts_mut(data, size as usize);
327+
(this, data_slice)
328+
};
302329
match <$type as $crate::FlashAlgorithm>::read_flash(this, addr, data_slice) {
303330
Ok(()) => 0,
304331
Err(e) => e.get(),
@@ -321,10 +348,12 @@ macro_rules! verify {
321348
#[no_mangle]
322349
#[link_section = ".entry"]
323350
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();
351+
let this = unsafe {
352+
if !_IS_INIT {
353+
return 1;
354+
}
355+
&mut *_ALGO_INSTANCE.as_mut_ptr()
356+
};
328357

329358
if data.is_null() {
330359
match <$type as $crate::FlashAlgorithm>::verify(this, addr, size, None) {
@@ -343,6 +372,34 @@ macro_rules! verify {
343372
};
344373
}
345374

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

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy