The startup sequence prepares the microcontroller to run your program. The reset vector tells the processor where to start running code after a reset.
Startup sequence and reset vector in Embedded C
void Reset_Handler(void) {
// Initialization code here
main();
}
// Vector table example
void (* const vector_table[])(void) __attribute__((section(".isr_vector"))) = {
Reset_Handler, // Reset vector
// Other interrupt handlers
};The reset vector is a pointer to the Reset_Handler function.
The startup sequence runs before main() and sets up memory and hardware.
void Reset_Handler(void) {
// Clear .bss section
// Copy .data section from flash to RAM
main();
}void (* const vector_table[])(void) __attribute__((section(".isr_vector"))) = {
Reset_Handler, // Reset vector
NMI_Handler,
HardFault_Handler,
// ... other handlers
};This program simulates the startup sequence by copying initialized data and clearing uninitialized data before running main.
#include <stdint.h> // Simulated memory sections uint32_t data_init[] = {1, 2, 3}; uint32_t data[3]; uint32_t bss[3]; void main(void) { // Main program starts here for (int i = 0; i < 3; i++) { // Print data and bss values // In embedded, you might toggle LEDs or send data } } void Reset_Handler(void) { // Copy initialized data from flash to RAM for (int i = 0; i < 3; i++) { data[i] = data_init[i]; } // Clear bss section for (int i = 0; i < 3; i++) { bss[i] = 0; } main(); } // Vector table with reset vector void (* const vector_table[])(void) __attribute__((section(".isr_vector"))) = { Reset_Handler }; // Simulate reset by calling Reset_Handler int main_wrapper() { Reset_Handler(); return 0; }
The reset vector is usually the first entry in the vector table.
The startup code runs before main() and prepares memory and hardware.
In real embedded systems, startup code is often written in assembly or provided by the compiler.
The reset vector tells the processor where to start after reset.
The startup sequence prepares memory and hardware before main() runs.
Understanding this helps you debug and customize embedded programs.
Practice
Solution
Step 1: Understand the reset vector concept
The reset vector is a special address in memory that points to the first instruction executed after a reset.Step 2: Identify its role in program start
When the microcontroller resets, it jumps to the reset vector to begin running the startup code.Final Answer:
It tells the microcontroller where to start executing code after a reset. -> Option DQuick Check:
Reset vector = start address after reset [OK]
- Confusing reset vector with interrupt vector
- Thinking reset vector initializes variables
- Assuming reset vector manages power modes
Solution
Step 1: Understand reset vector declaration
The reset vector is usually a pointer to a function placed in a special memory section.Step 2: Check syntax correctness
void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler; correctly declares a constant function pointer to Reset_Handler placed in the ".reset_vector" section using GCC attribute syntax.Final Answer:
void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler; -> Option CQuick Check:
Function pointer in reset vector section = correct declaration [OK]
- Declaring reset vector as int or char pointer
- Defining reset vector as a function instead of pointer
- Missing section attribute for placement
void Reset_Handler(void) {
int x = 5;
x += 10;
while(1) {}
}
void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler;Solution
Step 1: Analyze Reset_Handler behavior
Reset_Handler sets x to 5, adds 10 making x = 15, then enters an infinite loop.Step 2: Understand program flow after reset
After reset, the microcontroller jumps to Reset_Handler and stays in the infinite loop; no main() is called.Final Answer:
The program will enter an infinite loop after setting x to 15. -> Option AQuick Check:
Reset_Handler runs then loops forever = infinite loop [OK]
- Assuming main() is called automatically
- Expecting output or print statements
- Confusing variable x scope and effect
void Reset_Handler(void) {
// Initialize data
extern int _sidata, _sdata, _edata;
int *src = &_sidata;
int *dst = &_sdata;
while(dst < &_edata) {
*dst++ = *src++;
}
main();
}
void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler;Solution
Step 1: Check pointer types for memory copy
Memory sections like _sidata, _sdata, _edata represent byte addresses and should be pointers to char or unsigned char, not int.Step 2: Understand pointer arithmetic impact
Using int pointers causes incorrect copying because pointer arithmetic advances by sizeof(int), skipping bytes.Final Answer:
The pointers _sidata, _sdata, _edata should be declared as extern char, not int. -> Option BQuick Check:
Memory pointers for data init = char* not int* [OK]
- Using int pointers for byte-wise memory copy
- Changing loop condition incorrectly
- Thinking main() call is wrong here
Solution
Step 1: Verify .data section initialization
void Reset_Handler(void) { extern char _sidata, _sdata, _edata, _sbss, _ebss; char *src = &_sidata; char *dst = &_sdata; while(dst < &_edata) *dst++ = *src++; dst = &_sbss; while(dst < &_ebss) *dst++ = 0; main(); } void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler; correctly copies initialized data from flash (_sidata) to RAM (_sdata to _edata) using char pointers and proper loop.Step 2: Verify .bss section zero initialization
void Reset_Handler(void) { extern char _sidata, _sdata, _edata, _sbss, _ebss; char *src = &_sidata; char *dst = &_sdata; while(dst < &_edata) *dst++ = *src++; dst = &_sbss; while(dst < &_ebss) *dst++ = 0; main(); } void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler; zeroes the .bss section (_sbss to _ebss) by setting bytes to 0 before calling main().Step 3: Check reset vector declaration
void Reset_Handler(void) { extern char _sidata, _sdata, _edata, _sbss, _ebss; char *src = &_sidata; char *dst = &_sdata; while(dst < &_edata) *dst++ = *src++; dst = &_sbss; while(dst < &_ebss) *dst++ = 0; main(); } void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler; declares ResetVector as a constant function pointer placed in the reset vector section, which is correct.Final Answer:
Option A correctly implements startup sequence with .data and .bss initialization and reset vector. -> Option AQuick Check:
Proper .data/.bss init + correct reset vector = void Reset_Handler(void) { extern char _sidata, _sdata, _edata, _sbss, _ebss; char *src = &_sidata; char *dst = &_sdata; while(dst < &_edata) *dst++ = *src++; dst = &_sbss; while(dst < &_ebss) *dst++ = 0; main(); } void (* const ResetVector)(void) __attribute__((section(".reset_vector"))) = Reset_Handler; [OK]
- Using int pointers instead of char pointers
- Swapping source and destination pointers
- Missing .bss zero initialization
- Incorrect reset vector declaration
Ready to prove it?
Pass the test and this pattern moves unknown
