Toda la verdad sobre RTOS. Artículo # 11. Tareas: configuración e introducción a la API



El concepto de un problema se introdujo en artículos anteriores. De hecho, una tarea es simplemente un conjunto de valores que se pueden cargar en los registros del procesador (para que la tarea se realice) o se pueden almacenar en un estado listo para el cambio contextual a la tarea en el futuro. Muy a menudo, una tarea tiene su propia pila.

Por supuesto, cuando se usa el planificador Run to Completion (RTC), no se usa el cambio de contexto, y la tarea puede considerarse solo el valor del contador del programa (punto de entrada de código).

La definición de la tarea no incluye el código en sí. La tarea debe ejecutar el código, pero no le pertenece. Las tareas pueden tener funciones comunes. Además, se puede compartir todo el código para varias tareas. El código general casi siempre debe escribirse de acuerdo con los requisitos reentrantes. La mayoría de los compiladores manejan fácilmente dicho código, pero se debe tener cuidado con las funciones de la biblioteca, ya que pueden no ser adecuadas para aplicaciones multitarea.

Dicha definición dicta ciertas reglas que deben seguirse al desarrollar estructuras de datos de tareas y funciones API descritas en este artículo. Revisaré la configuración de tareas en Nucleus SE y comenzaré una descripción detallada de las llamadas de servicio (llamadas API) que se aplican a las tareas en Nucleus SE y Nucleus RTOS.

Artículos anteriores de la serie:
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.

Configuración de la tarea


Numero de tareas


En Nucleus SE, la configuración de la tarea está impulsada principalmente por las directivas #define en nuse_config.h . El parámetro clave NUSE_TASK_NUMBER determina el número de tareas que se pueden configurar en la aplicación. El valor predeterminado es 1 (es decir, una tarea durante la ejecución), y el valor máximo del parámetro es 16. Un valor incorrecto generará un error de compilación, que se generará al ingresar nuse_config_chech.h (se incluye en nuse_config.c , lo que significa compilado con este módulo), se activará la directiva #error . Este parámetro se usa para determinar las estructuras de datos; su tamaño depende de su valor.

En Nucleus SE, excepto cuando se usa el planificador RTC, es esencial que al menos una tarea esté siempre lista para su ejecución. Al utilizar el planificador prioritario, debe asegurarse de que la tarea con la prioridad más baja nunca estará en estado suspendido; dicha tarea debe considerarse una "tarea en segundo plano".

A diferencia de otros núcleos en tiempo real, Nucleus SE no utiliza "tareas del sistema", lo que significa que las 16 tareas están disponibles para el código de aplicación del usuario o Middleware.

Parámetros API


Cada función API (llamada de utilidad) en Nucleus SE se activa mediante la directiva #define en nuse_config.h . Para las tareas, estos parámetros son:

  • NUSE_TASK_SUSPEND
  • NUSE_TASK_RESUME
  • NUSE_TASK_SLEEP
  • NUSE_TASK_RELINQUISH
  • NUSE_TASK_CURRENT
  • NUSE_TASK_CHECK_STACK
  • NUSE_TASK_RESET
  • NUSE_TASK_INFORMATION
  • NUSE_TASK_COUNT

Por defecto, todos los parámetros anteriores están configurados en FALSO , desactivando así cada llamada de servicio y evitando la inclusión de cualquier código que los implemente. Para configurar tareas para la aplicación, debe seleccionar las llamadas API necesarias y establecer los caracteres correspondientes en VERDADERO .

El siguiente es un fragmento del archivo predeterminado nuse_config.h .



Si su código usa una llamada API que no ha sido activada, aparecerá un error durante el enlace porque el código de implementación no se incluyó en la aplicación.

Parámetros Funcionales


Nucleus SE puede agregar algunas funciones de tareas. Y nuevamente, los parámetros necesarios están en el archivo nuse_config.h :

NUSE_SUSPEND_ENABLE te permite pausar tareas. Si no se selecciona esta opción, todas las tareas esperan constantemente la programación. Se requiere la activación de este parámetro cuando se usa el planificador prioritario.

NUSE_BLOCKING_ENABLE le permite suspender tareas a llamadas de API de múltiples funciones. Si esta opción está activada, NUSE_SUSPEND_ENABLE también debe estar activada.

NUSE_INITIAL_TASK_STATE_SUPPORT le permite establecer el estado inicial de la tarea. Si no se selecciona esta opción, todas las tareas se agregarán al planificador inmediatamente después de la creación.

Llamadas de tareas de utilidad


