How to Prove Your Firmware Is Running
Once you flash firmware onto your development board, how can you tell if it’s running? A successful flash log only proves that bytes reached flash memory, not that the microcontroller booted, initialized peripherals, or executed your code.
To prove firmware execution reliably on any board, firmware engineers use three universal hardware-observable tests:
- LED loop
printflogging- GPIO pin measurement
In this guide, you’ll learn each technique and how to implement it on the Texas Instruments CC2340 series and Nordic Semiconductor 54 L series development boards.
Why Hardware-Observable Tests Matter
A flash tool reporting success does not guarantee that firmware is actually running. It only confirms that you successfully wrote data onto the board’s non-volatile memory. There are many things that can happen on your board to prevent firmware from running, including:
- Boot configuration errors
- Incorrect reset vector
- Crashes during initialization
- Peripheral clocks not enabled
- Pin mapping mistakes
Without directly observing hardware behavior, it would be impossible for you to distinguish between the firmware not running and running incorrectly.
Hardware-observable tests solve this problem by giving you external, measurable proof that the microcontroller executed the code and controlled peripherals. These tests answer the most important board bring-up question: Did my program really run on my development board?
Because this evidence appears in the physical world (light, text, voltage), you can always trust it, even when tools, SDKs, or configurations fail.
Choosing the Right Verification Level
Each hardware-observable test confirms a deeper level of firmware execution:
| Technique | What it proves |
|---|---|
| LED loop | Microcontroller executed the code loop and toggled GPIO |
printf log | Firmware reached a specific code path |
| GPIO measurement | Firmware controlled the electrical pin state |
The best practice during board bring-up is to move through these tests sequentially, proving different layers of your board on the way:
- LED blinking: Visual proof
printflog: Software proof- GPIO measurement: Electrical proof
When all three tests succeed, you can be confident that firmware execution, peripheral setup, and pin mapping are all correct, especially important if you are moving on to debugging higher-level problems on your board.
1. LED Loop: Visual Proof
An LED loop toggles a GPIO pin repeatedly so that your board’s LED blinks. If you see a periodic blink, you know:
- Microcontroller executed your program
- Clocks were initialized
- GPIO were configured
- Main loop runs continuously
That makes LED loop the fastest test on any development board, regardless of the vendor or type.
Example
You can implement an LED loop on your own board by following this guide. It contains a detailed walkthrough for both the TI CC2340R5 LaunchPad and the Nordic nRF54L15 boards, including setup, expected results, and troubleshooting tips.
2. printf Logging: Software Proof
An LED loop confirms hardware toggling, but printf logs prove software flow. Specifically, these logs prove:
- Firmware reached a specific code location
- Code executed in the correct order
- Variables were initialized, updated, and stored correctly
Example
A good test for your board is to add logging in your main application loop. That way, you can definitively see that the firmware is still running.
To get started on implementing this on your TI or Nordic board, follow this guide. Below is an example of code you can add to your Nordic firmware, followed by the output. If you would like to run this test on a different board (like TI), you can largely use the same code, but be sure to change the library functions like printk() to the equivalent for your specific board.
void main(void)
{
// Print a log into UART every second
while (1) {
printk("Firmware running\n");
k_msleep(1000);
}
}3. GPIO Measurement: Electrical Proof
Sometimes your board doesn’t have onboard LEDs, or you just want stronger validation for your board. Measuring a GPIO pin with a multimeter is a quick way to give you electrical proof that your firmware can successfully control hardware.
The best part is that this test can run on any board, even the simplest of PCBs.
Example
Follow this guide to get started on your TI or Nordic board. Below is an example of code you can add to your TI firmware, followed by the expected results. If you would like to run this test on a different board (like Nordic), you can largely use the same code, but be sure to change the library functions like GPIO_write() to the equivalent for your specific board.
int main(void)
{
// Toggle the voltage on TEST_PIN between HIGH and LOW every second
// NOTE: Change TEST_PIN to the alias of the GPIO pin you want to test
while (1) {
// Change the voltage on TEST_PIN to HIGH
GPIO_write(TEST_PIN, GPIO_CFG_OUT_HIGH);
sleep(1);
// Change the voltage on TEST_PIN to LOW
GPIO_write(TEST_PIN, GPIO_CFG_OUT_LOW);
sleep(1);
}
}Common Problems These Tests Catch
Flash Succeeded but Firmware Doesn’t Run
With the LED loop test, the LED won’t blink. This is caused by an incorrect boot address.
Wrong Pin Mapping
With the GPIO measurement test, you will see no voltage across the target pin. This is caused by an incorrect GPIO mapping.
Crashing After Startup
With the LED loop test, the LED will only blink once, then stop. This is caused by a watchdog reset.
Peripherals Not Initialized
With the printf logging test, you will see no logs in your PC terminal. This is caused by the disabled UART clock.
Wrapping Up
A successful flash does not guarantee that your firmware runs. Hardware-observable tests provide reliable proof of your firmware execution because they produce visible and/or measurable effects outside of a debugger or IDE. An LED loop quickly confirms that your microcontroller executed code and toggled a GPIO pin, while UART logging shows that specific software paths ran and generated output. Measuring a GPIO pin provides electrical confirmation that firmware controls the physical hardware state.
Using these tests together during board bring-up is the best way to give you confidence that execution, peripheral setup, and pin mapping are all correct before moving on to more complex firmware development.
Ready to connect your devices anywhere on Earth? Get started with Hubble Network for free →