Skip to main content

5 posts tagged with "STM32"

STM32 microcontrollers

View All Tags

Debugging a HardFault on a Cortex-M: from a mystery to a line of code

· 12 min read

Every embedded developer knows the moment: the firmware has been running, and then it does not. The debugger shows that the program sits in an infinite loop with a name like HardFault_Handler or Default_Handler, and the call stack is a few meaningless frames. That loop is the default handler of the startup code, and it says exactly nothing about what happened. The fault has a cause, and the processor has already written it down: in eight registers on the stack and in four status registers. It is only necessary to read them.

This article shows how to turn the loop into a line of source code, in two real examples that I ran in QEMU (a model of an STM32F4 board) and examined with GDB: a call of a NULL function pointer and a write to an address where nothing is. All outputs are real.

CMake for embedded firmware: a build that you can read

· 11 min read

An IDE project is a file that nobody reads: a few thousand lines of XML that the IDE writes and the IDE reads, and that nobody can review in a pull request. The build then exists only on the computer where somebody clicked it together. CMake solves it with a different philosophy: the build is a text that you read, review, version and run in the CI exactly the same way as on your desk.

The build system of the Embedbits platform (EmBi_Platform) is made in CMake, and this article explains the pieces that every embedded CMake build needs, on a small project that I built and ran: a toolchain file, flags with names, build types, the modules as libraries, the linker script, the files after the link and a test that runs the firmware in a simulator. All numbers and outputs are real.

Interrupts and main(): how to share data safely

· 11 min read

An interrupt handler and the main loop are two programs that run in the same memory and do not know about each other. The C compiler does not know that the interrupt exists, and the CPU does not know that two variables belong together. The programmer is the only one who knows, and the bugs that follow are the worst kind: they appear once in a thousand runs, they disappear when you attach the debugger and they never appear in the code review, because the code looks right.

This article goes through the three problems of the shared data, one by one, with the code that fails, and then shows the patterns that work. The experiments run on a Cortex-M4 (in QEMU, on a model of an STM32F4 board) or on a PC, and the outputs are real.

One BSP, many STM32 families: why Git branches, and what they cost

· 11 min read

STM32 is not one microcontroller, it is a dozen families: the G4, the H5, the U5, the F4 and so on. They have the same Cortex-M core, but different peripherals, different register names and a different vendor driver package. If you want one firmware architecture to run on all of them, you have to decide where the differences live. There is no free option, and this article describes the one that I chose for the Embedbits BSP, what the numbers from the real repositories say about it, and what it costs.

What happens before main(): reset, startup code and linker script

· 12 min read

Every C tutorial starts with int main(void). Nobody explains who calls it. And yet, when you write uint32_t counter = 5; as a global variable and the first line of main() reads 5, a lot of work already happened. When the work is not done, the symptom is a variable with a random value that "worked yesterday".

In this article we follow the microcontroller from the reset to the first line of main(): what the hardware does by itself, what the linker script says and what the startup code has to do. It is the content of two modules of the Embedbits BSP (Linker and Startup), but the principle is the same on every Cortex-M. All code in the article was built with arm-none-eabi-gcc 13.2.1 and run in QEMU, on a model of an STM32F405 board, so the addresses and the outputs are real.