Creating a Hardware Abstraction Layer (HAL) in C
In my last post, C to C++: Using Abstract Interfaces to Create Hardware Abstraction Layers (HAL), I discussed how vital hardware abstraction layers are and how to use a C++ abstract interface to create them. You may be thinking, that’s great for C++, but I work in C! How do I create a HAL that can easily swap in and out different drivers? In today’s post, I will walk through exactly how to do that while using the I2C bus as an example.
Summary
This blog post shows how to implement a Hardware Abstraction Layer (HAL) in C, using the I2C bus as a running example. It explains patterns and idioms—such as function-pointer-based interfaces and dependency injection—that make drivers swappable, testable, and portable across microcontrollers.
Key Takeaways
- Implement a HAL in C using structures of function pointers to define consistent driver interfaces.
- Design swappable I2C drivers so hardware-specific code can be replaced without changing application logic.
- Apply dependency injection techniques to select and initialize drivers at build or runtime.
- Write drivers to be testable and mockable to enable unit testing of higher-level firmware.
Who Should Read This
Embedded firmware engineers and developers working in C who need practical guidance on creating portable, testable HALs and swappable device drivers.
TimelessIntermediate
Related Documents
- Consistent Overhead Byte Stuffing TimelessIntermediate
- PID Without a PhD TimelessIntermediate
- Introduction to Embedded Systems - A Cyber-Physical Systems Approach Still RelevantIntermediate
- Can an RTOS be really real-time? TimelessAdvanced
- Memory Mapped I/O in C TimelessIntermediate








