MST

星途 面试题库

面试题:C语言中实现硬件抽象层的结构体设计

假设要为一款简单的微控制器设计硬件抽象层(HAL),该微控制器有GPIO端口、定时器和UART模块。请用C语言设计相应的结构体来抽象这些硬件资源,结构体中应包含初始化函数指针和控制函数指针。简要解释你的设计思路。
29.7万 热度难度
编程语言C

知识考点

AI 面试

面试题答案

一键面试

GPIO结构体设计

typedef struct {
    // GPIO端口配置寄存器地址等相关硬件信息
    volatile unsigned int *GPIOx_MODER;
    volatile unsigned int *GPIOx_OTYPER;
    volatile unsigned int *GPIOx_OSPEEDR;
    volatile unsigned int *GPIOx_PUPDR;
    volatile unsigned int *GPIOx_IDR;
    volatile unsigned int *GPIOx_ODR;
    // 初始化函数指针
    void (*init)(void);
    // 控制函数指针,例如设置引脚高低电平
    void (*set)(unsigned int pin, unsigned int value);
    unsigned int (*get)(unsigned int pin);
} GPIO_TypeDef;

定时器结构体设计

typedef struct {
    // 定时器相关寄存器地址等硬件信息
    volatile unsigned int *TIMx_CR1;
    volatile unsigned int *TIMx_PSC;
    volatile unsigned int *TIMx_ARR;
    volatile unsigned int *TIMx_CNT;
    // 初始化函数指针
    void (*init)(void);
    // 控制函数指针,例如启动、停止定时器
    void (*start)(void);
    void (*stop)(void);
} TIM_TypeDef;

UART结构体设计

typedef struct {
    // UART相关寄存器地址等硬件信息
    volatile unsigned int *USARTx_SR;
    volatile unsigned int *USARTx_DR;
    volatile unsigned int *USARTx_BRR;
    volatile unsigned int *USARTx_CR1;
    // 初始化函数指针
    void (*init)(void);
    // 控制函数指针,例如发送、接收数据
    void (*send)(unsigned char data);
    unsigned char (*receive)(void);
} UART_TypeDef;

设计思路解释

  1. 硬件信息封装:对于每个硬件模块(GPIO、定时器、UART),将与之相关的寄存器地址封装到结构体中,方便在函数中直接通过指针访问硬件寄存器。
  2. 函数指针:每个结构体都包含初始化函数指针和控制函数指针。初始化函数用于配置硬件模块的初始状态,如GPIO的引脚模式、定时器的分频器和周期、UART的波特率等。控制函数用于对硬件模块进行具体的操作,如GPIO引脚的电平设置、定时器的启停、UART的数据收发等。这样设计可以通过结构体实例化对象,方便地调用对应的初始化和控制函数,提高代码的可移植性和可读性,将硬件相关的操作抽象化,便于上层应用程序调用。