RTOS: ¿Por qué necesitamos versiones especiales de publicaciones para ISR?

6

En algunos kernels RT, si desea publicar en un semáforo o marca desde un ISR, debe llamar a una versión especial del método, en lugar de la llamada normal de una tarea normal. Ejemplos:

  • xSemaphoreGiveFromISR() en lugar de xSemaphoreGive() en FreeRTOS
  • Vole de la vara de la vara de la vera de la vera de la vera de la naturaleza / li>

Sin embargo, hay otros núcleos donde esto no es necesario. Por ejemplo:

  • isr_PostSem() en uC / OS puede llamarse desde las tareas y los ISR.
  • CoPostSem() en VxWorks parece que se puede llamar desde un ISR de acuerdo con los documentos y, a primera vista, no existe un método especial para los ISR.

¿Por qué necesitarías crear versiones especiales? Entiendo que la publicación de un semáforo o una bandera puede hacer que se despierte una tarea bloqueada de mayor prioridad. Y es por eso que el programador es más probable que se ejecute cuando se llame a la devolución de llamada de salida de ISR (estoy hablando de las funciones que se necesitan cuando se quiere usar el código del kernel dentro de ISR, como OSSemPost() en FreeRTOS, o release() en uC / OS). Entonces, ¿por qué el método de publicación especial además de la llamada ISRexit?

    
pregunta Mister Smith

2 respuestas

6

He estado leyendo el código fuente de FreeRTOS y CoOS.

En FreeRTOS (el puerto que encontré primero en Google), la función xSemaphoreGiveFromISR() llama a xQueueGenericSendFromISR() , y esta función tenía este comentario:

/* Similar to xQueueGenericSend, except we don't block if there is no room
    in the queue.  Also we don't directly wake a task that was blocked on a
    queue read, instead we return a flag to say whether a context switch is
    required or not (i.e. has a task with a higher priority than us been woken
    by this post). */

En cuanto a CoOS, la función isr_PostSem llamada desde un ISR simplemente pone en cola una solicitud a la llamada "Cola de solicitud de servicio", utilizando la función InsertInSRQ . No tengo idea de qué es esta cola, probablemente es una tarea del sistema para descargar el trabajo de los ISR y, por lo tanto, dejar que las interrupciones se completen rápidamente.

En cuanto a mbed, que solo tiene 1 versión del método, se basa en CMSIS RTOS y hay una llamada a la función osSemaphoreRelease() . Hay un comentario sobre esto y funciones similares:

The following CMSIS-RTOS functions can be called from threads and interrupt
service routines (ISR):
  - osSignalSet
  - osSemaphoreRelease
  - osPoolAlloc, osPoolCAlloc, osPoolFree
  - osMessagePut, osMessageGet
  - osMailAlloc, osMailCAlloc, osMailGet, osMailPut, osMailFree

Functions that cannot be called from an ISR are verifying the interrupt
status and return in case that they are called from an ISR context the status
code osErrorISR. In some implementations this condition might be caught using
the HARD FAULT vector.

Así que parece ser solo el diseño del kernel, algunos diseñadores optaron por tener funciones separadas y dejaron que el programador hiciera la distinción, y otros prefirieron tener solo un método y verificar internamente si la llamada se realizó desde un ISR.

    
respondido por el Mister Smith
5

En muchas arquitecturas de microcontroladores más pequeñas, no hay una verdadera pila de datos para las variables automáticas. En su lugar, estas variables se asignan de forma estática, utilizando una función de análisis que toma en cuenta todo el "árbol" de llamadas de función para asegurarse de que (la mayor parte de) la funcionalidad de una pila se conserve.

La implicación de esto es que las funciones individuales no pueden ser reentrantes, al menos, no sin una gran cantidad de sobrecarga. Si intentó llamar a una función desde un ISR, podría estar interrumpiendo la misma función que se había llamado desde el código de la línea principal. Esencialmente, cada ISR tiene su propio "árbol" de llamadas de función (generalmente un árbol muy pequeño), y todos esos árboles deben ser físicamente distintos en términos de la RAM de datos que utilizan.

Por lo tanto, cada función debe asignarse a un árbol u otro, y necesita copias separadas de las funciones que podrían llamarse desde múltiples árboles.

Creo que encontrará que las implementaciones de RTOS que tienen funciones separadas están dirigidas a esas arquitecturas de procesadores más pequeñas, mientras que las que no están dirigidas por completo a arquitecturas que tienen pilas de datos verdaderos.

    
respondido por el Dave Tweed

Lea otras preguntas en las etiquetas