Skip to content

Commit d7943dd

Browse files
authored
Merge pull request #10 from xobs/add-blank-check
add blank_check command
2 parents be44533 + eb629a3 commit d7943dd

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)