Unlocking the Power of ARM: Operating States, Modes and Access Levels
Published on 15/09/2024
Written by: Malek Boubahri and Khaled Dhif
Introduction
Welcome to the next installment in our series on ARM Cortex processors. In our previous articles, we explored the history of ARM, discussed fundamental concepts and components, and delved into the Instrumentation Trace Macrocell (ITM) while experimenting with printf for debugging. These foundational topics have set the stage for a deeper understanding of ARM Cortex-M processors.
In this article, we will focus on the operating modes, states, and access levels of ARM Cortex-M processors. These elements are crucial for optimizing system performance and ensuring proper operation within embedded applications. We’ll examine how these modes and states interact with the processor’s registers, with a particular emphasis on the Control register, which manages access levels and operational configurations.
By the end of this article, you will have a thorough understanding of how to configure and leverage these features to enhance your embedded systems' functionality and security.
The Armv7-M architecture is designed with two distinct operating states and two operating modes. In addition to these, the architecture incorporates two access levels: privileged and unprivileged. The privileged access level grants unrestricted access to all system resources, while the unprivileged level limits access to certain memory regions and restricts the use of specific operations. Understanding how these states, modes, and access levels work together is crucial for effectively managing system security and performance.
Operating States
The ARMv7-M architecture defines two primary operating states that the processor can operate in: Thumb state and Debug state. Each state serves a specific purpose and determines how the processor handles instructions and debugging events.
Note:
It's important to recognize that when the processor is stopped by a debugger, other parts of the system, such as peripherals and Direct Memory Access (DMA), continue to run. Many users expect that stopping code execution completely halts the entire microcontroller, but that is not the case. While the processor stops processing instructions, the rest of the system—such as clocks, memory systems, and peripherals—continues to function. For instance, peripherals may keep sending data, and DMA operations may continue transferring data in the background. This can result in changes to memory or peripheral registers while stepping through code or refreshing the debugger display, which can be surprising if one assumes the entire chip has stopped. This behavior reflects the System-on-Chip (SoC) nature of ARM Cortex-M processors, where different subsystems operate independently of the processor’s state.
These two states are fundamental to the ARM Cortex-M operation, enabling efficient code execution in Thumb state and robust debugging capabilities in Debug state, while maintaining peripheral activity during debugging.
Privileged and Unprivileged Execution
The ARM Cortex-M architecture supports two distinct access levels: privileged and unprivileged, which determine the extent of a program’s control over system resources.
Note: A page fault specifically occurs when the system’s memory management unit (MMU) cannot map a requested memory address to physical memory. This is usually the case with more complex processors like the ARM Cortex-A that implement this unit.
Operating Modes: Thread Mode and Handler Mode
ARM Cortex-M processors operate in one of two modes: Thread mode and Handler mode, which correspond to different levels of control and execution contexts.
Inline Assembly and Compiler Support
Several modern compilers support the use of inline assembly, allowing developers to embed low-level assembly instructions directly into high-level C or C++ code. This feature is especially useful for hardware-specific operations or optimizing critical sections of code. Common compilers that support inline assembly include:
- GCC (GNU Compiler Collection): Supports the GNU inline assembly syntax, widely used for ARM processors.
- ARM Compiler: Also supports GNU-style inline assembly, offering flexibility for developers targeting ARM architectures.
领英推荐
- Clang/LLVM: Provides compatibility with GCC-style inline assembly.
IDEs Supporting Inline Assembly for ARM Cortex-based MCUs:
For ARM Cortex-M based MCUs, several Integrated Development Environments (IDEs) provide support for inline assembly in C/C++ projects, such as:
- Keil MDK (Microcontroller Development Kit): A popular IDE for ARM Cortex-M development, featuring a built-in compiler that supports inline assembly.
- STM32CubeIDE: Developed by STMicroelectronics, it combines the power of Eclipse and GCC for developing STM32-based applications, supporting inline assembly.
- IAR Embedded Workbench: Another widely-used IDE for ARM Cortex development, with support for inline assembly and advanced debugging tools.
- Atollic TrueSTUDIO: Now part of STM32CubeIDE, this IDE also supports inline assembly through the GNU ARM toolchain.
These IDEs offer debugging features, project management, and code completion tools, making them excellent platforms for developers working on ARM Cortex-M microcontrollers.
Core Registers and Access Levels
ARM Cortex-M processors have a well-defined set of core registers that include general-purpose registers, special-purpose registers, and status registers. These registers are crucial for controlling the behavior of the processor, accessing memory, and managing execution states. Unlike memory-mapped peripherals, these core registers are not memory-mapped and thus cannot be accessed using traditional pointer-based methods. Instead, they must be accessed through assembly code instructions or specific compiler intrinsics designed for manipulating these registers directly.
General-Purpose Registers
The Cortex-M processor features R0 through R12 as general-purpose registers, which are primarily used for holding variables and intermediate values during execution. These registers can be accessed directly by both C/C++ code and inline assembly.
Special-Purpose Registers
In addition to general-purpose registers, there are several special-purpose registers critical for controlling the processor's state and behavior:
- Program Counter (PC): Holds the address of the next instruction to be executed.
- Stack Pointer (SP): Two stack pointers exist — the Main Stack Pointer (MSP) and the Process Stack Pointer (PSP), used in different execution modes.
- Link Register (LR): Holds the return address when a function call is made.
- Program Status Register (PSR): Holds the current state of the processor, including condition flags (e.g., zero, negative).
Among these, the CONTROL register is of particular interest when dealing with access levels in ARM Cortex-M processors.
The CONTROL Register
The CONTROL register is a special-purpose register that defines whether the processor is operating in privileged or unprivileged mode. It also controls which stack pointer (MSP or PSP) is used in Thread mode.
- CONTROL[0]: Defines the current privileged or unprivileged state.
??- 0: Privileged access level.
??- 1: Unprivileged access level.
- CONTROL[1]: Selects the stack pointer.
??- 0: Uses the Main Stack Pointer (MSP).
??- 1: Uses the Process Stack Pointer (PSP).
On reset, the processor starts in privileged Thread mode with the MSP stack pointer by default. To switch between privileged and unprivileged modes, software can modify the CONTROL register using inline assembly, since this register is not memory-mapped and cannot be accessed directly by normal C code.
Conclusion
In this article, we examined the operating modes and access levels of ARM Cortex-M processors. We covered the Thumb and Debug states, the significance of privileged and unprivileged execution, and the role of the CONTROL register in managing access levels. Understanding these elements is crucial for optimizing system performance and security in embedded applications.
Stay tuned for our hands-on video tutorial, where we'll demonstrate how to configure these settings on an ARM Cortex-M based MCU, offering a practical look at applying these concepts in real-world scenarios.