本帖最后由 DKENNY 于 2024-8-12 13:42 编辑
在讨论单片机时,一个常见的问题是,main 函数是否在中断处理程序内执行。特别是,当复位中断(Reset_Handler)直接调用 main 函数时,是否意味着所有程序都在复位中断中运行?
首先,让我们明确一点:Reset_Handler 实际上是单片机中的一个中断,而 main 函数确实是在这个中断被调用时执行的。因此,从某种角度来说,可以说 main 函数在中断中运行。 这个问题可能会让我们重新审视自己以前的理解,但不少人可能对此没有深刻的思考。尤其是在单片机的上下文中,这个概念可能并不容易被捉摸。
## 单片机的操作模式 我们以 ARM Cortex-M 单片机为例来探讨这个话题。Cortex-M架构支持两种运行模式和两种特权级别。 两种模式:
两个等级:
区别在于用户级和内核级在处理线程与中断的机制上有所不同。
在 Cortex-M3 的手册中,有提到一些关键事项:
根据这些内容,我们可以回答开头的问题。官方文档也提供了关于此的详细信息。
地址:https://developer.arm.com/documentation/dui0552/a/the-cortex-m3-processor/exception-model/exception-types
## BASEPRI寄存器解析
在ARM架构中,BASEPRI寄存器用于设置一个机制来控制中断的优先级,使得某些中断在执行特定代码时被屏蔽,从而提高系统的安全性和稳定性。BASEPRI寄存器的值定义了一个优先级阈值,只有优先级低于这个值的中断才能被响应。 当 BASEPRI 的值为 0 时,这意味着没有中断被屏蔽,系统能够响应所有优先级的中断。在这种情况下,可以说处于特权级(PrivilegedMode),因为在ARM架构中,特权级意味着能访问和控制硬件资源以及系统的核心功能。 用户级(User Mode)是一个较低的特权级别,通常不允许直接访问某些硬件资源和关键系统功能。因此,当一个任务以用户模式运行时,其一般情况下不能直接修改BASEPRI寄存器。 总结一下,如果BASEPRI=0,当前内核处于特权级。
## 示例分析 让我们结合 Keil MDK 与 APM32 的工程代码来作进一步分析:
1.进入Reset_Handler中断 在复位之后,处理器首先会进入 Reset_Handler,此刻,系统的工作在特权级别的线程模式下进行。
此时,就是文档中提到的:在复位后,处理器进入特权级的Thread模式。
2.进入SysTick_Handler中断 当我们进入普通中断,比如这里进入 SysTick_Handler 时钟滴答中断:
## 总结 复位中断(Reset_Handler)及普通中断(SysTick_Handler)在操作模式上有所不同,这是理解 main 函数其执行环境的关键。不同的开发环境如 Keil、GCC 等都依据此内核的设计理念,处理方式相似。
尽管我们可能没有深入探讨该问题,但这也是一个对内核机制的全新认识。了解这一点并非强制要求,但它为我们提供了更深入的知识理解。
|