Arm ';使用故障异常';臂皮质M

Arm ';使用故障异常';臂皮质M,arm,rtos,freertos,cortex-m,Arm,Rtos,Freertos,Cortex M,我参加了一个关于FreeRtos和Cortex M的讲座,讲师建议如果ISR未使用ISR安全版本的API,可能会导致Cortex M处理器中出现使用错误异常 我的问题是为什么这个任务切换会被认为是非法的,这种切换会产生什么影响?在Cortex-M(部分)上,当前上下文将存储在中断之前使用的堆栈上(在中断条目上),因此,如果您正在执行一项任务,并且任务被中断,那么当前的一些上下文将存储在任务堆栈上(通过PSP)。中断本身总是在MSP上运行。如果中断没有返回到它中断的任务,那么被中断的任务将有一个混

我参加了一个关于FreeRtos和Cortex M的讲座,讲师建议如果ISR未使用ISR安全版本的API,可能会导致Cortex M处理器中出现使用错误异常 我的问题是为什么这个任务切换会被认为是非法的,这种切换会产生什么影响?

在Cortex-M(部分)上,当前上下文将存储在中断之前使用的堆栈上(在中断条目上),因此,如果您正在执行一项任务,并且任务被中断,那么当前的一些上下文将存储在任务堆栈上(通过PSP)。中断本身总是在MSP上运行。如果中断没有返回到它中断的任务,那么被中断的任务将有一个混乱的堆栈(因为它在退出时恢复存储的上下文),并且尝试为切换到的任务恢复不正确的上下文

在上下文切换(发生在中断中)上,部分上下文会自动存储在任务堆栈上,但操作系统也会将其余上下文存储在任务堆栈上。当它切换并退出中断时,操作系统将恢复为任务存储的上下文,然后通过退出中断自动恢复上下文的其余部分。这可以确保堆栈保持正确的格式。查看Cortex-M4通用用户指南中的中断进入/退出


并非所有处理器都是这样工作的。

这个答案是通用的,不是FreeRTOS,也不是Cortex-M特定的-它适用于任何平台上的任何典型RTO:

无法从中断服务例程调用导致调度程序运行的RTOS API调用。例如,如果您给出一个信号量,通常调度程序运行以切换到该信号量上挂起的任何任务;这在ISR中是不合适的,因为当中断上下文退出时,调度程序必须运行一次;显然,您不希望在中断完成之前进行上下文切换,并且可能存在其他API调用或更高优先级中断的抢占,从而导致不同的任务变得可运行;当上下文切换发生时,只进行一次评估可以保持确定性行为

特定于ISR的函数版本不会立即调用调度程序;相反,它们设置了一个标志,指示调度器必须在退出中断上下文时运行

通常,进行RTOS API调用的ISR必须有序言和尾声;特定的输入/输出中断调用或宏。这个序言增加了一个计数器,该计数器在尾声中递减;如果计数器为零且设置了调度标志,则调度程序将运行。计数器用于防止调度程序在嵌套中断退出时运行。这可确保调度器仅在退出时从最低优先级的挂起中断运行一次

“uasge故障”是否会发生或为什么会发生是FreeRTOS特定的实现细节,主要是学术性的。RTO同样可以捕获ISR中非ISR安全调用的使用,并运行更具体的错误处理程序,如果它不费心这么做,那么由此产生的行为可能会触发使用错误;这似乎是一个可以依赖的有点粗糙的机制;使用故障是一个非常广泛的陷阱,可能发生的原因有很多:

使用错误:检测未定义、未对齐指令的执行 用于加载/存储多个数据的内存访问。启用时,除以零 并且还检测到其他未对齐的内存访问


一些RTO没有特定于ISR的功能,相反,导致调度的API调用会在内部检测ISR上下文,并在该上下文中表现出不同的行为-这对程序员来说更简单、更安全,但在每次这样的调用上测试上下文会带来很小的开销。在内部处理ISR安全的API还意味着调用本身可能进行操作系统API调用的函数更简单,因为这些函数本身不需要是特定于ISR的。

听起来是特定于软件的,与它所使用的cpu无关。