Nucleus RTOS admite 16 llamadas de servicio (API) para trabajar con tareas que proporcionan la siguiente funcionalidad:

Descripción FuncionalNúcleo RTOSNúcleo SE
Pausa una tareaNU_Suspend_Task ()NUSE_Task_Suspend ()
Reanudar tareaNU_Resume_Task ()NUSE_Task_Resume ()
Pausa una tarea para un específico
el periodo
NU_Sleep ()NUSE_Task_Sleep ()
Lanzamiento de control de CPUNU_Relinquish ()NUSE_Task_Relinquish ()
Obtener el ID de la tarea actualNU_Current_Task_Pointer ()NUSE_Task_Current ()
Comprobación del tamaño de pila disponibleNU_Check_Stack ()NUSE_Task_Check_Stack ()
Devolver tarea a no utilizada
estado (restablecer)
NU_Reset_Task ()NUSE_Task_Reset ()
Proporcionar información sobre una tarea específica.NU_Task_Information ()NUSE_Task_Information ()
Obtener el contador configurado
tareas (en este momento) en la aplicación
NU_Established_Tasks ()NUSE_Task_Count ()
Agregar una nueva tarea a la aplicación (creación)NU_Create_Task ()No implementado
Eliminar una tarea de la aplicaciónNU_Delete_Task ()No implementado
Devolver punteros a todas las tareas
en la aplicación
NU_Task_Pointers ()No implementado
Cambiar algoritmo de extrusiónNU_Change_Preemption ()No implementado
Cambiar prioridad de tareaNU_Change_Priority ()No implementado
Cambiar el tiempo cuántico de una tareaNU_Change_Time_Slice ()No implementado
Tarea completadaNU_Terminate_Task ()No implementado

La implementación de cada una de las llamadas de servicio anteriores se analiza en detalle a continuación, así como en los siguientes artículos sobre RTOS.

Servicios de gestión de tareas.


Operaciones básicas con tareas: pausar una tarea por un tiempo indefinido, reanudar, pausar una tarea por un tiempo específico, liberar el procesador. Nucleus RTOS y Nucleus SE proporcionan cuatro llamadas API básicas para realizar estas operaciones, que describiré a continuación.

Pausa una tarea


Nucleus PLUS proporciona una llamada API simple que le permite pausar una tarea específica indefinidamente. Nucleus SE tiene una llamada de oficina con una funcionalidad similar.

Suspender una tarea en Nucleus RTOS
Prototipo de llamada de servicio:
ESTADO NU_Suspend_Task (tarea NU_TASK *);

Parámetros:
tarea : un puntero a la unidad de control de la tarea en pausa (que puede ser actual, y su ID se puede obtener usando NU_Current_Task_Pointer () , más en el siguiente artículo).

Valor de retorno:
NU_SUCCESS : la llamada se completó correctamente;
NU_INVALID_TASK : puntero no válido a la tarea;
NU_INVALID_SUSPEND : la tarea especificada tiene el estado NU_FINISHED o NU_TERMINATED .

Pausa de tarea de desafío en Nucleus SE
Esta llamada a la API admite la funcionalidad principal de la API Nucleus PLUS.

Prototipo de llamada de servicio:
ESTADO NUSE_Task_Suspend (tarea NUSE_TASK);

Parámetros:
tarea : el índice (ID) de la tarea en pausa (que puede ser actual, y su ID se puede obtener usando NUSE_Task_Current () - más en el próximo artículo).

Valor de retorno:
NUSE_SUCCESS : la llamada se completó correctamente;
NUSE_INVALID_TASK : índice de tarea no válido.

Implementar la suspensión de una tarea en Nucleus SE
La funcionalidad principal de la función API es bastante simple:



De hecho, en esta implementación, la función del planificador NUSE_Suspend_Task () se llama con el parámetro "parada incondicional" ( NUSE_PURE_SUSPEND ). Esta función llama al planificador si la tarea pausada está en curso.

Reanudar tarea


Nucleus RTOS proporciona una llamada API simple que le permite reanudar una tarea que anteriormente estaba pausada indefinidamente. Nucleus SE tiene una llamada de oficina con una funcionalidad similar.

Desafía la tarea de reanudar en Nucleus RTOS
Prototipo de llamada de servicio:
ESTADO NU_Resume_Task (tarea NU_TASK *);

Parámetros:
tarea : un puntero a la unidad de control de la tarea renovada.

Valor de retorno:
NUSE_SUCCESS : la llamada se completó correctamente;
NUSE_INVALID_TASK : puntero no válido a la tarea;
NUSE_INVALID_RESUME : la tarea no se ha suspendido incondicionalmente.

