Keil Logo

ARM: Application Builds Without Error, But Does Not Run

Information in this knowledgebase article applies to:

  • Keil MDK v 5.14 and later for the Keil::Compiler Software Pack


I have built my application with the ARMCC toolchain and the standard runtime library. I can load the application, and set breakpoints. When I try to run it on my target, it does not work. It seems that the program does not even reach the main() function. The build process gave no error message or warning, that could explain this behavior.


Among many other possible individual reasons for this behavior, there are some common reasons that could explain this. They are:

  • Missing heap
  • Semihosting is enabled
  • RESET line incorrectly connected

This article briefly describes ways to resolve the issue's common causes so the code can execute. For more information on semihosting, please consult the runtime library guide.

An application that requires a heap may fail in the startup phase before main() is reached if the configured heap size is 0x0. Because prior to the main() function, if the program has not set up options to handle situations where heap initialization or dynamic memory allocation fails, a hard exit is performed and the program will not reach main().
When stopping your program in a debug session, you may notice it loops at a label called "_sys_exit".

When debugging, the View -> Disassembly window shows execution stopped either:

  • On a breakpoint assembly instruction e.g. BKPT 0xAB
  • While executing software interrupts e.g. SWI 0xAB

The standard runtime library links in certain low-level debugging routines, i.e. semihosting functions. Legacy ARM emulators supported semihosting by responding to the SWIs and BKPTs events. For the non-debug (released) version of the application, a programmer would retarget these semihosting functions to non-semihosting equivalents. The Keil debugger does not support semihosting - so these functions must be retargeted with a file.


Configure more heap in the startup file so the project will not fault before main(). Heap size is application dependent. Try allocating too much heap, and experiment with shrinking the size down. The functions __heapstats and __heapvalid may help in troubleshooting heap issues.


To remove low-level debugging functions, do one of the following: use the 'Compiler' Software Pack, Turn on Microlib, or add a retarget.c file.

  • Solve by using the Keil Compiler Pack:

    In Keil MDK version 5.14 and later, the software component Compiler retargets I/O functions of the standard C run-time library. Install the Keil::ARM_Compiler pack from the Pack Installer window. In the Manage RTE window, select a variant to change the target hardware interface of the I/O channel, e.g. retarget:

    • STDIN to an ITM debug channels
    • STDERR to a breakpoint
    • STDOUT to a "User" defined interface

    Manage RTE Window Compiler Software Component

    If selecting the variant "User", use an I/O User Code Template to implement custom functionality.

    User Templates
  • Solve by turning on Microlib:
    Microlib already has semihosting libraries removed. Besides smaller size, there are other small differences between Microlib and the standard c library.
  • Solve by using retarget.c:

    Retarget.c imports a label to prevent building the project with semihosting:

     #pragma import(__use_no_semihosting_swi)

    The rest of the file retargets the semihosted functions to non-semihosted ones. This was the standard way of handling semihosting functions in MDK-ARM version 4, and before the ARM::Compiler pack was released.
    See the retarget.c files attached to this case.

In custom boards, a user is responsible for setting up the device's hardware connection to a standard interface (SW or JTAG), used by a debug unit. In the Target Driver Setup dialog, if HW_RESET is selected or autodetected, then it is possible that running the application is the first test of the RESET line. An erase, flash programming, and debug connection may not require a hardware reset. If the physical connection is incorrect, then the default behavior of the device is undefined.

If a hardware reset is required, then connect the RESET line from a standard interface to the reset pin of the device. Review the schematics of a similar evaluation board to verify the design.





Request the files attached to this knowledgebase article.


The following Discussion Forum threads may provide information related to this topic.

Last Reviewed: Wednesday, April 11, 2018

Did this article provide the answer you needed?
Not Sure
  Arm logo
Important information

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies.

Change Settings

Privacy Policy Update

Arm’s Privacy Policy has been updated. By continuing to use our site, you consent to Arm’s Privacy Policy. Please review our Privacy Policy to learn more about our collection, use and transfers
of your data.