Queues in Nucleus SE: Introductie en Kern-Service-Calls
Bekijk de RTOS Revealed serie
Queues werden in een eerder artikel geïntroduceerd. Ze bieden een flexibeler middel om simpele berichten tussen taken te passeren dan mailboxes.
Queues Gebruiken
In Nucleus SE worden queues geconfigureerd op build-tijd. Maximaal 16 queues mogen voor een applicatie gedefinieerd worden. Als er geen queues geconfigureerd zijn, laat de RTOS alle queue-gerelateerde datastructuren en API-code weg, wat de binary lean houdt.
Een queue is simpelweg een array van opslag-slots, elk groot genoeg om een enkele ADDR data-item te bevatten. Toegang is gesynchroniseerd zodat meerdere taken veilig berichten kunnen enqueuen en dequeuen. Taken kunnen naar een queue schrijven totdat alle slots vol zijn, en van een queue lezen in first-in, first-out (FIFO) volgorde. Pogingen om naar een volle queue te sturen of van een lege te ontvangen triggeren een error of een task-suspensie, afhankelijk van de geselecteerde API-opties en de Nucleus SE-configuratie.
Queues vs. Pipes
Nucleus SE ondersteunt ook pipes, wat voornamelijk verschilt in berichtgrootte. Terwijl een queue een enkel ADDR (typisch een pointer) overbrengt, draagt een pipe een variable-length blok bytes; de blok-grootte is fixed op configuratietijd. Pipes worden diepgaand besproken in een toekomstig artikel.
Queues Configureren
Aantal Queues
Queue-configuratie wordt gecontroleerd door #define statements in nuse_config.h. De sleutelinstelling is NUSE_QUEUE_NUMBER, wat bepaalt hoeveel queues ingeschakeld zijn. De standaard is 0 (geen queues). U kunt het instellen op elke waarde van 0 tot 16; een out-of-range waarde triggert een compile-time #error geproduceerd door nuse_config_check.h.
Het instellen van NUSE_QUEUE_NUMBER op een non-zero waarde activeert het queue-subsysteem, allocerend de benodigde datastructuren en de geassocieerde API-calls enablend.
API Enables
Elke queue API-functie heeft een enabling #define symbool in nuse_config.h:
NUSE_QUEUE_SEND NUSE_QUEUE_RECEIVE NUSE_QUEUE_JAM NUSE_QUEUE_RESET NUSE_QUEUE_INFORMATION NUSE_QUEUE_COUNT Standaard zijn alle ingesteld op FALSE, wat de corresponderende service-calls uitschakelt. Om een bepaalde API te gebruiken, stel het symbool in op TRUE. Een API inschakelen terwijl geen queues geconfigureerd zijn (behalve NUSE_Queue_Count(), wat altijd toegestaan is) resulteert in een compile-time error. Als een API aangeroepen wordt in code die niet ingeschakeld is, treedt een link-time error op omdat de implementatie weggelaten is.
#define NUSE_QUEUE_NUMBER 0 /* Aantal queues in het systeem – 0‑16 */ /* Service call enablers */ #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 Queue Service Calls
Nucleus RTOS biedt tien queue-gerelateerde service-calls, waarvan zes geïmplementeerd in Nucleus SE. Ze bieden de volgende functionaliteit:
- Een bericht sturen – NUSE_Queue_Send()
- Een bericht ontvangen – NUSE_Queue_Receive()
- Een bericht naar de front jammen – NUSE_Queue_Jam()
- Een queue resetten – NUSE_Queue_Reset()
- Queue-informatie opvragen – NUSE_Queue_Information()
- Het aantal geconfigureerde queues verkrijgen – NUSE_Queue_Count()
- Overige calls (creëren, verwijderen, enumereren, broadcast) zijn niet beschikbaar in Nucleus SE.
De implementatie van elke API wordt in detail besproken in de volgende secties.
Schrijf- en Lees-Services
De kernoperaties op een queue zijn schrijven (sturen) en lezen (ontvangen). Schrijven naar de front van een queue heet jammen. Nucleus RTOS en Nucleus SE exposeren elk drie basis-API-calls voor deze acties.
Naar een Queue Schrijven
De RTOS-API NU_Send_To_Queue() is hoogst flexibel, wat indefinite suspending of een timeout toestaat als de queue vol is. Nucleus SE biedt dezelfde functie maar suspending is optioneel en timeouts worden niet ondersteund. RTOS ondersteunt ook een broadcast-operatie, wat niet beschikbaar is in SE.
RTOS API: NU_Send_To_Queue()
Prototype:
STATUS NU_Send_To_Queue(NU_QUEUE *queue, VOID *message, UNSIGNED size, UNSIGNED suspend); Parameters:
- queue – pointer naar het door de gebruiker geleverde queue control block
- message – pointer naar de data om te sturen
- size – aantal UNSIGNED elementen; moet matchen met de queue's message-size
- suspend – NU_NO_SUSPEND, NU_SUSPEND, of een timeout-waarde
Return-codes omvatten NU_SUCCESS, NU_QUEUE_FULL, NU_TIMEOUT, en diverse error-codes voor ongeldige pointers of queue-state.
SE API: NUSE_Queue_Send()
Prototype:
STATUS NUSE_Queue_Send(NUSE_QUEUE queue, ADDR *message, U8 suspend); Parameters:
- queue – queue-index (ID)
- message – pointer naar de ADDR waarde om te enqueuen
- suspend – NUSE_NO_SUSPEND of NUSE_SUSPEND
Return-waarden mirroren de RTOS-functie maar reflecteren SE's beperkte blocking-gedrag.
Implementatie Overzicht
Wanneer blocking uitgeschakeld is, checkt de routine simpelweg op ruimte en schrijft de waarde of returned NUSE_QUEUE_FULL. Met blocking ingeschakeld, loopt de functie, suspenderend de taak als de queue vol is totdat ruimte beschikbaar komt of een reset optreedt. De implementatie gebruikt NUSE_Queue_Blocking_Count om geblokkeerde taken te tracken en NUSE_Task_Blocking_Return om ze te hervatten zodra een slot open wordt.
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); De lus continueert totdat een bericht succesvol ge-enequeued is of de taak ontblokkeerd wordt door een reset. De implementatie waarborgt thread-safe toegang en efficiënte wake-up van geblokkeerde consumers.
Ingebed
- Precisie Afvlak Diensten: Expert Proces & Kwaliteit
- Cam-sloten Uitgelegd: Hoe Ze Kasten Discreet Beveiligen
- Wat Zijn Oogschroeven? Een Professionele Gids Naar Hun Ontwerp En Gebruik
- Oogjes Begrijpen: Typen, Toepassingen En Hoe Ze Uw Apparatuur Beschermen
- Roestvrij Staal Uitgelegd: Samenstelling, Productie En Mondiale Impact
- Mailboxes in Nucleus SE: Een Practische Gids voor Configuratie en Gebruik
- Semaphores in Nucleus RTOS: Utility Services & Datastructuren
- Semaphores in Nucleus SE: Overzicht, Configuratie en API-Essenties
- Event Flag Groups in Nucleus RTOS/SE Beheersen: Utility Services & Datastructuren
- Event Flag Groups in Nucleus SE: Een Introductie tot Configuratie en API-Gebruik
- C# Fundamentals: Invoer en Uitvoer Basis