top of page

Storage Classes in Embedded C

  • Writer: Ashok Kumar Kumawat
    Ashok Kumar Kumawat
  • Apr 25
  • 2 min read

Excellent, let’s now systematically cover Storage Classes in Embedded C with the structured breakdown you asked for.

1. Concept Overview

Storage classes define scope, lifetime, and visibility of variables/functions. In embedded systems, this directly impacts memory usage, ISR behavior, and cross-module communication. The main storage classes are:

  • auto → Default for local variables (stack-based, temporary).

  • static → Persistent across function calls, limited scope if declared inside a function.

  • extern → Declares a variable/function defined elsewhere (cross-file linkage).

  • register → Suggests storage in CPU registers (compiler decides).

  • volatile and const are qualifiers, but often combined with storage classes.

2. Embedded Industry Usage

  • auto: Local temporary variables (rarely emphasized in embedded, default anyway).

  • static:

    • ISR flags, persistent counters, lookup tables.

    • Used for variables that must retain values across calls but remain file-local.

  • extern:

    • Hardware register mappings, global configuration constants.

    • Used for variables shared across multiple source files.

  • register:

    • Historically used for performance hints, but modern compilers optimize automatically.

    • Rare in embedded production code.

3. Practical Examples

Example 1: static ISR flag

static volatile uint8_t adc_ready = 0;

void ADC_ISR(void) {
    adc_ready = 1;  // ISR sets flag
}

void main(void) {
    while (!adc_ready) {
        // Wait until ISR sets flag
    }
}

Example 2: extern hardware register

// uart.h
extern volatile uint8_t* const UART_DR;

// uart.c
volatile uint8_t* const UART_DR = (uint8_t*)0x4000C000;

void send_byte(uint8_t data) {
    *UART_DR = data;
}

Example 3: register hint

void sum_array(uint8_t *arr, uint16_t len) {
    register uint16_t i;  // Compiler may keep i in CPU register
    uint16_t sum = 0;
    for (i = 0; i < len; i++) {
        sum += arr[i];
    }
}

4. Best Practices

  • Always initialize static variables (MISRA-C requirement).

  • Use extern only in headers, define once in a .c file.

  • Avoid register; let compiler optimize.

  • Combine with qualifiers carefully:

    • static volatile for ISR flags.

    • extern const for shared constants.

    • const volatile for read-only hardware registers.

  • Keep scope as limited as possible → reduces coupling and improves safety.

5. When to Use

  • auto: Temporary local variables (default).

  • static: Persistent state, ISR flags, lookup tables.

  • extern: Shared variables across modules (e.g., hardware registers).

  • register: Rare, only in legacy code or performance-critical loops.

6. Memory & Performance Considerations

  • auto: Stored on stack → limited size on small MCUs.

  • static: Stored in global/static memory → persists for program lifetime, increases RAM usage.

  • extern: No memory allocated, just linkage.

  • register: May improve speed slightly, but compiler usually ignores.

  • Embedded impact:

    • static increases deterministic behavior (no stack dependence).

    • extern can lead to hidden dependencies if misused.

    • volatile prevents optimization → ensures correctness but may reduce speed.

👉 To keep our revision flow:Would you like me to next cover Pointers and Pointer Arithmetic in Embedded Context, or go deeper into volatile + storage class combinations (like static volatile vs extern volatile) before moving on?

Recent Posts

See All
Q&A: C Code

Q1: How do you find the size of an array in C? Q2: What is an array of pointers in C, and why is it useful? Q3: How can function pointers be used to trigger callbacks in C? Q4: How can we determine th

 
 
 
Bubble Sort Concept

Bubble Sort repeatedly compares adjacent elements and swaps them if they are in the wrong order. After each pass, the largest element "bubbles up" to its correct position at the end. C Code Example #i

 
 
 
Macros — Complete Guide for Embedded C

What is a Macro and How It Works at Compilation Stage Macros are handled by the C Preprocessor, which runs before the actual compilation begins. The compilation pipeline looks like this: Source.c →

 
 
 

Comments


© 2035 by Robert Caro. Powered and secured by Wix

bottom of page