FreeRTOS transplanted to Cortex-m3-m4

Source: Internet
Author: User

Translated from FreeRTOS official website document, original website: http://www.freertos.org/RTOS-Cortex-M3-M4.html

Reprint: Original source: Http://bbs.ednchina.com/BLOG_ARTICLE_3009240.HTM

Thousands of FreeRTOS applications run on the arm cortex-m core. Surprisingly, the RTOs is used in combination with the Cortex-m kernel, making the request for technical support so much less. Most of the problem points are caused by incorrect priority settings. This problem is also expected, because although the CORTEX-M core interrupt mode is very powerful, but for those who use the traditional interrupt priority architecture, the CORTEX-M kernel interrupt mechanism is also a bit awkward (or the use of more cumbersome), And counterintuitive (this is mainly because the larger the CORTEX-M priority level, the smaller the priority.) This chapter intends to describe the interrupt priority mechanism of CORTEX-M and describes how to use it in conjunction with the RTOs kernel.

Note: Although the priority scheme of the CORTEX-M3 kernel looks complicated, each of the FreeRTOS interface packages that are officially released (in the Freertosv7.2.0\freertos\source\portable folder, Normally port.c) there will be a properly configured demo routine, which can be used as a reference.

Valid priority level

CORTEX-M Hardware Details

The first step is to clear the total number of effective priorities, depending on how the microcontroller manufacturer uses the Cortex kernel. Therefore, not all cortex-m core microprocessors have the same interrupt priority level.

The CORTEX-M architecture itself allows up to 256 levels of programmable precedence (priority configuration registers up to 8 bits, so the priority range is from 0x00~0xff), but most microcontroller manufacturers use only a subset of these priorities. For example, TI Stellaris cortex-m3 and CORTEX-M4 microcontrollers use 3 bits of the priority configuration register, providing a 8-level priority. For example, the NXP lpc17xx CORTEX-M3 microcontroller uses 5 bits of the priority configuration register to provide a 32-level priority.

If your project contains Cmsis library header files (here is the Cmsis library header file for Cortex M3, which is core_cm3.h, which can be downloaded from the ARM website), the macros in the header file __nvic_prio_ BITS defines the bits that use the number of priority registers (the default is 4 bits).

Apply to RTOs

The RTOs interrupt nesting scheme divides the effective interrupt priority into two groups: one can be shielded by the RTOs critical section, the other is not affected by the RTOs, and will always be enabled. Configmax_syscall_interrupt_priority is configured in FreeRTOSConfig.h to define the boundaries of two sets of interrupt priorities. Interrupts with a logical priority above this value are not affected by the RTOs. The optimal value depends on the number of bits of the priority configuration register used by the microcontroller.

Precedence values and logical precedence settings in contrast to numeric values

CORTEX-M Hardware Details

It is necessary to first explain the priority value and the logical priority: in the Cortex-m kernel, if there is a level 8 priority, we say that the priority value is 0~7, but the highest value of the priority 7 represents the lowest logical priority. Many engineers who use traditional traditional interrupt-priority architectures feel that this is a bit of a detour and counterintuitive. The priorities mentioned below are carefully differentiated by priority values or logical precedence.

The next thing to be clear is that in the cortex-m kernel, the lower the priority value of an interrupt, the higher the logical precedence. For example, interrupts with an interrupt priority of 2 can preempt interrupts with an interrupt priority of 5, but not in turn. In other words, the interrupt Priority 2 is higher than the interrupt priority 5 priority.

This is the easiest way for the cortex-m kernel to make a mistake, since most of the non-cortex-m core microcontrollers have the opposite interrupt priority representation.

Apply to RTOS

The FreeRTOS function ending with "FROMISR" is protected with interrupt invocation (execution of these functions enters the critical section), but even these functions cannot be logically prioritized above configmax_syscall_interrupt_ The interrupt service function call for priority. (The macro configmax_syscall_interrupt_priority is defined in the header file FreeRTOSConfig.h). Therefore, any interrupt service routines that use the RTOs API function have a value greater than or equal to the value of the Configmax_syscall_interrupt_priority macro. This ensures that the logical priority of the interrupt is equal to or less than configmax_syscall_interrupt_priority.

