In this lesson, you will learn why and how to manually clear the BSS (Block Started by Symbol) section during your microcontroller’s startup sequence.
The Requirement for Zeroed Memory
When you declare a global or static variable in C without an explicit initial value—such as static int error_count;—the C standard dictates that it must be initialized to zero before main() begins. Unlike initialized variables, which have their starting values stored in Flash, uninitialized variables are placed in the .bss section in RAM. Because RAM contains random "garbage" data at power-on, your startup code must manually clear this area to ensure your program starts from a predictable state.
Identifying the BSS Boundaries
To clear this memory, your startup code (often written in Assembly or early C) needs to know the boundaries of the BSS section. These are typically defined in your linker script using symbols like __bss_start__ and __bss_end__. These symbols act as memory addresses that mark where your uninitialized data begins and ends.
The Zeroing Routine
The logic is straightforward: iterate through every memory address from the start of the BSS section to the end, writing a zero to each location. In a bare-metal environment, this is often implemented as a simple loop:
extern uint32_t __bss_start__;
extern uint32_t __bss_end__;
void clear_bss(void) {
uint32_t *ptr = &__bss_start__;
while (ptr < &__bss_end__) {
*ptr = 0;
ptr++;
}
}
By using pointers, we treat the memory range as an array of words (or bytes), ensuring that every bit assigned to a static variable is wiped clean. This routine should be called by your Reset_Handler immediately after the stack is configured and before the application jumps to the entry point of your C code. If you skip this step, your global variables might inherit random values from the previous power cycle, leading to "heisenbugs" that are nearly impossible to trace.
Key Takeaway: The BSS zeroing routine ensures that all uninitialized global and static variables start with a value of zero, transforming unpredictable power-on RAM noise into a reliable foundation for your C application.