0% found this document useful (0 votes)
141 views55 pages

Chapter 11 Interrupt

The document discusses interrupts in embedded systems with ARM Cortex-M microcontrollers, noting that interrupts inform programs of external events in a timely manner unlike polling and allow for prioritized multi-tasking. It explains interrupt service routines and interrupt vector tables which define the starting addresses for exception handlers. The document also covers stacking and unstacking of registers automatically performed by the processor when entering and exiting interrupt service routines.

Uploaded by

sammadali786800
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
141 views55 pages

Chapter 11 Interrupt

The document discusses interrupts in embedded systems with ARM Cortex-M microcontrollers, noting that interrupts inform programs of external events in a timely manner unlike polling and allow for prioritized multi-tasking. It explains interrupt service routines and interrupt vector tables which define the starting addresses for exception handlers. The document also covers stacking and unstacking of registers automatically performed by the processor when entering and exiting interrupt service routines.

Uploaded by

sammadali786800
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 55

Embedded Systems with ARM Cortex-M Microcontrollers in Assembly Language

and C

Chapter 11
Interrupt

Dr. Yifeng Zhu


Electrical and Computer Engineering
University of Maine

Spring 2018

1
Interrupts
 Motivations
 Inform a program of some external events timely
 Polling vs Interrupt
 Implement multi-tasking with priority support

Merriam-Webster:
“to break the uniformity or continuity of”

2
Polling vs Interrupt

Polling:
You pick up the phone every
three seconds to check
whether you are getting a
call.

Interrupt:
Do whatever you should do
and pick up the phone when
it rings.

3 Image from http://vecto.rs


Interrupt Service Routine Vector Table
 Start address for the Type of
Address Priority Acronym Description
priority
exception hander for 0x0000_0000 - - - Stack Pointer
each exception type is 0x0000_0004 -3 fixed Reset Reset Vector
fixed and pre-defined Non maskable interrupt. The RCC
Clock Security System (CSS) is
0x0000_0008 -2 fixed NMI_Handler
 Processor loads PC linked to the NMI vector.
0x0000_000C -1 fixed HardFault_Handler All class of fault
with this fixed, pre- 0x0000_0010 0 settable MemManage_Handler Memory management
defined address 0x0000_0014 1 settable BusFault_Handler Pre-fetch fault, memory access fault
 Exception Vector 0x0000_0018 2 settable UsageFault_Handler Undefined instruction or illegal state
0x0000_001C
Table starts at memory - - - - Reserved
0x0000_002B
address 0 System service call via SWI
0x0000_002C 3 settable SVC_Handler instruction
 Program Counter pc =
0x0000_0030 settable DebugMon_Handler Debug Monitor
0x00000004 initially 4

0x0000_0034 - - - Reserved

0x0000_0038 5 settable PendSV_Handler Pendable request for system service

0x0000_003C 6 settable SysTick_Handler System tick timer

4


ISR Vector
13 0x00000074 DMA1_Channel3_IRQHandler

12 0x00000070 DMA1_Channel2_IRQHandler
void DMA1_Channel1_IRQHandler () {
11 0x0000006C DMA1_Channel1_IRQHandler ...

Table 10 0x00000068 EXTI4_IRQHandler


}


9 0x00000064 EXTI3_IRQHandler void EXTI1_Handler () {
...
8 0x00000060 EXTI2_IRQHandler }

7 0x0000005C EXTI1_IRQHandler
void EXTI0_Handler () {
6 0x00000058 EXTI0_IRQHandler ...
}
5 0x00000054 RCC_IRQHandler

4 0x00000050 FLASH_IRQHandler

3 0x0000004C RTC_WKUP_IRQHandler


For interrupt number n: 2 0x00000048 TAMPER_STAMP_IRQHandler

CMSIS Interrupt Number = 16 + n 1 0x00000044 PVD_IRQHandler

0 0x00000040 WWDG_IRQHandler
void SysTick_Handler () {
-1 0x0000003C SysTick_Handler ...
}
-2 0x00000038 PendSV_Handler

-3 0x00000034 Reserved


-4 0x00000030 DebugMon_Handler
void SVC_Handler () {
-5 0x0000002C SVC_Handler ...
}
-6 0x00000028 Reserved

-7 0x00000024 Reserved

System -8 0x00000020 Reserved


Exceptions
-9 0x0000001C Reserved


-10 0x00000018 UsageFault_Handler

-11 0x00000014 BusFault_Handler

