... | ... | @@ -4,7 +4,7 @@ Interrupts can be generated by different events, such as exceptions, timer count |
|
|
|
|
|
This page gives some quick information on how to use Interrupts with MIOSIX in STM32 boards.
|
|
|
|
|
|
### Step 1: Enable IRQ Generation
|
|
|
## Step 1: Enable IRQ Generation
|
|
|
|
|
|
Some Interrupts, called *unmaskable* interrupts, are enabled by default and are handled by the OS, e.g. *exceptions*.
|
|
|
|
... | ... | @@ -45,7 +45,7 @@ EXTI->PR |= EXTI_PR_PR4; // Reset pending register of line 4 |
|
|
SYSCFG->EXTICR[2] = 0x2;
|
|
|
```
|
|
|
|
|
|
### Step 2: Enable IRQ Handling
|
|
|
## Step 2: Enable IRQ Handling
|
|
|
|
|
|
After enabling the interrupt generation, you also have to enable the interrupt **handling** in the NVIC (Nested Vector Interrupt Controller), giving it a priority. More information on NVIC can be found on the datasheet.
|
|
|
|
... | ... | @@ -56,15 +56,15 @@ NVIC_EnableIRQ(EXTI4_IRQn); |
|
|
NVIC_SetPriority(EXTI4_IRQn, 15);
|
|
|
```
|
|
|
|
|
|
### Step 3: Writing a IRQHandler
|
|
|
## Step 3: Writing a IRQHandler
|
|
|
|
|
|
In the `core/stage_1_boot.cpp` file of your board (located in `miosix-kernel/miosix/arch/<ARCH>/<BOARD>/`) all the possible IRQHandlers are defined. They are all defined with `__attribute__((weak))`: this means that if you provide your own implementation of the same function in a .cpp file and compile it, the default one will be overridden by yours.
|
|
|
|
|
|
To do this you will have to write the following code, which contains some magic related to [GCC name mangling](https://en.wikipedia.org/wiki/Name_mangling), in a .cpp file.
|
|
|
|
|
|
:warning: **RESET PENDING BIT REGISTER** in your IRQHandler, otherwise you will enter an infinite loop.
|
|
|
> :warning: **RESET PENDING BIT REGISTER in your IRQHandler, otherwise you will enter an infinite loop.**
|
|
|
|
|
|
:warning: **DON'T USE BLOCKING OR "HEAVY" FUNCTIONS (e.g. printf)** inside your interrupt. Remember that the CPU will stall for the whole time it will execute your IRQHandler. Most of the times, the only thing you will need in your IRQHandler is to set a global variable or to operate with registers.
|
|
|
> :warning: **DON'T USE BLOCKING OR "HEAVY" FUNCTIONS (e.g. *printf()*) inside your interrupt. Remember that the CPU will stall for the whole time it will execute your IRQHandler. Most of the times, the only thing you will need in your IRQHandler is to set a global variable or to operate with registers.**
|
|
|
|
|
|
```cpp
|
|
|
// You need to define the IRQHandler you want to override as "naked".
|
... | ... | |