Fading Coder

One Final Commit for the Last Sprint

Home > Notes > Content

Essential C Programming Concepts for Embedded Systems

Notes May 17 2

Constants and Macros

Define a constant representing seconds in a year:

#define SECONDS_IN_YEAR (365UL * 24 * 60 * 60)

Standard minimum value macro:

#define MIN_VALUE(x,y) (((x) < (y)) ? (x) : (y))

Preprocessor Directives

The #error directive halts compilation and displays custom error messages.

Infinite Loops

Common patterns for endless loops in embedded applications:

// Method 1
for (;;) {
    // loop body
}

// Method 2
while (1) {
    // loop body
}

// Method 3
do {
    // loop body
} while (1);

Variable Declarations

Various declarations using variable data:

  1. Integer: int data;
  2. Pointer to integer: int *data;
  3. Pointer to pointer to integer: int **data;
  4. Array of 10 integers: int data[10];
  5. Array of 10 pointers to integers: int *data[10];
  6. Pointer to array of 10 itnegers: int (*data)[10];
  7. Function pointer taking int and returning int: int (*data)(int);

Storage Class Specifiers

The static keyword:

  • Limits variable scope to file level
  • Preserves variable value between function calls

Type Qualifiers

const

Indicates that a variable's value should not be modified after initialization.

volatile

Tells the compiler that a variable's value may change unexpectedly, requiring fresh reads from memory rather than cached register values.

Example usage in embedded systems:

#define BIT_POSITION_3 (1U << 3)

static int register_value;

void activate_bit3(void) {
    register_value |= BIT_POSITION_3;
}

void deactivate_bit3(void) {
    register_value &= ~BIT_POSITION_3;
}

Memory-Mapped I/O

Direct memory access example:

unsigned int *memory_address = (unsigned int *)0x67a9;
*memory_address = 0xaa66;

Interrupt Handling

Interrupt Service Routines (ISRs) execute when hardware events occur, temporarily suspending main program flow.

Mixed-Type Arithmetic

void evaluate_expression(void) {
    unsigned int positive_val = 6;
    int negative_val = -20;
    
    if ((positive_val + negative_val) > 6) {
        printf("Result exceeds threshold\n");
    } else {
        printf("Result within limits\n");
    }
}

In mixed signed/unsigned operations, operands convert to unsigned types. The negative value becomes a large positive number, making the sum exceed the threshold.

Dynamic Memory Management

int *dynamic_array = NULL;
dynamic_array = (int *)malloc(128 * sizeof(int));

if (dynamic_array != NULL) {
    // use allocated memory
    free(dynamic_array);
    dynamic_array = NULL;
}

Type Definitions

Differance between #define and typedef:

#define POINTER_DEFINITION struct record *
typedef struct record *RecordPointer;

POINTER_DEFINITION ptr1, ptr2;  // Only ptr1 is a pointer
RecordPointer ptr3, ptr4;       // Both are pointers

Related Articles

Designing Alertmanager Templates for Prometheus Notifications

How to craft Alertmanager templates to format alert messages, improving clarity and presentation. Alertmanager uses Go’s text/template engine with additional helper functions. Alerting rules referenc...

Deploying a Maven Web Application to Tomcat 9 Using the Tomcat Manager

Tomcat 9 does not provide a dedicated Maven plugin. The Tomcat Manager interface, however, is backward-compatible, so the Tomcat 7 Maven Plugin can be used to deploy to Tomcat 9. This guide shows two...

Skipping Errors in MySQL Asynchronous Replication

When a replica halts because the SQL thread encounters an error, you can resume replication by skipping the problematic event(s). Two common approaches are available. Methods to Skip Errors 1) Skip a...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.