Home | Projects | Notes > ARM Cortex-M3/M4 Processor > Access Levels & Operation Modes of the Processor
This section applies to ARM Cortex M0/M3/M4 Processors. If you are using any other processors, please consult the corresponding document.
The processor provides 2 operation modes:
Thread mode (User mode)
All program code will execute under "Thread mode" of the processor by default. It can be privileged (full access to CPU resources) or unprivileged (limited access to CPU resources) software execution.
Handler mode
All the exception handlers (or interrupt handlers) will run under the "Handler mode" or the processor. It is ALWAYS privileged software execution.
The processor always starts with "Thread mode".
When there occurs a system exception or any interrupt (HW, SW) then the core will transition to "Handler mode" in order to service the Interrupt Service Routine (ISR) associated with the system exception or the external interrupt. (Only by triggering a system exception or an interrupt, the processor can transition into "Handler mode").
The processor provides 2 access levels:
Privileged Access Level (PAL)
Code running with PAL has a FULL access to all the processor specific resources and the restricted registers. Program will run with PAL by default.
Non-Privileged Access Levels (NPAL)
Code running with NPAL has a LIMITED access to the processor specific resources and the restricted registers.
When the processor is in "Thread mode" with PAL, it is possible to change its access level to NPAL. Once the processor's access level changes from PAL to NPAL, then it is NOT possible for the processor to come back to PAL unless the processor operation mode transitions into "Handler mode" first.
When a program runs in "Handler mode", its access level will always be PAL.
Use the CONTROL register of the processor to switch back and forth between the access levels.
Every program will start running with PAL, and the Control Register must be modified to change the program's access level to NAPL.
An RTOS project has two components; the kernel and the user tasks. It is important that user tasks do not modify the system level setting of the processor. So, before running a user task, the kernel should change the access level to unprivileged, and then launch the user task.
This is why, the real-time operating system or secured systems always launch user task in unprivileged access level. If the code running with unprivileged access level wants any services, then it can trigger system call, which will be serviced by the kernel.
This is a secured and robust system design. ARM Cortex Mx processors give these features in the processor itself.
The program to demonstrate switching between "Thread mode" and "Handler mode".
xxxxxxxxxx
551
2
3
4
5
6
7
8/*
9 * THREAD MODE : Privileged/Unprivileged access level
10 * HANDLER MODE : Privileged access level only!
11 */
12
13/*
14 * This function executes in THREAD MODE of the processor.
15 * Within this function, we are triggering software interrupt by accessing the
16 * system level registers of the ARM Cortex Mx processor.
17 */
18void generate_interrupt()
19{
20 uint32_t *pSTIR = (uint32_t *)0xE000EF00;
21 uint32_t *pISER0 = (uint32_t *)0xE000E100;
22
23 // enable IRQ3 interrupt
24 *pISER0 |= (1 << 3);
25
26 // generate an interrupt from software for IRQ3
27 // (interrupt handler "RTC_WKUP_IRQHandler" will be invoked)
28 *pSTIR = (3 & 0x1FF);
29}
30
31/*
32 * This function executes in THREAD MODE of the processor.
33 * (Remember, after reset, the processor always starts in THREAD MODE.)
34 * In reality, "Reset_Handler:" is the first function to be called on reset,
35 * but at this point we will assume that the "main" is the first to be called.
36 */
37int main(void)
38{
39 printf("Thread mode: before interrupt\n");
40 generate_interrupt();
41 printf("Thread mode: after interrupt\n");
42
43 /* Loop forever */
44 for(;;);
45}
46
47/*
48 * This function (ISR) executes in HANDLER MODE of the processor.
49 * In HANDLER MODE, you have the full control over the processor. You have the
50 * privilege to access any resources you want.
51 */
52void RTC_WKUP_IRQHandler(void)
53{
54 printf("Handler mode: ISR\n");
55}
How do you know whether the the program is running in "Thread mode" or "Handler mode"?
Inspect the ISR_NUMBER
field of Interrupt Program Status Register (IPSR).
Thread mode if
ISR_NUMBER
= 0Handler mode if
ISR_NUMBER
= non-zero (only when system exception or interrupt (HW, SW) occurs)Set a break point at L56, and you will see that the
ISR_NUMBER
field is set to 19 (10011(2)) when the execution reaches there.Consult the Cortex-M4 Devices Generic User Guide for more information.
The program to demonstrate switching between "Privileged mode" and "Non-privileged mode".
xxxxxxxxxx
891
2
3
4
5
6
7
8/*
9 * THREAD MODE : Privileged/Unprivileged access level
10 * HANDLER MODE : Privileged access level only!
11 */
12
13/*
14 * This function executes in THREAD MODE of the processor.
15 * Within this function, we are triggering software interrupt by accessing the
16 * system level registers of the ARM Cortex Mx processor.
17 */
18void generate_interrupt()
19{
20 /*
21 * These are ARM Cortex M4 processor's system control register addresses which
22 * can only be accessed in PRIVILEGED ACCESS LEVEL.
23 * Any attempt to change the contents of these registers from being in UNPRIVILEGED
24 * ACCESS LEVEL will cause a processor fault exception.
25 */
26 uint32_t *pSTIR = (uint32_t *)0xE000EF00;
27 uint32_t *pISER0 = (uint32_t *)0xE000E100;
28
29 // enable IRQ3 interrupt
30 *pISER0 |= (1 << 3);
31
32 // generate an interrupt from software for IRQ3
33 // (interrupt handler "RTC_WKUP_IRQHandler" will be invoked)
34 *pSTIR = (3 & 0x1FF);
35}
36
37void change_access_level_unpriv(void)
38{
39 /*
40 * To make the processor transition into UNPRIVILEGED ACCESS LEVEL,
41 * bit 0 of the CONTROL register must be set to 1.
42 * CONTROL register is NOT a memory mapped register which means that
43 * it is impossible for a programmer to access this register using C
44 * code only. Inline assembly technique is necessary.
45 */
46 __asm volatile("mrs r0, CONTROL"); // read
47 __asm volatile("orr r0, r0, 0x01"); // modify
48 __asm volatile("msr CONTROL, r0"); // write (this is where access level changes to
49 // UNPRIVILEGED
50}
51
52/*
53 * This function executes in THREAD MODE + PRIVILEGED ACCESS LEVEL of the processor.
54 * (Remember, after reset, the processor always starts in THREAD MODE.)
55 * In reality, "Reset_Handler:" is the first function to be called on reset,
56 * but at this point we will assume that the "main" is the first to be called.
57 */
58int main(void)
59{
60 printf("Thread mode: before interrupt\n");
61
62 change_access_level_unpriv(); // PRIVILEGED -> UNPRIVILEGED
63 generate_interrupt();
64
65 printf("Thread mode: after interrupt\n");
66
67 /* Loop forever */
68 for(;;);
69}
70
71/*
72 * This function (ISR) executes in HANDLER MODE of the processor.
73 * In HANDLER MODE, you have the full control over the processor. You have the
74 * privilege to access any resources you want.
75 */
76void RTC_WKUP_IRQHandler(void)
77{
78 printf("Handler mode: ISR\n");
79}
80
81/*
82 * This function will be called when a system level register is accessed in a
83 * program with UNPRIVILEGED ACCESS LEVEL. (Processor fault exception)
84 */
85void HardFault_Handler(void)
86{
87 printf("Hard fault detected\n");
88 while(1);
89}
Summary:
The program first runs in THREAD MODE with PRIVILEGED ACCESS LEVEL.
We set the bit 0 of the CONTROL register to 1 to change the access level to UNPRIVILEGED.
The program tries to access the system control register which is not allowed with UNPRIVILEGED ACCESS LEVEL.
Hard fault occurs and the corresponding handler gets called.
Now, how do you go back to PRIVILEGED ACCESS LEVEL? When in UNPRIVILEGED ACCESS LEVEL, you are not allowed to access and modify the CONTROL register, which means you cannot go back to PRIVILEGED ACCESS LEVEL. To make it possible, the processor must first transition into the HANDLER MODE which always runs with PRIVILEGED ACCESS LEVEL. There are two, and only two ways to push the processor to HANDLER MODE:
External interrupt
Exception
When an ISR is invoked, then there the CONTROL register can be modified (bit 0 back to 0). Upon returning back to the THREAD MODE, the access level will have been set back to PRIVILEGED.
Nayak, K. (2022). Embedded Systems Programming on ARM Cortex-M3/M4 Processor [Video file]. Retrieved from https://www.udemy.com/course/embedded-system-programming-on-arm-cortex-m3m4/