API GUIDE / GPIO / HAL
G32S10 GPIO HAL 接口
HAL 层接口:当前支持 5 个 GPIO 端口:
1. 资源模型与公开类型
1.1 GPIO 端口与 pin
当前支持 5 个 GPIO 端口:
GPIOAGPIOBGPIOCGPIODGPIOE
每个端口建模 32 个 pin:
GPIO_PIN_0~GPIO_PIN_31GPIO_PIN_ALL
基础常量:
HAL_GPIO_PINS_PER_PORT = 32HAL_GPIO_PORT_COUNT = 5GPIO_PIN_COUNT = 32
1.2 GPIO 功能编码
当前 HAL 不采用传统的 mode + pull + output type + af 组合模型,而是直接采用功能编码:
HAL_GPIO_FUNCTION_0HAL_GPIO_FUNCTION_1HAL_GPIO_FUNCTION_2HAL_GPIO_FUNCTION_3HAL_GPIO_FUNCTION_OUTPUT_LOWHAL_GPIO_FUNCTION_OUTPUT_HIGHHAL_GPIO_FUNCTION_INPUT
功能编码与寄存器位的稳态映射关系如下:
| HAL 功能 | interrupt_select | mask | pattern_1 | pattern_0 | 说明 |
|---|---|---|---|---|---|
HAL_GPIO_FUNCTION_0 | 0 | 0 | 0 | 0 | 复用功能 0 |
HAL_GPIO_FUNCTION_1 | 0 | 0 | 0 | 1 | 复用功能 1 |
HAL_GPIO_FUNCTION_2 | 0 | 0 | 1 | 0 | 复用功能 2 |
HAL_GPIO_FUNCTION_3 | 0 | 0 | 1 | 1 | 复用功能 3 |
HAL_GPIO_FUNCTION_OUTPUT_LOW | 0 | 1 | 0 | 0 | GPIO 输出,初始低电平 |
HAL_GPIO_FUNCTION_OUTPUT_HIGH | 0 | 1 | 0 | 1 | GPIO 输出,初始高电平 |
HAL_GPIO_FUNCTION_INPUT | 0 | 1 | 1 | 0 | GPIO 输入 |
1.3 GPIO 中断触发类型
中断触发类型由 hal_gpio_irq_trigger_t 单独建模:
HAL_GPIO_IRQ_TRIGGER_NONEHAL_GPIO_IRQ_TRIGGER_LEVEL_LOWHAL_GPIO_IRQ_TRIGGER_LEVEL_HIGHHAL_GPIO_IRQ_TRIGGER_EDGE_FALLINGHAL_GPIO_IRQ_TRIGGER_EDGE_RISINGHAL_GPIO_IRQ_TRIGGER_EDGE_BOTH
当前实现约束:
只有
HAL_GPIO_FUNCTION_INPUT模式允许调用hal_gpio_enable_irq()HAL_GPIO_IRQ_TRIGGER_EDGE_BOTH通过软件在中断处理函数中切换下一次边沿方向实现
中断模式与寄存器位的稳态映射关系如下:
| 中断触发类型 | interrupt_select | mask | pattern_1 | pattern_0 | 说明 |
|---|---|---|---|---|---|
HAL_GPIO_IRQ_TRIGGER_LEVEL_LOW | 1 | 0 | 0 | 0 | 低电平触发 |
HAL_GPIO_IRQ_TRIGGER_LEVEL_HIGH | 1 | 0 | 0 | 1 | 高电平触发 |
HAL_GPIO_IRQ_TRIGGER_EDGE_FALLING | 1 | 0 | 1 | 0 | 下降沿触发 |
HAL_GPIO_IRQ_TRIGGER_EDGE_RISING | 1 | 0 | 1 | 1 | 上升沿触发 |
HAL_GPIO_IRQ_TRIGGER_EDGE_BOTH | 1 | 0 | 动态切换 | 动态切换 | HAL 根据当前电平在上升沿和下降沿配置间切换 |
1.4 Pad 属性
GPIO HAL 当前提供以下 pad 属性:
hal_gpio_pull_tHAL_GPIO_PULL_NONEHAL_GPIO_PULL_UPHAL_GPIO_PULL_DOWNhal_gpio_speed_tHAL_GPIO_SPEED_LOWHAL_GPIO_SPEED_HIGHhal_gpio_drive_strength_tHAL_GPIO_DRIVE_STRENGTH_10MAHAL_GPIO_DRIVE_STRENGTH_20MAHAL_GPIO_DRIVE_STRENGTH_30MAHAL_GPIO_DRIVE_STRENGTH_40MAschmitttrue:使能 Schmitt triggerfalse:关闭 Schmitt trigger
1.5 公开结构体
1.5.1 hal_gpio_init_t
GPIO 初始化结构体,字段说明如下:
| 字段 | 类型 | 说明 |
|---|---|---|
gpiox | gpio_regs_t * | GPIO 端口基地址,如 GPIOA |
pin_mask | uint32_t | 端口内 pin mask |
mode | hal_gpio_mode_t | GPIO 功能编码 |
pull | hal_gpio_pull_t | 上下拉配置 |
speed | hal_gpio_speed_t | slew rate 档位 |
drive_strength | hal_gpio_drive_strength_t | 驱动能力档位 |
schmitt | bool | Schmitt trigger 开关 |
1.5.2 hal_gpio_pin_function_state_t
GPIO 当前功能状态解码结构体:
| 字段 | 类型 | 说明 |
|---|---|---|
function | hal_gpio_mode_t | 当前功能编码 |
is_interrupt | bool | 当前 pin 是否处于中断功能选择状态 |
interrupt_masked | bool | 当前中断是否处于 mask 状态 |
2. HAL 接口规范
2.1 初始化与生命周期
2.1.1 hal_gpio_struct_init
void hal_gpio_struct_init(hal_gpio_init_t *gpio_init);
功能说明:
将 hal_gpio_init_t 填充为安全默认值,用于后续按需覆写。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpio_init | hal_gpio_init_t * | 输出 | 待初始化的配置结构体 |
返回值表:
| 返回值 | 说明 |
|---|---|
| 无 | 接口不返回状态码;调用方需保证 gpio_init 非空 |
补充说明:
默认值为
gpiox = NULL、pin_mask = 0、mode = HAL_GPIO_FUNCTION_INPUT默认 pad 属性为无上下拉、低速、10mA、Schmitt 关闭
2.1.2 hal_gpio_init
error_code_t hal_gpio_init(const hal_gpio_init_t *gpio_init);
功能说明: 按给定配置初始化一个端口内的一个或多个 pin。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpio_init | const hal_gpio_init_t * | 输入 | GPIO 初始化参数,pin_mask 可为多 bit |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 初始化成功 |
IM_ERR_INVALID_PARAM | gpiox、pin_mask、mode 或 pad 参数非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持请求的 pad 属性组合 |
补充说明:
支持多 pin 批量配置
接口内部会通过 shadow 机制提交功能位更新
成功后会标记对应 pin 的 HAL 中断软件状态为 disabled,但不会清除已注册 callback
2.1.3 hal_gpio_deinit
error_code_t hal_gpio_deinit(const hal_gpio_init_t *gpio_init);
功能说明:
将 gpio_init->gpiox 与 gpio_init->pin_mask 指定的 pin 恢复为默认输入状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpio_init | const hal_gpio_init_t * | 输入 | 反初始化参数,仅使用 gpiox 和 pin_mask |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 恢复成功 |
IM_ERR_INVALID_PARAM | gpio_init、端口或 pin mask 非法 |
补充说明:
mode、pull、speed、drive_strength、schmitt字段在本接口中会被忽略默认恢复状态为
HAL_GPIO_FUNCTION_INPUT对应 pin 的 GPIO IRQ 会被 mask,pending flag 会被清除,已注册 callback 也会被清除
2.2 电平读写与功能态操作
2.2.1 hal_gpio_read_pin
error_code_t hal_gpio_read_pin(const gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_pin_state_t *pin_state_out);
功能说明: 读取一个或多个 pin 的当前输入采样电平。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 待读取的 pin mask,可为多 bit |
pin_state_out | hal_gpio_pin_state_t * | 输出 | 读取结果 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 读取成功 |
IM_ERR_INVALID_PARAM | 端口、pin mask 或输出指针非法 |
补充说明:
多 pin 读取结果为“按位或”语义,不返回逐 bit 电平图
pin_state_out = HAL_GPIO_PIN_SET表示选中的 pin 中至少有一个采样为高电平pin_state_out = HAL_GPIO_PIN_RESET表示所有选中的 pin 采样均为低电平本接口读取的是
pin采样寄存器
2.2.2 hal_gpio_write_pin
error_code_t hal_gpio_write_pin(gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_pin_state_t pin_state);
功能说明: 直接对一个或多个已处于 GPIO 输出模式的 pin 输出高/低电平。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 待写入的 pin mask,可为多 bit |
pin_state | hal_gpio_pin_state_t | 输入 | 目标输出电平 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 写入成功 |
IM_ERR_INVALID_PARAM | 端口、pin mask 或 pin_state 非法 |
IM_ERR_UNSUPPORTED | 选中的 pin 不全处于 GPIO 输出模式 |
补充说明:
目标 pin 必须已处于
HAL_GPIO_FUNCTION_OUTPUT_LOW或HAL_GPIO_FUNCTION_OUTPUT_HIGH属于端口级直接写接口
2.2.3 hal_gpio_toggle_pin
error_code_t hal_gpio_toggle_pin(gpio_regs_t *gpiox, uint32_t pin_mask);
功能说明: 翻转指定 pin 的当前电平。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 待翻转的 pin mask,可为多 bit |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 翻转成功 |
IM_ERR_INVALID_PARAM | 端口或 pin mask 非法 |
IM_ERR_UNSUPPORTED | 选中的 pin 不全处于 GPIO 输出模式 |
补充说明:
先读取
pin采样寄存器,再生成set_mask与clear_mask目标 pin 必须已处于
HAL_GPIO_FUNCTION_OUTPUT_LOW或HAL_GPIO_FUNCTION_OUTPUT_HIGH
2.3 Pin 合法性与资源占用管理
2.3.1 hal_gpio_is_pin_valid
bool hal_gpio_is_pin_valid(const gpio_regs_t *gpiox, uint32_t pin_mask);
功能说明:
判断 gpiox + pin_mask 是否构成一个合法的单 pin GPIO 位置。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
返回值表:
| 返回值 | 说明 |
|---|---|
true | 端口合法且 pin_mask 恰好选择一个 pin |
false | 端口非法、pin mask 为空或包含多个 bit |
2.3.2 hal_gpio_request_pin
error_code_t hal_gpio_request_pin(const gpio_regs_t *gpiox, uint32_t pin_mask, const char *owner_name);
功能说明: 在 HAL 软件层登记某个 pin 已被占用。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
owner_name | const char * | 输入 | 占用者名称,不可为 NULL |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 登记成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或 owner_name 参数非法 |
IM_ERR_BUSY | 该 pin 已被登记占用 |
补充说明:
这是软件资源登记接口,不会修改硬件寄存器
owner_name仅保存指针,不复制字符串内容,调用方需保证该指针在登记期间有效不可传入局部数组、栈上 buffer 或其他生命周期短于 pin 登记周期的临时存储指针
2.3.3 hal_gpio_release_pin
error_code_t hal_gpio_release_pin(const gpio_regs_t *gpiox, uint32_t pin_mask);
功能说明: 释放一个已经登记占用的 pin。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 释放成功 |
IM_ERR_INVALID_PARAM | 端口或 pin 参数非法 |
IM_ERR_NOT_READY | 该 pin 当前未登记占用 |
2.3.4 hal_gpio_is_pin_requested
error_code_t hal_gpio_is_pin_requested(const gpio_regs_t *gpiox, uint32_t pin_mask, bool *is_requested_out);
功能说明: 查询某个 pin 是否已在 HAL 软件层登记占用。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
is_requested_out | bool * | 输出 | 查询结果,true 表示已占用 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
2.3.5 hal_gpio_get_pin_owner_name
error_code_t hal_gpio_get_pin_owner_name(const gpio_regs_t *gpiox, uint32_t pin_mask, const char **owner_name_out);
功能说明: 查询某个 pin 的登记 owner 名称指针。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
owner_name_out | const char ** | 输出 | owner 名称输出指针 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
IM_ERR_NOT_READY | 该 pin 当前未登记占用 |
2.4 功能状态与 pad 属性接口
2.4.1 hal_gpio_get_function_state
error_code_t hal_gpio_get_function_state(const gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_pin_function_state_t *state_out);
功能说明: 读取单个 pin 当前寄存器状态,并将其解码为 HAL 层可理解的功能/中断状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
state_out | hal_gpio_pin_function_state_t * | 输出 | 功能与中断状态解码结果 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
IM_ERR_UNSUPPORTED | 当前寄存器组合无法映射到已建模功能态 |
补充说明:
若 pin 当前配置为双边沿中断,HAL 会结合软件上下文将其恢复为
HAL_GPIO_IRQ_TRIGGER_EDGE_BOTH
2.4.2 hal_gpio_set_pull
error_code_t hal_gpio_set_pull(gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_pull_t pull);
功能说明: 配置一个或多个 pin 的上下拉状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | pin mask,可为多 bit |
pull | hal_gpio_pull_t | 输入 | 目标上下拉模式 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 配置成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或 pull 非法 |
2.4.3 hal_gpio_get_pull
error_code_t hal_gpio_get_pull(const gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_pull_t *pull_out);
功能说明: 查询单个 pin 的上下拉配置。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
pull_out | hal_gpio_pull_t * | 输出 | 查询得到的上下拉模式 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
IM_ERR_UNSUPPORTED | 当前寄存器状态表现为 pull-up 与 pull-down 同时使能,无法映射到 HAL 枚举 |
2.4.4 hal_gpio_set_drive_strength
error_code_t hal_gpio_set_drive_strength(gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_drive_strength_t drive_strength);
功能说明: 配置一个或多个 pin 的驱动能力档位。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | pin mask,可为多 bit |
drive_strength | hal_gpio_drive_strength_t | 输入 | 目标驱动能力档位 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 配置成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或驱动档位非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持 drive strength 配置 |
2.4.5 hal_gpio_get_drive_strength
error_code_t hal_gpio_get_drive_strength(const gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_drive_strength_t *drive_strength_out);
功能说明: 查询单个 pin 的驱动能力档位。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
drive_strength_out | hal_gpio_drive_strength_t * | 输出 | 查询得到的驱动能力档位 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持 drive strength 读取 |
2.4.6 hal_gpio_set_speed
error_code_t hal_gpio_set_speed(gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_speed_t speed);
功能说明: 配置一个或多个 pin 的 slew rate 档位。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | pin mask,可为多 bit |
speed | hal_gpio_speed_t | 输入 | 目标速度档位 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 配置成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或速度档位非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持 slew rate 配置 |
2.4.7 hal_gpio_get_speed
error_code_t hal_gpio_get_speed(const gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_speed_t *speed_out);
功能说明: 查询单个 pin 的 slew rate 档位。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
speed_out | hal_gpio_speed_t * | 输出 | 查询得到的速度档位 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持 slew rate 读取 |
2.4.8 hal_gpio_set_schmitt
error_code_t hal_gpio_set_schmitt(gpio_regs_t *gpiox, uint32_t pin_mask, bool is_enabled);
功能说明: 配置一个或多个 pin 的 Schmitt trigger 开关。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | pin mask,可为多 bit |
is_enabled | bool | 输入 | true 使能,false 关闭 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 配置成功 |
IM_ERR_INVALID_PARAM | 端口或 pin 非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持 Schmitt trigger 配置 |
2.4.9 hal_gpio_get_schmitt
error_code_t hal_gpio_get_schmitt(const gpio_regs_t *gpiox, uint32_t pin_mask, bool *is_enabled_out);
功能说明: 查询单个 pin 的 Schmitt trigger 状态。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | const gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
is_enabled_out | bool * | 输出 | 查询结果,true 表示已使能 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 查询成功 |
IM_ERR_INVALID_PARAM | 端口、pin 或输出指针非法 |
IM_ERR_UNSUPPORTED | 当前端口不支持 Schmitt trigger 读取 |
2.4.10 hal_gpio_dump_functions
void hal_gpio_dump_functions(void);
功能说明:
将 GPIOA 到 GPIOE 所有 pin 的当前功能状态打印到日志。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
| 无 | - | - | 无 |
返回值表:
| 返回值 | 说明 |
|---|---|
| 无 | 接口不返回状态码;输出依赖日志系统 |
补充说明:
适用于 bring-up、pinmux 排查与中断模式排查
输出使用
INFO级别日志
2.5 GPIO 中断接口
2.5.1 hal_gpio_register_irq_callback
error_code_t hal_gpio_register_irq_callback(gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_irq_callback_t callback, void *user_ctx);
功能说明: 为单个 GPIO pin 注册中断回调函数。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
callback | hal_gpio_irq_callback_t | 输入 | 中断回调函数,可为 NULL |
user_ctx | void * | 输入 | 用户上下文指针,回调时原样透传 |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 注册成功 |
IM_ERR_INVALID_PARAM | 端口或 pin 信息非法 |
IM_ERR_NOT_READY | 内部 IRQ 上下文未建立 |
补充说明:
该接口只登记软件回调关系,不自动开启中断
回调在 GPIO IRQ 上下文执行,不能阻塞、sleep、等待锁或做重日志输出
传入
NULLcallback 可注销回调,但不会改变 pin 的硬件配置
2.5.2 hal_gpio_enable_irq
error_code_t hal_gpio_enable_irq(gpio_regs_t *gpiox, uint32_t pin_mask, hal_gpio_irq_trigger_t trigger);
功能说明: 使能一个单 pin GPIO 的中断投递。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
trigger | hal_gpio_irq_trigger_t | 输入 | 中断触发类型,不允许为 HAL_GPIO_IRQ_TRIGGER_NONE |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 中断使能成功 |
IM_ERR_INVALID_PARAM | 端口、pin 信息或 trigger 非法 |
IM_ERR_NOT_READY | 内部 IRQ 上下文未建立 |
IM_ERR_UNSUPPORTED | 当前 pin 不处于输入或中断模式 |
补充说明:
接口内部先通过 shadow 机制编程中断触发方式,再清 pending flag 并取消 mask
若
trigger = HAL_GPIO_IRQ_TRIGGER_EDGE_BOTH,会先根据当前输入电平选定首次上升沿或下降沿
2.5.3 hal_gpio_disable_irq
error_code_t hal_gpio_disable_irq(gpio_regs_t *gpiox, uint32_t pin_mask);
功能说明: 关闭一个 GPIO pin 的中断投递。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | GPIO 端口基地址 |
pin_mask | uint32_t | 输入 | 单 pin mask |
返回值表:
| 返回值 | 说明 |
|---|---|
IM_OK | 关闭成功 |
IM_ERR_INVALID_PARAM | 端口或 pin 信息非法 |
IM_ERR_NOT_READY | 内部 IRQ 上下文未建立 |
补充说明:
当前实现通过设置 pin mask 并清除 pending flag 来停止中断投递
该操作不会清除已登记的 callback 指针
2.5.4 hal_gpio_irq_handler
void hal_gpio_irq_handler(gpio_regs_t *gpiox);
功能说明: 处理某个 GPIO 端口的 grouped interrupt。
参数表:
| 参数 | 类型 | 方向 | 说明 |
|---|---|---|---|
gpiox | gpio_regs_t * | 输入 | 产生 grouped interrupt 的 GPIO 端口 |
返回值表:
| 返回值 | 说明 |
|---|---|
| 无 | 接口不返回状态码;若端口无效或无软件状态,直接返回 |
补充说明:
处理流程为:读取 pending mask、逐 pin 清中断、按需切换双边沿、最后回调上层
该接口通常由 SoC 中断域调用,不建议业务层直接调用
3. 当前实现约束与行为说明
3.1 hal_gpio_init() 支持非空 pin mask
hal_gpio_init()使用hal_gpio_init_t描述目标端口与 pin maskpin_mask可以为多 bit,用于同一端口多个 pin 的批量初始化hal_gpio_deinit()与hal_gpio_init()对应,也接收hal_gpio_init_t *hal_gpio_deinit()只使用gpiox和pin_mask字段
3.2 中断只允许在输入模式下启用
hal_gpio_enable_irq()会根据当前寄存器功能状态判断 pin 是否处于输入或中断模式当前仅
HAL_GPIO_FUNCTION_INPUT允许开启 GPIO IRQ
3.3 双边沿中断由 HAL 软件补齐
HAL_GPIO_IRQ_TRIGGER_EDGE_BOTH的首次硬件编程会根据当前电平转换成上升沿或下降沿之一中断到来后,
hal_gpio_irq_handler()会切换下一次边沿方向因此双边沿并不是单次硬件寄存器写入即可完成的原生模式
3.4 request_pin 是软件登记,不是硬件锁
hal_gpio_request_pin()仅更新 HAL 内部软件状态它不会阻止其他代码直接调用 LL 接口或直接改写 GPIO 寄存器
4. 典型用法
4.1 配置单个输出 pin
hal_gpio_init_t init; hal_gpio_struct_init(&init); init.gpiox = GPIOD; init.pin_mask = GPIO_PIN_5; init.mode = HAL_GPIO_FUNCTION_OUTPUT_LOW; init.pull = HAL_GPIO_PULL_NONE; hal_gpio_init(&init); hal_gpio_write_pin(init.gpiox, init.pin_mask, HAL_GPIO_PIN_SET);
4.2 配置单个输入 pin
hal_gpio_init_t init; hal_gpio_struct_init(&init); init.gpiox = GPIOD; init.pin_mask = GPIO_PIN_4; init.mode = HAL_GPIO_FUNCTION_INPUT; init.pull = HAL_GPIO_PULL_UP; hal_gpio_init(&init);
4.3 配置 GPIO 中断
static void gpio_irq_cb(gpio_regs_t *gpiox,
uint32_t pin_mask,
bool level,
void *user_ctx)
{
(void)gpiox;
(void)pin_mask;
(void)user_ctx;
(void)level;
}
hal_gpio_init_t init;
hal_gpio_struct_init(&init);
init.gpiox = GPIOD;
init.pin_mask = GPIO_PIN_4;
init.mode = HAL_GPIO_FUNCTION_INPUT;
init.pull = HAL_GPIO_PULL_NONE;
hal_gpio_init(&init);
hal_gpio_register_irq_callback(init.gpiox, init.pin_mask, gpio_irq_cb, NULL);
hal_gpio_enable_irq(init.gpiox, init.pin_mask, HAL_GPIO_IRQ_TRIGGER_EDGE_BOTH);