Toda la verdad sobre RTOS. Artículo # 18. Grupos de banderas de eventos: servicios auxiliares y estructuras de datos



Este artículo continúa describiendo grupos de banderas de eventos.

Artículos anteriores de la serie:

Artículo # 17. Grupos de banderas de eventos: Introducción y servicios básicos
Artículo # 16. Señales
Artículo # 15. Particiones de memoria: servicios y estructuras de datos
Artículo # 14. Secciones de memoria: introducción y servicios básicos.
Artículo 13. Estructuras de datos de tareas y llamadas de API no compatibles
Artículo # 12. Servicios para trabajar con tareas.
Artículo # 11. Tareas: configuración e introducción a la API
Artículo # 10. Programador: funciones avanzadas y preservación del contexto
Artículo # 9. Programador: implementación
Artículo # 8. Nucleus SE: diseño interno y despliegue
Artículo # 7. Núcleo SE: Introducción
Artículo # 6. Otros servicios RTOS
Artículo # 5. Interacción de tareas y sincronización
Artículo # 4. Tareas, cambio de contexto e interrupciones
Artículo # 3. Tareas y planificación
Artículo # 2. RTOS: estructura y modo en tiempo real
Artículo # 1. RTOS: introducción.


Servicios de ayuda de grupo de eventos


Nucleus RTOS tiene tres llamadas API que proporcionan funciones auxiliares para grupos de indicadores de eventos: recuperar información del grupo, recuperar información sobre el número de grupos de indicadores de eventos en una aplicación y recuperar punteros a todos los grupos de indicadores de eventos. Los dos primeros desafíos se implementan en Nucleus SE.

Recuperando información de grupo de banderas de eventos


Esta llamada de utilidad devuelve información sobre el grupo de banderas de eventos. La implementación de esta llamada en Nucleus SE difiere de la implementación en Nucleus RTOS en que se devuelve menos información, ya que no se admite la denominación de objetos y el orden de pausa de la tarea, y la pausa de la tarea en sí misma puede desactivarse.

Una llamada para recuperar información del grupo de eventos en Nucleus RTOS
Prototipo de llamada de servicio:
ESTADO NU_Event_Group_Information (grupo NU_EVENT_GROUP *, CHAR * nombre, UNSIGNED * event_flags, UNSIGNED * task_waiting, NU_TASK ** first_task);

Parámetros:
grupo : un puntero a un bloque de control proporcionado por el usuario para un grupo de indicadores de evento;
nombre : un puntero a la región de 8 caracteres para el nombre del grupo de banderas de eventos, esto también incluye el cero final;
event_flags : puntero a una variable que tomará el valor actual del grupo especificado de banderas de eventos;
task_waiting : un puntero a una variable que tomará el número de tareas suspendidas en este grupo de indicadores de evento;
first_task : un puntero a una variable de tipo NU_TASK , que llevará un puntero a la primera tarea suspendida.

Valor de retorno:
NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_GROUP : puntero no válido a un grupo de banderas de eventos.

Una llamada para recuperar información del grupo de eventos en Nucleus SE
Esta llamada admite la funcionalidad principal de la API Nucleus RTOS.

Prototipo de llamada de servicio:
ESTADO NUSE_Event_Group_Information (grupo NUSE_EVENT_GROUP, U8 * event_flags, U8 * task_waiting, NUSE_TASK * first_task);

Parámetros:
grupo : el índice del grupo de indicadores de eventos sobre los que se solicita información;
event_flags : puntero a una variable que tomará el valor actual del grupo especificado de banderas de eventos;
task_waiting : un puntero a una variable que tomará el número de tareas suspendidas en este grupo de indicadores de evento (no se devuelve nada si la suspensión de la tarea está desactivada);
first_task : un puntero a una variable del tipo NUSE_TASK que tomará el índice de la primera tarea suspendida (no se devuelve nada si la suspensión de la tarea se desactiva).

Valor de retorno:
NUSE_SUCCESS : la llamada se completó correctamente;
NUSE_INVALID_GROUP : índice de grupo de indicadores de eventos no válido.

Implementación de información del grupo de eventos en Nucleus SE
Implementar esta llamada a la API es bastante simple:

*event_flags = NUSE_Event_Group_Data[group]; #if NUSE_BLOCKING_ENABLE *tasks_waiting = NUSE_Event_Group_Blocking_Count[group]; if (NUSE_Event_Group_Blocking_Count[group] != 0) { U8 index; for (index=0; index<NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_EVENT_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == group)) { *first_task = index; break; } } } else { *first_task = 0; } #else *tasks_waiting = 0; *first_task = 0; #endif return NUSE_SUCCESS; 

