4.1.1. 设计说明¶
4.1.1.1. 源码说明¶
Interrupt 相关 .c 和 .h 文件分别位于 luban-lite\kernel\common\include\osal\aic_osal_platform_lbl.h 和 luban-lite\bsp\artinchip\sys\dxxx\ 目录。主要源文件说明如下:
| 文件 | 说明 | 
|---|---|
| aic_osal_platform_lbl.h | aicos 层中断 注册 & 使能 函数 | 
| aic_drv_irq.c | drv 层 interrupt 的实现 | 
| aic_drv_gpio.c | drv 层 gpio 中断的扩展 | 
4.1.1.2. 模块架构¶
4.1.1.2.1. 普通中断¶
对于普通中断来说实现的原理非常简单,核心就是两个数组 g_irqvector[] 和 g_irqdata[],分别用来存储中断处理函数的函数指针和附加数据。对应具体操作如下:
- 中断注册。用户调用 - aicos_request_irq()根据中断号把中断处理函数和附加数据存入到- g_irqvector[]和- g_irqdata[]数组。
- 中断处理。中断发生后所有中断首先会跳入 - Default_IRQHandler()通用中断处理函数中,然后根据- MCAUSE寄存器查询当前的中断号,根据中断号在- g_irqvector[]和- g_irqdata[]数组中查询具体的中断处理函数指针和附加数据,然后再跳转到具体 ISR 中执行。
 
4.1.1.2.2. GPIO 中断¶
GPIO 中断的实现稍有不同。因为 GPIO 一个 Group 只能共享一个中断(一个 Group 最多包含 32 个 Pin),但是用户要求对每个 Pin 单独的注册中断处理函数,所以需要对 GPIO Pin 二级中断进行特殊处理。既能实现功能又能让用户零感知。具体做法如下:
- 扩大 - g_irqvector[]和- g_irqdata[]数组。让每个 GPIO Pin 中断都拥有独立的存放位置,另外也可以做到对一级中断和二级中断格式一样。
- 中断注册。目前在 rt-thread 下可以使用 - rt_pin_attach_irq()函数来注册 GPIO Pin 中断,使用- rt_pin_irq_enable()函数来使能 GPIO Pin 中断。
- 处断处理。GPIO Pin 发生中断以后,首先会跳转到一级中断处理函数 - drv_gpio_group_irqhandler()中执行,通过查询发生中断的 Group 和 Pin Offset,最终在- g_irqvector[]和- g_irqdata[]数组中查询到具体的中断处理函数指针和附加数据,然后再跳转到具体 ISR 中执行。
 
CMU 驱动的逻辑比较简单,目前只在 HAL 层提供了 Clock 和 Reset 的 API 接口。RTOS 驱动和 Baremetal 驱动都可以直接使用。
4.1.1.3. 数据结构设计¶
Interrupt 模块关键结构体定义如下:
4.1.1.3.1. irq_handler_t/pin_irq_handler_t¶
enum irqreturn
{
    IRQ_NONE        = (0 << 0),
    IRQ_HANDLED     = (1 << 0),
    IRQ_WAKE_THREAD = (1 << 1),
};
typedef enum irqreturn irqreturn_t;
typedef irqreturn_t (*irq_handler_t)(int, void *);
typedef irqreturn_t (*pin_irq_handler_t)(void *);
4.1.1.4. 接口设计¶
4.1.1.4.1. AICOS Irq API¶
4.1.1.4.1.1. aicos_request_irq¶
| 函数原型 | int aicos_request_irq (unsigned int irq, irq_handler_t handler, unsigned int flags, const char *name, void *data) | 
|---|---|
| 功能说明 | 注册中断 | 
| 参数 | irq    :中断号 handler:中断处理函数 flags  :中断标志 name   :中断号名称 data   :中断附加数据 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
4.1.1.4.1.2. aicos_irq_enable¶
| 函数原型 | void aicos_irq_enable(unsigned int irq) | 
|---|---|
| 功能说明 | 使能中断 | 
| 参数 | irq:中断号 | 
| 返回值 | 无 | 
| 注意事项 | 
4.1.1.4.1.3. aicos_irq_disable¶
| 函数原型 | void aicos_irq_disable(unsigned int irq) | 
|---|---|
| 功能说明 | 关闭中断 | 
| 参数 | irq:中断号 | 
| 返回值 | 无 | 
| 注意事项 | 
4.1.1.4.1.4. aicos_local_irq_enable¶
| 函数原型 | void aicos_local_irq_enable(void) | 
|---|---|
| 功能说明 | 使能 CPU 全局中断中断 | 
| 参数 | 无 | 
| 返回值 | 无 | 
| 注意事项 | 
4.1.1.4.1.5. aicos_local_irq_disable¶
| 函数原型 | void aicos_local_irq_disable(void) | 
|---|---|
| 功能说明 | 关闭 CPU 全局中断中断 | 
| 参数 | 无 | 
| 返回值 | 无 | 
| 注意事项 | 
4.1.1.4.2. RTT GPIO Irq API¶
4.1.1.4.2.1. rt_pin_attach_irq¶
| 函数原型 | rt_err_t rt_pin_attach_irq (rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) | 
|---|---|
| 功能说明 | 注册 gpio pin 中断 | 
| 参数 | pin :pin 管脚编号 mode:pin 中断模式,上升下降沿、高低电平 hdr :pin 中断处理函数 args:pin 中断附加数据 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
4.1.1.4.2.2. rt_pin_detach_irq¶
| 函数原型 | rt_err_t rt_pin_detach_irq(rt_int32_t pin) | 
|---|---|
| 功能说明 | 注销 gpio pin 中断 | 
| 参数 | pin:pin 管脚编号 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 | 
4.1.1.4.2.3. rt_pin_irq_enable¶
| 函数原型 | rt_err_t rt_pin_irq_enable(rt_base_t pin, rt_uint32_t enabled) | 
|---|---|
| 功能说明 | 使能/关闭 gpio pin 中断 | 
| 参数 | pin    :pin 管脚编号 enabled:使能/关闭 | 
| 返回值 | 操作是否成功 (0=OK, other=Error) | 
| 注意事项 |