Interrupt Controller(NVIC)

smallcracker 2021-01-29 00:00:00
Categories: Tags:

Interrupt Controller(NVIC)

The interrupt controller API provides a set of functions for dealing with the Nested Vectored Interrupt
Controller (NVIC). Functions are provided to enable and disable interrupts, register interrupt
handlers, and set the priority of interrupts.

中断控制器API提供了一系列与内置向量式中断控制器有关的函数,这些函数能使能/使不能中断,注册中断,设置中断优先级等

The NVIC provides global interrupt masking, prioritization, and handler dispatching. Devices within
the Tiva family support up to 154 interrupt sources and eight priority levels. Individual interrupt
sources can be masked, and the processor interrupt can be globally masked as well (without affecting
the individual source masks).

NVIC提供了全局中断屏蔽,优先级和处理器调度功能,在Tiva系列设备里至多支持154个中断和8个中断级,单个中断源可以被屏蔽,处理器屏蔽也可以被全局屏蔽(不影响单个中断源的屏蔽哦)

The NVIC is tightly coupled with the Cortex-M microprocessor. When the processor responds to
an interrupt, the NVIC supplies the address of the function to handle the interrupt directly to the
processor. This action eliminates the need for a global interrupt handler that queries the interrupt
controller to determine the cause of the interrupt and branch to the appropriate handler, reducing
interrupt response time.

NVIC紧密搭配着cortex_M微处理器。当处理器对中断作出反应时,NVIC直接把处理中断的函数的地址提供给处理器,此操作无需使用全局中断处理程序来查询中断控制器以确定中断的原因,并分支到相应的处理程序,从而减少中断响应时间。

The interrupt prioritization in the NVIC allows higher priority interrupts to be handled before lower
priority interrupts, as well as allowing preemption of lower priority interrupt handlers by higher priority
interrupts. Again, this helps reduce interrupt response time (for example, a 1 ms system control
interrupt is not held off by the execution of a lower priority 1 second housekeeping interrupt handler).

中断处理优先级使得高优先级的中断在低优先级中断之前处理,并允许高优先级中断抢占低优先级中断。这还能减少中断响应时间,比如1ms的系统控制中断不会被更低优先级的1ms中断所延迟。

Sub-prioritization is also possible; instead of having N bits of preemptable prioritization, the NVIC
can be configured (via software) for N - M bits of preemptable prioritization and M bits of sub-priority.
In this scheme, two interrupts with the same preemptable prioritization but different sub-priorities
do not cause a preemption; tail chaining is used instead to process the two interrupts back-to-back.

还可以设置子优先级,如果不设置N位可抢占优先级的话,可以通过软件设置N-M个可抢占优先级和M个子优先级,在这种方案下,两个仅仅子优先级不同的可抢占中断不会导致抢占,单片机会使用尾链来来回处理两个中断

If two interrupts with the same priority (and sub-priority if so configured) are asserted at the same
time, the one with the lower interrupt number is processed first. The NVIC keeps track of the nesting
of interrupt handlers, allowing the processor to return from interrupt context only once all nested
and pending interrupts have been handled.

如果两个中断有相同的优先级(和子优先级)还被同时触发了,中断数更低的有限执行,NVIC会跟踪中断处理程序的嵌套,要求处理器在处理完所有被嵌套和挂起的中断后再返回

Interrupt handlers can be configured in one of two ways; statically at compile time or dynamically at
run time. Static configuration of interrupt handlers is accomplished by editing the interrupt handler
table in the application’s startup code. When statically configured, the interrupts must be explicitly
enabled in the NVIC via IntEnable() before the processor can respond to the interrupt (in addition to
any interrupt enabling required within the peripheral itself). Statically configuring the interrupt table
provides the fastest interrupt response time because the stacking operation (a write to SRAM) can
be performed in parallel with the interrupt handler table fetch (a read from Flash), as well as the
prefetch of the interrupt handler itself (assuming it is also in Flash).

中断处理程序可以用两种方式中的一种来设置,编译时设置或者运行时动态设置。静态配置使用的是IntEnable()函数完成的,运行的时候静态配置的中断处理程序更快一点。

Alternatively, interrupts can be configured at run-time using IntRegister() (or the analog in each
individual driver). When using IntRegister(), the interrupt must also be enabled as before; when
using the analogue in each individual driver, IntEnable() is called by the driver and does not need
to be called by the application. Run-time configuration of interrupts adds a small latency to the
interrupt response time because the stacking operation (a write to SRAM) and the interrupt handler
table fetch (a read from SRAM) must be performed sequentially.

在运行时设置的话,需要用到IntRegister()函数,会有延迟。

Run-time configuration of interrupt handlers requires that the interrupt handler table be placed on a
1-kB boundary in SRAM (typically this is at the beginning of SRAM). Failure to do so results in an
incorrect vector address being fetched in response to an interrupt. The vector table is in a section
called “vtable” and must be placed appropriately with a linker script.

中断处理程序的配置需要将中断处理表放在SARM1kb的边缘上。。。。。

This driver is contained in driverlib/interrupt.c, with driverlib/interrupt.h containing
the API declarations for use by applications.

他的函数非常少

image-20201212164149113

前两个是使能/使不能一个中断

第三个 确认一个中断是否在运行,如果一个中断在运行的话,会返回一个非零数

第四个 第五个 使能/使不能处理器中断

image-20201212164210385

第一个 第二个 挂起/放下一个中断

第三个 获取一个中断的优先级

第四个 获取中断控制器的优先级分组 就是返回可抢占优先级的位数

第五个 设置可抢占优先级的位数

第六个 获取优先级屏蔽

This function gets the current setting of the interrupt priority masking level. The value returned is the priority level such that all interrupts of that and lesser priority are masked. A value of 0 means that priority masking is disabled.
Smaller numbers correspond to higher interrupt priorities. So for example a priority level mask of 4 allows interrupts of priority level 0-3, and interrupts with a numerical priority of 4 and greater are blocked.
The hardware priority mechanism only looks at the upper 3 bits of the priority level, so any prioritization must be performed in those bits.

第七个 设置优先级屏蔽

第八个 设置中断优先级

image-20201212165114559

第一个 注册一个函数,中断发生是就调用它

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//
// UART 0 interrupt handler.
//
void
UART0Handler(void)
{
//
// Handle interrupt.
//
}
//
// Set the UART 0 interrupt handler.
//
IntRegister(INT_UART0, UART0Handler);

第二个 触发一个中断 (直接触发)

第三个 解注册一个中断

所以怎样使用中断呢?

直接去对应外设那里去查询中断怎样使用,然后回来使能中断即可,有需要就设置优先级啊,子优先级啊,屏蔽啊等等。

有需要还可以直接触发一个中断的。