Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nrf52840: crash running heartrate example #310

Open
deadprogram opened this issue Dec 12, 2024 · 10 comments
Open

nrf52840: crash running heartrate example #310

deadprogram opened this issue Dec 12, 2024 · 10 comments
Labels
bug Something isn't working next-release nrf Nordic Semi SoftDevice

Comments

@deadprogram
Copy link
Member

I tried to run the heartrate example with the latest dev branch of both this package and TinyGo, only to discover that it crashes:

$ tinygo flash -size short -target itsybitsy-nrf52840 -monitor ./examples/heartrate
   code    data     bss |   flash     ram
  41216    1464    4680 |   42680    6144
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
Sread error: Port has been closed

Some println() debugging seems to indicate that this the line where it crashes:
https://github.com/tinygo-org/bluetooth/blob/release/examples/heartrate/main.go#L60

Changing that line to

return uint8(min)

allows the example to execute as expected.

Calling rand.Intn() function from a normal serial program without softdevice does not cause any problems.

Running the heartrate example on HCI or Linux does not cause any problems either.

I also experience this same crash on most recent TinyGo release.

@deadprogram
Copy link
Member Author

I experienced problem also on pca10040 board:

$ tinygo flash -size short -target pca10040-s132v6 -monitor ./examples/heartrate
   code    data     bss |   flash     ram
  38624    1356    4588 |   39980    5944
Open On-Chip Debugger 0.12.0
Licensed under GNU GPL v2
For bug reports, read
        http://openocd.org/doc/doxygen/bugs.html