-12 0x00000010 MemManage_Handler void Reset_Handler () {


...
-13 0x0000000C HardFault_Handler main();
...
-14 0x00000008 NMI_Handler }

0x00000004 Reset_Handler Value to initialize the Program Counter (PC)

0x00000000 Top_of_Stack Value to initialize the Stack Pointer (SP)


5 Interrupt Memory
Memory Contents (32 bits)
Number Address
Stacking & Unstacking
Old SP SP + 0x20 xxxxxxxx
SP + 0x1C xPSP
SP + 0x18 PC (r15) • Stacking: The processor
automatically pushes these eight
SP + 0x14 LR (r14) registers into the main stack before
Full
Descendin SP + 0x10 r12 an interrupt handler starts
g Stack SP + 0x0C r3
• Unstacking: The processor
SP + 0x08 r2 automatically pops these eight
SP + 0x04 r1 register out of the main stack when
SP + 0x00 r0 an interrupt hander exits.
New SP

 Two stack pointers: Main SP (MSP) and Process SP (PSP)


 Determined by operating mode, and bit 0 of the CONTROL register
 Handler mode ⟶ SP = MSP
 Thread mode ⟶ SP = MSP, if CONTROL[0] = 0 (i.e., privileged thread mode);
SP = PSP, if CONTROL[0] = 1 (i.e., unprivileged thread mode)

6
Interrupt

7
Stacking & Unstacking

Interrupt
Exit
Interrupt Handler
Interrupt
Unstacking
Signal

User Program User Program


Stacking
Time
Thread Mode Handler Mode Thread Mode

8
Registers

MSP: Main Stack Pointer


PSP: Process Stack Pointer
9
Processor Mode:
Handler Mode vs Thread Mode
 Handler mode and Thread mode
 Handler mode always use MSP (Main Stack Pointer)
 Thread Mode uses either PSP (Process Stack Pointer) or MSP
 Control[1] = 0, SP = MSP (default)
 Control[1] = 1, SP = PSP
 When the processor is reset, the default is the thread
mode.
 The processor enters the handler mode when an exception
occurs.

10
11
 The CONTROL register can only be modified in the
privileged access level and can be read in both privileged
and unprivileged access levels. The definition of each bit
field in the CONTROL register is shown in Table

12
 After reset, the CONTROL register is 0. This means the Thread
mode uses the Main Stack Pointer as Stack Pointer and Thread
mode has privileged accesses. Programs in privileged Thread
mode can switch the Stack Pointer selection or switch to
unprivileged access level by writing to CONTROL (Figure 4.10).
However, once nPRIV (CONTROL bit 0) is set, the program
running in Thread can no longer access the CONTROL register.

13
 A program in unprivileged access level cannot switch itself back
to privileged access level. This is essential in order to provide a
basic security usage model. For example, an embedded system
might contain untrusted applications running in unprivileged
access level and the access permission of these applications
must be restricted to prevent security breaches or to prevent an
unreliable application from crashing the whole system.
 If it is necessary to switch the processor back to using privileged
access level in Thread mode, then the exception mechanism is
needed. During exception handling, the exception handler can
clear the nPRIV bit (Figure 4.11). When returning to Thread
mode, the processor will be in privileged access level.

14
 When an embedded OS is used, the CONTROL register
could be reprogrammed at each context switch to allow
some application tasks to run with privileged access level
and the others to run with unprivileged access level.
 The settings of nPRIV and SPSEL are orthogonal. Four
different combinations of nPRIV and SPSEL are possible,
although only three of them are commonly used in
real world applications, as shown in Table 4.4.
15
Register values in a
interrupt service
routine

LR = 0xFFFFFFF9

SP = MSP

ISR always in
hander mode.

16
Which stack to use
when exiting an interrupt?
Link Register (LR) now has two usages:
 LR = address of the instruction immediately after BL
 LR indicates whether MSP or PSP is used to restore register from
when exiting an interrupt
 LR value generated by processor
 The processor set LR to 0xFFFFFFFF on reset.
 If return to handler mode, the MSP stack is always used

17
Which stack to use
when exiting an interrupt?
Link Register (LR) now has two usages:
 LR = address of the instruction immediately after BL
 LR indicates whether MSP or PSP is used to restore register from when
exiting an interrupt
No FP extension:
Link Register (LR) Return Mode Return Stack
0xFFFFFFF1 Handler SP = MSP
0xFFFFFFF9 Thread SP = MSP
0xFFFFFFFD Thread SP = PSP
With FP extension:
Link Register (LR) Return Mode Return Stack
0xFFFFFFE1 Handler SP = MSP
0xFFFFFFE9 Thread SP = MSP
0xFFFFFFED Thread SP = PSP
18
Stacking & Unstacking
Control[1] = 0 ⟹ User program uses MSP.

