I am trying to upload a simple program that does nothing to my samd51. Here is the code:

void main(){}

I have compiled it to the exact samd51 model I have using platformio. But when I telnet to OpenOCD and do a reset run, it halts saying that there is a Handler HardFault.

  • 1
    \$\begingroup\$ you can't just "use gcc" and get something that runs on any microcontroller of the same processor family, no. You'll need to use linker scripts and startup code specific to your target machine - but Microchip offers an IDE and support for their chips, tutorials and example projects that will work with your chip, if you configure them appropriately to respect the peripherals you have on your board and for your specific version of the microcontroller. \$\endgroup\$ Commented Sep 28, 2020 at 12:46
  • 1
    \$\begingroup\$ Seriously, where did you look? I looked at www.microchip.com -> products -> 32 bit MCUs -> SAM D5x -> "Software" -> "MPLAB X integrated development environment", took me less than 30s. \$\endgroup\$ Commented Sep 28, 2020 at 13:00
  • 1
    \$\begingroup\$ yes, so get an IDE that comes with a correct compiler with correct configuration and a way to generate correct startup code for your specific board. This is not too much for your needs, unless you understand what you need to be doing, I promise. \$\endgroup\$ Commented Sep 28, 2020 at 13:04
  • 1
    \$\begingroup\$ James, could you believe it's not that trivial, please? You don't only need a compiler for your target architecture, you need a lot more to make your code run on the target. I've explained that in my comment from 20 minutes ago, already.) \$\endgroup\$ Commented Sep 28, 2020 at 13:09
  • 1
    \$\begingroup\$ Yes, I write my code in my favourite editor, too, and I don't use the vendor IDE to compile, link and upload it, but I sure as hell won't be writing the linker scripts and startup code for any new MCU that I'll be using myself – but without that, my software won't run. So, I need someone else (in this case, the vendor IDE) to provide these necessary components for me. You're very clearly a beginner – maybe start with an IDE that supports your device, and when you have a project in that that works, you can certainly make that build out of your IDE. \$\endgroup\$ Commented Sep 28, 2020 at 13:10

3 Answers 3


A minimal bare metal microcontroller program should contain at least this: an interrupt vector table. On SAMD and similar ARM, this is the boot area flash from address zero and beyond, which also contains the stack start address. As well as the address of the hardfault handler & friends, and of course every interrupt used, if any.

Usually this is solved by tool vendors in some specific way, through linker scripts or as part of the C run-time. If you aren't using a tool chain but just a "naked" compiler, you must manually generate the whole interrupt vector, fill it up with relevant information and make sure to download it into flash.

Additionally, in order to enable C programming, you must have a "C run-time" (CRT) library that sets up the various memory segments before it calls main(). On ELF-like linkers these are .bss and .data as a bare minimum. You also need to configure system clock, watchdog and other fundamental stuff early on, preferably from the reset vector. Some systems require MMU setup as well, but that shouldn't be necessary on Cortex M, from what I remember.

If you haven't got a clue about any these things, get a tool that does it for you.


There are many likely issues here, and probably more than one is an actual problem, though it's hard to guess which is first tripping the hard fault.

  • As explained by others, one cannot simply run C code on a bare target; startup code is needed, and on an ARM MCU that must begin with a vector table containing at least the entry address and the initial stack pointer value

  • Your main() returns, in an embedded setting that in and of itself could be a fault - typically if main returns, startup code will either hard fault, or simply re-run main, and absent information about your startup code (if any) either result is entirely expectable.

  • It's not at all clear that you've even loaded your code into the flash or RAM of your target, and not merely made the openocd tool aware of it. The openocd command reset run merely restarts the processor in running mode, if you have not already made it such that your processor will execute the desired code on reset, then that is not what is going to happen.

  • Your chip likely has various startup modes and flash banks, the current setup via programmable configuration bits or pin strapping may not be compatible with your goals.

  • code could have accidentally been built targeting a slightly different processor, for example building for one with more RAM than actually present would typically result in the initial stack pointer (traditionally the top of physical RAM) being at an invalid address

  • while in most cases clock selection falls to user code, eg, in main() or something it calls, it's possible that a routine trying to startup an external crystal oscillator and PLL could hard fault if that circuitry were not working

In terms of possible paths forward, the IDE-independent support code and examples package for the SAM chips is the ex-Atmel Advanced Software Framework (ASF).

But given that this question originally contained Arduino code, the asker may prefer to do a project or two using the vendor's offered IDE and not merely the stand alone support package. That IDE ultimately uses an ARM gcc as its toolchain, and it can export something akin to a Makefile, which is in horrid form but can with some manual effort be cleaned up into a model of how to maintain one's own project.

If openocd is going to be used as the flashing solution rather than the vendor's IDE, then effort will need to be invested in learning how to flash and control the chip with openocd. Generally this is possible, but some SAM targets in the past have needed minor fixes from the configuration files which shipped with certain versions of openocd.

If you feel that "platformio" has already dealt with some of the target specific issues for you, then you should probably focus effort on:

  • use arm-none-eabi-objdump to product a listing file of your program, and verify that it has the required vector table, startup code, etc

  • learn to use openocd to verify that your code is actually loaded into the processor

  • fix main to contain an infinite loop and not return

  • run your test with a sequence of commands more along the lines of a reset to halted mode and then single stepping, or place a breakpoint as early in startup code as possible


I have installed Atmel Studio 7 to a windows VM and copied the required files to my workplace on Linux. I tweaked the build commands a little bit and now it works. Here is the link to build the main.c file if anyone is interested. Running the build.sh results in a main.bin, which can be programmed to the samd51, without an IDE.

Edit: Assuming, of course, you have the arm toolchain and libnewlib-arm-none-eabi

  • \$\begingroup\$ So what exactly was the problem? \$\endgroup\$
    – Lundin
    Commented Sep 29, 2020 at 7:30
  • \$\begingroup\$ @Lundin i guess it was about the linker scripts and stuff. As I said in my answer below, copying the necessary files from the atmel studio worked perfectly \$\endgroup\$ Commented Sep 29, 2020 at 7:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.