A background
There are a lot of configuration data on FreeRTOS interrupt priorities on the web, but individual configuration items have changed in v10.0, and the entire priority management configuration scenario is described in detail in this article.
ARM chip priority for 0~255, different chip manufacturers use different priorities, not all use, here with Arm CORTEX-M3 series as an example. The priorities of the CM3 kernel are grouped as follows:
In order to more easily manage interrupt priority, St official suggestion and default use 5th group: Nvic_prioritygroup_4, its priority register is 8 bit registers, CM3 only use high 4 bits, constitute 0~15 total 16 priority, the following figure:
In the Stm32f2xx.h file, the CM3 kernel priority is defined by __nvic_prio_bits with a high four bit, with the following code:
/**
* @brief Configuration of the cortex-m3 Processor and Core peripherals */
#define __cm3_rev 0x0200< c4/>/*!< Core Revision r2p0 * *
#define __MPU_PRESENT 1/*!< stm32f2xx provides an MPU * *
#define __nvic_prio_bits 4 /*!< stm32f2xx uses 4 BITS for the Priority levels */
#define __vendor _systickconfig 0 /*!< Set to 1 if different Systick Config is used/ *
Two-FreeRTOS priority configuration (important)
There are three configuration items in FreeRTOSConfig.h that are responsible for priority management: #define CONFIGKERNEL_INTERRUPT_PRIORITY 255//Configure interrupt priority for kernel use, here is 8 bit, default lowest priority # Define configmax_syscall_interrupt_priority 95/** configuration system can call the highest priority of management, 95 to hexadecimal is 0x5f, the highest priority is 5, priority 0-4 is not system-managed **/#define Configlibrary_kernel_interrupt_priority 15/* Configure system Kernel priority, where the 4bit priority is used, so the minimum is 15, the same as the configuration in 1 */
The above configuration in the arm-cm3 kernel of the specific definition is: FreeRTOS operating system kernel use the lowest priority, the operating system can invoke the highest priority of management is 5~15 level.
I gave two examples to illustrate the implications of this configuration, Figure 1 is the official example given in the manual, where priority 1 is lowest and priority 7 is highest. If CONFIGMAX_SYSCALL_INTERRUPT_PRIORITY=3 is configured separately and Configkernel_interrupt_priority=1, the 1~3 interrupt is affected and managed by the operating system kernel. Can be shielded in a critical section; Priority 4~7 interrupts are not affected by the operating system, but in the event of an interrupt, a function of the systems API (operating system in a system-not-administered priority may result in timing confusion, anomalies, etc.).
Figure 2 is in the arm-cm3 kernel, such as the Stm32f2xx and STM32F1 series microcontroller, the kernel uses 4bit priority, priority 0 highest, priority 15 lowest. If you set configmax_syscall_interrupt_priority=111 (0x6f) and configkernel_interrupt_priority=255 (0xFF), the priority for 0-5 is not managed by the system. Also can not call the system's API functions, priority 6-15 interrupt by the system management, you can use API functions (end with FROMISR function), and may be affected by kernel latency, because the operating system critical section can temporarily block global interrupts, resulting in the interruption occurs when the corresponding , it needs to wait until it exits the critical section before executing.
Figure 1 Official example of FreeRTOS
Figure 2 cm Kernel arm priority
Three-FreeRTOS task priority
The FreeRTOS task priority is configured for system proprietary, hardware independent, and is responsible for scheduling orders between multiple tasks in the operating system. The number of task priorities is the #define CONFIGMAX_PRIORITIES (16) in FreeRTOSConfig.h, the task priority 0 is the lowest, and 16 is the highest. Here is a simple point, because the operating system task scheduling in the search for leading zeros of the assembly (CLZ) instructions, high efficiency, so the recommended maximum number of task priority is not more than 32. Configure #define Configuse_port_optimised_task_selection 1, open the leading 0 mode, the premise is the kernel support CLZ instructions, Baidu. Configure #define CONFIGMAX_PRIORITIES (16) and use 16 priority quantities. The kernel defaults to use level 0, lowest priority, idle task. Configure #define Configidle_should_yield 0, which affects only the idle priority task, so that the task at the idle priority (level 0) is given the same CPU time. Summary of four issues
Critical Area Problem Task Name Task a task B Priority 1 2 critical section has, time-consuming 2s no blocking time 10ms 20ms run results Run once
Cause analysis: Because blocking uses Vtaskdelay (), the function is shielded in the critical section, excluding the blocking cycle, so when task a blocks for half of Task B, task A performs two blocking times to get task B into a ready state. Then switch to high-priority task B when task a exits the critical section. Task Name Task a task B Priority 1 2 critical section no blocking time 10ms 20ms running result has been running
When the critical section is closed, high-priority tasks are normally preempted by low-priority task A.