Interrupt
Exit
Interrupt Handler
Interrupt
Unstacking
Signal
from MSP

User Program User Program


Stacking
onto MSP
Time
Thread Mode Handler Mode Thread Mode

MSP MSP MSP


LR = 0xFFFFFFF9
19
Stacking & Unstacking
Control[1] = 1 ⟹ User program uses PSP.
If the interrupt handler calls
push or pop, the MSP is used. Interrupt
Exit
Interrupt Handler
Interrupt
Signal Unstacking
from PSP

User Program User Program


Stacking
onto PSP
Time
Thread Mode Handler Mode Thread Mode
PSP MSP PSP
LR = 0xFFFFFFFD

20
Which is being used?
When exiting an interrupt:
 If LR = 0xFFFFFFF9, then SP = MSP
 If LR = 0xFFFFFFFD, then SP = PSP

9 = 1001
D = 1101

TST r7, #0x04


MRSEQ r4, msp
MRSNE r4, psp
STMFD r4!, {r7-r9} ; Push onto a Full Descending Stack

21
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 0x200001FC
… R1 1
MOV r3,#0 R2 2 0x200001F8
… 0x200001F4
R3 3
ENDP
addr = 0x0800001C R4 4 0x200001F0
R12 12 0x200001EC
SysTick_Handler PROC
EXPORT SysTick_Handler R13(SP) MSP 0x200001E8
ADD r3, #1 R14(LR) 0x08001000 0x200001E4
ADD r4, #1 R15(PC) 0x08000044 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
MSP 0x20000200
0x200001D0
PSP 0x00000000
0x200001CF
Memory
22
Suppose SysTick interrupt occurs
Interrupt: Stacking
when PC&=Unstacking
0x08000044
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 0x200001FC
… R1 1
MOV r3,#0 R2 2 0x200001F8
… 0x200001F4
R3 3
ENDP
addr = 0x0800001C R4 4 0x200001F0
R12 12 0x200001EC
SysTick_Handler PROC
EXPORT SysTick_Handler R13(SP) MSP 0x200001E8
ADD r3, #1 R14(LR) 0x08001000 0x200001E4
ADD r4, #1 R15(PC) 0x08000044 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
MSP 0x20000200
0x200001D0
PSP 0x00000000
0x200001CF
Memory
23
Interrupt: Stacking & Unstacking
STACKING
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 3 LR 0x08001000 0x200001F4
ENDP
addr = 0x0800001C R4 4 R12 12 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r3, #1 R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
ADD r4, #1 R15(PC) 0x0800001C R0 0 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
MSP 0x200001E0
0x200001D0
PSP 0x00000000
0x200001CF
Memory
24
Interrupt: Stacking & Unstacking
STACKING
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 3 LR 0x08001000 0x200001F4
ENDP
addr = 0x0800001C R4 4 R12 12 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r3, #1 R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
ADD r4, #1 R15(PC) 0x0800001C R0 0 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
LR = 0xFFFFFFF9 to MSP 0x200001E0
0x200001D0
indicate MSP is used. PSP 0x00000000
0x200001CF
Memory
25
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

ENDP
R3 4 LR 0x08001000 0x200001F4
addr = 0x0800001C R4 4 R12 12 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r3, #1 R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
ADD r4, #1 R15(PC) 0x0800001C R0 0 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
MSP 0x200001E0
0x200001D0
PSP 0x00000000
0x200001CF
Memory
26
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 4 LR 0x08001000 0x200001F4
ENDP
addr = 0x0800001C R4 5 R12 12 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r3, #1 R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
ADD r4, #1 R15(PC) 0x08000020 R0 0 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
MSP 0x200001E0
0x200001D0
PSP 0x00000000
0x200001CF
Memory
27
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 4 LR 0x08001000 0x200001F4
ENDP
addr = 0x0800001C R4 5 R12 12 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r3, #1 R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
ADD r4, #1 R15(PC) 0x08000024 R0 0 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
LR = 0xFFFFFFF9 to MSP 0x200001E0
0x200001D0
indicate MSP is used. PSP 0x00000000
0x200001CF
Memory
28
Interrupt: Stacking & Unstacking
UNSTACKING
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 4 LR 0x08001000 0x200001F4
ENDP
addr = 0x0800001C R4 5 R12 12 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r3, #1 R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
ADD r4, #1 R15(PC) 0x08000024 R0 0 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
LR = 0xFFFFFFF9 to MSP 0x200001E0
0x200001D0
indicate MSP is used. PSP 0x00000000
0x200001CF
Memory
29
Interrupt: Stacking & Unstacking
UNSTACKING
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 0x200001FC
… R1 1
MOV r3,#0 R2 2 0x200001F8

