#18 interrupts Part-3: How interrupts work on ARM Cortex-M?

  Рет қаралды 53,672

Quantum Leaps, LLC

Quantum Leaps, LLC

Күн бұрын

This lesson finally explains how ARM Cortex-M handles interrupts and why interrupt handlers can be regular C functions on this CPU. Specifically, you will see how the designers of the chip have solved the problem by saving all the right CPU registers and returning from interrupt functions.
------
Resources:
Companion web page for this video course:
www.state-mach...
GitHub repository for projects for this video course:
github.com/Qua...
Transcript of this lesson:
www.state-mach...
Music credits:
The background music comes from:
www.bensound.c...

Пікірлер: 60
@alexcipriani6003
@alexcipriani6003 3 жыл бұрын
I took two embedded systems classes in college and wasted $50k without getting this level of instruction. Thank you for this course
@StateMachineCOM
@StateMachineCOM 3 жыл бұрын
Thank you for the nice comment. This course is designed as a "missing curriculum" for embedded systems, because colleges don't usually teach at this deeper level. --MMS
@jankeshchakravarthy9389
@jankeshchakravarthy9389 11 ай бұрын
I totally agree. Very clear and precise explanation.
@jorgis123
@jorgis123 8 ай бұрын
For those working in Keil microVision: I found the NVIC registers in the menu Peripherals->Core Peripherals.
@StateMachineCOM
@StateMachineCOM 8 ай бұрын
KEIL provides specialized views for all peripherals, both standard (e.g., NVIC, MPU, SYSTEM) and vendor-specific (e.g., UART, GPIO, etc). Very useful.
@Iplaynfs1
@Iplaynfs1 2 ай бұрын
And then what is supposed to be set? I try changing SCB->ICSR to 0x0040.0000 (bit 26 to 1) but when I press enter the value changes back 0x0?
@Iplaynfs1
@Iplaynfs1 2 ай бұрын
Nevermind, I set SCB->ICSR to 0x0480F000 and it worked
@keithevans6450
@keithevans6450 7 жыл бұрын
One important statement from the datasheet "When the processor is halted for debugging, the counter does not decrement" - this explains why Miro's use of the PENDSTSET bit in the debugger is what causes the interrupt and not the wrapping of SysTick while the user is getting things setup manually in the debugger. Just figured that I would add this comment in case anyone had any doubts.
@Chataou
@Chataou 8 жыл бұрын
Hello Mr.Samek, I was watching these tutorials long time ago and thought you have abandoned the tutorial series... but now I see lots of new videos added! Thank you for the wonderful effort!
@mengnan24
@mengnan24 6 жыл бұрын
Watched several times and learned new stuff every time. Amazing! Can not wait your second lesson on RTOS!
@salmantechnologies282
@salmantechnologies282 10 ай бұрын
at 4:19 you said we are stopped at the MOVS instruction but actually we are stopped at LDR instruction thank you for the Nice course Sir
@StateMachineCOM
@StateMachineCOM 10 ай бұрын
Actually, at 4:19 the code *is* stopped at the MOVS instruction because MOVS has *not* executed yet. But when you continue execution in the debugger, MOVS is already committed and will be executed. The first hardware check of the interrupt line will then happen after the MOVS instruction and before the LDR instruction. I hope this clarifies the situation. --MMS
@loverboyhk
@loverboyhk 3 жыл бұрын
I cannot thank you enough for this truly incredible tutorial.
@04mfjoyce
@04mfjoyce 3 жыл бұрын
Yet again, the best explanation i've found yet. Thanks!
@Sayf12349
@Sayf12349 7 жыл бұрын
Amazing job Dr.Samek and please keep it up. Many thanks indeed.
@siefeldinyones4147
@siefeldinyones4147 8 жыл бұрын
Sir Miro thanks for your lessons, i had watched 11 lessons till now and i thought it's a complete course. Im having a little problem where im having an interview and i must get to the rest of the issues in embedded C, So i wish you can tell me the rest of topics so that i get through them in any other sites. Thanks ...
@anthonyrocha8075
@anthonyrocha8075 2 жыл бұрын
Excellent video ! A question about the file structure : Given the Systick is present in every single implementation of ARMV7-M architecture, why would the systick handler be part of a board support package file?
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
The SysTick ISR is available in all ARM Cortex-M CPUs, but its *implementation* is different for every project. For example, some simple projects might only increment a counter in SysTick_Handler() ISR, while other projects (e.g., based on an RTOS) might to sophisticated time management there. For these reasons, SystTick_Handler() is logically a part of the BSP. --MMS
@ankitfparmar
@ankitfparmar 9 жыл бұрын
Been waiting for very long..Thanx already. :)
@pavelpalivec7042
@pavelpalivec7042 5 жыл бұрын
Hello Miro, first of all, this is the best video tutorial about programming I have ever seen! My question: Is the the 12-cylcles long instructuion for entering the ISR somewhere in FLASH? Where? Thank you!
@StateMachineCOM
@StateMachineCOM 5 жыл бұрын
There is no code instruction to enter an interrupt, so you cannot find it in flash. Instead, the interrupt entry/exit behavior is hardwired inside the CPU. In other words, as soon as the CPU recognizes an interrupt, it will push the registers to the stack, change the internal state, look up the ISR from the vector table, etc. --MMS
@jankeshchakravarthy9389
@jankeshchakravarthy9389 11 ай бұрын
HI MMS - @time 4.19, don;t you think that the interrupt will fire after executing LDR.N instruction in the main loop and not after MOVS as interrupt line will be checked after executing LDR.N instruction. Let me know, if I missing something. Thanks a lot. Listening to your video again, I guess the interrupt line goes high moment NVIC bit is set manually. It is just that interrupt line should have drawn going high while executing MOVS instruction.
@StateMachineCOM
@StateMachineCOM 11 ай бұрын
Yes, the interrupt line goes high as soon as the SystTick interrupt is pended in the NVIC. This happens when the code is stopped at a breakpoint and MOVS has NOT been executed yet. So, yes, the timing diagram should be drawn such that the interrupt line goes high while MOVS is "executing". When you continue code execution, the first instruction to execute is MOVS, so the first chance to check the interrupt line is between instructions MOVS and LDR.N. --MMS
@saiganesh9989296043
@saiganesh9989296043 8 жыл бұрын
Samek, Do you have any videos about unions , and using structures as members of union. it actually gets very confusing where there are many nested structures and pointers to structures (! not in your videos though !) for my application for writing drivers ( using the Registers )
@georgealex19
@georgealex19 5 жыл бұрын
Great content!
@thucngoxuan9011
@thucngoxuan9011 6 ай бұрын
hi Mr.Samek. I think you said about "How interrupts work on ARM Cortex-M" related to NVIC. Why you don't talk about NVIC ??. I'm so sorry becauce my English so bad :
@StateMachineCOM
@StateMachineCOM 6 ай бұрын
Of course, the NVIC is unique to ARM Cortex-M and it decides which interrupt to handle (especially in case when multiple interrupts are pending at the same time). However, the NVIC is not the main reason why interrupt handling in ARM Cortex-M is different than most other CPUs. The main differences are in the way interrupts are entered by pushing all these CPU registers to the main stack. And even more amazing is how interrupts return with the instruction BX LR (a regular function return), but with the special value LR=0xFFFFFFF9. These are the main points of this lesson about "How interrupts work on ARM Cortex-M?". --MMS
@ameyaphadke9404
@ameyaphadke9404 4 жыл бұрын
please make videos on multi-core processor software design
@bibekkoirala8802
@bibekkoirala8802 5 жыл бұрын
Hi Miro, I have some questions regarding memory and flash. Since the program is in flash memory, are the memory addresses pointed by PC part of flash memory ? If I'm correct, in x86 instructions(program) are copied to RAM first and then executed by CPU. However, the contents of SRAM in ARM are data(global and static variables ) and the contents of stack only, right ? Also, are the instructions from flash fetched by Address Bus and contents of SRAM by Data Bus ?
@StateMachineCOM
@StateMachineCOM 5 жыл бұрын
In embedded single-chip microcontrollers (MCUs) the code is executed directly from ROM (often NOR-Flash), so there is no copying of code from ROM to RAM. Therefore, the boot time in MCUs is measured in milliseconds, not in seconds like with (embedded) Linux or other "big" operating systems. The ROM also holds constants, such as addresses of variables and functions, look-up-tables (LUTs), etc. The RAM (typically static RAM) is quite precious, because there is only a few KB of it and the ratio of RAM:ROM in a typical MCU is like 1:10. The RAM holds data sections, the stack and the heap. Regarding the code execution, ARM Cortex-M3/4/7 have Harvard bus architecture, where instructions are fetched by a different bus than data. This is, however transparent to the programmer (unlike, for example AVRmega, where you have different instructions to fetch data from RAM and different for the ROM). ARM Cortex-M0/M0+ fetch both code and data through the same bus. I hope this answers your questions. --MMS
@mahalinga2006
@mahalinga2006 3 жыл бұрын
Greetings team QP, I first thank for this great playlist and for your significant efforts. I have followings doubts on the interrupts kindly help to clarify them, thanks in advance. 1. The stack frame without using FPU is of 8-bytes long and the aligner is needed to align the memory address in stack based on 8-bytes frame block, As you stated an example of stack misalignment 3F4 is not divisible by 8 so there was an aligner word for 1 byte is added to compensate. Similarly when using with FPU, the stack frame size is 26-Bytes initially which is not divisible by 8, How will the block get divided with 26 Bytes? 2. I have understood the need for aligner word, its function is just similar to the padding bits which is added in between the structure data's to align memory in even address to access it easily, Similarly in the stack frame the aligner word does this based on AAPCS guideline, Is my understanding correct?
@StateMachineCOM
@StateMachineCOM 3 жыл бұрын
1. No, the stack frame without the FPU is 8 registers (R0-R3,R12,LR,PC,xPSR), each 4 bytes wide, which makes the stack frame 32-bytes long. This stack frame must be aligned at 8-byte boundary for different reasons, and that is for speed in hardware. The interrupt entry and exit are highly optimized in the Cortex-M CPU, and take only 12 cycles. But to push 8 registers and to the other things so fast, the hardware must get a nicely aligned chunk of memory. 2. The "stack aligner" is never needed in correctly designed code and the compiler will not generate code that would require an "aligner". Only when you have some hand-written assembly code, the stack might become misaligned (meaning that the SP will not be divisible by 8).
@mahalinga2006
@mahalinga2006 3 жыл бұрын
@@StateMachineCOM Thanks for clarifications, It makes much sense to my understandings :)
@rubenspatterson
@rubenspatterson Жыл бұрын
Hi Dr. Samek, I followed your instructions but always when I run the program from first interrupt it never stop at second interrupt in SysTick_Handler(), even though I set PENDSTSET bit. What could be the problem?
@StateMachineCOM
@StateMachineCOM Жыл бұрын
In all such situations, when your own code does something "strange" I recommend downloading the project for this lesson from the companion page to this video course at state-machine.com/quickstart . Then try the same thing in the downloaded project. If it works, you have a known, *working* version that you can compare against your own code. (One good and free code differencing tool is WinMerge, just google for it.) You should be able to find the relevant difference quite quickly. Then you will see for yourself why your code doesn't work as expected. Best of all, you will have a generic strategy: always start from the *working* code. --MMS
@mahalinga2006
@mahalinga2006 2 жыл бұрын
Hi Team QP, Question: Does Interrupt with FPU enabled also has 12 clock cycles on its entry and exit or does it have even more cycles as the stacking increases with FPU. Thanks, Regards
@StateMachineCOM
@StateMachineCOM 2 жыл бұрын
Of course, a context save/restore with FPU requires many more cycles! I don't have precise numbers, but it must be at least 3-4 times more than without the FPU. So we're talking about 40 CPU cycles or so. The FPU in Cortex-M is rather poorly integrated with the rest of the CPU... -MMS
@mahalinga2006
@mahalinga2006 2 жыл бұрын
@@StateMachineCOM Thanks Team
@charleshung157
@charleshung157 8 жыл бұрын
Hi, Dr. Miro. I just want to know, what is the different between PRIMASK bit and GIE bit ? Why they both existed, while I could just use one to control the interrupt signal to CPU ? Thank you. Warm regards.
@StateMachineCOM
@StateMachineCOM 8 жыл бұрын
The ARM Cortex-M documentation does not mention the GIE bit, so I'm not sure where you got it. But the PRIMASK bit is documented here: infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0553a/CHDBIBGJ.html
@charleshung157
@charleshung157 8 жыл бұрын
Ah, It's my mistake Dr. Miro. I got mixed up between GIE from MSP430 and PRIMASK in ARM. I thought both of them are in ARM, after review your previous code, I realized my mistake. I'm sorry for my sloppy question. And Thank you for your response.
@ABDULSATTARM
@ABDULSATTARM 8 жыл бұрын
Dear Dr. Miro Samek, I have question about the interrupt service routine. Is it always good practice to disable interrupt at the beginning of ISR routine, do some process there and before exiting again re-enable interrupts. even though nested interrupts are supported and priority for each interrupt has been set. still is it necessary to have disable interrupt, do some work inside IsR and re-enable interrupt. If you can please elaborate this I will be thankful. Regards Sattar Malokani
@StateMachineCOM
@StateMachineCOM 8 жыл бұрын
+Abdul Sattar The right policy of disabling interrupts in the ISRs depends on the CPU you are using. Most CPUs (e.g., MSP430) disable further interrupts automatically upon the entry to the interrupt, so in most cases you need to make the opposite decision (Should I enable interrupts in this ISR?). However, ARM Cortex-M is different in that it does NOT disable further interrupts upon entry to the ISR. And my recommendation is NOT to disable interrupts explicitly in the Cortex-M ISRs. Instead, you can always prioritize interrupts in the NVIC such that they either can or cannot preempt each other. I will talk about disabling interrupts and about prioritizing interrupts in the future lessons.
@mitzomevan2778
@mitzomevan2778 5 жыл бұрын
Hello Mr. Samek, can we turn off interrupt from the same interrupt's ISR? I have been trying it and its not exiting from the ISR, what could be broken? Thank you.
@StateMachineCOM
@StateMachineCOM 5 жыл бұрын
First, it is highly recommended that you run the example without making your own changes. The SysTick interrupt demonstrated in this lesson clears the interrupt sources automatically, but some other interrupt sources need to be cleared in the ISR so that the ISR won't fire again and again. An example of such interrupt is provided later in this video course in lesson 27 (see GPIOPortF_IRQHandler() in bsp.c from that lesson). --MMS
@anup619thapa
@anup619thapa 3 жыл бұрын
While the downloaded lesson 18 compiles with no issues, lesson 17 fails to compile with 3 errors. All errors pertain to "cannot open source file "core_cm4.h". Any pointers as to what has changed in the project settings between lesson 17 and 18?
@StateMachineCOM
@StateMachineCOM 3 жыл бұрын
This lesson (#17) requires the separate CMSIS directory, from which it includes the "core_cm4.h" header file. More specifically, this is the first lesson that uses the CMSIS-compliant TM4C123GH6PM.h header file, and this one include "core_cm4.h". The CMSIS directory is packaged separately in "CMSIS.zip" file, which you need to download from the companion web page at www.state-machine.com/quickstart . Please just scroll down to lesson 17 and see what's available for download. --MMS
@44gala
@44gala 5 жыл бұрын
Hello After flashing this code i am unable to flash any code into my tiva c board.
@SuperBebostar
@SuperBebostar 7 жыл бұрын
every time i run the code it doesn't go into the interrupt
@lukaspfeiffer179
@lukaspfeiffer179 5 жыл бұрын
Going one step further than switching LEDs using interrupts using this startup-code/vector table: Is there an accepted way of passing arguments (structs) to the interrupt function? For example, if you want to hand over a struct which is defined in main.c to an I2C processing interrupt function? Function in bsp.c void ExampleI2CIntHandler(void) { I2CMIntHandler(&g_sI2CInst); }
@StateMachineCOM
@StateMachineCOM 5 жыл бұрын
Interrupt Service Routines (ISRs) don't take any parameters and don't return any value, so there is no way to pass data to or from them that way. But ISRs can share global data with other parts of the code. For example, I2C interrupt could produce data into a global buffer, which then could be accessed from the main loop. But you always need to be very careful about any such sharing, so that you don't create *race conditions*. Race conditions are discussed in lesson 20 of this video course. You should definitely watch this one. --MMS
@44gala
@44gala 5 жыл бұрын
I stuck at flashing dialog box in IAR.
@向宇-d4b
@向宇-d4b 3 жыл бұрын
seems like that the correct way to trigger ARM ISR in C is not introduced
@AndreiDalcu
@AndreiDalcu 7 жыл бұрын
Hello Miro, I'm trying to generate an interrupt on pressing the SW1 (PF4), but it doesn't seem to work and I don't know what I'm doing wrong... Here is the code in main.c: int main() { SYSCTL->RCGCGPIO |= (1U GPIOHBCTL |= (1U DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->LOCK = 0x4C4F434B; GPIOF_AHB->CR = 0xFF; GPIOF_AHB->DEN |= (SW2 | LED_RED | LED_BLUE | LED_GREEN | SW1); GPIOF_AHB->PUR |= (SW2 | SW1); GPIOF_AHB->IS &= ~(SW1); // edge detect for SW1 GPIOF_AHB->IBE &= ~(SW1); // only one edge generate the interrupt (set into IEV) GPIOF_AHB->IEV |= SW1; // a rising edge triggers the interrupt __enable_irq(); while (1) ; } In bsp.c I defined the function GPIOPortF_IRQHandler: void GPIOPortF_IRQHandler(void) { GPIOF_AHB->DATA_Bits[LED_RED] = LED_RED; GPIOF_AHB->DATA_Bits[LED_GREEN] = LED_GREEN; GPIOF_AHB->DATA_Bits[LED_BLUE] = LED_BLUE; } The GPIORIS register is changing when I push the button, but the GPIOPortF_IRQHandler function is not called... Can you please tell me what am I doing wrong here?
@StateMachineCOM
@StateMachineCOM 7 жыл бұрын
You need to enable the interrupt both in the GPIOF peripheral and in the NVIC: GPIOF_AHB->IM |= SW1; NVIC_EnableIRQ(GPIOF_IRQn); You don't need to mess with the CR register, so the lines GPIOF_AHB->LOCK and GPIOF_AHB->CR are unnecessary. Finally, here is the GPIOF interrupt handler: void GPIOPortF_IRQHandler(void) { if ((GPIOF_AHB->RIS & BTN_SW1) != 0U) { l_sw1pressed = 1U; } GPIOF_AHB->ICR = 0xFFU; /* clear interrupt sources */ } --MMS
@AndreiDalcu
@AndreiDalcu 7 жыл бұрын
That worked! Thank you very much Miro! With the CR register is another story which gave me headache... I used it in order to have access to SW2 button (PF0) in a while loop, without interrupts. This was the code: int main() { SYSCTL->RCGCGPIO |= (1U GPIOHBCTL |= (1U DIR |= (LED_RED | LED_BLUE | LED_GREEN); GPIOF_AHB->LOCK = 0x4C4F434B; GPIOF_AHB->CR = 0xFF; GPIOF_AHB->DEN |= (SW2 | LED_RED | LED_BLUE | LED_GREEN | SW1); GPIOF_AHB->PUR |= (SW2 | SW1); while (1) { switch (GPIOF_AHB->DATA_Bits[SW1] | GPIOF_AHB->DATA_Bits[SW2]) { case 0x10: GPIOF_AHB->DATA_Bits[LED_RED] = 0U; GPIOF_AHB->DATA_Bits[LED_GREEN] = LED_GREEN; GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; break; case 0x01: GPIOF_AHB->DATA_Bits[LED_RED] = LED_RED; GPIOF_AHB->DATA_Bits[LED_GREEN] = 0U; GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; break; case 0x00: GPIOF_AHB->DATA_Bits[LED_RED] = 0U; GPIOF_AHB->DATA_Bits[LED_GREEN] = 0U; GPIOF_AHB->DATA_Bits[LED_BLUE] = LED_BLUE; break; default: GPIOF_AHB->DATA_Bits[LED_RED] = 0U; GPIOF_AHB->DATA_Bits[LED_GREEN] = 0U; GPIOF_AHB->DATA_Bits[LED_BLUE] = 0U; break; } } } I wasn't able to find other solution for this. I had to make the CR register writable in TM4C123GH6PM.h. I don't thing this is ok, but what was the alternative (except interrupts)?
@TemporalRecall
@TemporalRecall 9 жыл бұрын
Title has a typo, fyi
@zhaoxiao2002
@zhaoxiao2002 4 жыл бұрын
too fast. I can not follow your speed.
@StateMachineCOM
@StateMachineCOM 4 жыл бұрын
That's why it is a video, which you can pause, rewind and interrupt for some additional research. Please also take advantage of the closed captions (the CC button at the bottom of the video player), where you can read the narration. --MMS
#19 GNU-ARM Toolchain and Eclipse IDE
22:18
Quantum Leaps, LLC
Рет қаралды 70 М.
#16 Interrupts Part-1: What are interrupts, and how they work
15:58
Quantum Leaps, LLC
Рет қаралды 79 М.
Стойкость Фёдора поразила всех!
00:58
МИНУС БАЛЛ
Рет қаралды 6 МЛН
Когда отец одевает ребёнка @JaySharon
00:16
История одного вокалиста
Рет қаралды 11 МЛН
Good teacher wows kids with practical examples #shorts
00:32
I migliori trucchetti di Fabiosa
Рет қаралды 10 МЛН
#17 interrupts Part-2: How most CPUs (e.g. MSP430) handle interrupts?
19:52
Quantum Leaps, LLC
Рет қаралды 57 М.
#23 RTOS Part-2: Automating the context switch
37:37
Quantum Leaps, LLC
Рет қаралды 51 М.
Super-Simple Tasker -- The Hardware RTOS for ARM Cortex-M, Part-1
22:01
Quantum Leaps, LLC
Рет қаралды 10 М.
#3 Variables and Pointers
12:22
Quantum Leaps, LLC
Рет қаралды 183 М.
#9 Modules, Recursion, ARM Application Procedure Call Standard (AAPCS)
19:07
#27 RTOS Part-6: Synchronization and communication among concurrent threads
43:04
#6 Bit-wise operators in C
17:05
Quantum Leaps, LLC
Рет қаралды 123 М.
iPhone теперь БЕСПОЛЕЗНО воровать 🛠
0:25
Последствия выхода Айфона 16
0:23
ТРЕНДИ ШОРТС
Рет қаралды 5 МЛН
iPad Domino has been in use for a long time. Let's see the effect
0:12
3D Fantasy Life
Рет қаралды 636 М.
Выпрыгивает ли аккумулятор в iPhone 16?
0:43
ÉЖИ АКСЁНОВ
Рет қаралды 3,9 МЛН