Skip to content

Commit 0b65346

Browse files
committed
chore(lib): version 0.1.0
1 parent 6b469f6 commit 0b65346

File tree

9 files changed

+159
-19
lines changed

9 files changed

+159
-19
lines changed

CHANGELOG.md

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@
22

33
All notable changes to this project will be documented in this file.
44

5-
## [unreleased]
5+
## [0.1.0] - 2025-02-02
66

77
### 🚀 Features
88

99
- Add support for the basic commands (including ble stack upgrade)
1010
- Add cli crate with download-hex command
11+
- Add cli crate, change overall api and add support for fus and memory r/w
12+
- Rework cli using bpaf and cleanup code and structure
13+
- Add json output to cli
14+
- Add core register read and write functions
15+
16+
### 🐛 Bug Fixes
17+
18+
- Linux support of wrapper
19+
- Linux not building
20+
- Add missing update reason to output
21+
- Wrong symbol names for read and write of cortex register
1122

1223
### 🚜 Refactor
1324

@@ -17,14 +28,26 @@ All notable changes to this project will be documented in this file.
1728

1829
- Fix readme
1930
- Update readme
31+
- Fix .env file sample
32+
- Adjust readme
33+
- Add readme to sys crate
2034

2135
### ⚙️ Miscellaneous Tasks
2236

23-
- Add changelog
37+
- Update changelog
38+
- Update changelog
39+
- Add github suggested workflow
40+
- Add readme files and metadata; fix clippy warnings
41+
- Add github workflow with checks
42+
- Fix clippy lints
43+
- Check docs
44+
- Do not fail fast to check the build on both os
45+
- Bump version of sys crate
2446

2547
### Build
2648

2749
- Add git-cliff config to generate changelogs with conventional commits
2850
- Add justfile
51+
- Generate bindings via bindgen cli
2952

3053
<!-- generated by git-cliff -->

Cargo.lock

Lines changed: 12 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