ENDP
R3 3 0x200001F4

addr = 0x0800001C R4 5 0x200001F0


R12 12 0x200001EC
SysTick_Handler PROC
EXPORT SysTick_Handler R13(SP) MSP 0x200001E8
ADD r3, #1 R14(LR) 0x08001000 0x200001E4
ADD r4, #1 R15(PC) 0x08000044 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
Note the new value of MSP 0x20000200
0x200001D0
R3 is lost!!! PSP 0x00000000
0x200001CF
Memory
30
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 0x200001FC
… R1 1
MOV r3,#0 R2 2 0x200001F8

ENDP
R3 3 0x200001F4

addr = 0x0800001C R4 5 0x200001F0


R12 12 0x200001EC
SysTick_Handler PROC
EXPORT SysTick_Handler R13(SP) MSP 0x200001E8
ADD r3, #1 R14(LR) 0x08001000 0x200001E4
ADD r4, #1 R15(PC) 0x08000044 0x200001E0
BX lr
0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
The Main program MSP 0x20000200
0x200001D0
resumes!!! PSP 0x00000000
0x200001CF
Memory
31
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 0x200001FC
… R1 1
MOV r3,#0 R2 2 0x200001F8
… 0x200001F4
R3 3
ENDP
addr = 0x0800001C R4 4 0x200001F0
R12 12 0x200001EC
SysTick_Handler PROC
EXPORT SysTick_Handler R13(SP) MSP 0x200001E8
ADD r4, #1 0x0800001C R14(LR) 0x08001000 0x200001E4
BL sine 0x08000020 R15(PC) 0x08000044 0x200001E0
BX lr 0x08000024 0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
MSP 0x20000200
0x200001D0
PSP 0x00000000
0x200001CF
Memory
32
Interrupt: Stacking & Unstacking
STACKING
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r4, #1 0x0800001C R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
BL sine 0x08000020 R15(PC) 0x0800001C R0 0 0x200001E0
BX lr 0x08000024 0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
LR = 0xFFFFFFF9 to MSP 0x200001E0
0x200001D0
indicate MSP is used. PSP 0x00000000
0x200001CF
Memory
33
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 5 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r4, #1 0x0800001C R14(LR) 0xFFFFFFF9 R1 1 0x200001E4
BL sine 0x08000020 R15(PC) 0x08000020 R0 0 0x200001E0
BX lr 0x08000024 0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
LR = 0xFFFFFFF9 to MSP 0x200001E0
0x200001D0
indicate MSP is used. PSP 0x00000000
0x200001CF
Memory
34
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x08000044 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r4, #1 0x0800001C R14(LR) 0x08000024 R1 1 0x200001E4
BL sine 0x08000020 R15(PC) 0x080000F0 R0 0 0x200001E0
BX lr 0x08000024 0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
BL sine MSP 0x200001E0
0x200001D0
Updates LR register PSP 0x00000000
0x200001CF
Memory
35
Assume sine() is located at 0x08000024.
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x00000002 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r4, #1 0x0800001C R14(LR) 0x08000024 R1 1 0x200001E4
BL sine 0x08000020 R15(PC) 0x080000F0 R0 0 0x200001E0
BX lr 0x08000024 0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
BL sine MSP 0x200001E0
0x200001D0
Updates LR register PSP 0x00000000
0x200001CF
Memory
36
UNSTACKING
Interrupt: Stacking & Unstacking
won’t occur!
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x00000002 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r4, #1 0x0800001C R14(LR) 0x08000024 R1 1 0x200001E4
BL sine 0x08000020 R15(PC) 0x080000F0 R0 0 0x200001E0
BX lr 0x08000024 0x200001DC
ENDP
xPSR 0x21000000 0x200001D8
0x200001D4
BL sine MSP 0x200001E0
0x200001D0
Updates LR register PSP 0x00000000
0x200001CF
Memory
37
Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x00000002 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8

PUSH {lr} R14(LR) 0x08000024 R1 1 0x200001E4


