Is SysTick priority high or low

Publisher:骄阳少年Latest update time:2018-07-20 Source: eefocusKeywords:SysTick Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The SysTick system tick timer is not unique to STM32. It is part of the Cortex core. CM3 has a special exception type for it and it has a place in the interrupt vector table (exception number 15). In this way, it can be easily ported to chips with CM3 cores from different manufacturers. Especially for software with real-time operating systems, it is generally used as the time base of the entire system, so it is very important for the operating system.

However, there is very little introduction to it in the STM32 development manual, almost to the extent of being glossed over. For a detailed introduction to SysTick, please refer to Chapter 8 on page 133 and Chapter 13 on page 179 of the "Cortex-M3 Authoritative Guide".

When I first came into contact with SysTick, because it belongs to the kernel interrupt priority, I always had a question: is it higher or lower than all maskable interrupt priorities, or are they in the same setting position?
At first, I thought that the kernel interrupt priority was higher than all maskable interrupt priorities. After carefully reading the information and doing experiments, I found that this was not the case.

SysTick has four registers in total:
1. This register is represented by the SysTick->CTRL variable in the system code; 2. This register is represented by the SysTick->LOAD variable in the system code; 3. This register is represented by the SysTick->VAL variable in the system code; 4. This register is represented by the SysTick->CALIB variable in the system code. It has not been used and is not often used, so it will not be introduced for the time being. The offsets of these registers are shown in the figure below:


















The definition of the above register structure in \CMSIS\CM3\CoreSupport core_cm3.h is as follows:


/

**@addtogroup CMSIS_CM3_SysTick CMSIS CM3 SysTick

  memory mapped structure for SysTick

  @{

  */

typedef struct

{

    __IO uint32_t CTRL; /*!< Offset: 0x00 SysTick Control and Status Register */

    __IO uint32_t LOAD; /*!< Offset: 0x04 SysTick Reload Value Register */

    __IO uint32_t VAL; /*!< Offset: 0x08 SysTick Current Value Register */

    __I uint32_t CALIB; /*!< Offset: 0x0C SysTick Calibration Register */

} SysTick_Type;

SysTick is a 24-bit timer, which means it can count up to 224 clock pulses at a time. This pulse count value is saved in the SysTick->VAL current count value register. It can only count down. Each time a clock pulse is received, the value of SysTick->VAL is reduced by 1 until it reaches 0. Then the hardware automatically reloads the value in the reload register SysTick->LOAD to SysTick->VAL and recounts. When the SysTick->VAL value counts to 0, an exception is triggered and the void SysTick_Handler(void) function is called. The timer interrupt event can be processed in this interrupt service function, which is generally a count-down operation for the set value. As long as the 0th enable bit in the SysTick control and status register SysTick->CTRL is not cleared, it will never stop.


It is a system exception, a kernel-level interrupt, and the priority can be set. The specific settings are also in core_cm3.h code as follows:



/**

 * @brief Initialize and start the SysTick counter and its interrupt.

 *

 * @param ticks number of ticks between two interrupts

 * @return 1 = failed, 0 = successful

 *

 * Initialise the system tick timer and its interrupt and start the

 * system tick timer / counter in free running mode to generate 

 * periodical interrupts.

 */

static __INLINE uint32_t SysTick_Config(uint32_t ticks)

    if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */

    SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */

    NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); 

    SysTick->VAL = 0; 

    SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | 

        SysTick_CTRL_TICKINT_Msk | 

        SysTick_CTRL_ENABLE_Msk; 

    return (0); /* Function successful */

}

In this code, the priority is set by the NVIC_SetPriority() function. This function can set both kernel interrupt priority and external interrupt priority, which is quite powerful, but requires manual calculation of preemption and slave priorities, which is not very convenient. When jumping into this function, we can calculate that Systick has the lowest default priority (the effect is equivalent to SCB->SHP[11] = 0xF0. If you calculate, SHP[11] corresponds to the Systick priority setting). For maskable interrupts, the priority is generally set by the NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct) function. For specific applications, please refer to the sample code below.


After introducing the theory, I found that I still didn't understand the initial doubt! Now let's implement it to reveal the truth.


First set an event interrupt and set the priority higher.



void Exti_Config(void)

{

    EXTI_InitTypeDef EXTI_InitStructure;

    NVIC_InitTypeDef NVIC_InitStructure;

    EXTI_InitStructure.EXTI_Line = EXTI_Line1;

    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Event;

    EXTI_InitStructure.EXTI_LineCmd = ENABLE;

    EXTI_Init(&EXTI_InitStructure);

    NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; 

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; 

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

}



Note: In my experiment, the interrupt grouping was initially initialized as follows:



NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

Set as the second group.


Trigger an external interrupt event in the system tick interrupt and light up LED1:



void SysTick_Handler(void)

    EXTI_GenerateSWInterrupt(EXTI_SWIER_SWIER1); 

    LED_1 = ON;

    Delay();

}

Light up LED0 in the external interrupt processing function as follows:



void EXTI1_IRQHandler(void)

{

    if (EXTI_GetITStatus(EXTI_Line1) != RESET) 

    {

        EXTI_ClearITPendingBit(EXTI_Line1); 

        LED_0 = ON;

        Delay();

    }

}

When the external interrupt priority is higher, it can preempt the Systick interrupt and execute first. The experimental result of the above code is that LED0 lights up first, and then returns to LED1 to light up.



But when the external interrupt is set to the same priority as systick, the systick priority will be relatively high. For example, change the above priority to:



NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3; 

NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;

Then LED1 will light up first, and EXTI1_IRQHandler will execute only after the SysTick_Handle function is executed.


From the above experiments, it can be concluded that when the priorities are the same, kernel-level interrupts take precedence over external maskable interrupts. However, when the priority of an external maskable interrupt is set higher than that of a kernel-level interrupt, it can preempt the kernel interrupt.


In addition, I personally think that if you want to achieve accurate systick delay, it is best to set the systick priority higher, such as NVIC_SetPriority (SysTick_IRQn, 0);

That is, by setting SCB->SHP[11] = 0x00; the priority of systick can be higher than any external interrupt. At this time, the delay will be less affected by other interrupts and will be more accurate.


Keywords:SysTick Reference address:Is SysTick priority high or low

Previous article:Summary of systick usage errors
Next article:Detailed explanation of Systick delay function

Latest Microcontroller Articles
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号