_typos.toml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2+
[default.extend-identifiers]
3+
# Typo in CubeProgrammer API symbol
4+
writeCortexRegistres = "writeCortexRegistres"
5+
16
[files]
27
extend-exclude = [
38
"stm32cubeprogrammer-sys/include",

stm32cubeprogrammer/Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ hardware_tests = []
2828
serde = ["dep:serde"]
2929

3030
[dependencies]
31-
stm32cubeprogrammer-sys = { path = "../stm32cubeprogrammer-sys" }
31+
stm32cubeprogrammer-sys = { version = "0.1.1" }
3232
derive_more = { version = "1", features = [
3333
"from",
3434
"deref",
@@ -48,6 +48,9 @@ serde = { version = "1", optional = true, features = ["derive"] }
4848

4949
ihex = { optional = true, version = "3.0" }
5050

51+
# # [patch.crates-io]
52+
# stm32cubeprogrammer-sys = { path = "../stm32cubeprogrammer-sys" }
53+
5154
[dev-dependencies]
5255
dotenvy.workspace = true
5356
test-log.workspace = true

stm32cubeprogrammer/README.md

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ This crate provides a high-level rust API for the STM32CubeProgrammer DLL.
66
```rust
77
use stm32cubeprogrammer::{
88
probe::{ConnectionParameters, Protocol, ResetMode},
9-
CubeProgrammer,
9+
CubeProgrammer, CoreRegister
1010
};
1111

1212
// You need to supply the path to the root directory of the STM32CubeProgrammer installation
@@ -31,6 +31,16 @@ let connected = programmer
3131

3232
println!("Target information: {}", connected.general_information());
3333

34+
// Write and read core register R0
35+
let value = 0x12345678;
36+
connected
37+
.write_core_register(CoreRegister::R0, value)
38+
.expect("Failed to write core register");
39+
let r0 = connected
40+
.read_core_register(CoreRegister::R0)
41+
.expect("Failed to read core register");
42+
println!("R0: 0x{:08X}", r0);
43+
3444
// If there are multiple connected probes with a target, you can establish multiple connections simultaneously
3545
let connected_other = programmer
3646
.connect_to_target(&probes[1], &Protocol::Swd, &ConnectionParameters::default())
@@ -58,6 +68,7 @@ More examples can be found in the `tests` directory.
5868
- Downloading files as hex or bin
5969
- Reading and writing memory
6070
- Uses the [`bytemuck::Pod`](https://docs.rs/bytemuck/1.21.0/bytemuck/trait.Pod.html) trait for reading and writing data from/to memory
71+
- Reading and writing of core registers
6172
- Resetting the target
6273
- Enabling and disabling readout protection (Level B)
6374
- Reset target

stm32cubeprogrammer/src/cube_programmer.rs

Lines changed: 53 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,32 @@
1-
use std::{
2-
cell::RefCell,
3-
collections::HashMap,
4-
sync::{Arc, Mutex},
5-
};
6-
71
use crate::{
82
api_log, api_types, display,
93
error::{CubeProgrammerError, CubeProgrammerResult},
104
utility,
115
};
12-
136
use bon::bon;
147
use derive_more::Into;
158
use log::{debug, error};
9+
use std::{
10+
cell::RefCell,
11+
collections::HashMap,
12+
sync::{Arc, Mutex},
13+
};
14+
use stm32cubeprogrammer_sys::libloading;
1615
use stm32cubeprogrammer_sys::SRAM_BASE_ADDRESS;
1716

18-
use stm32cubeprogrammer_sys::libloading;
17+
macro_rules! verify_api_struct {
18+
($api:expr, $($field:ident),*) => {{
19+
$(
20+
match &$api.$field {
21+
Ok(_) => (), // Symbol exists, continue
22+
Err(err) => return Err(CubeProgrammerError::MissingDllSymbol{message: format!(
23+
"Missing symbol '{}': {}", stringify!($field), err
24+
)}),
25+
}
26+
)*
27+
Ok(())
28+
}};
29+
}
1930

2031
/// HashMap to store connected probes.
2132
/// The key is the serial number of the probe.
@@ -87,6 +98,34 @@ impl CubeProgrammer {
8798
.map_err(CubeProgrammerError::LibLoading)?
8899
};
89100

101+
// Verify if all API functions are available before proceeding
102+
verify_api_struct!(
103+
api,
104+
setVerbosityLevel,
105+
setDisplayCallbacks,
106+
setLoadersPath,
107+
getStLinkList,
108+
deleteInterfaceList,
109+
connectStLink,
110+
getDeviceGeneralInf,
111+
disconnect,
112+
startFus,
113+
reset,
114+
downloadFile,
115+
massErase,
116+
saveMemoryToFile,
117+
sendOptionBytesCmd,
118+
readUnprotect,
119+
checkDeviceConnection,
120+
readMemory,
121+
freeLibraryMemory,
122+
startWirelessStack,
123+
writeCortexRegistres,
124+
readCortexReg,
125+
firmwareDelete,
126+
firmwareUpgrade
127+
)?;
128+
90129
if let Some(display_callback) = display_callback {
91130
debug!("Set display callback handler");
92131
display::set_display_callback_handler(display_callback);
@@ -674,6 +713,10 @@ impl ConnectedProgrammer<'_> {
674713

675714
let pod_data = pod_data.to_vec();
676715

716+
unsafe {
717+
self.api().freeLibraryMemory(data as *mut std::ffi::c_void);
718+
}
719+
677720
if pod_data.len() != count {
678721
return Err(CubeProgrammerError::ActionOutputUnexpected {
679722
action: crate::error::Action::ReadMemory,
@@ -735,7 +778,7 @@ impl ConnectedProgrammer<'_> {
735778
self.check_connection()?;
736779

737780
api_types::ReturnCode::<0>::from(unsafe {
738-
self.api().writeCoreRegister(register.into(), value)
781+
self.api().writeCortexRegistres(register.into(), value)
739782
})
740783
.check(crate::error::Action::WriteCoreRegister)
741784
}
@@ -750,7 +793,7 @@ impl ConnectedProgrammer<'_> {
750793
let mut value = 0;
751794

752795
api_types::ReturnCode::<0>::from(unsafe {
753-
self.api().readCoreRegister(register.into(), &mut value)
796+
self.api().readCortexReg(register.into(), &mut value)
754797
})
755798
.check(crate::error::Action::ReadCoreRegister)?;
756799

stm32cubeprogrammer/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,4 +79,8 @@ pub enum CubeProgrammerError {
7979
FileIo(std::io::Error),
8080

8181
LibLoading(stm32cubeprogrammer_sys::libloading::Error),
82+
83+
MissingDllSymbol {
84+
message: String,
85+
},
8286
}

stm32cubeprogrammer/src/lib.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,14 @@
2929
//!
3030
//! println!("Target information: {}", connected.general_information());
3131
//!
32-
//! connected.write_core_register(CoreRegister::R0, 0x12345678).expect("Failed to write core register");
33-
//!
34-
//! let r0 = connected.read_core_register(CoreRegister::R0).expect("Failed to read core register");
32+
//! // Write and read core register R0
33+
//! let value = 0x12345678;
34+
//! connected
35+
//! .write_core_register(CoreRegister::R0, value)
36+
//! .expect("Failed to write core register");
37+
//! let r0 = connected
38+
//! .read_core_register(CoreRegister::R0)
39+
//! .expect("Failed to read core register");
3540
//! println!("R0: 0x{:08X}", r0);
3641
//!
3742
//! // If there are multiple connected probes with a target, you can establish multiple connections simultaneously
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#![cfg(feature = "hardware_tests")]
2+
3+
use std::assert_eq;
4+
use stm32cubeprogrammer::CoreRegister;
5+
6+
#[path = "./test_common.rs"]
7+
mod test_common;
8+
9+
#[test_log::test]
10+
/// Test reading and writing memory on the target using a custom data structure which implements [`bytemuck::Pod`] and [`bytemuck::Zeroable`]
11+
fn read_and_write_core_register() {
12+
let programmer = test_common::init_programmer();
13+
let target_programmer = test_common::connect_to_target(
14+
&programmer,
15+
&stm32cubeprogrammer::probe::Protocol::Swd,
16+
&stm32cubeprogrammer::probe::ConnectionParameters {
17+
// Use under reset mode to halt the target before running any instructions
18+
// to avoid the RAM being overwritten by the target firmware
19+
connection_mode: stm32cubeprogrammer::probe::ConnectionMode::UnderReset,
20+
..Default::default()
21+
},
22+
);
23+
24+
let value = 0x12345678;
25+
target_programmer
26+
.write_core_register(CoreRegister::R0, value)
27+
.expect("Failed to write core register");
28+
let r0 = target_programmer
29+
.read_core_register(CoreRegister::R0)
30+
.expect("Failed to read core register");
31+
println!("R0: 0x{:08X}", r0);
32+
33+
assert_eq!(r0, value);
34+
35+
// Drop also handles the disconnect
36+
}

0 commit comments

Comments
 (0)