ADD r4, #1 R15(PC) 0x080000F0 R0 0 0x200001E0
BL sine LR 0xFFFFFFF9 0x200001DC
POP {lr} xPSR 0x21000000 0x200001D8
BX lr 0x200001D4
MSP 0x200001E0
ENDP
0x200001D0
PSP 0x00000000
0x200001CF

38 Fix the bug! Method 1 Memory


Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x00000002 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8

PUSH {lr} R14(LR) 0x08000024 R1 1 0x200001E4


ADD r4, #1 R15(PC) 0x080000F0 R0 0 0x200001E0
BL sine LR 0xFFFFFFF9 0x200001DC
POP {PC} xPSR 0x21000000 0x200001D8
ENDP 0x200001D4
MSP 0x200001E0
0x200001D0
PSP 0x00000000
0x200001CF

39 Fix the bug! Method 2 Memory


Interrupt: Stacking & Unstacking
__main PROC R0 0 xxxxxxxx 0x20000200
addr = 0x08000044 xPSR 0x21000000 0x200001FC
… R1 1
MOV r3,#0 R2 2 PC 0x00000002 0x200001F8

R3 3 SP 0x20000200 0x200001F4
ENDP
addr = 0x0800001C R4 4 LR 0x08001000 0x200001F0

SysTick_Handler PROC R12 12 R3 3 0x200001EC

EXPORT SysTick_Handler R13(SP) MSP R2 2 0x200001E8


ADD r4, #1 R14(LR) 0x08000024 R1 1 0x200001E4
BL sine R15(PC) 0x080000F0 R0 0 0x200001E0
LDR lr,=0xFFFFFFF9
0x200001DC
BX lr
xPSR 0x21000000 0x200001D8
ENDP
0x200001D4
MSP 0x200001E0
0x200001D0
PSP 0x00000000
0x200001CF

Fix
40 the bug! Method 3 (not recommended)
Memory
Interrupt Number
 Cortex-M supports up to 256 interrupts.
System Peripheral interrupt
Exceptions Interrupts number

-16 -1 0 239
CMSIS Interrupt Number
 First 16 are system exceptions
 CMSIS defines their interrupt numbers as negative
 Defined by ARM core
 The rest 240 are peripheral interrupts
 Peripheral interrupt number starts with 0.
 Defined by chip manufacturers.

41
Interrupt Number
in CMSIS vs in PSR
Interrupt number for CMSIS functions
NVIC_DisableIRQ (IRQn); // Disable interrupt
NVIC_EnableIRQ (IRQn); // Enable interrupt
NVIC_ClearingPending (IRQn); // clear pending status
NVIC_SetPriority (IRQn, priority); // set priority level

Interrupt number in Program Status Register (PSR)


31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

N Z C V Q IT[7:6] T Reserved GE[3:0] IT[5:0] 0 or Exception Number

IT[7:0]: If-Then bits

Thumb state flag GE[3:0]: Greater or equal flags (only available on Cortex-M4 and M7)

Stick saturation flag for SSAT and USAT

Overflow flag

Carry/Borrow flag

Zero flag

Negative or less than flag

Interrupt Number in PSR = 16 + Interrupt Number for CMSIS


42
CMSIS Interrupt Number
/****** Cortex-M4 System Exceptions ********************************************************/
NonMaskableInt_IRQn = -14, /* 2 Cortex-M4 Non Maskable Interrupt */
HardFault_IRQn = -13, /* 3 Cortex-M4 Hard Fault Interrupt */
MemoryManagement_IRQn = -12, /* 4 Cortex-M4 Memory Management Interrupt */
BusFault_IRQn = -11, /* 5 Cortex-M4 Bus Fault Interrupt */
System
UsageFault_IRQn = -10, /* 6 Cortex-M4 Usage Fault Interrupt */
Exceptions
SVCall_IRQn = -5, /* 11 Cortex-M4 SV Call Interrupt */
DebugMonitor_IRQn = -4, /* 12 Cortex-M4 Debug Monitor Interrupt */
PendSV_IRQn = -2, /* 14 Cortex-M4 Pend SV Interrupt */
SysTick_IRQn = -1, /* 15 Cortex-M4 System Tick Interrupt */
/****** Peripheral Interrupt Numbers *******************************************************/
WWDG_IRQn = 0, /* Window WatchDog Interrupt */
PVD_PVM_IRQn = 1, /* PVD/PVM1,2,3,4 through EXTI Line detection Interrupts */
TAMP_STAMP_IRQn = 2, /* Tamper and TimeStamp interrupts through the EXTI line */
RTC_WKUP_IRQn = 3, /* RTC Wakeup interrupt through the EXTI line */
FLASH_IRQn = 4, /* FLASH global Interrupt */
RCC_IRQn = 5, /* RCC global Interrupt Peripheral */
EXTI0_IRQn = 6, /* EXTI Line0 Interrupt Interrupts */
...
43 stm32l476xx.h
Enable an Interrupt
 Enable a system exception
 Some are always enabled (cannot be disabled)
 No centralized registers for enabling/disabling
 Each are control by its corresponding components, such as
