Closed kuon closed 2 years ago
The softdevice has some reserved peripherals that you must not touch, or you'll get a crash. The forbidden peripherals are: POWER, CLOCK, RADIO, RTC0, TIMER0, RNG, ECB, CCM_AAR, TEMP, SWI5, EGU5
In your case you're lucky, you simply don't need to setup CLOCK. The softdevice does it for you (and you can configure it in the Config but the defaults are likely fine). You can simply enable the softdevice and then use TIMERs and RTCs etc directly.
This will become fully safe once #4 is implemented (it'll make it so it's impossible to use the peripherals after enabling softdevice without unsafe)
I don't know what the 2nd crash is about though. :( nrf-softdevice
logs debug and panic messages with defmt
. Can you set up defmt-rtt
and run with probe-run
so that we can check if there's a panic? here are some getting started docs, or you can just copy the config from the example
dir in this repo.
I think RTIC should be usable if you don't use the softdevice's reserved priority levels and interrupts. It's somewhat unsafe because RTIC uses cortex_m's NVIC api directly instead of nrf_softdevice::interrupt
, but as long as you don't touch them it should be OK. It'd be nice to have fully safe RTIC+softdevice but I think that requires changes to RTIC code.
Apparently before even running my code, cortex-m-rtic try to disable all interrupt, but this doesn't play well with the softdevice.
Is this to be expected? I mean at this point, the softdevice is not enable, but it was called as bootloader.
That shouldn't crash if the softdevice is disabled. (In fact disabling interrupts when it's enabled doesn't crash either, it only crashes if you have them disabled for more than a few uS).
From reading your output it looks like you have a breakpoint at that address, and are simply hitting it (ie, it's not a crash). Maybe try removing all breakpoints?
(BTW breakpoints are not usable with the softdevice. The softdevice crashes if the CPU is stopped for a while, for the same reason it crashes if you disable interrupts for a long time)
Actually I had a breakpoint on main, but because of what you mentioned (breakpoints not usable with softdevice) I realized that breakpoint was causing the softdevice to crash.
Now I have another issue (I migrated to probe-run
and defmt
):
(HOST) INFO flashing program
(HOST) INFO success!
────────────────────────────────────────────────────────────────────────────────
0.000000 DEBUG Starting up
└─ playground::init @ src/main.rs:40
0.000000 DEBUG Config created
└─ playground::init @ src/main.rs:74
stack backtrace:
0: 0x00027dfe - HardFaultTrampoline
<exception entry>
1: 0x000273ec - nrf_softdevice::softdevice::Softdevice::enable
2: 0x000272d8 - playground::init
3: 0x00027358 - main
4: 0x0002783a - ResetTrampoline
5: 0x000271a8 - Reset
6: 0x00025f74 - <unknown>
Error: debug information is missing. Likely fixes:
1. compile the Rust code with `debug = 1` or higher. This is configured in the `profile.*` section of Cargo.toml
2. use a recent version of the `cortex-m` crates (e.g. cortex-m 0.6.3 or newer). Check versions in Cargo.lock
3. if linking to C code, compile the C code with the `-g` flag
Caused by:
Do not have unwind info for the given address.
My init code is executed properly, then I try to enable the softdevice, and I have this crash.
I update my example repo with current code: https://github.com/kuon/nrf-playground
If you want to see logs from nrf-softdevice
, you have to enable the feature defmt-trace
, otherwise you're only seeing logs from your app.
Turns out the issue is RTIC runs init
with interrupts disabled and sd_softdevice_enable
hardfaults if interrupts are disabled. :( I checked it by adding unsafe { cortex_m::interrupt::enable(); }
before enabling, but that's not the right fix, it'll probably break RTIC.
Try enabling it from a task instead of init, hope it helps.
I did hit the following issue (do not put an empty idle function): https://github.com/rtic-rs/cortex-m-rtic/issues/122
Once, I fixed this. Running softdevice::enable frrom a task would just hang forever. I enabled defmt-trace
but I see no output from the softdevice.
I updated my example repo.
Just tried your latest repo and it's panicking for me (not hanging)
0.000000 DEBUG Starting up
└─ playground::init @ src/main.rs:38
0.000000 DEBUG Start init
└─ playground::init @ src/main.rs:60
0.000000 DEBUG End init
└─ playground::init @ src/main.rs:75
0.000000 DEBUG Config created
└─ playground::softdevice @ src/main.rs:123
0.000000 ERROR too little RAM for softdevice. Change your app's RAM start address to 536925320
└─ nrf_softdevice::softdevice::{{impl}}::enable @ /home/dirbaio/.cargo/git/checkouts/nrf-softdevice-9b99539d60cc72a7/7567bff/nrf-softdevice/src/util/macros.rs:6
stack backtrace:
0: 0x0002998a - HardFaultTrampoline
<exception entry>
1: 0x00028d0e - __udf
2: 0x0002987c - cortex_m::asm::udf
3: 0x000298b2 - rust_begin_unwind
4: 0x00028e16 - core::panicking::panic_fmt
5: 0x00028dae - core::panicking::panic
6: 0x000280e6 - nrf_softdevice::softdevice::Softdevice::enable
7: 0x000276b2 - SWI0_EGU0
<exception entry>
8: 0x00027a9c - main
9: 0x00028888 - ResetTrampoline
10: 0x000271a8 - Reset
11: 0x00025f74 - <unknown>
After changing memory.x
RAM origin to 0x2000d488, it works fine (it's 536925320 in hex, unfortunately defmt doesn't support printing in hex yet knurling-rs/defmt#145
I tried changing the ram, but it still hangs with no output. I'm using an nrf52840 on a laird dev kit, but I don't see what problem this could cause.
I've added an RTIC example here: https://github.com/akiles/nrf-softdevice/blob/master/examples/src/bin/rtic.rs
It enables the softdevice, starts advertising and accepts connections. Tested working on both nrf52840-dk and a custom board with the nrf52840. You just have to cd examples; cargo run --bin rtic --features cortex-m-rtic
.
Please check if it works for you. If it doesn't it must be something related to your setup, your Rust version...
Your example also hangs. I will investigate on my side and maybe try with a different board.
BTW: I do ask quite a many questions in the issues, but I hope it will help for documentation and serve a bit as an FAQ. Anyway, thanks a lot for the support.
Ok, I found the issue. The laird board comes with an external crystal, but I read the doc a bit too fast and thought it was enabled by default, but it is not. To use the external crystal on the laird device, I had to remove two resistors and short 2 smd pads.
I think having a note about this behavior (enable will hang if clock source is not available) is a good way to address this issue.
I will leave this open while I work on a more complete rtic example.
Glad you found the issue! In the softdevice's clock config you can choose whether to use external or internal clock. The examples use the external clock: source: raw::NRF_CLOCK_LF_SRC_XTAL as u8,
. Using internal one would've probably worked without modifying the hw
I'll make sure to note that in the docs when we do the new config struct (#7)
Yeah I noticed the option in the config afterward, but that's good, I hope it will prevent other from falling into this pit.
The rtic example has been deleted in commit https://github.com/embassy-rs/nrf-softdevice/commit/74d6f78cd3085a9de36cd72fdb4059302677eae7, why is it? Is there a reason not to use nrf-softdevice and rtic together anymore?
@badrbouslikhin Yes, it should work. The example was removed because it was broken and I didn't have brain juices to fix it at the time, but there should be nothing fundamental preventing it from working.
Thanks! I was able to get a proof of concept working on a Thingy:52. The next step is to figure out how to trigger an RTIC interrupt from a GATT characteristic change.
I tried to use the softdevice with cortex-m-rtic, but if I specify
"peripherals=true"
and try to access CLOCK, I got the following crashAnd if I try to use it with no peripherals, I got the following crash:
Should I not try to use
rtic
and consider it incompatible with the softdevice?