**Design summary**Provide a small, deterministic GPIO HAL that: 1) preserves a persistent low-power wake config, 2) allows multiple drivers to share a pin via reference-counted ownership and priority arbitration, and 3) exposes IRQ-safe, lock-free operations for ISRs.**API sketch**c
// simple C API
typedef enum { GPIO_DIR_IN, GPIO_DIR_OUT } gpio_dir_t;
typedef enum { WAKE_NONE, WAKE_RISING, WAKE_FALLING, WAKE_BOTH, WAKE_LEVEL } gpio_wake_t;
typedef void (*gpio_cb_t)(uint16_t pin, void *ctx);
int gpio_request(uint16_t pin, uint8_t owner_id, uint8_t priority);
int gpio_release(uint16_t pin, uint8_t owner_id);
int gpio_config(uint16_t pin, gpio_dir_t dir, uint32_t flags); // non-ISR
int gpio_config_wake(uint16_t pin, gpio_wake_t wake); // must persist into low-power
int gpio_set_irqsafe(uint16_t pin, int level); // can be called from ISR
int gpio_clear_irqsafe(uint16_t pin);
int gpio_write_irqsafe(uint16_t pin, bool val); // lock-free for ISR
bool gpio_read(uint16_t pin);
int gpio_attach_callback(uint16_t pin, gpio_cb_t cb, void *ctx, uint8_t owner_id);
**Internal data structures**- struct gpio_pin { - uint16_t pin; - uint8_t owners_bitmap; // small bitmap or fixed array of owner_ids - uint8_t refcount; - uint8_t active_owner; // selected by arbitration - uint8_t priority_map[ MAX_OWNERS ]; - volatile uint32_t hw_state_bits; // reflects output/input and IRQ-safe cached value - gpio_wake_t wake_cfg; // persisted to retained RAM or hardware registers - irq_callback_list_t callbacks; // small fixed-size array - uint8_t flags; }Store table per port to batch atomic ops.**Locking & concurrency**- For thread context: use a lightweight mutex or RTOS spinlock per-port for operations that modify owner lists, priorities, or non-ISR config.- For ISR context: provide only bounded, lock-free functions: - Use atomic bit-set/clear (CMSIS LDREX/STREX or single-instruction bit ops) for output toggles. - Keep a small cached hw_state_bits in RAM updated atomically; gpio_write_irqsafe modifies this with atomic ops then writes to ODR. - gpio_config_wake writes hardware wake registers (must be done in thread context); the ISR API only toggles runtime state.- Critical sections: where atomic ops unavailable, temporarily disable interrupts for < 50 cycles to update shared data (document worst-case).**Conflict resolution**- Request includes owner_id + priority. When multiple owners request conflicting modes (e.g., pull-up vs pull-down), arbitration picks the highest priority owner. Lower-priority owners get error or fallback mode.- Implement a resolve() callback per-pin for special cases (ADC vs GPIO).**Low-power**- Expose gpio_config_wake storing wake_cfg into retained RAM and configuring hardware wake registers before sleep.- On suspend, freeze current active_owner and wake_cfg; on resume, re-evaluate owner priorities.**ISR callbacks**- IRQ handler enqueues minimal work: use lock-free ring buffer or set an atomic flag per-pin; actual callbacks run in thread/deferred context to avoid long ISR work. Offer an optional immediate minimal callback for hard real-time needs (document restrictions).This design keeps ISR paths short and deterministic, supports multi-owner policies, and explicitly separates wake configuration (thread-safe) from IRQ-safe runtime toggles.