SysTick module

 Enable a peripheral interrupt


 Centralized register arrays for enabling/disabling
 ISER registers for enabling
 ICER registers for disabling

44
Enabling Peripheral Interrupts

TIM7_IRQn = 44
NVIC->ISER[1] = 1 << 12; // Enable Timer 7 interrupt
45
Disabling Peripheral Interrupts

TIM7_IRQn = 44
NVIC->ICER[1] = 1 << 12; // Diable Timer 7 interrupt
46
Disable/Enable Peripheral Interrupts
 For all peripheral interrupts: IRQn ≥ 0
 Method 1:
 NVIC_EnableIRQ (IRQn); // Enable interrupt
 NVIC_DisableIRQ (IRQn); // Disable interrupt
 Method 2:
 Enable:
 NVIC->ISER[ IRQn / 32] = 1 << (IRQn % 32);
 Better solution:
 NVIC->ISER[ IRQn >> 5] = 1 << (IRQn & 0x1F);
 Disable:
 NVIC->ICER[ IRQn >> 5] = 1 << (IRQn & 0x1F);

47
Interrupt Priority
 Inverse Relationship:
 Lower priority value means higher urgency.
 Priority of Interrupt A = 5,
 Priority of Interrupt B = 2,
 B has a higher priority/urgency than A.

 Fixed priority for Reset, HardFault, and NMI.


Exception IRQn Priority
Reset N/A -3 (the highest)
Non-maskable Interrupt (NMI) -14 -2 (2nd highest)
Hard Fault -13 -1

 Adjustable for all the other interrupts


48
Interrupt Priority
 Interrupt priority is configured by Interrupt Priority Register (IP)
 Each priority consists of two fields, including preempt priority
number and sub-priority number.
 The preempt priority number defines the priority for preemption.
 The sub-priority number determines the order when multiple interrupts are pending
with the same preempt priority number.

default setting

49
Interrupt Priority Levels
NVIC_SetPriority(7, 6);
core_cm4.h or core_cm3.h
typedef struct {
0 1 1 0 0 0 0 0 ...
// Interrupt Priority Register
volatile uint8_t IP[240];
...
} NVIC_Type;

IP = 0x60 = 96

It is equivalent to:
NVIC->IP[7] = (6 << 4) & 0xff;

50
Preemption and Sub-priority
Configuration
 NVIC_SetPriorityGrouping(n)
 Perform unlock, and update AIRCR register

n # of bits in preemption # of bits in sub-


priority priority
0 0 4
1 1 3
2 (default) 2 2
3 3 1
4 4 0

Default
n=2

51
Priority of Peripheral Interrupts

// Set the priority for EXTI 0 (Interrupt number 6)


NVIC->IP[6] = 0xF0;
52
Priority of System Interrupts

// Set the priority of a system interrupt IRQn


SCB->SHP[(IRQn) & 0xF) - 4] = (priority << 4) & 0xFF;
53
Masking Priority
 Disable all interrupts with less urgency
 For critical code, only certain interrupts are allowed.
 BASEPRI: Disable all interrupts of specific priority level or
higher priority level

// Disable interrupts with priority value same or higher


__set_BASEPRI( 5 << 4 )

// Critical code
...

// Remove BASEPRI masking


__set_BASEPRI(0);

54
Exception-masking registers (PRIMASK,
FAULTMASK and BASEPRI)
 PRIMASK: Used to disable all exceptions except Non-maskable interrupt
(NMI) and hard fault.
 Write 1 to PRIMASK to disable all interrupts except NMI
MOV R0, #1
MSR PRIMASK, R0

 Write 0 to PRIMASK to enable all interrupts


MOV R0, #0
MSR PRIMASK, R0

 FAULTMASK: Like PRIMASK but change the current priority level to -


1, so that even hard fault handler is blocked

 BASEPRI: Disable interrupts only with priority lower than a certain level
 Example, disable all exceptions with priority level higher than 0x60
MOV R0, #0x60
MSR BASEPRI, R0
55

You might also like