swd
Info : J-Link OB-SAM3U128-V2-NordicSemi compiled Jan  7 2019 14:07:15
Info : Hardware version: 1.00
Info : VTarget = 3.300 V
Info : clock speed 1000 kHz
Info : SWD DPIDR 0x2ba01477
Info : [nrf51.cpu] Cortex-M4 r0p1 processor detected
Info : [nrf51.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for nrf51.cpu on 3333
Info : Listening on port 3333 for gdb connections
[nrf51.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x00000a80 msp: 0x20000400
** Programming Started **
Info : nRF52832-QFAA(build code: E0) 512kB Flash, 64kB RAM
Warn : Adding extra erase range, 0x0002fc30 .. 0x0002ffff
** Programming Finished **
** Resetting Target **
shutdown command invoked
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
BBBstarting
tick 00:00.009
SoftDevice assert
starting
tick 00:00.009
SoftDevice assert
starting
tick 00:00.009
SoftDevice assert
starting
tick 00:00.009
SoftDevice assert

The program does not crash, but it does not correctly publish the heart rate notifications. This same board does work correctly when running the scanner example.

@deadprogram deadprogram added bug Something isn't working nrf Nordic Semi SoftDevice labels Jan 2, 2025
@deadprogram
Copy link
Member Author

Further update: nrf51 does not appear to work at all at present as an Advertiser.

@deadprogram
Copy link
Member Author

@aykevl perhaps you could please take a look?

@bgould
Copy link
Member

bgould commented Jan 5, 2025

I tried to run the heartrate example with the latest dev branch of both this package and TinyGo, only to discover that it crashes:

$ tinygo flash -size short -target itsybitsy-nrf52840 -monitor ./examples/heartrate
   code    data     bss |   flash     ram
  41216    1464    4680 |   42680    6144
Connected to /dev/ttyACM0. Press Ctrl-C to exit.
Sread error: Port has been closed

I am also able to reproduce this using tinygo.org/x/bluetooth@dev with the latest release (0.35.0) of TinyGo:

$ go get tinygo.org/x/bluetooth@dev

$ tinygo version
tinygo version 0.35.0 windows/amd64 (using go version go1.23.4 and LLVM version 18.1.2)

$ tinygo flash -target feather-nrf52840 -monitor tinygo.org/x/bluetooth/examples/heartrate
Connected to COM12. Press Ctrl-C to exit.
Sread error: Port has been closed: The I/O operation has been aborted because of either a thread exit or an application request.

@bgould
Copy link
Member

bgould commented Jan 5, 2025

I believe math/rand.Intn ends up delegating to machine.GetRNG - https://github.com/tinygo-org/tinygo/blob/52983794d702af7a00833ae12b0d2e7175e46017/src/machine/machine_nrf.go#L323

If that is true, I wonder if the crash here is similar to the root cause of tinygo-org/tinygo#4170

@deadprogram
Copy link
Member Author

So this line of code here? https://github.com/tinygo-org/tinygo/blob/dev/src/machine/machine_nrf.go#L335

If it were to be able to call the same waitForEvent() code then it might not fail?

There is of course no simple way to accomplish that at present since cannot call runtime from machine package.

Calling on @aykevl for help! ⛑️

@aykevl
Copy link
Member

aykevl commented Jan 12, 2025

I suspect we need to call SoftDevice functions to get random numbers. Probably the SoftDevice locks the RNG for its own use.

See: sd_rand_application_vector_get

So basically, like wfi, we need to call this SoftDevice function if the SoftDevice is enabled. In pseudocode:

if softdevice enabled:
    return random byte using sd_rand_application_vector_get
else:
    return random byte directly from the RNG periperhal

(This needs to be under build tags: if the program is compiled without SoftDevice we can use the RNG package directly).

@aykevl
Copy link
Member

aykevl commented Jan 12, 2025

See: tinygo-org/tinygo@9d625a1

In all supported chips right now, the SVCall number is SOC_SVC_BASE_NOT_AVAILABLE + 5 (where SOC_SVC_BASE_NOT_AVAILABLE varies between nrf51 and nrf52*).

@aykevl
Copy link
Member

aykevl commented Jan 12, 2025

Source:

$ git grep SOC_SVC_BASE_NOT_AVAILABLE | grep define
s110_nrf51_8.0.0/s110_nrf51_8.0.0_API/include/nrf_soc.h:59:#define SOC_SVC_BASE_NOT_AVAILABLE (0x2B)
s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/nrf_soc.h:65:#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C)                   /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/nrf_soc.h:65:#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C)                   /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/nrf_soc.h:65:#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C)                   /**< Base value for SVCs that are not available when the SoftDevice is disabled. */
s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/nrf_soc.h:65:#define SOC_SVC_BASE_NOT_AVAILABLE (0x2C)                   /**< Base value for SVCs that are not available when the SoftDevice is disabled. */


$ git grep SD_RAND_APPLICATION_VECTOR_GET
s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/nrf_soc.h:154:  SD_RAND_APPLICATION_VECTOR_GET          = SOC_SVC_BASE_NOT_AVAILABLE + 5,
s113_nrf52_7.0.1/s113_nrf52_7.0.1_API/include/nrf_soc.h:474:SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/nrf_soc.h:166:  SD_RAND_APPLICATION_VECTOR_GET          = SOC_SVC_BASE_NOT_AVAILABLE + 5,
s132_nrf52_6.1.1/s132_nrf52_6.1.1_API/include/nrf_soc.h:479:SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/nrf_soc.h:165:  SD_RAND_APPLICATION_VECTOR_GET          = SOC_SVC_BASE_NOT_AVAILABLE + 5,
s140_nrf52_6.1.1/s140_nrf52_6.1.1_API/include/nrf_soc.h:507:SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));
s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/nrf_soc.h:153:  SD_RAND_APPLICATION_VECTOR_GET          = SOC_SVC_BASE_NOT_AVAILABLE + 5,
s140_nrf52_7.3.0/s140_nrf52_7.3.0_API/include/nrf_soc.h:495:SVCALL(SD_RAND_APPLICATION_VECTOR_GET, uint32_t, sd_rand_application_vector_get(uint8_t * p_buff, uint8_t length));

@deadprogram
Copy link
Member Author

Leaving this open until the next release of TinyGo that includes the needed fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working next-release nrf Nordic Semi SoftDevice
Projects
None yet
Development

No branches or pull requests

3 participants