-
Notifications
You must be signed in to change notification settings - Fork 96
Description
I have a pretty basic application (peripheral only) which has a GATT server containing a BAS, DeviceInfo and a custom service.
The custom service is defined as follows:
#[nrf_softdevice::gatt_service(uuid = "my-service-uuid")]
pub struct CustomService {
#[characteristic(
uuid = "my-char1-uuid",
security = "justworks",
read,
write
)]
u64_value: u64,
#[characteristic(
uuid = "my-char2-uuid",
security = "justworks",
read,
notify
)]
data: heapless::Vec<u8, 17>,
#[characteristic(
uuid = "my-char3-uuid",
security = "justworks",
write
)]
u8_value: u8,
}
My GATT server runs in a dedicated task as follow:
#[embassy_executor::task]
async fn gatt_server_task(connection: Connection, server: &'static Server) {
let handle = connection.handle();
let e = gatt_server::run(&connection, server, |evt| match evt {
ServerEvent::DeviceInfo(_) => { /* Read-only service */ }
ServerEvent::Bas(bas_evt) => { /* do something */,
ServerEvent::CustomService(custom_service_event) => {
match custom_service_event {
CustomServiceEvent::U64ValueWrite(val) => {
// WARNING! Accessing val here stalls the application in release mode!
info!("Got new u64 value {}", val);
},
_ => { /* ... */ }
}
}
})
.await;
In debug-mode, the code performs as expected.
When I build and run my code in release mode though, everything runs as expected until the point in which I access the GATT value in the OnWrite event: info!("Got new u64 value {}", val);
As soon as the BLE client writes the u64_value characteristic, the whole MCU stalls and nothing runs anymore.
A reset is required to recover from that state.
If I do not access the val
at all (log message commented out) in the event (just a debugging step, not really a valuable workaround), the MCU doesn't stuck anymore.
My build-release configuration is as follow:
[profile.release]
codegen-units = 1
debug = 2
debug-assertions = false
incremental = false
lto = "fat"
opt-level = 's'
overflow-checks = false
I have been able to work around this issue with the usage of a heapless::Vec<u8, 8>
instead of a u64
, and a manual (de-)serialization of the byte array into/from a u64 value.
Can someone explain this behaviour or has ideas on how further debug this?