Skip to content

Feature update n rf5 sdk 15.0.0#9473

Closed
pekkanikander wants to merge 7 commits intoRIOT-OS:masterfrom
AaltoNEPPI:feature-update-nRF5-SDK-15.0.0
Closed

Feature update n rf5 sdk 15.0.0#9473
pekkanikander wants to merge 7 commits intoRIOT-OS:masterfrom
AaltoNEPPI:feature-update-nRF5-SDK-15.0.0

Conversation

@pekkanikander
Copy link
Copy Markdown
Contributor

Contribution description

This PR updates the nRF5 and Nordic Softdevice support to nRF SDK5 version 15.0.0.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

This version now seems to compile for all nRF51 and nRF52 boards I found. It seems to work (at least to some extend) with nRF52DK. However, I don't have currently a possibility of testing the actual IPv6 support (since I'm developing on a Mac instead of Linux). Hence, at minimum, the IPv6 functionality must be tested before this can be merged.

I will now continue to make a useful BLE GATT example.

Todo:

  • remove dependency on Nordic Timers, i.e. create Nordic Timer API on the top of RIOT timers

@pekkanikander
Copy link
Copy Markdown
Contributor Author

@kaspar030 @haukepetersen Here is the first version of the PR updating nRF5 SDK support to the latest released SDK. There is still some way to go (e.g. static tests fail), but I'm placing this here as a start and with the hope that also other people would contribute.

@dylad dylad added Area: pkg Area: External package ports Area: BLE Area: Bluetooth Low Energy support Area: cpu Area: CPU/MCU ports labels Jul 4, 2018
@dylad dylad added this to the Release 2018.07 milestone Jul 4, 2018
@pekkanikander pekkanikander force-pushed the feature-update-nRF5-SDK-15.0.0 branch from c09fac9 to 557f0e1 Compare July 7, 2018 13:42
@pekkanikander
Copy link
Copy Markdown
Contributor Author

I restructured to commits to make it easier to review the various changes. I believe this starts now to be ready for better testing and reviews. I have tested the basic BLE functionality and seems to work just fine. I haven't tested 6lowpan since I don't have a possibility for that.

I am planning next to refactor ble-core.c (and perhaps ble-mac.c) to make it easier to use just BLE, without 6lowpan or IPv6. I will also try to create some easier to use syntactic sugar on the top of Nordic BLE calls...

@pekkanikander
Copy link
Copy Markdown
Contributor Author

There still seems to be a problem that at least some of the BLE callbacks take place in the idle stack. The default idle stack is apparently (sometimes) too small, causing instability.

I don't know how we should handle this: should there be some trampoline that executes the BLE callbacks in the isr_stack, or should the cpu_conf.h increase THREAD_STACKSIZE_IDLE?

Any opinions? If a trampoline, where could I find a suitable example?

@pekkanikander
Copy link
Copy Markdown
Contributor Author

pekkanikander commented Jul 9, 2018

Another issue seems to be that I get hardfaults when using xtimer_usleep:

Context before hardfault:
   r0: 0x00000000
   r1: 0x00000002
   r2: 0xe000ed00
   r3: 0x10000000
  r12: 0x200049c3
   lr: 0x00029569
   pc: 0x000265b8
  psr: 0x01000200

FSR/FAR:
 CFSR: 0x00040000
 HFSR: 0x40000000
 DFSR: 0x00000000
 AFSR: 0x00000000
Misc
EXC_RET: 0xfffffffd
Attempting to reconstruct state for debugging...
In GDB:
  set $pc=0x265b8
  frame 0
  bt

It seems to crash when trying to lock a mutex:

(gdb) bt
#0  0x000265b8 in thread_yield_higher ()
    at cpu/cortexm_common/thread_arch.c:296
#1  0x00029a38 in _mutex_lock (mutex=0x200049e8 <main_stack+1360>, blocking=1)
    at core/mutex.c:62
#2  0x0002b828 in mutex_lock (mutex=0x200049e8 <main_stack+1360>)
    at core/include/mutex.h:113