Cortex interrupts have a priority value of 0 by default. In most cases 0 represents the highest priority. Therefore, it is absolutely not possible to invoke the RTOS API function in a priority 0 Interrupt Service routine .

CORTEX-M Internal Priority Overview

CORTEX-M Hardware Details

The interrupt priority register for the CORTEX-M kernel is aligned with the highest bit (MSB). For example, if 3 bits are used to express the priority, these 3 bits are located in the Bit5, BIT6, bit7 bits of the interrupt priority register. The remaining BIT0~BIT4 can be set to any value, but for compatibility, it is best to set them to 1.

The CORTEX-M priority register has a maximum of 8 bits, and if a microcontroller uses only 3 bits, the 3 bits are aligned at the highest bit, see:

A microcontroller only uses 3 bits in the priority register, showing how the priority level 5 (binary 101B) is stored in the priority register. If position 1 is not used in the priority register, it also shows why the value 5 (binary 0000 0101B) can be considered as the value 191 (binary 1011 1111).

A microcontroller only uses 4 bits in the priority register, showing how the priority level 5 (binary 101B) is stored in the priority register. If position 1 is not used in the priority register, it also shows why the value 5 (binary 0000 0101B) can be considered as the value 95 (binary 0101 1111).

(Original source, this picture is wrong, find the English source revision changed)

Apply to RTOS

As already described, the interrupt logic priority for invoking an RTOS API function in an interrupt service routine must be less than or equal to configmax_syscall_interrupt_priority (low logical precedence means high-priority progression values).

Cmsis and different microcontroller vendors provide a library function that can set an interrupt priority. Some library functions have parameters that use the lowest bit alignment, while others may use the highest bit alignment, so you should consult the library function's application manual for proper setup.

You can set the values of macro configmax_syscall_interrupt_priority and configkernel_interrupt_priority in FreeRTOSConfig.h. (For these two macros you can refer to the parameter setting chapter, URL: http://openmcu.net/post/kernel-config.html). These two macros need to be set according to the CORTEX-M kernel itself, to be aligned with the most significant bit. For example, if a microcontroller uses 3 bits in the interrupt priority register and the value of setting configkernel_interrupt_priority is 5, the code is:

#define Configkernel_interrupt_priority (5<< (8-3))

For each of the official FreeRTOS demo routines, this is why you set it to 255 (1111 1111B) when you want to set the macro configkernel_interrupt_priority to the lowest priority in FreeRTOSConfig.h. The reason for specifying this value in this way is that the FreeRTOS kernel runs directly on the CORTEX-M kernel hardware (no third-party interface library functions are used), and runs first than most library functions. Now there is also the development of the first CORTEX-M library function plan.

Critical section

CORTEX-M Hardware Details

The RTOs kernel uses the BASEPRI register of the CORTEX-M kernel to implement the critical section (note: BASEPRI is the priority masking register, the priority value is greater than or equal to the register interrupt will be masked, the higher the priority value, the lower the logical priority, but no interrupt is masked at zero). This allows the RTOs kernel to mask only a subset of interrupts, thus providing a flexible interrupt nesting pattern.

For those API functions that need to be protected during interrupt invocation, FreeRTOS uses the register BASEPRI to implement the Interrupt Protection critical section. When entering the critical section, set the value of the register Basepri to configmax_syscall_interrupt_priority, and when exiting the critical section, set the value of the register Basepri to 0. Many bug feeds mention that when you exit a critical section, you should not set the register to 0, and you should revert to its previous state (the previous state is not necessarily 0). However, Cortex-m Nvic will never allow a low-priority interrupt to interrupt a high-priority interrupt that is currently executing, regardless of the value in the BASEPRI register. Compared with the method of saving Basepri before entering the critical section, the method of setting the BASEPRI register to 0 when exiting the critical section can achieve a faster execution speed than that of the critical section.

Apply to RTOs kernel

The RTOs kernel creates a critical section by writing the value of the configmax_syscall_interrupt_priority to the BASEPRI register. Interrupt priority 0 (with the highest logical priority) cannot be masked by the BASEPRI register, so configmax_syscall_interrupt_priority can never be set to 0.

FreeRTOS transplanted to Cortex-m3-m4

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.