La función devuelve el valor del grupo de banderas de eventos. Luego, si se activan llamadas de API de bloqueo de tareas, se devuelve el número de tareas pendientes y el índice de la primera de ellas (de lo contrario, estos dos parámetros se establecen en cero).

Obtener el número de grupos de banderas de eventos


Esta llamada de utilidad devuelve el número de grupos de marcadores de eventos en la aplicación. En Nucleus RTOS, este valor cambia con el tiempo, y el valor de retorno muestra el número actual de grupos, mientras que en Nucleus SE este valor se determina durante el ensamblaje y no cambia con el tiempo.

Llamar al contador de grupos de banderas de eventos en Nucleus RTOS
Prototipo de llamada de servicio:
NO FIRMADO NU_Establised_Event_Groups (VOID);

Parámetros:
Están ausentes

Valor de retorno:
El número actual de grupos de marcadores de eventos creados.

Llamar al contador de grupos de banderas de eventos en Nucleus SE
Prototipo de llamada de servicio:
U8 NUSE_Event_Group_Count (nulo);

Parámetros:
Están ausentes

Valor de retorno:
El número de grupos de indicadores de eventos configurados.

Implementación de un contador de grupo de banderas de eventos en Nucleus SE
La implementación de esta llamada API es bastante trivial: se devuelve el valor del símbolo #define NUSE_EVENT_GROUP_NUMBER .

Estructuras de datos


Al igual que todos los demás objetos de Nucleus SE, los grupos de indicadores de eventos usan una o dos matrices de estructuras de datos (ambas se encuentran en RAM), el tamaño de las matrices depende del número de grupos definidos en la configuración.

Recomiendo encarecidamente que el código de la aplicación no utilice el acceso directo a estas estructuras de datos, sino que se refiera a ellas a través de las funciones API proporcionadas. Esto evitará la incompatibilidad con futuras versiones de Nucleus SE y los efectos secundarios no deseados, además de simplificar la transferencia de la aplicación a Nucleus RTOS. Para una mejor comprensión del código de llamada de servicio y la depuración, a continuación se proporciona una descripción detallada de las estructuras de datos.

Datos de RAM


Estos datos tienen la siguiente estructura:
NUSE_Event_Group_Data [] : una matriz de datos del tipo U8 que tiene un registro para cada grupo configurado de banderas; Almacena los datos del indicador de eventos.
NUSE_Event_Group_Blocking_Count [] : una matriz de tipo U8 que contiene un contador de tareas bloqueadas en cada grupo de banderas de eventos. Esta matriz existe solo cuando la funcionalidad de bloqueo en la API está activada.

Estas estructuras de datos se inicializan con ceros en la función NUSE_Init_Event_Group () cuando se inicia Nucleus SE. Uno de los siguientes artículos proporcionará una descripción completa de los procedimientos de inicio de Nucleus SE.

La siguiente es una descripción de estas estructuras de datos en el archivo nuse_init.c :

 RAM U8 NUSE_Event_Group_Data[NUSE_EVENT_GROUP_NUMBER]; #if NUSE_BLOCKING_ENABLE RAM U8 NUSE_Event_Group_Blocking_Count[NUSE_EVENT_GROUP_NUMBER]; #endif 

Datos ROM


Para implementar grupos de indicadores de eventos, no se utilizan datos en ROM.

Tamaño de memoria para grupos de banderas de eventos


Al igual que con todos los objetos del núcleo de Nucleus SE, la cantidad de memoria requerida para los grupos de indicadores de eventos es predecible.

La cantidad de datos en la ROM para todos los grupos de banderas de eventos en la aplicación es 0.

La cantidad de memoria en RAM para todos los grupos de indicadores de eventos con la funcionalidad de bloqueo de API activada es NUSE_EVENT_GROUP_NUMBER * 2 .

De lo contrario, es NUSE_EVENT_GROUP_NUMBER .

Llamadas API no realizadas


No se implementaron tres llamadas API para grupos de indicadores de eventos que se pueden encontrar en Nucleus RTOS en Nucleus SE.

Crear un grupo de banderas de eventos


Esta llamada a la API crea un grupo de banderas de eventos. Nucleus SE no necesita esta llamada porque los grupos de indicadores de eventos se crean estáticamente.

Prototipo de llamada de servicio:
ESTADO NU_Create_Event_Group (grupo NU_EVENT_GROUP *, CHAR * nombre);

Parámetros:

