Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Industrial Internet of Things >> Incrustado

Colas en Nucleus SE: Introducción y llamadas de servicio principales

Colas en Nucleus SE: Introducción y llamadas de servicio principales
Ver la serie RTOS Revealed

Las colas (queues) se introdujeron en un artículo anterior. Proporcionan un medio más flexible de pasar mensajes simples entre tareas que los buzones.

Uso de Colas

En Nucleus SE, las colas se configuran en tiempo de compilación. Se pueden definir un máximo de 16 colas para una aplicación. Si no se configuran colas, el RTOS omite todas las estructuras de datos y código API relacionados con colas, manteniendo el binario ligero.

Una cola es simplemente un array de ranuras de almacenamiento, cada una lo suficientemente grande para contener un solo elemento de datos ADDR. El acceso está sincronizado para que múltiples tareas puedan encolar y desencolar mensajes de forma segura. Las tareas pueden escribir en una cola hasta que todas las ranuras estén llenas, y leer de una cola en orden first-in, first-out (FIFO). Los intentos de enviar a una cola llena o recibir de una vacía disparan un error o una suspensión de tarea, dependiendo de las opciones de API seleccionadas y la configuración de Nucleus SE.

Colas vs. Pipes

Nucleus SE también soporta pipes, que difieren principalmente en el tamaño del mensaje. Mientras una cola transmite un solo ADDR (típicamente un puntero), un pipe transporta un bloque de bytes de longitud variable; el tamaño del bloque se fija en tiempo de configuración. Los pipes se discutirán en profundidad en un artículo futuro.

Configuración de Colas

Número de Colas

La configuración de colas se controla mediante sentencias #define en nuse_config.h. El ajuste clave es NUSE_QUEUE_NUMBER, que determina cuántas colas están habilitadas. El valor por defecto es 0 (sin colas). Puede establecerlo en cualquier valor de 0 a 16; un valor fuera de rango dispara un #error en tiempo de compilación producido por nuse_config_check.h.

Establecer NUSE_QUEUE_NUMBER a un valor no cero activa el subsistema de colas, asignando las estructuras de datos necesarias y habilitando las llamadas API asociadas.

Habilitación de API

Cada función API de cola tiene un símbolo #define de habilitación en nuse_config.h:

NUSE_QUEUE_SEND NUSE_QUEUE_RECEIVE NUSE_QUEUE_JAM NUSE_QUEUE_RESET NUSE_QUEUE_INFORMATION NUSE_QUEUE_COUNT 

Por defecto todas están en FALSE, deshabilitando las llamadas de servicio correspondientes. Para usar una API particular, establezca su símbolo en TRUE. Habilitar una API sin colas configuradas (excepto NUSE_Queue_Count(), que siempre está permitido) resulta en error en tiempo de compilación. Si una API se llama en código que no ha sido habilitado, ocurre un error en tiempo de enlace porque la implementación se omite.

#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 

Llamadas de Servicio de Cola

Nucleus RTOS ofrece diez llamadas de servicio relacionadas con colas, de las cuales seis están implementadas en Nucleus SE. Proporcionan la siguiente funcionalidad:

La implementación de cada API se discute en detalle en las secciones siguientes.

Servicios de Escritura y Lectura

Las operaciones centrales en una cola son escritura (envío) y lectura (recepción). Escribir al frente de una cola se llama "jam". Nucleus RTOS y Nucleus SE cada uno exponen tres llamadas API básicas para estas acciones.

Escritura en una Cola

La API RTOS NU_Send_To_Queue() es altamente flexible, permitiendo suspensión indefinida o timeout si la cola está llena. Nucleus SE ofrece la misma función pero la suspensión es opcional y los timeouts no se soportan. RTOS también soporta una operación broadcast, no disponible en SE.

API RTOS: NU_Send_To_Queue()

Prototipo:

STATUS NU_Send_To_Queue(NU_QUEUE *queue, VOID *message, UNSIGNED size, UNSIGNED suspend); 

Parámetros:

