目录
- 1 esp32 series的中断控制器
- 2 基于riscv和xtensa的芯片中断模块的区别
- 3 使用esp32 series的中断
-
- 3.1 中断的配置
- 3.2 中断的处理
- 3.2 中断的清除
1 esp32 series的中断控制器
和一些中断控制器固定了中断连线不同,esp32 series采用
中断矩阵
来连接
中断源
和
中断输入引脚
。这样做的好处是可以灵活配置中断源对应的中断号。至于中断控制器的内部实现,难以探究,且对于软件来说,也无需知道,通常我们关心的也就是中断控制器在逻辑上的等效,如下图所示:
需要说明的是:
- 上图中UART部分不属于中断控制器,列举这样一个常见的外设是为了解释清楚外设的中断相关寄存器与中断控制器的关系;
- 中断控制器的寄存器的名字并非与TRM中完全一致,但命名也算讲究,不难将它们相互对应起来;
- 基于riscv和xtensa的esp芯片在中断控制器上稍有差别,有些寄存器对于xtensa-based芯片来说是没有的,下一节将会说明。
TODO:多核与中断矩阵
2 基于riscv和xtensa的芯片中断模块的区别
乐鑫当前使用的核心有两种,分别是
xtensa
和
riscv
,前者的代表有:
- esp32
- esp32s2
- esp32s3
后者的代表有:
- esp32c3
- esp32h2
下面分别以
esp32s2
和
esp32c3
为代表,比较一下两种芯片在中断控制器方面的异同:
esp32c3(riscv) | 来自中断控制器(0)/核心(1) | esp32s2(xtensa) | 来自中断控制器(0)/核心(1) |
---|---|---|---|
INT_ENABLE_REG | INTENABLE | 1 | |
INT_TYPE_REG | N/A | N/A | |
INT_CLR_REG | INTCLEAR | 1 | |
INT_EIP_REG | INTERRUPT | 1 | |
INT_PRIORITY_REG | N/A | N/A | |
INT_THRESHOLD_REG | PS.INTLEVEL | 1 | |
INT_MAP_REG | INT_MAP_REG | ||
INT_STATUS_REG | INT_STATUS_REG | ||
INT_CLOCK_REG | INT_CLOCK_REG | ||
INT_DATA_REG | INT_DATA_REG |
不难看出,xtensa-based有一些寄存器是核心提供的,因此中断控制器就不再重复提供,且由于xtensa不支持中断类型及优先级的配置,因此相应的寄存器也不存在(注意是不支持配置,但类型和优先级是存在的)。
值得一提的是,符合标准的riscv核心也有一些关于中断的特权寄存器,常见的比如
mip
,
mie
等,它们构建了如下的逻辑:
再看esp32c3,由于已经具备了
INT_ENABLE_REG
和
INT_EIP_REG
,且仅支持机器模式,因此就没有再设计
mip
和
mie
,没有需要。
3 使用esp32 series的中断
3.1 中断的配置
- 设置中断类型
- 设置优先级
- 配置matrix映射
- 注册中断handler
- 一系列的ENABLE
- 需要时设置中断阈值(通常是全局)
3.2 中断的处理
中断配置好以后,等到触发,CPU就会响应,此时需要提供相应的中断处理函数。不同于cortex-M3使用的NVIC,使用支持ABI规范的硬件机制使得一个C函数就可以作为中断入口。esp32 series的中断入口要稍微复杂一点,从入口到执行用户提供的中断处理函数有一个过程,这个放在本系列的下一篇博客细说。
3.2 中断的清除
中断处理完成后(或开始前)需要清楚中断的pending位,否则刚出中断又会触发,最终陷进中断出不来,这当然是常识。esp32 series的中断清除有些需要注意的地方,电平类型(高点平)和脉冲类型(上升沿)的中断对于清除操作的要求是不同的:
- 对于电平类型,需要清除中断源。在逻辑上可以理解为电平类型中断的pending与中断源连通,电平没了,pending也就没了。
- 对于脉冲类型,需要清除中断源以及pending,在逻辑上理解位脉冲类型中断的pending在捕获到脉冲后会保持,直到在中断处理函数中使用INT_CLR_REG清除它。