#3  0x0002b8e6 in _xtimer_tsleep (offset=10000000, long_offset=0)
    at sys/xtimer/xtimer.c:70
#4  0x00028e40 in _xtimer_tsleep32 (ticks=10000000)
    at sys/include/xtimer/implementation.h:152
#5  0x00028e5e in xtimer_usleep (microseconds=10000000)
    at sys/include/xtimer/implementation.h:166
#6  0x00029952 in main () at main.c:533

L296 in my source code is the return after setting PendSVSet:

	void thread_yield_higher(void)
	{
	    /* trigger the PENDSV interrupt to run scheduler and schedule new thread if
	     * applicable */
            SCB->ICSR |= SCB_ICSR_PENDSVSET_Msk;
	}   <=== Here!

@pekkanikander
Copy link
Copy Markdown
Contributor Author

pekkanikander commented Jul 9, 2018

What is even more interesting that with exactly the same binary, and no flashing in between, sometimes I get a hardfault fairly soon, even before the system has booted up, sometimes the system seems stable for a long time and is able to serve multiple connections.

So, I currently suspect that the hardfaults are somehow strongly related to the timing internal to the system. Perhaps to interrupt priorities. Perhaps RIOT uses interrupt priorities that the SoftDevice would like to be preserved to itself.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

pekkanikander commented Jul 10, 2018

I am currently suspecting NVIC conflicts. The SDS 6.0 states the following: "For robust system function, the application program must comply with the restriction and use the NVIC API for configuration when the SoftDevice is enabled." However, it will take me some time to figure out how RIOT uses NVIC.

At this point (July 10 2018) it looks like that the crashing is somehow related to NVIC priorities.

It looks like that the crash comes from xtimer_usleep trying to return, i.e. from the timer interrupt.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

It looks like that I tentatively managed to fix the problem. Apparently the problem was with the default RIOT interrupt level being too low for the SoftDevice, and interrupt priority initialisation missing in nRF52 cpu.c. It will take me some time to clean up the code, as some of my fixing attempts were quite ugly.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

pekkanikander commented Jul 10, 2018

This fix has now been pushed, but apparently I still need to rebase.

The only remaining issue I see is running the SD callbacks in the idle stack. The PR contains a fix for this, simply increasing the IDLE stack size:

541ee73#diff-6ab4895ed5053af8e5f73d302112cf7dR79

However, I am not sure if that is the right way of fixing this.

@pekkanikander pekkanikander force-pushed the feature-update-nRF5-SDK-15.0.0 branch from e61e9af to c985532 Compare July 10, 2018 13:19
@pekkanikander
Copy link
Copy Markdown
Contributor Author

Rebased on master.

@pekkanikander pekkanikander force-pushed the feature-update-nRF5-SDK-15.0.0 branch from c985532 to 5b932fc Compare July 10, 2018 13:29
@pekkanikander
Copy link
Copy Markdown
Contributor Author

Please note that I do not know how to fix the following Travis CI problem:

Command output:
	Pull request needs squashing:
	    e1529e2b Fix nRF5 initialisation with SoftDevice

I don't even understand why the PR gets that complained.

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Jul 10, 2018

I don't even understand why the PR gets that complained.

Because the commit message starts with fix.

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Jul 10, 2018

BTW, all the commit messages need rewording. The RIOT convention is to prefix the commits with the path (complete or partial) of the files that are being touched.

@kYc0o kYc0o self-assigned this Jul 10, 2018
Copy link
Copy Markdown
Contributor

@kYc0o kYc0o left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Small comment, I'll try to test soon.


# special options when using SoftDevice
ifneq (,$(filter nordic_softdevice_ble,$(USEPKG)))
ifneq (,$(filter nordic_softdevice_ble nordic_softdevice_sixlowpan,$(USEPKG) $(USEMODULE)))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If nordic_softdevice_ble is deprecated, please remove.

Copy link
Copy Markdown
Contributor Author