Códigos de retorno incluyen NU_SUCCESS, NU_QUEUE_FULL, NU_TIMEOUT y varios códigos de error para punteros inválidos o estado de cola.

API SE: NUSE_Queue_Send()

Prototipo:

STATUS NUSE_Queue_Send(NUSE_QUEUE queue, ADDR *message, U8 suspend); 

Parámetros:

Los valores de retorno reflejan la función RTOS pero reflejan el comportamiento de bloqueo limitado de SE.

Resumen de Implementación

Cuando el bloqueo está deshabilitado, la rutina simplemente comprueba espacio y o bien escribe el valor o retorna NUSE_QUEUE_FULL. Con bloqueo habilitado, la función hace un bucle, suspendiendo la tarea si la cola está llena hasta que haya espacio disponible o ocurra un reset. La implementación usa NUSE_Queue_Blocking_Count para rastrear tareas bloqueadas y NUSE_Task_Blocking_Return para reanudarlas una vez que se abre una ranura.

if (NUSE_Queue_Items[queue] == NUSE_Queue_Size[queue]) { return_value = NUSE_QUEUE_FULL; } else { NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] = *message; if (NUSE_Queue_Head[queue] == NUSE_Queue_Size[queue]) NUSE_Queue_Head[queue] = 0; NUSE_Queue_Items[queue]++; return_value = NUSE_SUCCESS; } 
do { if (NUSE_Queue_Items[queue] == NUSE_Queue_Size[queue]) { if (suspend == NUSE_NO_SUSPEND) { return_value = NUSE_QUEUE_FULL; } else { NUSE_Queue_Blocking_Count[queue]++; NUSE_Suspend_Task(NUSE_Task_Active, (queue << 4) | NUSE_QUEUE_SUSPEND); return_value = NUSE_Task_Blocking_Return[NUSE_Task_Active]; if (return_value != NUSE_SUCCESS) suspend = NUSE_NO_SUSPEND; } } else { NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] = *message; if (NUSE_Queue_Head[queue] == NUSE_Queue_Size[queue]) NUSE_Queue_Head[queue] = 0; NUSE_Queue_Items[queue]++; if (NUSE_Queue_Blocking_Count[queue] != 0) { U8 index; NUSE_Queue_Blocking_Count[queue]--; for (index = 0; index < NUSE_TASK_NUMBER; index++) { if ((LONIB(NUSE_Task_Status[index]) == NUSE_QUEUE_SUSPEND) && (HINIB(NUSE_Task_Status[index]) == queue)) { NUSE_Task_Blocking_Return[index] = NUSE_SUCCESS; NUSE_Wake_Task(index); break; } } } return_value = NUSE_SUCCESS; suspend = NUSE_NO_SUSPEND; } } while (suspend == NUSE_SUSPEND); 

El bucle continúa hasta que un mensaje se encola con éxito o la tarea es desbloqueada por un reset. La implementación asegura acceso thread-safe y despertar eficiente de consumidores bloqueados.

Incrustado

  1. Servicios de Rectificado de Superficies de Precisión: Proceso Experto y Calidad
  2. Cerraduras de leva (cam locks) explicadas: cómo aseguran gabinetes discretamente
  3. ¿Qué Son los Tornillos de Ojo (Eye Screws)? Guía Profesional de Diseño y Usos
  4. Entendiendo los ojales (grommets): tipos, usos y cómo protegen sus equipos
  5. Acero inoxidable explicado: composición, producción e impacto global
  6. Buzones en Nucleus SE: Guía práctica de configuración y uso
  7. Semaforos en Nucleus RTOS: Servicios de utilidad y estructuras de datos
  8. Semaforos en Nucleus SE: Visión general, configuración y API esenciales
  9. Dominando grupos de banderas de evento: Servicios de utilidad y estructuras de datos en Nucleus RTOS/SE
  10. Grupos de banderas de evento en Nucleus SE: Guía introductoria de configuración y uso de API
  11. Fundamentos de C#: Entrada y salida esenciales