top of page

qualifiers interacting with storage classes

  • Writer: Ashok Kumar Kumawat
    Ashok Kumar Kumawat
  • Feb 8
  • 2 min read

1. Concept Overview

When qualifiers (const, volatile, signed, unsigned) are combined with storage classes (static, extern, register), they define scope, lifetime, mutability, and optimization rules.

  • const volatile: Read-only from software, but value may change unexpectedly (common in hardware registers).

  • static volatile: Persistent variable across function calls, but updated asynchronously (ISR flags).

  • extern const: Shared constant across modules.

  • extern volatile: Shared hardware register across modules.

2. Embedded Industry Usage

  • const volatile:

    • Hardware status registers (read-only, but updated by hardware).

    • Example: ADC result register.

  • static volatile:

    • ISR flags that persist across function calls.

  • extern volatile:

    • Peripheral registers declared in headers, accessed globally.

  • const static:

    • Lookup tables stored in Flash, local to a file.

3. Practical Examples

Example 1: const volatile hardware register

#define ADC_RESULT (*(const volatile uint16_t*)0x40012000)

uint16_t read_adc(void) {
    return ADC_RESULT;  // Value changes by hardware, software cannot modify
}

Example 2: static volatile ISR flag

static volatile uint8_t uart_rx_ready = 0;

void UART_ISR(void) {
    uart_rx_ready = 1;  // ISR sets flag
}

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

Example 3: extern volatile 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;
}

4. Best Practices

  • Always use volatile for hardware registers and ISR-shared variables.

  • Use const volatile for read-only hardware registers (status flags, sensor outputs).

  • Explicitly declare extern for cross-file variables to avoid multiple definitions.

  • Avoid register keyword; compilers optimize better automatically.

  • MISRA-C: Always initialize static variables; avoid hidden dependencies with extern.

5. When to Use

  • const volatile: Hardware registers that are read-only but change asynchronously.

  • static volatile: ISR flags that persist across calls.

  • extern volatile: Hardware registers accessed globally.

  • const static: Lookup tables, ROM-stored data local to a file.

6. Memory & Performance Considerations

  • const: Saves RAM by placing data in Flash/ROM.

  • volatile: Prevents compiler optimizations → may increase code size and execution time, but ensures correctness.

  • static: Allocated in global/static memory → persists for program lifetime.

  • extern: No memory allocated; just a reference.

  • const volatile: Ensures correct hardware access but prevents optimization, so slightly heavier on performance.

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

 
 
 
Storage Classes in Embedded C

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 varia

 
 
 

Comments


© 2035 by Robert Caro. Powered and secured by Wix

bottom of page