@pekkanikander pekkanikander Jul 10, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, it is not deprecated. The package has now been split into to a package proper (nordic_softdevice_ble) and a module (nordic_softdevice_sixlowpan) inside the package. The package itself brings in the softdevice and BLE, including the possibility of using the BLE GATT APIs from the SD. The module adds 6lowpan glue on the top of that.

I needed to separate them so that I can compile binaries that want only GATT and not 6lowpan. Without the split there was an implicit dependency that brought in the whole TCP/IP stack into the binary, even though it was not needed.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

I can rebase and edit the commits at some point. However, this should be tested first, and as I have written, I don't have the possibility of testing the IPv6 / 6lowpan functionality. I have tested the BLE / GATT functionality now. It works and looks stable.

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Jul 10, 2018

I have two nrf52dk boards. I'm testing ping6 between them and it doesn't work... I have no idea how 6loWPAN is adapted on top of BLE and if a "simple" ping6 is proof enough that the implementation doesn't work.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

I'm not 100% that it has ever worked between two boards, @kaspar030 ? The instructions are for between nRF52DK and Linux. I'm using Mac OS X, not Linux.

The instructions can be found here: https://github.com/AaltoNEPPI/RIOT/blob/5b932fc707562f73b55eb59f38d8623812225263/pkg/nordic_softdevice_ble/README-BLE-6LoWPAN.md

@attdona
Copy link
Copy Markdown
Member

attdona commented Jul 10, 2018

I've tried to compile examples/{skald_ibeacon, skald_eddystone, nimble_gatt} but each one use the linker script nrf52840xxaa.ld instead of nrf52840xxaa_sd.ld linker script.

@kaspar030
Copy link
Copy Markdown
Contributor

I'm not 100% that it has ever worked between two boards, @kaspar030 ?

I never tried that. Probably doesn't and never did.

@pekkanikander
Copy link
Copy Markdown
Contributor Author

examples/skald_ibeacon does not seem to use use the nordic_softdevice_ble package nor IPv6, so it should not include the Softdevice. Ditto for skald_eddystone.

I think nimble_gatt seems to use the Nimble stack, which is separate from the Nordic stack.

I've been testing with examples/default.

@kYc0o
Copy link
Copy Markdown
Contributor

kYc0o commented Jul 11, 2018

skald_ibeacon and skald_eddystone are completely from scratch implementations to support BLE, thus they don't require any external package. Any example associated to nimble uses the former mynewt BLE stack, now in it's own repo.

    When using the nRF5 SD, Nordic recommends that
    instead of using the NVIC_* macros / inline functions
    directly, one shoudl use the corresponding
    sd_nvic_* inline functions.  At least in SKD 15, they
    are simple wrappers that check that the parameters
    are among the allowed values, return an error if not
    and perform the corresponding NVIC_* call if allowed.

    Hence, in order to be effective, we have to check
    for the error return value and act appropriately
    if we get an error.

    In cortexm_init.c we cannot use the safety macros,
    since there we want to set things that are not supported
    by the SD, prior to initialising the SD.
    This commit changes the PendSV interrupt priority to
    one lower than the default priority, using Cortex-M
    sub-priorities.
@pekkanikander pekkanikander force-pushed the feature-update-nRF5-SDK-15.0.0 branch from b8c7858 to fbf84cb Compare October 10, 2018 15:02
@pekkanikander
Copy link
Copy Markdown
Contributor Author

pekkanikander commented Oct 12, 2018

With the lastest commit a7cc4c4 Linux is now able to connect to the nRF and send packets. However, for some reason there seems to be something wrong in either packet handling or sending packets in the nRF52 end.

That is, I can see the bl0 interface on Linux, when connected, and I can see how the nRF52 IPSP level receives the packets and passes them on to BLE-MAC and from there to 6lowpan. On the other hand, I don't see any received packets at Linux, with tcpdump.

Furthermore, the current version defines enormous (20k) packet buffers, as we have to buffer two full 1280 byte input packets and apparently reallocate them larger when sending out, or something.