Desafío de reanudar tareas en Nucleus SE
Esta llamada a la API admite la funcionalidad principal de la API Nucleus RTOS.

Prototipo de llamada de servicio:
ESTADO NUSE_Task_Resume (tarea NUSE_TASK);

Parámetros:
tarea : índice (ID) de la tarea renovada.

Valor de retorno:
NUSE_SUCCESS : la llamada se completó correctamente;
NUSE_INVALID_TASK : índice de tarea no válido;
NUSE_INVALID_RESUME : la tarea no se ha suspendido incondicionalmente.

Implementación de tareas de currículum en Nucleus SE
La funcionalidad principal de la función API es bastante simple:



De hecho, la función del planificador NUSE_Wake_Task () se llama en esta implementación. Esta función llama al planificador si se utiliza el planificador prioritario y la tarea renovada tiene una prioridad más alta que la tarea actual.

Pausar una tarea por un período de tiempo específico


Nucleus RTOS proporciona una llamada API simple para pausar la tarea actual durante un período de tiempo específico. Nucleus SE tiene una llamada de oficina con una funcionalidad similar.

Llame a suspender tareas por un período específico de tiempo Nucleus RTOS
Prototipo de llamada de servicio:
ANULAR NU_Sleep (marcas NO FIRMADAS);

Parámetros:
ticks : período de tiempo durante el cual la tarea debe suspenderse (en tics de reloj en tiempo real).

Valor de retorno:
No

Desafiar una pausa de tarea por un período de tiempo específico Nucleus SE
Esta llamada a la API admite la funcionalidad principal de la API Nucleus RTOS.

Prototipo de llamada de servicio:
anular NUSE_Task_Sleep (tics U16);

Parámetros:
ticks : período de tiempo durante el cual la tarea debe suspenderse (en tics de reloj en tiempo real).

Valor de retorno:
No

Implementar una suspensión de una tarea por un período de tiempo específico en Nucleus SE
La funcionalidad principal de la función API es bastante simple:



Este código carga el valor de retraso en el parámetro de tarea actual en NUSE_Task_Timeout_Counter [] . Después de eso, la tarea se detiene usando NUSE_Suspend_Task () con el período de tiempo de suspensión ( NUSE_SLEEP_SUSPEND ).

El valor de tiempo de espera lo utiliza el controlador de interrupción de reloj en tiempo real. El código se muestra a continuación y se analizará con más detalle en un artículo futuro.



Lanzamiento de la CPU


Nucleus PLUS proporciona una llamada API simple para permitir la transferencia del control del procesador a cualquiera de las tareas listas para ejecutar con la misma prioridad basada en el algoritmo Round Robin. Nucleus SE tiene una llamada de oficina con una funcionalidad muy similar. Sin embargo, no se puede usar con el Programador prioritario, ya que no se admiten varias tareas con la misma prioridad. Intentar utilizar esta llamada API con el planificador prioritario dará como resultado un error. Una llamada de utilidad funciona con los programadores Round Robin y Time Slice; con el programador Run To Completion, esta llamada API es ineficiente.

Llamada de lanzamiento del procesador Nucleus RTOS
Esta llamada a la API admite la funcionalidad principal de la API Nucleus PLUS.

Prototipo de llamada de servicio:
VOID NU_Relinquish (VOID);

Parámetros:
Están ausentes

Valor de retorno:
No

Llamada de lanzamiento del procesador Nucleus SE
Esta llamada a la API admite la funcionalidad principal de la API Nucleus PLUS.

Prototipo de llamada de servicio:
vacío NUSE_Task_Relinquish (vacío);

Parámetros:
Están ausentes

Valor de retorno:
No

Implementación de lanzamiento del procesador Nucleus SE
La funcionalidad principal de la función API:



Esencialmente, esta implementación llama a la función del planificador NUSE_Reschedule () . Esta función simplemente le dice al planificador que complete la siguiente tarea.

Los siguientes dos artículos continuarán revisando las llamadas a la utilidad RTOS relacionadas con la tarea utilizando los ejemplos Nucleus RTOS y Nucleus SE.

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.

Acerca de la traducción: esta serie de artículos parecía interesante porque, a pesar de los enfoques desactualizados descritos en algunos lugares, el autor, en un lenguaje muy comprensible, presenta al lector poco capacitado las características del sistema operativo en tiempo real. Yo mismo pertenezco al equipo de creadores del RTOS ruso , que pretendemos liberar , y espero que el ciclo sea útil para los desarrolladores novatos.

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


All Articles