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

Initialising peripheral fails NRFX_DRV_STATE_UNINITIALIZED and program hangs with Invalid State hardfault

Hello, I am stuck initalising both TWIM and UARTE. I am focusing on the TWI Scanner example but using TWIM instead of TWI. No matter what I do I cannot get past the initalisation. The problem is that for both peripherals they fail the condition p_cb->state != NRFX_DRV_STATE_UNINITIALIZED.

I am seeing consistantly p_cb->state = 0x28 for UARTE and 0x10 for TWIM.

To simplify the reproduction I've now removed TWIM from my code and am only focusing on UARTE. I am really stuck at the moment and could use some advice.

My setup

  • Development Software:
    • nRF52 SDK v17.0.2
    • No software device
    • IDE: Visual Studio Code v1.53.2
  • Hardware: nRF52 DK (nRF52832) It says 2.0.0 on the sticker, I'm guessing that's the version?
  • Computer Platform: Ubuntu 20.10

Code

extern "C" {
    #include <stdio.h>
    #include "boards.h"
    #include "app_util_platform.h"
    #include "app_error.h"
    #include "sdk_config.h"
    #include "nrf.h"
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
}

int main() {
    APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
    NRF_LOG_DEFAULT_BACKENDS_INIT(); // Hangs here

    while (true)
    {
        NRF_LOG_INFO("TWI scanner started.");
        NRF_LOG_FLUSH();
    }

    return 0;
}

Preprocessor definitions

  • BOARD_PCA10040
  • NRF52832_XXAA
  • ENABLE_SWO
  • ENABLE_TRACE
  • DEBUG
  • DEBUG_NRF

Screenshots

You can see on the left that state is assigned 0x28. Where does that value come from? Perhaps the variable is uninitalised and random?

SDK Source files

  • /components/libraries/util/app_util_platform.c
  • /components/libraries/util/app_error.c
  • /components/libraries/util/app_error_handler_gcc.c
  • /components/serialization/connectivity/ser_conn_error_handling.c
  • /components/libraries/ringbuf/nrf_ringbuf.c
  • /components/libraries/memobj/nrf_memobj.c
  • /components/libraries/balloc/nrf_balloc.c
  • /components/libraries/atomic/nrf_atomic.c
  • /components/libraries/log/src/nrf_log_frontend.c
  • /components/libraries/log/src/nrf_log_default_backends.c
  • /components/libraries/log/src/nrf_log_backend_uart.c
  • /components/libraries/log/src/nrf_log_backend_serial.c
  • /components/libraries/log/src/nrf_log_str_formatter.c
  • /external/fprintf/nrf_fprintf.c
  • /external/fprintf/nrf_fprintf_format.c
  • /modules/nrfx/drivers/src/nrfx_uart.c
  • /modules/nrfx/drivers/src/nrfx_uarte.c
  • /modules/nrfx/drivers/src/prs/nrfx_prs.c
  • /integration/nrfx/legacy/nrf_drv_uart.c