I will continue with this, but I would appreciate help with understanding how the 6lowpan and IPv6 layers are working.

@pekkanikander pekkanikander force-pushed the feature-update-nRF5-SDK-15.0.0 branch from 815e08c to a7cc4c4 Compare October 12, 2018 11:11
pekkanikander added a commit to AaltoNEPPI/RIOT that referenced this pull request Nov 13, 2018
    This commit enables Cortex-M CPU interrupt sub-priorities
    and allows the PendSV interrupt to have a priority different
    from the default one.  Together these two preprocessor
    defines can be used to have PendSV always run as the last interrupt
    before returning from the interrupt stack back to the user space.

    Running PendSV as the last interrupt before returning to the
    user space is recommended by ARM, as it increases efficiency.
    Furthermore, that change enhances stability a lot with the
    new nRF52 SoftDevice support, currently being worked in
    PR RIOT-OS#9473.

    This commit merely enables sub-priorities and a separate
    PendSV priority to be used without changing the default
    RIOT behaviour.
pekkanikander added a commit to AaltoNEPPI/RIOT that referenced this pull request Nov 13, 2018
    This commit enables Cortex-M CPU interrupt sub-priorities
    and allows the PendSV interrupt to have a priority different
    from the default one.  Together these two preprocessor
    defines can be used to have PendSV always run as the last interrupt
    before returning from the interrupt stack back to the user space.

    Running PendSV as the last interrupt before returning to the
    user space is recommended by ARM, as it increases efficiency.
    Furthermore, that change enhances stability a lot with the
    new nRF52 SoftDevice support, currently being worked in
    PR RIOT-OS#9473.

    This commit merely enables sub-priorities and a separate
    PendSV priority to be used without changing the default
    RIOT behaviour.
pekkanikander added a commit to AaltoNEPPI/RIOT that referenced this pull request Nov 13, 2018
    This commit enables Cortex-M CPU interrupt sub-priorities
    and allows the PendSV interrupt to have a priority different
    from the default one.  Together these two preprocessor
    defines can be used to have PendSV always run as the last interrupt
    before returning from the interrupt stack back to the user space.

    Running PendSV as the last interrupt before returning to the
    user space is recommended by ARM, as it increases efficiency.
    Furthermore, that change enhances stability a lot with the
    new nRF52 SoftDevice support, currently being worked in
    PR RIOT-OS#9473.

    This commit merely enables sub-priorities and a separate
    PendSV priority to be used without changing the default
    RIOT behaviour.
@pekkanikander
Copy link
Copy Markdown
Contributor Author

I'm afraid I will not be able to continue with this in the foreseeable future. Anyone to adopt?

@miri64
Copy link
Copy Markdown
Member

miri64 commented Aug 10, 2019

@chrysn you raised #11951. Are you maybe willing to adopt?

@chrysn
Copy link
Copy Markdown
Member

chrysn commented Aug 10, 2019 via email

@kb2ma kb2ma removed this from the Release 2019.10 milestone Oct 8, 2019
benpicco pushed a commit that referenced this pull request Apr 3, 2020
This commit enables Cortex-M CPU interrupt sub-priorities
and allows the PendSV interrupt to have a priority different
from the default one.  Together these two preprocessor
defines can be used to have PendSV always run as the last interrupt
before returning from the interrupt stack back to the user space.

Running PendSV as the last interrupt before returning to the
user space is recommended by ARM, as it increases efficiency.
Furthermore, that change enhances stability a lot with the
new nRF52 SoftDevice support, currently being worked in
PR #9473.

This commit merely enables sub-priorities and a separate
PendSV priority to be used without changing the default
RIOT behaviour.
@stale
Copy link
Copy Markdown

stale bot commented Apr 10, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Apr 10, 2020
@stale stale bot closed this May 11, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Area: BLE Area: Bluetooth Low Energy support Area: cpu Area: CPU/MCU ports Area: pkg Area: External package ports State: stale State: The issue / PR has no activity for >185 days

Projects

None yet

Development

Successfully merging this pull request may close these issues.