grupo : un puntero a un bloque de control proporcionado por el usuario para un grupo de indicadores de evento; Se utiliza como descriptor para administrar grupos de indicadores de eventos en otras llamadas API
nombre : un puntero al nombre de 8 caracteres del grupo de banderas de eventos con un byte nulo de terminación incluido en esta área.

Valor de retorno:

NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_GROUP : puntero nulo a la unidad de control del grupo de banderas de eventos ( NULL ) o que ya está en uso.

Eliminar un grupo de banderas de eventos


Esta llamada a la API elimina el grupo de marca de evento creado anteriormente. Nucleus SE no necesita esta llamada porque los grupos de indicadores de eventos se crean de forma estática y no se pueden eliminar.

Prototipo de llamada de servicio:

ESTADO NU_Delete_Event_Group (grupo NU_EVENT_GROUP *);

Parámetros:

grupo : un puntero al bloque de control del grupo de banderas de eventos.

Valor de retorno:

NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_GROUP : puntero no válido a un grupo de banderas de eventos.

Indicadores de grupo de banderas de eventos


Esta llamada a la API forma una lista secuencial de punteros a todos los grupos de banderas de eventos en el sistema. Nucleus SE no necesita esta llamada porque los grupos de indicadores de eventos tienen índices simples, no punteros.

Prototipo de llamada de servicio:

UNSIGNED NU_Event_Group_Pointers (NU_EVENT_GROUP * pointer_list, UNSIGNED maximum_pointers);

Parámetros:

pointer_list : un puntero a una matriz de punteros NU_EVENT_GROUP , esta matriz está llena de punteros a grupos de banderas de eventos creados en el sistema;
maximum_pointers : el número máximo de punteros en la matriz.

Valor de retorno:

El número de punteros NU_EVENT_GROUP en la matriz.

Nucleus RTOS Compatible


Al desarrollar Nucleus SE, mi objetivo era asegurar el máximo nivel de compatibilidad de código con Nucleus RTOS. Los grupos de indicadores de eventos no fueron una excepción y, desde el punto de vista del desarrollador, se implementaron casi de la misma manera que en Nucleus RTOS. Hay algunas incompatibilidades que considero válidas, dado que el código final será más comprensible y más eficiente en términos de la cantidad de memoria requerida. De lo contrario, las llamadas a la API Nucleus RTOS se pueden usar casi directamente como llamadas a Nucleus SE.

Identificadores de objetos


En Nucleus RTOS, todos los objetos se describen mediante estructuras de datos (unidades de control) de un tipo específico. Un puntero a esta unidad de control es un identificador para un grupo de banderas de eventos. Decidí que en Nucleus SE, se necesita un enfoque diferente para el uso eficiente de la memoria: todos los objetos del núcleo se describen en varias tablas en RAM y / o ROM. El tamaño de estas tablas está determinado por el número de objetos configurados de cada tipo. El identificador de un objeto particular es el índice en esta tabla. Así que definí NUSE_EVENT_GROUP como el equivalente de U8 , una variable de este tipo (no un puntero) sirve como identificador del grupo de banderas de eventos. Esta ligera incompatibilidad es fácil de manejar si el código se transfiere de Nucleus SE a Nucleus RTOS y viceversa. Por lo general, no se realizan operaciones en identificadores de objetos que no sean mover y almacenar.

Nucleus RTOS también admite nombres de grupos de banderas de eventos. Estos nombres se usan solo para la depuración. Los excluí de Nucleus SE para ahorrar memoria.

El número de banderas en el grupo.


En Nucleus RTOS, los grupos de indicadores de eventos contienen 32 indicadores cada uno, en Nucleus SE reduje su número a ocho, ya que esto es suficiente para aplicaciones simples y ahorra RAM. Nucleus SE puede modificarse fácilmente si se requieren grupos más grandes de banderas de eventos.

Función de absorción de bandera


Nucleus RTOS tiene una función para borrar (absorber) indicadores de eventos después de leerlos. Decidí excluir esta función de Nucleus SE para simplificar el sistema, ya que la absorción (eliminación) de marcas se produce cuando todas las tareas bloqueadas reciben banderas para leer, y esto sería difícil de implementar. Si es necesario, una tarea de lectura de indicadores siempre puede borrarlos usando una llamada API separada.

Llamadas API no realizadas


Nucleus RTOS admite siete llamadas de servicios públicos para trabajar con grupos de indicadores de eventos. De estos, tres no se implementan en Nucleus SE. Los detalles de estos desafíos, así como la decisión de excluirlos de Nucleus SE, se han descrito anteriormente.
El siguiente artículo analizará los semáforos.

Sobre el autor: Colin 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.

Source: https://habr.com/ru/post/es428890/


All Articles