改变NVIC中当前中断的优先级

问题描述 投票:1回答:2

我有一个难题。我正在使用的部分(NXP KL27,Cortex-M0 +)在其I2C外设中有一个勘误,因此在接收期间没有流量控制。因此,它需要是一个高优先级的中断。我也在使用UART,由于它的异步特性,它的接收没有流量控制。因此,它需要是一个高优先级的中断。

循环优先

I2C中断需要比UART中断更高的优先级,否则在读取之前,输入字节可能会在移位寄存器中被拆除。它确实不应该以这种方式工作,但那是勘误,所以它需要更高的优先级。

UART中断需要比I2C中断更高的优先级,因为要关闭I2C事务,驱动程序(来自NXP的KSDK)需要设置一个标志并等待状态位。在此期间,UART上的输入字符可能会溢出非FIFO移位寄存器。

在尝试解决UART的问题时,我发现了这种循环依赖。最初的问题是UART接收中的字符消失,并且设置了溢出标志。在交换优先级时,UART坚如磐石,从未错过任何字符,但由于超支,I2C事务最终停止。

可能解决方案

我想出的解决方案涉及到动态改变中断优先级。当I2C驱动程序关闭事务时,它没有接收,这意味着导致字节不受控制地流动的勘误不是问题。我希望在此期间降低NVIC中的I2C中断优先级,以便UART能够优先于它,从而使UART满意(并且不会丢失任何字符)。

我无法从ARM中找到任何内容,说明在执行该中断时更改中断优先级是立即生效,还是当前中断的优先级在开始执行时被锁存。我希望有人能够从他们对架构的深入了解或者从改变优先级的经验中立即保存,或者不会立即生效。

其他可行解决方案

还有许多其他可能的解决方案以及它们为什么不合需要的原因。重构I2C驱动程序以处理进程上下文中的循环而不是中断上下文将是一项重要工作,需要深入研究供应商代码并影响调用它的应用程序代码。对这些外设中的任何一个使用DMA会占用可用的非常少量的DMA通道,并且会产生为每个事务设置DMA的开销(并且还会影响调用驱动程序的应用程序代码)。

我对其他解决方案持开放态度,但对于导致供应商代码发生重大变化的任何路径犹豫不决。

测试

我有一个实验来测试NVIC在这方面是如何工作的,但我想我会先在这里查看。如果我参加实验,我会发布一个结果的后续答案。

arm interrupt interrupt-handling cortex-m
2个回答
1
投票

在架构上,这似乎是不可预测的(改变当前活动例外的优先级)。似乎没有逻辑来强制执行更一致的行为(即您关注的注册逻辑显然不存在于M0 / M0 +中)。

这意味着,如果您测试变通方法的有效性,它可能会起作用 - 在您受约束的情况下,它可能会有效。但是,不能保证相同的代码可以在M3上运行,或者它在所有场景中都可靠地工作(例如与调试的任何交互)。您甚至可能会观察到一些完全不可预测的角落案例行为,但区域受限制

这在ARM v6-M ARM的B1.5.4节中被指定为不可预测的。

对于v7-M(B1.5.4,异常优先级和抢占)

执行优先级的这种定义意味着异常处理程序可以以高于相应异常的优先级的优先级执行。特别是,如果处理程序降低了其相应异常的优先级,则执行优先级仅下降到优先级最高的抢占异常的优先级。因此,降低当前异常的优先级绝不允许:

  • 抢占当前异常处理程序的抢占异常。
  • 反转抢占异常的优先级。

v7-M方面阐明了一些复杂的场景,如果你试图利用你认为对M0 +部分有用的不可预测的行为,必须避免这些场景。


0
投票

实验

我今天编写了一个快速实验来测试我在Cortex M0 +的特定变体上的这种行为。我将此作为一个不可接受的答案,我相信@Sean Houlihane的答案是最正确的(即它是不可预测的)。我仍然想测试行为并在特定情况下报告我正在使用它。

该实验在FRDM-KL43Z板上进行。它有一个红色LED,一个绿色LED和两个按钮。应用程序执行了一些GPIO设置和中断,然后进入无限循环。

按钮1:按钮1的中断处理程序初始化为中间电平优先级(0x80)。在按钮1的每个下降沿,它都会中断。此中断将切换绿色LED的状态。

按钮2:按钮2的中断处理程序初始化为中间级别优先级(0x80),但会作为执行的一部分进行更改。按钮2中断处理程序将运行一个持续大约8秒(两个阶段为四个)的循环,无限期地重复。它将打开红色LED并将其自身优先级降低到低于按钮1的优先级。四秒后,它将关闭红色LED并将其自身优先级提高到高于按钮1的优先级。四秒后它将重复。

预期成绩

如果假设为真,则当红色LED亮起时,按下按钮1将切换绿色LED,当红色LED熄灭时,按下按钮1将无效,直到红色LED熄灭。在永久循环按钮2中断具有较低优先级之前,按钮1中断不会执行。

结果

这是无聊的部分。我在上一节中所期待的一切都发生了。

结论

对于实验设置(NXP KL43Z Cortex M0 +),在中断运行时更改当前正在执行的中断的中断优先级。因此,我在忙碌的等待期间降低优先级并在之后恢复它的hacky解决方法应该能够满足我的需求。

编辑:以后的结果

尽管实验成功,但一旦实现了原始问题的解决方法,就会出现问题。 UART和I2C处理程序之间的交互相对一致,但第三个外设在其中断处理程序中开始出现非常奇怪的行为。注意不可预知的警告。

© www.soinside.com 2019 - 2024. All rights reserved.