Parents
  • Hi,

    Looking at your code I do not see anything that should not work if you use a supported toolchain. I notice the extern "C" part, so perhaps you are using a C++ compiler? If so note that it is not tested and not supported (and we know some SDK modules will not work). I do not immediately see the issue here though. Can you let me know which toolchain you use and share your Makefile or project file or similar? Note that the list of supported toolchains is listed in the SDK release notes (that does not mean that other cannot work, but I would strongly recommend using a supported toolchain if you have issues).

  • Hi Einar, 

    Can you let me know which toolchain you use and share your Makefile or project file or similar?

    > I was using gcc-arm-none-eabi-10-2020-q4-major and I have now switched to the compiler the SDK release notes mention: gcc-arm-none-eabi-9-2019-q4-major. I am using CMake for this.

    There was no change. But I did eventually resolve the issue.

    I have one big target_source in CMake and was able to resolve the issue by making nrfx_uarte.c appear in the list before nrf_log_frontend.c. Then I had another issue and that was resolve by making nrfx_prs.c appear in the list before nrfx_uarte.c .

    For both of the issues I noticed that static typedef structs were not being zero-initalised which made me think that something was wrong with the linking process. 

    target_sources(twim PUBLIC
        "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/prs/nrfx_prs.c" # needs to come before nrfx_uarte.c
        "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_uarte.c" # needs to come before nrf_log_frontend.c
        "${NRF5_SDK_PATH}/integration/nrfx/legacy/nrf_drv_uart.c"
        "${NRF5_SDK_PATH}/modules/nrfx/drivers/src/nrfx_uart.c"
        "${NRF5_SDK_PATH}/components/libraries/log/src/nrf_log_frontend.c"
    }

    But now I face another issue. I spent almost 6 hours on this today and am left feeling a bit frustrated.

    The problem is here in nrf_log_backend_interface.h :

    __STATIC_INLINE bool nrf_log_backend_is_enabled(nrf_log_backend_t const * const p_backend)
    
    {
    
        return p_backend->p_cb->enabled;
    
    }

    I even changed my project from C++ to C to have things just like the TWI Scanner example. But there was no difference.

    My debugger reads this expression p_backend->p_cb->enabled as false, which matches the bool type. But just executing the expression p_backend->p_cb->enabled triggers a Hard fault. The return is not at fault here.

  • Hi,

    regarding his specific point, in C all static variables are automatically initialized to zero, which includes m_log_data. So this should definitely be initialized to zero. Regarding the bigger picture it is difficult to make much suggestions as you do not use a build system we supply or test.

  • I understand. My goal by using CMake was to prevent myself from being bounded to an IDE which I would only use with Nordic MCUs. (Similar to STCubeIDE for STM32 and Code Composer for TI). 

     

    it is difficult to make much suggestions as you do not use a build system we supply or test.

    Is Segger Studio the recommended IDE? I've also given Zephyr RTOS a try (only examples).

  • I got it finally to work :D I copied the linker script used in theTWI Scanner example and now the logging library works. I am seeing the prints on my Putty terminal.

    I will investigate this further to learn what the reason my custom linker script did not work. Exciting! 

  • Hi,

    I see.

    If you want an integrated IDE to use with the nRF5 SDK, then Segger is what we typically recommend. We also support Keil and IAR. However, we also provide support for GNU ARM CC using Makefiles, and with that you can sue any editor. If you want to spend a bit of effort you can configure e.g. VS Code like an IDE handling debugging etc. Another simple approach is to use Makefiles to build, your favorite editor to edit and a stand alone debugger to debug. Segger Ozone is a user friendly and highly capable stand alone debugger that you can use free of charge with any nRF device (in the same way as Segger Embedded Studio).

  • Good to hear! Thank you for letting us know. If you can share your configuration that would be great, perhaps it can be useful for someone else.

Reply Children
  • Hi just to report in case this helps anyone else... There seems to be a bug either with the linker itself or maybe binutils (I'm not sure).

    But the problem arises when you copy the text inside nrf_common.ld and paste it into another linker script and use one merged linker script instead of one which includes nrf_common.ld. See issue here: https://devzone.nordicsemi.com/f/nordic-q-a/59161/merging-two-linkerscripts-from-an-nrf5-project-causes-a-malfunction

    I looked at the linker map produced by the two cases.

    1. copying the exact contents of nrf_common.ld and replacing the include "nrf_common.ld"

    2. No copying, and using two linker scripts, where one of them calls include "nrf_common.ld".

    The two cases produce a different linker map and the program won't work. Also when I call arm-none-eabi-objdump I see the the faulty program has wrong VMA addresses for .bss and .data sections compared to the program that works. That is the faulty code has same VMA address as LMA, but I'm not sure if it's enough to cause a hardfault, it's just one difference I noticed.

    My expectation was the two cases would produce the exact same linker map file, but it appears that's not the case.

    Edit: this does not seem to happen with the blinky example

Related