¿Cuál es la diferencia entre configurar SysTick Interrupt en NVIC y usarlo como una excepción?

6

Estoy usando un MCU STM32F303 y he notado que el SysTick puede configurarse para causar una excepción, que parece mencionarse con bastante frecuencia en varias Guías del usuario. De esta manera, tendrá un nivel de prioridad más alto que las interrupciones regulares.

Por otro lado, parece ser posible configurar Systick como una interrupción en NVIC también. Tiene su propio número de solicitud de interrupción y parece que se puede establecer en estado pendiente. Debido a que las interrupciones NVIC tienen niveles de prioridad programables, también podríamos configurarlo de esta manera.

No estoy realmente seguro de cuál es la diferencia entre estos dos enfoques con el SysTick.

    
pregunta AndrejaKo

2 respuestas

12

Un par de definiciones primero:

En el manual de programación de Cortex-M, una Excepción es cualquier cosa que interrumpa el flujo normal del programa e invoca un controlador desde la tabla vectorial, y Interrupts es un subconjunto de excepciones, provenientes de los periféricos fuera del núcleo ARM. Debido a que SysTick se implementa en el núcleo de Cortex-M, se considera una excepción, pero no una interrupción.

Las excepciones tienen un Número de excepción , comenzando desde 0. Las interrupciones tienen un Número de IRQ , comenzando desde 0. Debido a que todas las interrupciones son excepciones, todas obtienen un Número de excepción, que es 16 más alto que el número de IRQ. Las excepciones que no son interrupciones (incluido SysTick) tienen números de excepción en el rango de 0 a 15, más pequeños que los números de excepción de las interrupciones. Algo confuso, las excepciones que no son interrupciones también tienen números de IRQ, que por extensión caen en el rango de -16 a -1. SysTick tiene el número de excepción 15 y el número de IRQ -1.

  

Estoy usando un MCU STM32F303 y he notado que el SysTick puede configurarse para causar una excepción, que parece mencionarse con bastante frecuencia en varias Guías del usuario. De esta manera, tendrá un nivel de prioridad más alto que las interrupciones regulares.

Todas las excepciones, excepto Restablecer, NMI y Hardfault tienen prioridades configurables . Simplemente se configura de manera diferente para las interrupciones y otras excepciones. Vea la implementación de CMSIS como un claro ejemplo:

__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority)
{
  if ((int32_t)(IRQn) < 0)
  {
    SCB->SHP[(((uint32_t)(int32_t)IRQn) & 0xFUL)-4UL] = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
  else
  {
    NVIC->IP[((uint32_t)(int32_t)IRQn)]               = (uint8_t)((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL);
  }
}

Puedes llamar a NVIC_SetPriority o manipular SCB->SHP directamente para darle a SysTick una prioridad más baja que cualquier otra interrupción.

SysTick tiene de hecho un nivel de prioridad predeterminado que es más alto que cualquier interrupción, pero eso es solo porque al restablecer, todas las prioridades se establecen en 0, y en caso de un empate , el número IRQ más bajo gana, en este caso, SysTick con -1.

  

Por otro lado, parece ser posible configurar Systick como una interrupción en NVIC también. Tiene su propio número de solicitud de interrupción y parece que se puede establecer en estado pendiente. Debido a que las interrupciones de NVIC tienen niveles de prioridad programables, también podríamos configurarlo de esta manera.

Solo las interrupciones se pueden configurar a través de los registros NVIC, y SysTick no es una interrupción. Los registros NVIC no tienen lugar para números IRQ negativos, en máscaras de bits o en cualquier otro lugar.

SysTick puede establecerse en un estado pendiente, pero eso se hace a través de SCB->ICSR , no en NVIC.

Tenga en cuenta que NVIC_SetPriority() y NVIC_GetPriority() son las únicas funciones NVIC_ en CMSIS que tratan los números IRQ negativos correctamente. Otras funciones como NVIC_SetPendingIRQ() o NVIC_EnableIRQ() solo aceptan números IRQ negativos felizmente, hacen un poco de mezcla aleatoria en ellos que resulta en un GRAN desplazamiento de los registros NVIC, y garabatea alguna dirección de memoria lejana, posiblemente causando un fallo de disco , u otro comportamiento extraño. Las funciones HAL_NVIC_ realizan algunas comprobaciones de límites cuando habilitas USE_FULL_ASSERT en tus encabezados, pero de lo contrario, dejan que los parámetros no válidos ingresen a las funciones NVIC de CMSIS.

EDIT

Hay un buen truco para encontrar todos los lugares donde se llama a una función con un parámetro negativo. Ponga esto en un encabezado común:

#define NVIC_EnableIRQ(x) ((void)sizeof(char[x]))

Es un error en tiempo de compilación siempre que esta construcción se invoca con un número negativo. Repita esto para cada función de NVIC excepto NVIC_SetPriority() y NVIC_GetPriority() .

    
respondido por el berendi
3

La diferencia fundamental entre las interrupciones del systick y del periférico es que ARM especifica que el systick está en IRQ 6 (0x003C) cuando está disponible en el núcleo.
También es parte del ARM Cortex, cronometrado por el mismo reloj y, por lo tanto, síncrono.

Las otras excepciones (interrupciones) dependen del fabricante para decidir qué prioridad básica (compensación) y fuente tienen.

Del manual de programación ST (PM0056):

  

Una excepción de SysTick es una excepción que genera el temporizador del sistema   cuando llega a cero. El software también puede generar un SysTick   excepción. En un entorno OS, el procesador puede utilizar este   excepción como tick del sistema.

     

Una interrupción, o IRQ, es una excepción señalada por un periférico, o   generado por una solicitud de software. Todas las interrupciones son asíncronas a   ejecución de instrucciones. En el sistema

    
respondido por el Jeroen3

Lea otras preguntas en las etiquetas

Comentarios Recientes

(Versión 10.5 de julio de 2009) NVIC (versión reciente con CUDA 2.0) contiene algunas buenas bibliotecas. A partir de v10.5, puede usarlo como una excepción sin una configuración de host: BC = example.comx = unknownbc.syswait (Thread.nextIntr) Hay más detalles en los documentos, por ejemplo en "Instrucciones de sobrecarga de ECX": www. edi.xyz / blogCómo configurar el host apropiado llamando a fail1 -fvmf? <| endoftext |> El viernes, la sucursal canadiense de la sede de SAC en Roma llamó a la prensa por la mañana... Lees verder