This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Segmentation fault after enabling BLE stack

I have my system working with softdevice compiled in but not enabled. System communicates with external chip using SPIM peripheral, everything is working fine until I enable the softdevice.

As soon as I issue

    ret_code_t err_code;
    err_code = nrf_sdh_enable_request();

the first spim_xfer ends with segmentation fault:

#0  0x000257ae in ?? ()
#1  <signal handler called>
#2  nrf_spim_event_clear (spim_event=NRF_SPIM_EVENT_END, p_reg=<optimized out>) at /home/miceuz/nrf/nRF5_SDK/modules/nrfx/hal/nrf_spim.h:517
#3  spim_xfer (flags=0, p_xfer_desc=0x2003ff9c, p_cb=0x20004220 <m_cb+44>, p_spim=<optimized out>) at /home/miceuz/nrf/nRF5_SDK/modules/nrfx/drivers/src/nrfx_spim.c:501
#4  nrfx_spim_xfer (p_instance=<optimized out>, p_xfer_desc=0x2003ff9c, flags=0) at /home/miceuz/nrf/nRF5_SDK/modules/nrfx/drivers/src/nrfx_spim.c:607
#5  0x0000000e in ?? ()
#6  0x000373b0 in _fini ()

I am sure I am missing something simple here, but I can't remember what. Any tips?

