Colas:introducción y servicios básicos
Ver la serie RTOS Revealed
Las colas se introdujeron en un artículo anterior. Proporcionan un medio más flexible para pasar mensajes simples entre tareas que los buzones de correo.
Uso de colas
En Nucleus SE, las colas se configuran en el momento de la compilación. Puede haber un máximo de 16 colas configuradas para una aplicación. Si no se configuran colas, la aplicación no incluye estructuras de datos ni códigos de llamadas de servicio pertenecientes a las colas.
Una cola es simplemente un conjunto de ubicaciones de almacenamiento, cada una lo suficientemente grande como para contener un solo elemento de datos de tipo ADDR , cuyo acceso está controlado para que pueda ser utilizado de forma segura por múltiples tareas. Las tareas pueden escribir en una cola repetidamente hasta que todas las ubicaciones estén llenas. Las tareas pueden leer desde una cola y los datos normalmente se reciben según el principio de primero en entrar, primero en salir (FIFO). Intentar enviar a una cola llena o leer desde una vacía puede resultar en un error o la suspensión de la tarea, según las opciones seleccionadas en la llamada API y la configuración de Nucleus SE.
Colas y tuberías
Nucleus SE también admite tuberías, que también se presentaron en un artículo anterior y se tratan en detalle en un artículo futuro. La principal diferencia entre colas y canalizaciones es el tamaño del mensaje. Las colas transportan mensajes que comprenden una única ADDR - estos serían comúnmente punteros. Una tubería transporta mensajes que tienen una longitud arbitraria de bytes; el tamaño se fija para cada tubería en la aplicación y se establece en el momento de la configuración.
Configuración de colas
Número de colas
Como ocurre con la mayoría de los aspectos de Nucleus SE, #define controla principalmente la configuración de las colas declaraciones en nuse_config.h . La configuración de la clave es NUSE_QUEUE_NUMBER , que determina cuántas colas se configuran para la aplicación. La configuración predeterminada es 0 (es decir, no hay colas en uso) y puede establecerlo en cualquier valor hasta 16. Un valor erróneo resultará en un error de tiempo de compilación, que es generado por una prueba en nuse_config_check.h (esto está incluido en nuse_config.c y por lo tanto compilado con este módulo) resultando en un #error declaración que se está compilando.
La elección de un valor distinto de cero es la "habilitación maestra" para las colas. Esto da como resultado que algunas estructuras de datos se definan y dimensionen en consecuencia, de las cuales hablaremos más en el próximo artículo. También activa la configuración de habilitación de API.
API habilitadas
Cada función de API (llamada de servicio) en Nucleus SE tiene un #define habilitante símbolo en nuse_config.h . Para las colas, estos son:
NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_COUNT
De forma predeterminada, todos estos están configurados como FALSO . , deshabilitando así cada llamada de servicio e inhibiendo la inclusión de cualquier código de implementación. Para configurar las colas para una aplicación, debe seleccionar las llamadas a la API que desea utilizar y establecer sus símbolos de habilitación en TRUE .
Aquí hay un extracto del archivo nuse_config.h predeterminado.
#define NUSE_QUEUE_NUMBER 0 / * Número de colas en el
Sistema - 0-16 * /
/ * Habilitadores de llamadas de servicio * /
#define NUSE_QUEUE_SEND FALSE
#define NUSE_QUEUE_RECEIVE FALSE
#define NUSE_QUEUE_JAM FALSE
#define NUSE_QUEUE_RESET FALSE
#define NUSE_QUEUE_INFORMATION FALSE
#define NUSE_QUEUE_COUNT FALSE
Se producirá un error de tiempo de compilación si se habilita una función de API de cola y no se configuran colas (excepto NUSE_Queue_Count () que siempre está permitido). Si su código utiliza una llamada a la API, que no se ha habilitado, se producirá un error de tiempo de enlace, ya que no se habrá incluido ningún código de implementación en la aplicación.
Llamadas de servicio en cola
Nucleus RTOS admite diez llamadas de servicio que pertenecen a las colas, que proporcionan la siguiente funcionalidad:
-
Envía un mensaje a una cola. Implementado por NUSE_Queue_Send () en Nucleus SE.
-
Reciba un mensaje de una cola. Implementado por NUSE_Queue_Receive () en Nucleus SE.
-
Envía un mensaje al principio de una cola. Implementado por NUSE_Queue_Jam () en Nucleus SE.
-
Restaura una cola al estado no utilizado, sin tareas suspendidas (restablecer). Implementado por NUSE_Queue_Reset () en Nucleus SE.
-
Proporciona información sobre una cola especificada. Implementado por NUSE_Queue_Information () en Nucleus SE.
-
Devuelve un recuento de cuántas colas están (actualmente) configuradas para la aplicación. Implementado por NUSE_Queue_Count () en Nucleus SE.
-
Agregar una nueva cola a la aplicación (crear). No implementado en Nucleus SE.
-
Elimina una cola de la aplicación (eliminar). No implementado en Nucleus SE.
-
Devuelve punteros a todas las colas (actualmente) en la aplicación. No implementado en Nucleus SE.
-
Envía un mensaje a todas las tareas que están suspendidas en una cola (difusión). No implementado en Nucleus SE.
La implementación de cada una de estas llamadas de servicio se examina en detalle.
Servicios de escritura y lectura en cola
Las operaciones fundamentales, que se pueden realizar en una cola, son escribir datos en ella, lo que a veces se denomina envío - y leer datos de él, lo que también se denomina recibir . También es posible escribir datos al principio de una cola, lo que también se denomina atasco . Nucleus RTOS y Nucleus SE proporcionan cada uno tres llamadas API básicas para estas operaciones, que se discutirán aquí.
Escribir en una cola
La llamada a la API Nucleus RTOS para escribir en una cola es muy flexible, lo que le permite suspender indefinidamente, o con un tiempo de espera, si la operación no se puede completar de inmediato; es decir, intenta escribir en una cola completa. Nucleus SE proporciona el mismo servicio, excepto que la suspensión de tareas es opcional y el tiempo de espera no está implementado.
Nucleus RTOS también ofrece la posibilidad de transmitir a una cola, pero Nucleus SE no lo admite. Se describe en API no implementadas en el siguiente artículo.
Llamada a la API Nucleus RTOS para enviar a una cola
Prototipo de llamada de servicio:
ESTADO NU_Send_To_Queue (cola NU_QUEUE *, mensaje VOID *,
tamaño SIN FIRMAR, suspender SIN FIRMAR);
Parámetros:
cola - puntero al bloque de control de cola proporcionado por el usuario
mensaje - un puntero al mensaje que se va a enviar
tamaño - el número de SIN FIRMAR elementos de datos en el mensaje. Si la cola admite mensajes de longitud variable, este parámetro debe ser igual o menor que el tamaño del mensaje admitido por la cola. Si la cola admite mensajes de tamaño fijo, este parámetro debe ser exactamente el mismo que el tamaño de mensaje admitido por la cola.
suspender - especificación para la suspensión de tareas; puede ser NU_NO_SUSPEND o NU_SUSPEND o un valor de tiempo de espera
Devoluciones:
NU_SUCCESS - la llamada se completó con éxito
NU_INVALID_QUEUE - el puntero de la cola no es válido
NU_INVALID_POINTER - el puntero del mensaje es NULL
NU_INVALID_SIZE - el tamaño del mensaje es incompatible con el tamaño del mensaje admitido por la cola
NU_INVALID_SUSPEND - se intentó suspender desde un hilo que no es de tarea
NU_QUEUE_FULL - la cola está llena y no se especificó la suspensión
NU_TIMEOUT - la cola todavía está llena incluso después de suspender por el valor de tiempo de espera especificado
NU_QUEUE_DELETED - la cola se eliminó mientras la tarea estaba suspendida
NU_QUEUE_RESET - la cola se restableció mientras la tarea estaba suspendida
Llamada a la API de Nucleus SE para enviar a una cola
Esta llamada a la API admite la funcionalidad clave de la API Nucleus RTOS.
Prototipo de llamada de servicio:
STATUS NUSE_Queue_Send (cola NUSE_QUEUE, mensaje ADDR *,
suspensión U8);
Parámetros:
cola - el índice (ID) de la cola que se utilizará
mensaje - un puntero al mensaje que se va a enviar, que es una única variable de tipo ADDR
suspender - especificación para la suspensión de tareas; puede ser NUSE_NO_SUSPEND o NUSE_SUSPEND
Devoluciones:
NUSE_SUCCESS - la llamada se completó con éxito
NUSE_INVALID_QUEUE - el índice de la cola no es válido
NUSE_INVALID_POINTER - el puntero del mensaje es NULL
NUSE_INVALID_SUSPEND - se intentó suspender desde un hilo que no es de tarea o cuando el bloqueo de llamadas a la API no estaba habilitado
NUSE_QUEUE_FULL - la cola está llena y no se especificó la suspensión
NUSE_QUEUE_WAS_RESET - la cola se restableció mientras la tarea estaba suspendida
Implementación de Nucleus SE de Queue ASend
La mayor parte del código de NUSE_Queue_Send () La función API, después de la verificación de parámetros, se selecciona mediante compilación condicional, dependiendo de si está habilitada la compatibilidad con el bloqueo (suspensión de tareas) de las llamadas a la API. Veremos las dos variantes por separado aquí.
Si el bloqueo no está habilitado, el código para esta llamada a la API es bastante simple:
if (NUSE_Queue_Items [cola] ==NUSE_Queue_Size [cola]) / * cola llena * / {return_value =NUSE_QUEUE_FULL;} else / * elemento de cola disponible * / {NUSE_Queue_Data [cola] [NUSE_Queue_Head =*mensaje; if (NUSE_Queue_Head [cola] ==NUSE_Queue_Size [cola]) {NUSE_Queue_Head [cola] =0; } NUSE_Queue_Items [cola] ++; return_value =NUSE_SUCCESS;}
La función simplemente verifica que haya espacio en la cola y usa NUSE_Queue_Head [] index para almacenar el mensaje en el área de datos de la cola.
Cuando el bloqueo está habilitado, el código se vuelve más complejo:
hacer {if (NUSE_Queue_Items [cola] ==NUSE_Queue_Size [cola]) / * cola llena * / {if (suspender ==NUSE_NO_SUSPEND) {return_value =NUSE_QUEUE_FULL; } else {/ * bloquear tarea * / NUSE_Queue_Blocking_Count [cola] ++; NUSE_Suspend_Task (NUSE_Task_Active, (cola <<4) | NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; if (return_value! =NUSE_SUCCESS) {suspender =NUSE_NO_SUSPEND; }}} else {/ * elemento de cola disponible * / NUSE_Queue_Data [cola] [NUSE_Queue_Head [cola] ++] =* mensaje; if (NUSE_Queue_Head [cola] ==NUSE_Queue_Size [cola]) {NUSE_Queue_Head [cola] =0; } NUSE_Queue_Items [cola] ++; if (NUSE_Queue_Blocking_Count [cola]! =0) {índice U8; / * comprobar si una tarea está bloqueada en esta cola * / NUSE_Queue_Blocking_Count [cola] -; for (index =0; indexAlguna explicación del código puede ser útil:
El código está encerrado en do… while bucle, que continúa mientras el parámetro suspender tiene el valor NUSE_SUSPEND .
Si la cola está llena y suspender está configurado en NUSE_NO_SUSPEND , la llamada a la API finaliza con NUSE_QUEUE_FULL . Si la suspensión se estableció en NUSE_SUSPEND , la tarea está suspendida. Al regresar (es decir, cuando se despierta la tarea), si el valor de retorno es NUSE_SUCCESS , lo que indica que la tarea se despertó porque se había leído un mensaje (a diferencia de un reinicio de la cola), el código vuelve a la parte superior.
Si la cola no está llena, el mensaje proporcionado se almacena mediante NUSE_Queue_Head [] index para almacenar el mensaje en el área de datos de la cola. Se comprueba si hay tareas suspendidas (esperando recibir) en la cola. Si hay tareas esperando, se despierta la primera. El suspender la variable está establecida en NUSE_NO_SUSPEND y la llamada a la API finaliza con NUSE_SUCCESS .
La plataforma de código abierto apunta a IoT con Linux incorporado Controladores de dispositivo Linux integrados:escritura de un controlador de dispositivo del kernel
Incrustado
- Introducción a los bloqueos de levas y cómo funcionan
- Introducción a los tornillos de ojo y cómo funcionan
- Introducción a los ojales y cómo funcionan
- Introducción al acero inoxidable y cómo se fabrica
- Entrada y salida básica de C#
- Buzones de correo:introducción y servicios básicos
- Semáforos:servicios públicos y estructuras de datos
- Semáforos:introducción y servicios básicos
- Grupos de indicadores de eventos:servicios públicos y estructuras de datos
- Grupos de indicadores de eventos:introducción y servicios básicos
- Servicios de rectificado de superficies:proceso y precisión