LED Toggle: Implement a Bitfield LED Driver with Toggle, Set, and Clear Operations
Interview Experience
Problem
You are implementing a bare-metal LED driver in C. LEDs are controlled via an 8-bit hardware register where each bit corresponds to one LED (bit 0 = LED0, bit 7 = LED7). Implement functions to set, clear, toggle, and query individual LEDs without affecting others.
c
#include <stdint.h>
#include <stdbool.h>
typedef struct {
volatile uint8_t reg; // memory-mapped hardware register
} LedController;
void led_set(LedController* ctrl, uint8_t led_index);
void led_clear(LedController* ctrl, uint8_t led_index);
void led_toggle(LedController* ctrl, uint8_t led_index);
bool led_is_on(const LedController* ctrl, uint8_t led_index);
Example:
// reg initially = 0x00
led_set(ctrl, 3); // reg = 0x08
led_set(ctrl, 0); // reg = 0x09
led_toggle(ctrl, 3); // reg = 0x01
led_is_on(ctrl, 3) -> false
led_is_on(ctrl, 0) -> true
Follow-ups
- Why is the register declared
volatile, and what happens if you omit it with compiler optimizations enabled? - How do you atomically read-modify-write the register on a microcontroller that does not have hardware atomic instructions?
- How would you implement a
led_set_all(pattern)function that sets all 8 LEDs to a bitmask pattern in a single write? - How would you extend this driver to support a 16-bit register (e.g., two chained shift registers)?
Full Details
Problem
You are implementing a bare-metal LED driver in C. LEDs are controlled via an 8-bit hardware register where each bit corresponds to one LED (bit 0 = LED0, bit 7 = LED7). Implement functions to set, clear, toggle, and query individual LEDs without affecting others.
c
#include <stdint.h>
#include <stdbool.h>
typedef struct {
volatile uint8_t reg; // memory-mapped hardware register
} LedController;
void led_set(LedController* ctrl, uint8_t led_index);
void led_clear(LedController* ctrl, uint8_t led_index);
void led_toggle(LedController* ctrl, uint8_t led_index);
bool led_is_on(const LedController* ctrl, uint8_t led_index);
Example:
// reg initially = 0x00
led_set(ctrl, 3); // reg = 0x08
led_set(ctrl, 0); // reg = 0x09
led_toggle(ctrl, 3); // reg = 0x01
led_is_on(ctrl, 3) -> false
led_is_on(ctrl, 0) -> true
Follow-ups
- Why is the register declared
volatile, and what happens if you omit it with compiler optimizations enabled? - How do you atomically read-modify-write the register on a microcontroller that does not have hardware atomic instructions?
- How would you implement a
led_set_all(pattern)function that sets all 8 LEDs to a bitmask pattern in a single write? - How would you extend this driver to support a 16-bit register (e.g., two chained shift registers)?
About This Question
This is a candidate experience report from a anduril interview during the phone round.
It covers the following topics: Embedded, Coding, Phone, Bit Manipulation .