Parents Reply Children
  • I am not sure - my design pretty much depends on use of SPIM3 because all the additional functionality it has - now I can fill my 40kb buffer completely with no CPU using hardware CS control, also I am using 16MHz - very cool functionality and doing it manually on lower frequency will severely impact my battery life and general design (which is nearing production at fast pace)

    Did I stumble on some kind of undiscovered errata?

  • Hi Andreas,

    I have looked into my code history - indeed, last time SPI and BLE was working together I have used SPI driver, not SPIM and I have used SPI instance 0.

    I have tried running the same segfault example I have posted before changing SPIM instance from 3 to 1 and it worked flawlessly.

    So yes, I can confirm, SoftDevice has problems working together with SPIM3.

    SPIM3 is pretty critical for our application as I have mentioned in previous post. Please let me know how I could be of assistance in solving this issue.

  • Hi.

    I have found the same results as you and reported it to the SDK team.

    In the mean time, I think I have a workaround hack that solves the problem somehow:

    In your main.c file:

    void spi_write() {
        ret_code_t error_code2;
    	m_tx_buf[0] = 0x42;
    	m_tx_buf[1] = 0x42;
    	nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(m_tx_buf, 2, m_rx_buf, 2);
    	error_code2 = nrfx_spim_xfer(&spim, &xfer, 0);
        APP_ERROR_CHECK(error_code2);
    }
    
    void app_mwu_enable(void)
    {
      NRF_MWU->REGIONENSET
        = ((MWU_REGIONENSET_RGN0WA_Set << MWU_REGIONENSET_RGN0WA_Pos) | (MWU_REGIONENSET_PRGN0WA_Set << MWU_REGIONENSET_PRGN0WA_Pos));
    }
    
    void app_mwu_disable(void)
    {
      NRF_MWU->REGIONENCLR
        = ((MWU_REGIONENCLR_RGN0WA_Clear << MWU_REGIONENCLR_RGN0WA_Pos) | (MWU_REGIONENCLR_PRGN0WA_Clear << MWU_REGIONENCLR_PRGN0WA_Pos));
    }
    
    
    
    int main(void) {
    
        power_management_init();
        log_init();
        NRF_LOG_INFO("Hello");
    	ble_stack_init();
        app_mwu_disable();
        spi_init();
        spi_write();
        app_mwu_enable();
        while(1) {
    	    NRF_LOG_INFO("I am fine");
            idle_state_handle();
        }
    }

    The problem with Invalid Access Memory was that an area protected by the memory watch unit is attempting to be written to when nrfx_spim_xfer() is called. I've avoided the error by disabling the memory watch unit before calling any SPIM related API calls, and enabling it afterwards.

    Could this help you perhaps?

    Best regards,

    Andreas

  • Hi Andreas

    Thank you for your post, I have tested the suggestion and we are getting somewhere, but the issue is not fully resolved yet. Simple SPIM initialization and xfer works fine with the MWU workaround you have specified, but more sophisticated initialization still segfaults.

    I have tracked it down to spim handler specification -- if handler is provided for nrfx_spim_init function it still segfaults.

    Maybe another memory region has to be unprotected also?

    This is the code that illustrates the fault:

    #include <ble_infrastructure.h>
    #include <stdbool.h>
    #include <stdint.h>
    
    #include "nrf.h"
    #include "nordic_common.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "nrfx_spim.h"
    #include "nrf_gpio.h"
    
    #include "ble_infrastructure.h"
    #include "power.h"
    
    static void log_init(void) {
    	ret_code_t err_code = NRF_LOG_INIT(NULL);
    	APP_ERROR_CHECK(err_code);
    
    	NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    static const nrfx_spim_t spim = NRFX_SPIM_INSTANCE(3);
    static uint8_t       m_tx_buf[2];           /**< TX buffer. */
    static uint8_t       m_rx_buf[3];    /**< RX buffer. */
    
    void spim_event_handler(nrfx_spim_evt_t const * p_event, void *p_context) {
    }
    
    void spi_init() {
        nrfx_spim_config_t config  =NRFX_SPIM_DEFAULT_CONFIG;
        config.frequency = NRF_SPIM_FREQ_16M;
        config.ss_pin   = SPI_SS_PIN;
        config.miso_pin = SPI_MISO_PIN;
        config.mosi_pin = SPI_MOSI_PIN;
        config.sck_pin  = SPI_SCK_PIN;
        config.use_hw_ss= true;
        config.rx_delay = 0;
        config.ss_duration = 0;
        config.orc = 0;
    
        APP_ERROR_CHECK(nrfx_spim_init(&spim, &config, spim_event_handler, NULL));
    }
    
    #define LED_GREEN_PIN 24
    #define LED_RED_PIN 25
    
    void leds_init(void) {
        nrf_gpio_cfg_output(LED_GREEN_PIN);
        nrf_gpio_cfg_output(LED_RED_PIN);
    }
    
    void spi_write() {
    	m_tx_buf[0] = 0x42;
    	m_tx_buf[1] = 0x42;
    	nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(m_tx_buf, 2, m_rx_buf, 2);
    	APP_ERROR_CHECK(nrfx_spim_xfer(&spim, &xfer, 0));
    }
    
    void app_mwu_enable(void)
    {
      NRF_MWU->REGIONENSET
        = ((MWU_REGIONENSET_RGN0WA_Set << MWU_REGIONENSET_RGN0WA_Pos) | (MWU_REGIONENSET_PRGN0WA_Set << MWU_REGIONENSET_PRGN0WA_Pos));
    }
    
    void app_mwu_disable(void)
    {
      NRF_MWU->REGIONENCLR
        = ((MWU_REGIONENCLR_RGN0WA_Clear << MWU_REGIONENCLR_RGN0WA_Pos) | (MWU_REGIONENCLR_PRGN0WA_Clear << MWU_REGIONENCLR_PRGN0WA_Pos));
    }
    int main(void) {
    
        power_management_init();
        log_init();
        leds_init();
        NRF_LOG_INFO("Hello");
        nrf_gpio_pin_set(LED_RED_PIN);
    	ble_init();
        app_mwu_disable();
        spi_init();
        spi_write();
        app_mwu_enable();
        nrf_gpio_pin_clear(LED_RED_PIN);
        nrf_gpio_pin_set(LED_GREEN_PIN);
        while(1) {
    	    NRF_LOG_INFO("I am fine");
            idle_state_handle();
        }
    }
    
    

  • Also, if this makes a difference, the most complicated form of nrfx_spim_xfer I use is like this:

    	nrfx_spim_xfer_desc_t xfer = NRFX_SPIM_SINGLE_XFER(spi_txbuf, 1, curr_buffer, 4);
        nrfx_spim_xfer(&spim, &xfer, NRFX_SPIM_FLAG_NO_XFER_EVT_HANDLER | NRFX_SPIM_FLAG_RX_POSTINC | NRFX_SPIM_FLAG_HOLD_XFER | NRFX_SPIM_FLAG_REPEATED_XFER));

Related