FreeRTOS Interrupt Management | FreeRTOS Five

Table of contents

illustrate:

1. Interruption Basics

1.1. Interruption of understanding

1.2. Interrupt execution steps

1.3. Interrupt register selection bit

1.4. Interrupt priority classification

2. Interrupt priority grouping settings

2.1. Classification

2.2. Features

3. Interrupt related registers

3.1. SHPR1 register

3.2. SHPR2 register

3.3. SHPR3 register

3.4. Steps to configure PendSV and Systick interrupt priority in FreeRTOS

4. FreeRTOS interrupt management

4.1. Interrupt related functions

4.2. Interrupt example


illustrate:

1) The following contents are mostly conceptual understanding and step analysis

2) There is no personal sample code yet, the sample code of FreeRTOS is used.

3) If you want to transplant the code for testing, please look elsewhere. There is no personal sample code for testing in the following content.

About others:

1) Operating system: win 10

2) Platform: keil 5 mdk

3) Language: c language

4) Board: STM32 series transplanted to FreeRTOS

1. Interruption Basics

1.1. Interruption of understanding

        An event (program) that allows the CPU to interrupt the normal running of a program and instead process it is called an interrupt.

1.2. Interrupt execution steps

        1) Interrupt request, the peripheral generates an interrupt request (GPIO external interrupt, timer interrupt);

        2) In response to the interrupt, the CPU stops executing the current program and instead processes the interrupt program (ISR);

        3) Exit the interrupt, return to the program location interrupted by the interrupt, and continue executing the program.

1.3. Interrupt register selection bit

        1) ARM Cortex-M uses an 8-bit wide register to configure the priority level of interrupts. This register is the interrupt priority configuration register; 2) But STM32 only
        uses the high 4 bits of the interrupt priority configuration register [7: 4 ] (as shown in Figure 1), so STM32 provides a maximum of 16 levels of interrupt priority, which is used to express that the priority is not implemented and is read back to zero;

figure 1

1.4. Interrupt priority classification

1) The interrupt priority of STM32 can be divided into preemption priority and sub-priority

2) Preemption priority: An interrupt with a high preemption priority can interrupt an interrupt that is executing but with a low preemption priority.

3) Sub-priority: When two interrupts with the same preemption priority occur at the same time, the one with the smaller sub-priority value will be executed first.

2. Interrupt priority grouping settings

2.1. Classification

It can be divided into 5 types, as shown in Figure 2 below:

figure 2

2.2. Features

1) FreeRTOS API functions are only allowed to be called in interrupts with a priority lower than the macro definition configMAX_ SYSCALL INTERRUPT_ PRIORITY;

2) It is recommended to specify all priority bits as preemption priority bits to facilitate FreeRTOS management
(call the function HAL_ NVIC_ SetPriorityGrouping(NVIC PRIORITYGROUP_4). This is the HAL library. The standard library should be: NVIC_ SetPriorityGrouping(NVIC PRIORITYGROUP_4)

3) The smaller the interrupt priority value, the higher the priority. The larger the task priority value, the higher the priority.
 

3. Interrupt related registers

3.1. SHPR1 register

Register address: 0xE000ED18

3.2. SHPR2 register

Register address: 0xE000ED1C

3.3. SHPR3 register

Register address: 0xE000ED20

The details are as shown in Figure 3 (from page 286 of the Cortex M3 Authoritative Guide (Chinese)):

 image 3

3.4. Steps to configure PendSV and Systick interrupt priority in FreeRTOS

1) Get the SHPR3 register address and shift it 16 bits to the left to get the register address where PendSV is set.

2) Get the SHPR3 register address and shift it 24 bits to the left to get the register address where Systick is set.

3) Through a series of assignments, the last step is to perform assembly operations and assign values ​​directly to registers, configure them, and finally set the priority of PendSV and Systick to 15, the lowest priority.

4. FreeRTOS interrupt management

4.1. Interrupt related functions

Turn off interrupt function prototype: portDISABLE_INTERRUPTS()

If the port used supports the configMAX_SYSCALL_INTERRUPT_PRIORITY (or configMAX_API_CALL_INTERRUPT_PRIORITY) constant, taskDISABLE_interrupts will disable all interrupts, or mask (disable) interrupts before configMAX_SYSCALL_INTRUPT_PROJECT is set. Check the implementation of taskDISABLE_INTERRUPTS in the port used.

If the port used does not support the configMAX_SYSCALL_INTERRUPT_PRIORITY constant, taskDISABLE_INTERRUPTS() will globally disable all maskable interrupts.

Normally this macro is not called directly, but taskENTER_CRITICAL() and taskEXIT_CRITICAL() are used instead.

Enable interrupt function prototype: portENABLE_INTERRUPTS()

Macro to enable microcontroller interrupts.

Normally this macro is not called directly, but taskENTER_CRITICAL() and taskEXIT_CRITICAL() are used instead.

4.2. Interrupt example

The board is not around, so I can't test it. I will make it up later. The following is the official FreeRTOS example:

/* A function that makes use of a critical section. */
void vDemoFunction( void )
{
    /* Enter the critical section.  In this example, this function is itself called
    from within a critical section, so entering this critical section will result
    in a nesting depth of 2. */
    taskENTER_CRITICAL();

    /* Perform the action that is being protected by the critical section here. */

    /* Exit the critical section.  In this example, this function is itself called
    from a critical section, so this call to taskEXIT_CRITICAL() will decrement the
    nesting count by one, but not result in interrupts becoming enabled. */
    taskEXIT_CRITICAL();
}

/* A task that calls vDemoFunction() from within a critical section. */
void vTask1( void * pvParameters )
{
    for( ;; )
    {
        /* Perform some functionality here. */

        /* Call taskENTER_CRITICAL() to create a critical section. */
        taskENTER_CRITICAL();


        /* Execute the code that requires the critical section here. */


        /* Calls to taskENTER_CRITICAL() can be nested so it is safe to call a
        function that includes its own calls to taskENTER_CRITICAL() and
        taskEXIT_CRITICAL(). */
        vDemoFunction();  

        /* The operation that required the critical section is complete so exit the
        critical section.  After this call to taskEXIT_CRITICAL(), the nesting depth
        will be zero, so interrupts will have been re-enabled. */
        taskEXIT_CRITICAL();
    }
}

Guess you like

Origin blog.csdn.net/qq_57663276/article/details/128790527