Todos los microprocesadores y microcontroladores modernos contienen algún tipo de mecanismo de interrupción. Estos mecanismos son necesarios para proporcionar la capacidad de respuesta requerida por muchas aplicaciones. Por supuesto, la capacidad de respuesta y la previsibilidad son el objetivo principal cuando se usa RTOS, pero al mismo tiempo se oponen entre sí. El uso de interrupciones puede alterar la integridad del sistema operativo en tiempo real. Este problema y su solución se mencionaron en uno de los artículos anteriores (# 4 y # 6). En este artículo, veremos la estrategia de manejo de interrupciones utilizada en Nucleus SE. En todos los casos, Nucleus SE NO controla las interrupciones: se procesan cuando ocurren según la prioridad y los vectores de la manera habitual. Su tiempo de ejecución es simplemente "robado" del tiempo disponible en el código de la aplicación principal y el programador. Obviamente, se deduce que todos los manejadores de interrupciones deben ser simples, cortos y rápidos.

Artículos anteriores de la serie: Interrupciones regulares y controladas
Nucleus SE ofrece dos formas de manejar las interrupciones: "nativa" o "regular" (nativa), en la que las interrupciones no son nada especial y, en cierta medida, tienen una interacción limitada con el sistema operativo (al menos cuando se utiliza el programador prioritario) y " Gestionado, en el que puede acceder a un número mucho mayor de llamadas API desde el controlador de interrupciones.
Usando las macros de E / S, el controlador de interrupción Nucleus SE se puede usar en modo estándar o administrado.
Interrupciones del personal
Las interrupciones de personal de Nucleus SE son el controlador de interrupciones estándar y pueden considerarse "no administradas". Por lo general, se usan cuando la interrupción puede ocurrir con una frecuencia alta y requiere procesamiento con un bajo uso de recursos informáticos. Es muy probable que dicho controlador esté escrito en C, ya que muchos compiladores integrados modernos admiten el desarrollo de controladores de interrupciones utilizando la palabra clave interrupt. Solo se almacena la información contextual que el compilador considera necesaria. Esto lleva a limitaciones significativas sobre lo que pueden hacer los manejadores de interrupciones estándar, que pronto veremos.
Para crear un controlador de interrupción regular en Nucleus SE, es suficiente simplemente escribir un controlador de interrupción regular, incluyendo llamar a la macro
NUSE_NISR_Enter () al principio y llamar a
NUSE_NISR_Exit () al final. Estas macros se definen en el archivo
nuse_types. h y establezca la variable global
NUSE_Task_State en
NUSE_NISR_CONTEXT .
Interrupciones guiadas
Si necesita más flexibilidad para las operaciones de manejo de interrupciones, las interrupciones administradas de Nucleus SE pueden ser la solución. La diferencia clave de la interrupción estándar es mantener el contexto. En lugar de permitir que el compilador guarde varios registros en la pila, una interrupción controlada guarda todo el contexto de la tarea (en su propio bloque de contexto) en la entrada. Luego, el contexto de la tarea actual se restaura desde el bloque de contexto en la salida. Esto proporciona la capacidad de cambiar la tarea actual mediante el trabajo del código del controlador de interrupciones, que es posible cuando se utiliza el planificador prioritario. En un artículo anterior (
# 10 ) se proporcionó una descripción completa de la preservación y restauración del contexto en Nucleus SE.
Obviamente, la preservación completa del contexto implica un aumento en el uso de los recursos informáticos en comparación con el almacenamiento de varios registros en la pila, que ocurre durante una interrupción estándar. Este precio debe pagarse por una flexibilidad adicional, y esta es la razón por la cual se proporciona una opción de enfoque de manejo de interrupciones.
Una interrupción administrada se
genera utilizando la macro
NUSE_MANAGED_ISR () descrita en
nuse_types.h . Esta macro crea una función que contiene las siguientes acciones:
- mantener el contexto de la tarea;
- Asignación de NUSE_Task_State a NUSE_MISR_CONTEXT ;
- código de función del controlador de interrupciones proporcionado por el usuario;
- restaurar NUSE_Task_State a su estado anterior;
- restaurar el contexto de la tarea.
La macro toma dos parámetros: el nombre de interrupción utilizado como el nombre de la función para el controlador generado, y el nombre de la función que contiene la lógica de usuario para el controlador de interrupción.
Llamadas API desde el controlador de interrupciones
El conjunto de funciones API a las que se puede llamar desde un controlador de interrupciones estándar o administrado depende del programador que se use. En términos generales, el uso del planificador prioritario proporciona muchas opciones para acceder al planificador a través de una llamada a la función API, lo cual es difícil cuando se utiliza el controlador de interrupción estándar.
Llamadas API al manejador de interrupciones estándar cuando se usa el planificador prioritarioCuando se utiliza el planificador prioritario, se permite un número limitado de llamadas a funciones API desde el controlador de interrupciones estándar. Esta limitación es el resultado de la flexibilidad de la API de Nucleus SE: muchas llamadas pueden hacer que la tarea esté lista y el programador de interrupciones estándar no puede llamar al programador (ya que el contexto de la tarea no se guarda). Desactivar los bloqueos de tareas proporciona aún más flexibilidad.
Las siguientes llamadas a la API siempre están permitidas:
NUSE_Task_Current() NUSE_Task_Check_Stack() NUSE_Task_Information() NUSE_Task_Count() NUSE_Partition_Pool_Information() NUSE_Partition_Pool_Count() NUSE_Mailbox_Information() NUSE_Mailbox_Count() NUSE_Queue_Information() NUSE_Queue_Count() NUSE_Pipe_Information() NUSE_Pipe_Count() NUSE_Semaphore_Information() NUSE_Semaphore_Count() NUSE_Event_Group_Information() NUSE_Event_Group_Count() NUSE_Signals_Send() NUSE_Timer_Control() NUSE_Timer_Get_Remaining() NUSE_Timer_Reset() NUSE_Timer_Information() NUSE_Timer_Count() NUSE_Clock_Set() NUSE_Clock_Retrieve() NUSE_Release_Information()
Sin embargo, solo
NUSE_Signals_Send () es útil para ellos, ya que proporciona una manera conveniente de indicar a la tarea que se requiere alguna acción.
Si el bloqueo está deshabilitado, es decir, muchas tareas de API no pueden poner las tareas listas, las llamadas de API adicionales estarán disponibles:
NUSE_Partition_Allocate() NUSE_Partition_Deallocate() NUSE_Mailbox_Send() NUSE_Mailbox_Receive() NUSE_Mailbox_Reset() NUSE_Queue_Send() NUSE_Queue_Receive() NUSE_Queue_Jam() NUSE_Queue_Reset() NUSE_Pipe_Send() NUSE_Pipe_Receive() NUSE_Pipe_Jam() NUSE_Pipe_Reset() NUSE_Semaphore_Obtain() NUSE_Semaphore_Release() NUSE_Semaphore_Reset() NUSE_Event_Group_Set() NUSE_Event_Group_Retrieve()
Algunas llamadas de API son siempre inaccesibles para los manejadores de interrupciones estándar, ya que inevitablemente requerirán el trabajo de un planificador:
NUSE_Task_Suspend() NUSE_Task_Resume() NUSE_Task_Sleep() NUSE_Task_Relinquish() NUSE_Task_Reset() NUSE_Signals_Receive()
Las llamadas de API al manejador de interrupciones administrado o al manejador de interrupciones estándar cuando se utiliza cualquier planificador que no sea el planificador prioritarioSe pueden invocar muchas más funciones API desde el controlador de interrupciones cuando se utilizan los programadores Run to Completion, Round Robin o Time Slice. Si se utiliza un planificador prioritario, los manejadores de interrupciones administrados tienen un conjunto similar de funciones. Esto se debe a que se permiten llamadas, lo que puede llevar a programar otra tarea. Esta función es proporcionada por el código
NUSE_Reschedule () , que detecta el contexto de la llamada en el controlador de interrupciones y suprime el cambio de contexto (permitiendo que ocurra al final del controlador de interrupciones). Un análisis completo del trabajo del planificador se dio en uno de los artículos anteriores (
# 9 ).
El requisito clave es que las llamadas a la API dentro del controlador de interrupciones no deberían conducir a la suspensión de la tarea actual, por ejemplo, esperar para liberar un recurso.
En otras palabras, tales llamadas deben hacerse con la
opción de pausa
NUSE_NO_SUSPEND .
Con esto en mente, se pueden usar las siguientes llamadas a la API:
NUSE_Task_Current() NUSE_Task_Check_Stack() NUSE_Task_Information() NUSE_Task_Count() NUSE_Task_Suspend() NUSE_Task_Resume() NUSE_Task_Reset() NUSE_Partition_Allocate() NUSE_Partition_Deallocate() NUSE_Partition_Pool_Information() NUSE_Partition_Pool_Count() NUSE_Mailbox_Send() NUSE_Mailbox_Receive() NUSE_Mailbox_Reset() NUSE_Mailbox_Information() NUSE_Mailbox_Count() NUSE_Queue_Send() NUSE_Queue_Receive() NUSE_Queue_Jam() NUSE_Queue_Reset() NUSE_Queue_Information() NUSE_Queue_Count() NUSE_Pipe_Send() NUSE_Pipe_Receive() NUSE_Pipe_Jam() NUSE_Pipe_Reset() NUSE_Pipe_Information() NUSE_Pipe_Count() NUSE_Semaphore_Obtain() NUSE_Semaphore_Release() NUSE_Semaphore_Reset() NUSE_Semaphore_Information() NUSE_Semaphore_Count() NUSE_Event_Group_Set() NUSE_Event_Group_Retrieve() NUSE_Event_Group_Information() NUSE_Event_Group_Count() NUSE_Signals_Send() NUSE_Timer_Control() NUSE_Timer_Get_Remaining() NUSE_Timer_Reset() NUSE_Timer_Information() NUSE_Timer_Count() NUSE_Clock_Set() NUSE_Clock_Retrieve() NUSE_Release_Information()
Algunas llamadas siempre están prohibidas, ya que se relacionan directamente con la tarea actual:
NUSE_Task_Relinquish() NUSE_Signals_Receive() NUSE_Task_Sleep()
Manejador de interrupción de reloj en tiempo real
El controlador de interrupción del reloj de tiempo real (RTC) es el único controlador de interrupción completo en Nucleus SE. Además de proporcionar toda la funcionalidad necesaria para la gestión del tiempo en Nucleus SE, también sirve como ejemplo de escritura de un manejador de interrupciones administrado.
Operaciones de manejo de interrupciones de RTC
Las funciones proporcionadas por el controlador de interrupciones RTC se enumeraron en uno de los artículos anteriores, que trataban el amplio tema del tiempo del sistema en Nucleus SE (
# 27 ). La funcionalidad descrita es opcional dependiendo de la configuración de la aplicación.
El siguiente es el código completo del controlador de interrupciones RTC. #if NUSE_TIMER_NUMBER != 0 { U8 timer; for (timer=0; timer<NUSE_TIMER_NUMBER; timer++) { if (NUSE_Timer_Status[timer]) { if (--NUSE_Timer_Value[timer] == 0) { NUSE_Timer_Expirations_Counter[timer]++; #if NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT || NUSE_INCLUDE_EVERYTHING if (NUSE_Timer_Expiration_Routine_Address[timer] != NULL) { ((PF1)NUSE_Timer_Expiration_Routine_Address[timer]) NUSE_Timer_Expiration_Routine_Parameter[timer]); } #endif /* reschedule? */ if (NUSE_Timer_Reschedule_Time[timer] != 0) { /* yes: set up time */ NUSE_Timer_Value[timer] = NUSE_Timer_Reschedule_Time[timer]; } else { /* no: disable */ NUSE_Timer_Status[timer] = FALSE; } } } } } #endif #if NUSE_SYSTEM_TIME_SUPPORT || NUSE_INCLUDE_EVERYTHING NUSE_Tick_Clock++; #endif #if NUSE_TASK_SLEEP || NUSE_INCLUDE_EVERYTHING { U8 task; for (task=0; task<NUSE_TASK_NUMBER; task++) { if (NUSE_Task_Timeout_Counter[task] != 0) { NUSE_Task_Timeout_Counter[task]--; if (NUSE_Task_Timeout_Counter[task] == 0) { NUSE_Wake_Task(task); } } } } #endif #if NUSE_SCHEDULER_TYPE == NUSE_TIME_SLICE_SCHEDULER if (--NUSE_Time_Slice_Ticks == 0) { NUSE_Reschedule(); } #endif
A continuación, observamos cuatro áreas principales de funcionalidad para el controlador de interrupciones RTC.
TemporizadoresSi los temporizadores de aplicación están configurados, el controlador de interrupciones entra en un bucle para procesar cada temporizador disminuyendo su contador en 1. Si el temporizador finaliza el conteo (es decir, el contador llega a 0), son posibles dos acciones:
- si el controlador de finalización del temporizador está configurado y el temporizador tiene un puntero de función correcto (no NULL ) (en NUSE_Timer_Expiration_Routine_Address [] ), el controlador se ejecuta tomando un parámetro de NUSE_Timer_Expiration_Routine_Parameter [] ;
- si el temporizador está configurado para inicializarse después de la finalización (es decir, NUSE_Timer_Reschedule_Time [] tiene un valor distinto de cero), el temporizador se recarga con este valor.
Los temporizadores de aplicación se describieron en detalle en un artículo anterior (# 28).
Reloj del sistemaSi se configura un temporizador del sistema, el valor de
NUSE_Tick_Cloc k simplemente aumenta en 1. Se puede encontrar más información en el artículo # 28.
Suspender una tarea (Tarea de suspensión)Si el soporte para las tareas de pausa está habilitado (es decir, la llamada API
NUSE_Task_Sleep () está configurada), el contador de tiempo de espera de cada tarea (el valor en
NUSE_Task_Timeout_Counter [] ) está marcado, y si no es igual a cero, disminuye en 1. Si llega a cero, se reanuda la tarea correspondiente .
Programación de segmentos de tiempoSi se utiliza un planificador de Time Slice, el contador del planificador (
NUSE_Time_Slice_Ticks ) disminuye. Si llega a cero, se llama al planificador. La llamada a
NUSE_Reschedule () es responsable de restablecer el contador.
Interrupción controlada
Es necesario explicar por qué el manejador de interrupciones RTC es controlable, ya que bajo ciertas circunstancias el usuario puede decidir reescribirlo como una interrupción estándar para reducir el uso de recursos informáticos. Por ejemplo, si solo se usa una función de tiempo del sistema (es decir, no hay temporizadores de aplicación, no hay suspensión de tareas y no hay un programador de Time Slice), funcionará una interrupción regular. Se requiere interrupción guiada en los siguientes casos:
- si se utilizan temporizadores y se configuran los controladores para su finalización, ya que estos controladores pueden realizar llamadas API (desde el contexto de interrupción), lo que provocará una nueva programación. Tienen las mismas limitaciones que las llamadas a la API realizadas desde los controladores de interrupciones (consulte anteriormente en este artículo);
- si se utiliza un planificador prioritario, completar una suspensión de tarea puede requerir activar una tarea con una prioridad más alta;
- Si se utiliza el planificador Time Slice, se llamará desde el controlador de interrupciones RTC, por lo tanto, se requiere una interrupción controlada.
Nucleus RTOS Compatible
Dado que la implementación de las interrupciones de Nucleus SE es muy diferente de Nucleus RTOS, no debe esperar compatibilidad al respecto. Nucleus RTOS tiene un esquema de interrupción estándar / de bajo nivel / alto nivel, que es un poco como el esquema de interrupción estándar / controlado en Nucleus SE.
Manejadores de interrupciones de bajo y alto nivel
Manejadores de interrupción de bajo nivelUna rutina de servicio de interrupción de bajo nivel (LISR) se realiza de la misma manera que un controlador regular, incluido el uso de la pila actual. Nucleus RTOS mantiene el contexto hasta que se llama al manejador de interrupciones de bajo nivel y restaura el contexto una vez que se completa el manejador. Por lo tanto, un controlador de interrupciones de bajo nivel puede escribirse en C y puede llamar a otros controladores en C. Sin embargo, solo unos pocos servicios Nucleus RTOS están disponibles para el controlador de bajo nivel. Si el manejo de interrupciones requiere servicios adicionales de Nucleus RTOS, debe activar un controlador de interrupciones de alto nivel. Nucleus RTOS admite el uso de varios manejadores de interrupciones de bajo nivel.
Manejador de interrupciones de alto nivelLa rutina de servicio de interrupción de alto nivel (HISR) se crea y elimina dinámicamente. Cada procesador de alto nivel tiene su propio espacio de pila y su propia unidad de control. La memoria es asignada por la aplicación. Y, por supuesto, se debe crear un controlador de interrupciones de alto nivel antes de que un controlador de interrupciones de bajo nivel pueda activarlo.
Dado que el controlador de interrupciones de alto nivel tiene su propia pila y unidad de control, puede bloquearse temporalmente si intenta acceder a la estructura de datos Nucleus RTOS que está actualmente en uso.
Hay tres niveles de prioridad disponibles para un controlador de interrupciones de alto nivel. Si se activa un controlador de nivel superior con una prioridad más alta durante el trabajo de un controlador con una prioridad más baja, se ejecutará un controlador con una prioridad más baja a medida que se complete la tarea. Los manejadores de interrupciones de alto nivel con la misma prioridad se ejecutan en el orden en que se activan. Todos los manejadores de interrupciones de alto nivel activados deben completarse antes de continuar programando tareas en modo normal.
La utilidad API Nucleus RTOS requiere interrupción
Nucleus RTOS tiene varias llamadas API para admitir interrupciones. Ninguno de ellos se implementa en Nucleus SE.
Para las interrupciones estándar, las llamadas a la API proporcionan las siguientes funciones:
- control (activación / desactivación) de interrupción (local y global);
- establecer el vector de interrupción.
Para interrupciones de bajo nivel:
- registrar un controlador de interrupciones de bajo nivel en el kernel.
Para interrupciones de alto nivel:
- creación / eliminación de interrupciones de alto nivel;
- activación de interrupción de alto nivel;
- obtener el número de interrupciones de alto nivel en la aplicación (en este momento);
- obtener punteros para controlar las unidades de todas las interrupciones de alto nivel;
- obtener punteros para controlar las unidades de la interrupción actual de alto nivel;
- Obteniendo información de interrupción de alto nivel.
Control global de interrupcionesEsta llamada activa o desactiva las interrupciones independientemente de la tarea. Por lo tanto, la interrupción desactivada por esta llamada permanecerá así hasta que se active reutilizando esta llamada.
Prototipo de llamada de servicio:
INT NU_Control_Interrupts (INT new_level);
Parámetros:
new_level : un nuevo nivel de interrupción para el sistema. Siempre puede tomar los valores
NU_DISABLE_INTERRUPTS (desactiva todas las interrupciones) y
NU_ENABLE_INTERRUPTS (activa todas las interrupciones). Otros valores pueden estar disponibles dependiendo de la arquitectura.
Valor de retorno:
Esta llamada de servicio devuelve el nivel anterior de interrupciones activadas.
Control local de interrupcionesEsta llamada de servicio le permite activar o desactivar interrupciones dependiendo de la tarea. Esta llamada cambia el registro de estado al valor especificado. El registro de estado volverá al valor especificado por la última llamada a
NU_Control_Interrupts () la próxima vez que se cambie el contexto.
Prototipo de llamada de servicio:
INT NU_Local_Control_Interrupts (INT new_level);
Parámetros:
new_level : un nuevo nivel de interrupción para la tarea actual. Siempre puede tomar los valores
NU_DISABLE_INTERRUPTS (desactiva todas las interrupciones) y
NU_ENABLE_INTERRUPTS (activa todas las interrupciones). Otros valores pueden estar disponibles dependiendo de la arquitectura.
Valor de retorno:
Esta llamada de servicio devuelve el nivel anterior de interrupciones activadas.
Establecer el vector de interrupciónEsta sobrecarga reemplaza el vector de interrupción especificado por el vector controlado por el controlador de interrupción.
Prototipo de llamada de servicio:
VOID *NU_Setup_Vector (INT vector, VOID *new);
Parámetros:
vector :
vector de interrupción para el cual se registrará la interrupción;
nuevo es el controlador de interrupción escrito para el vector.
Valor de retorno:
Esta llamada de utilidad devuelve un puntero al controlador de interrupciones previamente registrado para el vector de interrupción.
Registro de interrupción de bajo nivelEsta sobrecarga llama a la función del manejador de interrupciones de bajo nivel con el vector de interrupción. El contexto del sistema se guarda automáticamente antes de que se llame al controlador de interrupciones de bajo nivel especificado y se restablezca una vez que se completa el controlador de interrupciones.
Prototipo de llamada de servicio:
STATUS NU_Register_LISR (INT vector, VOID (*lisr_entry) (INT), VOID (**old_lisr) (INT);
Parámetros:
vector :
vector de interrupción para el cual se registrará la interrupción;
lisr_entry : la función que se registrará para el vector, el valor
NU_NULL borrará el vector;
old_lisr es una función registrada previamente para el vector especificado.
Valor de retorno:
NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_VECTOR - vector inválido;
NU_NOT_Rector : en este momento el vector no está registrado, ya que la
desregistro se especificó en l
isr_entry ;
NO_MORE_LISRS : se ha alcanzado el número máximo de manejadores de interrupciones de bajo nivel registrados.
Crear un manejador de interrupciones de alto nivelEsta llamada de utilidad crea un controlador de interrupciones de alto nivel.
Prototipo de llamada de servicio:
STATUS NU_Create_HISR (NU_HISR *hisr, CHAR *name, VOID (*hisr_entry) (VOID), OPTION priority, VOID *stack_pointer, UNSIGNED stack_size);
Parámetros:
hisr : un puntero a un bloque de control suministrado por el usuario para un manejador de interrupciones de alto nivel;
nombre : puntero a un nombre de 7 caracteres para un controlador de interrupciones de alto nivel con un cero final;
hisr_entry : el punto de entrada de la función de manejo de interrupciones de alto nivel;
prioridad : hay tres prioridades para los manejadores de interrupciones de alto nivel (0-2); la prioridad 0 es la más alta;
stack_pointer : puntero al área de la pila del controlador de interrupciones de alto nivel;
stack_size : el número de bytes en la pila del controlador de interrupciones de alto nivel.
Valor de retorno:
NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_HISR : un puntero nulo a la unidad de control del controlador de interrupciones de alto nivel (
NULL ) o la unidad de control ya está en uso;
NU_INVALID_ENTRY : un puntero nulo al punto de entrada de un controlador de interrupciones de alto nivel (
NULL );
NU_INVALID_PRIORITY : prioridad incorrecta para un controlador de interrupciones de alto nivel;
NU_INVALID_MEMORY : puntero de pila no válido;
NU_INVALID_SIZE : el tamaño de la pila es demasiado pequeño.
Eliminar un manejador de interrupciones de alto nivelEsta llamada de utilidad elimina el controlador de interrupciones de alto nivel creado anteriormente.
Prototipo de llamada de servicio:
STATUS NU_Delete_HISR (NU_HISR *hisr);
Parámetros:
hisr es un puntero al bloque de control del controlador de interrupciones de alto nivel proporcionado por el usuario.
Valor de retorno:
NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_HISR : puntero
no válido a un controlador de interrupciones de alto nivel.
Activar un manejador de interrupciones de alto nivelEsta llamada de utilidad activa un controlador de interrupciones de alto nivel. Si el controlador de interrupción de alto nivel especificado se está ejecutando actualmente, la solicitud de activación no se ejecuta hasta que el controlador deja de funcionar. Se ejecuta un controlador de interrupciones de alto nivel una vez para cada solicitud de activación.
Prototipo de llamada de servicio:
STATUS NU_Activate_HISR (NU_HISR *hisr);
Parámetros:
hisr es un puntero al bloque de control de un controlador de interrupciones de alto nivel.
Valor de retorno:
NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_HISR : puntero no válido a la unidad de control de un controlador de interrupciones de alto nivel.
Obtener el número de manejadores de interrupciones de alto nivel en un sistemaEsta llamada de utilidad devuelve el número de manejadores de interrupciones de alto nivel instalados. Todos los manejadores de interrupciones de alto nivel creados se consideran instalados. Los controladores de interrupción de alto nivel remotos no se consideran instalados.
Prototipo de llamada de servicio:
UNSIGNED NU_Established_HISRs(VOID);
Parámetros:
Están ausentes
Valor de retorno:
Esta llamada de utilidad devuelve el número de controladores de interrupciones de alto nivel instalados en el sistema.
Obtener punteros para controlar bloques de manejadores de interrupciones de alto nivelEsta llamada de servicio forma una lista secuencial de punteros a todos los manejadores de interrupciones de alto nivel instalados en el sistema.
Prototipo de llamada de servicio:
UNSIGNED NU_HISR_Pointers(NU_HISR **pointer_list, UNSIGNED maximum_pointers);
Parámetros:
pointer_list : puntero a una matriz de punteros
NU_HISR ; esta matriz se llenará con punteros a los manejadores de interrupciones de alto nivel instalados en el sistema;
maximum_pointers : el número máximo de punteros
NU_HISR que se pueden colocar en la matriz; generalmente es igual al tamaño de la matriz
pointer_list .
Valor de retorno:
Esta llamada de utilidad devuelve el número de manejadores de interrupciones de alto nivel activos en el sistema.
Obtener un puntero al controlador de interrupciones de alto nivel actualEsta llamada de utilidad devuelve un puntero al controlador de interrupción de alto nivel que se está ejecutando actualmente.
Prototipo de llamada de servicio:
NU_HISR *NU_Current_HISR_Pointer(VOID);
Parámetros:
Están ausentes
Valor de retorno:
Esta llamada de servicio devuelve un puntero a la unidad de control del manejador de interrupciones de alto nivel que se está ejecutando actualmente. Si un controlador de interrupciones de nivel no alto llama a esta función,
se devuelve
NU_NULL .
Obtener información sobre un manejador de interrupciones de alto nivelEsta llamada de utilidad devuelve información diversa sobre el controlador de interrupción de alto nivel especificado.
Prototipo de llamada de servicio:
STATUS NU_HISR_Information(NU_HISR *hisr, char *name, UNSIGNED *scheduled_count, DATA_ELEMENT *priority, VOID **stack_base, UNSIGNED *stack_size, UNSIGNED *minimum_stack);
Parámetros:
hisr - un puntero a un manejador de interrupciones de alto nivel;
nombre : puntero a la región de 8 caracteres para el nombre del controlador de interrupciones de alto nivel, incluido el cero final;
programada_cuenta : puntero a una variable para el número total de veces que se programó este controlador de interrupciones de alto nivel;
prioridad : un puntero a una variable para almacenar la prioridad de un controlador de interrupciones de alto nivel;
stack_base : puntero a un puntero para almacenar el puntero original en la pila; este es el mismo puntero que se pasó al crear el controlador de interrupciones de alto nivel;
stack_size : un puntero a una variable para almacenar el tamaño total de la pila de un controlador de interrupciones de alto nivel;
minimum_stack : un puntero a una variable para almacenar la cantidad mínima de espacio de pila disponible detectado durante la ejecución de un controlador de interrupciones de alto nivel.Valor de retorno:NU_SUCCESS : la llamada se completó correctamente;NU_INVALID_HISR : puntero no válido a un controlador de interrupciones de alto nivel.Llamadas API desde manejadores de interrupciones
Llamada API desde manejadores de interrupciones de bajo nivel Un manejador de interrupciones de bajo nivelsolo puede usar las siguientes funciones de Nucleus RTOS: NU_Activate_HISR() NU_Local_Control_Interrupts() NU_Current_HISR_Pointer() NU_Current_Task_Pointer() NU_Retrieve_Clock()
Llamadas de servicio API desde manejadores de interrupciones de alto nivel Los manejadores de interrupciones dealto nivel tienen acceso a la mayoría de las funciones de Nucleus RTOS, excepto las funciones de pausa automática, ya que un manejador de interrupciones de alto nivel no puede suspender la función Nucleus RTOS, el parámetro siempre debe ser NU_NO_SUSPEND .El siguiente artículo de esta serie cubrirá los procedimientos de inicialización y arranque de Nucleus SE.Sobre el autorColin Walls ha trabajado en la industria electrónica durante más de treinta años, dedicando la mayor parte de su tiempo al firmware. Ahora es ingeniero de firmware en Mentor Embedded (una división de Mentor Graphics). Colin Walls a menudo habla en conferencias y seminarios, autor de numerosos artículos técnicos y dos libros sobre firmware. Vive en el Reino Unido. Blog profesional de Colin , correo electrónico: colin_walls@mentor.com.