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

Why does a do-nothing main.c HardFault when run with a softdevice?

If you have the most trivial main.c possible, with a main() which does nothing at all, compile, link and load it at 0x00000000, it runs fine and does nothing .. that's basically the main.c from the template example.

If you build the same exact code, link it at 0x14000, load a 110 softdevice onto the chip and then flash the code at 0x14000, the device HardFaults. It HardFaults before it even gets to main().

Why is this? I assume that the Softdevice requires one or more of the low-level handlers to be defined and if they're not, ends up branching to nowhere and HardFaulting .. but which are they? It can't be anything which is actually done in main(), it never gets there, so it must be named, linked-in routines which handle interrupts while the Reset_Handler() code is running.

I've debugged it at length. The code always makes it into the Reset_Handler() [at 0x14xxx], it rarely gets out of it. Somewhere during the copy to RAM it HardFaults. If you single step it all the way through, which takes a good long while, it makes it to main(), but if you let it run, it immediately fails. I assume an interrupt the softdevice set up before it branched to the user code Reset_Handler() fires and fails to find something it needs.

The reason I'm trying to do something so stupid is to come up with the simplest template do-nothing main.c which works with or without a loaded softdevice. This is part of the, currently going fairly well, work I'm doing to build natively with Eclipse. I just need the simplest main.c I can which works with or without a softdevice as an example file.

  • I was having the same debugger problems (ooooold Eclipse on Ubuntu 12.04), so I tried using the raw gdb and no issues. I compared what JLinkGDB was logging for both sessions and the main difference was that eclipse wasn't resetting the device in the same way / time. I added "mon reset" to my debug configuration under "Run Commands" (very bottom of Startup tab) and everything fixed. It even fixed this weird issue I was having with ANT channels not resetting inbetween debug sessions.

  • I'm having very similar problems. The code I have actually get to main, where I have a breakpoint set. I then proceed to single step. The first routine enables the uart and uart interrupts. Everything goes well until I put a byte into the uart out register. This apparently causes an interrupt and GDB jumps to 0xffffffffe (mostly "f"s followed by 1 "e"). The code runs fine without the debugger. The code I need to debug is the main application that is not working, but I can't get past the uart interrupt not being handled properly. I was thinking that maybe there is a separate thread that could handle the uart interrupt without telling me (GDB non-stop mode?) but Jlink gdbserver says not supported. There has to be a way to properly hand;le interrupts without getting sigint? I'm running on windows with GCC, jlink, all latest revisions of software. I'm not getting anywhere.

  • Hi,

    I'm experiencing the same with nrf51_sdk_v5_2_0_39364 and s110_nrf51822_6.0.0 with the same addresses.

    Running gdb the program received SIGTRAP:

    Program received signal SIGTRAP, Trace/breakpoint trap. 0xfffffffe in ?? ()

    Has anyone been able to run the s110 + App with the gcc toolchain ?

    BR, -Ken.

  • Exactly. I finally got GDB running, no thanks to the Nordic GCC environment document. The Nordic app note tells you how to get GDB working, but the app note says to put mon speed 10000 when it should actually be mon speed 1000, only a slight order of magnitude different (in the wrong direction). Once I got that changed, I was able to get GSB to actually get to "main", but then the first routine enables the uart interrupt (I think going through softdevice using : NVIC_ClearPendingIRQ( UART0_IRQn ); NVIC_SetPriority( UART0_IRQn, APP_IRQ_PRIORITY_LOW ); NVIC_EnableIRQ( UART0_IRQn );

    Once I do that, the very next thing is to put a character into the NRF_UART->TXD and that's all she wrote. The next thing is "0xFFFFFFFE" world. I can't live with this. If I can't debug with reasonable tools, I'm back to the stone ages again. I'm sure Keil wouldn't have this problem, but my boss isn't happy about the price. We've used Keil for test programs and that is fine, it works with softdevice, but my app is much more than the 32k limit. My code is more like 232k (maybe more) so it's big bucks for Keil or no bucks for GCC. But if the tools work (or don't work), the big bucks wins and I consider that sad.

  • The gcc toolchain is not to blame here, ARM has people contributing to the toolchain. The gcc toolchain is a very good toolchain with a proven track record for Intel, AVR, etc.

    The issue is that Nordic has not done any QA at all for the gcc POSIX part of the SDK. This proves it; from nrf51822/Source/templates/gcc/Makefile.common:

    #ifeq ($(OS),Windows_NT) include $(TEMPLATE_PATH)Makefile.windows #else #include $(TEMPLATE_PATH)Makefile.posix #endif

    This will never work, it works for Windows by luck, the lines starting with # are comments. Seems someone has misunderstood the syntax for makefiles.

    And, the Makefile.posix file does not exist.

    I hope Nordic finds resources to streamline the gcc POSIX part of their SDK; they are almost there, and a engineer at Nordic is trying to get a toolchain working on his spare time: github.com/.../nrf51-pure-gcc-setup

    BR, -Ken.

Related