Fundamentals 7 min read

Essential C Utility Code Snippets Every Embedded Developer Should Know

This article presents a curated collection of high‑impact C utility code examples—including a circular buffer, assertion macro, bit‑reversal function, fixed‑point arithmetic, endianness conversion, bit masks, timer handling, binary search, and a simple bitset—explaining their purpose and showing ready‑to‑use implementations for embedded systems.

Liangxu Linux
Liangxu Linux
Liangxu Linux
Essential C Utility Code Snippets Every Embedded Developer Should Know

Circular Buffer

A circular buffer implements a fixed‑size FIFO queue using a statically allocated array and two wrap‑around indices (head and tail). It is useful for streaming data such as UART reception where memory must be deterministic.

typedef struct {
    int buffer[SIZE];   // storage, SIZE must be defined by the user
    int head;           // index of next write
    int tail;           // index of next read
    int count;          // number of valid elements (0 ≤ count ≤ SIZE)
} CircularBuffer;

/* Insert an element at the head. If the buffer is full the element is discarded. */
void push(CircularBuffer *cb, int data) {
    if (cb->count < SIZE) {
        cb->buffer[cb->head] = data;
        cb->head = (cb->head + 1) % SIZE;
        cb->count++;
    }
}

/* Remove and return the element at the tail. Returns –1 when empty. */
int pop(CircularBuffer *cb) {
    if (cb->count > 0) {
        int data = cb->buffer[cb->tail];
        cb->tail = (cb->tail + 1) % SIZE;
        cb->count--;
        return data;
    }
    return -1; // buffer empty
}

Assertion Macro

The macro enables runtime checks in debug builds while removing the overhead in release builds. When NDEBUG is not defined, a failed assertion calls assert_failed with file and line information.

#define assert(expression) ((void)0)   /* default: no‑op */
#ifndef NDEBUG
#undef assert
#define assert(expression) ((expression) ? (void)0 : assert_failed(__FILE__, __LINE__))
#endif

void assert_failed(const char *file, int line) {
    printf("Assertion failed at %s:%d
", file, line);
    // user‑defined error handling can be added here
}

Bit Reversal

This function reverses the order of bits in an unsigned integer. It is often required by communication protocols that transmit least‑significant bits first.

unsigned int reverse_bits(unsigned int num) {
    unsigned int numOfBits = sizeof(num) * 8; // total bits in the type
    unsigned int reverseNum = 0;
    for (unsigned int i = 0; i < numOfBits; i++) {
        if (num & (1u << i)) {
            reverseNum |= (1u << ((numOfBits - 1) - i));
        }
    }
    return reverseNum;
}

Fixed‑Point Arithmetic

Fixed‑point representation replaces floating‑point operations on processors without an FPU. The example uses an 8‑bit fractional part (Q8 format).

#include <stdint.h>

typedef int16_t fixed_t;          // 16‑bit signed fixed‑point value
#define FIXED_SHIFT 8               // number of fractional bits
#define FLOAT_TO_FIXED(f) ((fixed_t)((f) * (1 << FIXED_SHIFT)))
#define FIXED_TO_FLOAT(f) ((float)(f) / (1 << FIXED_SHIFT))

/* Multiply two Q8 numbers and keep the result in Q8 format. */
fixed_t fixed_multiply(fixed_t a, fixed_t b) {
    return (fixed_t)(((int32_t)a * (int32_t)b) >> FIXED_SHIFT);
}

Endianness Conversion

Swaps the high and low bytes of a 16‑bit value, converting between big‑endian and little‑endian representations.

#include <stdint.h>

uint16_t swap_bytes(uint16_t value) {
    return (value >> 8) | (value << 8);
}

Bit Masks

Utility macro that creates a mask with a single bit set at the specified position.

#define BIT_MASK(bit) (1U << (bit))

Timer Counting (AVR Example)

Shows how to include the AVR I/O header, configure a hardware timer, and read its current count register ( TCNT1). The code is portable to any AVR MCU that provides TCNT1.

#include <avr/io.h>

/* Configure Timer/Counter1 for a desired prescaler and mode. */
void setup_timer(void) {
    // Example: normal mode, prescaler = 64
    TCCR1B = (1 << CS11) | (1 << CS10); // set prescaler bits
    TCNT1 = 0;                           // reset counter
}

/* Return the current 16‑bit count value. */
uint16_t read_timer(void) {
    return TCNT1;
}

Binary Search

Classic O(log n) search algorithm for a sorted integer array. Returns the index of target or –1 if not found.

int binary_search(const int arr[], int size, int target) {
    int left = 0, right = size - 1;
    while (left <= right) {
        int mid = left + (right - left) / 2; // avoid overflow
        if (arr[mid] == target) {
            return mid;
        } else if (arr[mid] < target) {
            left = mid + 1;
        } else {
            right = mid - 1;
        }
    }
    return -1; // not found
}

Simple Bitset

A lightweight structure that stores up to 32 boolean flags in a single 32‑bit integer. Provides functions to set and query individual bits.

#include <stdint.h>

typedef struct {
    uint32_t bits; // each bit represents a flag
} Bitset;

void set_bit(Bitset *bs, int bit) {
    bs->bits |= (1U << bit);
}

int get_bit(const Bitset *bs, int bit) {
    return (bs->bits >> bit) & 1U;
}
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

CData StructuresembeddedCode Samplesbit manipulationFixed-Point
Liangxu Linux
Written by

Liangxu Linux

Liangxu, a self‑taught IT professional now working as a Linux development engineer at a Fortune 500 multinational, shares extensive Linux knowledge—fundamentals, applications, tools, plus Git, databases, Raspberry Pi, etc. (Reply “Linux” to receive essential resources.)

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.