Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial Internet of Things >> Ingebed

Wachtrijen:introductie en basisservices


Bekijk de RTOS Revealed-serie

Wachtrijen werden geïntroduceerd in een eerder artikel. Ze bieden een flexibelere manier om eenvoudige berichten tussen taken door te geven dan mailboxen.

Wachtrijen gebruiken

In Nucleus SE worden wachtrijen geconfigureerd tijdens het bouwen. Er kunnen maximaal 16 wachtrijen zijn geconfigureerd voor een toepassing. Als er geen wachtrijen zijn geconfigureerd, worden er geen datastructuren of service-oproepcode behorende bij wachtrijen in de applicatie opgenomen.

Een wachtrij is gewoon een set opslaglocaties, elk groot genoeg om een ​​enkel gegevensitem van het type ADDR te bevatten. , waarvan de toegang wordt gecontroleerd, zodat het veilig kan worden gebruikt door meerdere taken. Taken kunnen herhaaldelijk naar een wachtrij schrijven totdat alle locaties vol zijn. Taken kunnen uit een wachtrij worden gelezen en gegevens worden normaal gesproken ontvangen op basis van first in, first out (FIFO). Als u probeert naar een volle wachtrij te verzenden of te lezen uit een lege wachtrij, kan dit leiden tot een fout of taakonderbreking, afhankelijk van de opties die zijn geselecteerd in de API-aanroep en de Nucleus SE-configuratie.

Wachtrijen en leidingen

Nucleus SE ondersteunt ook buizen, die ook in een eerder artikel zijn geïntroduceerd en in een toekomstig artikel in detail worden behandeld. Het belangrijkste verschil tussen wachtrijen en leidingen is de berichtgrootte. Wachtrijen bevatten berichten die bestaan ​​uit een enkele ADDR – dit zijn gewoonlijk aanwijzingen. Een pijp bevat berichten die een willekeurig aantal bytes lang zijn; de maat wordt voor elke leiding in de toepassing vastgelegd en tijdens de configuratie ingesteld.

Wachtrijen configureren

Aantal wachtrijen

Zoals met de meeste aspecten van Nucleus SE, wordt de configuratie van wachtrijen voornamelijk beheerd door #define uitspraken in nuse_config.h . De belangrijkste instelling is NUSE_QUEUE_NUMBER , die bepaalt hoeveel wachtrijen voor de toepassing zijn geconfigureerd. De standaardinstelling is 0 (dwz er zijn geen wachtrijen in gebruik) en u kunt deze instellen op elke waarde tot 16. Een foutieve waarde zal resulteren in een compileerfout, die wordt gegenereerd door een test in nuse_config_check.h (dit is opgenomen in nuse_config.c en dus gecompileerd met deze module) resulterend in een #error verklaring wordt gecompileerd.

Het kiezen van een waarde die niet nul is, is de "master enable" voor wachtrijen. Dit heeft tot gevolg dat sommige datastructuren dienovereenkomstig worden gedefinieerd en gedimensioneerd, waarover meer in het volgende artikel. Het activeert ook de instellingen voor het inschakelen van de API.

API ingeschakeld

Elke API-functie (serviceaanroep) in Nucleus SE heeft een activerende #define symbool in nuse_config.h . Voor wachtrijen zijn dit:

NUSE_QUEUE_SEND
NUSE_QUEUE_RECEIVE
NUSE_QUEUE_JAM
NUSE_QUEUE_RESET
NUSE_QUEUE_INFORMATION
NUSE_QUEUE_COUNT

Standaard zijn deze allemaal ingesteld op FALSE , waardoor elke serviceoproep wordt uitgeschakeld en het opnemen van implementatiecodes wordt voorkomen. Om wachtrijen voor een toepassing te configureren, moet u de API-aanroepen selecteren die u wilt gebruiken en hun activeringssymbolen instellen op TRUE .

Hier is een uittreksel uit het standaard nuse_config.h-bestand.

#define NUSE_QUEUE_NUMBER    0  /* Aantal wachtrijen in de
systeem - 0-16 * /
/ * serviceoproep enablers * /
#define NUSE_QUEUE_SEND VALSE
#define NUSE_QUEUE_RECEIVE VALSE
#define NUSE_QUEUE_JAM VALSE
#define NUSE_QUEUE_RESET        FALSE
#define NUSE_QUEUE_INFORMATION  FALSE
#define NUSE_QUEUE_COUNT        FALSE

Er treedt een compileerfout op als een wachtrij-API-functie is ingeschakeld en er geen wachtrijen zijn geconfigureerd (behalve voor NUSE_Queue_Count() wat altijd is toegestaan). Als uw code een API-aanroep gebruikt, die niet is ingeschakeld, zal er een linktime-fout optreden, omdat er geen implementatiecode in de applicatie is opgenomen.

Wachtrijserviceoproepen

Nucleus RTOS ondersteunt tien service calls die horen bij wachtrijen, die de volgende functionaliteit bieden:

  • Stuur een bericht naar een wachtrij. Geïmplementeerd door NUSE_Queue_Send() in Nucleus SE.

  • Ontvang een bericht uit een wachtrij. Geïmplementeerd door NUSE_Queue_Receive() in Nucleus SE.

  • Stuur een bericht naar de voorkant van een wachtrij. Geïmplementeerd door NUSE_Queue_Jam() in Nucleus SE.

  • Herstel een wachtrij in de ongebruikte staat, zonder dat taken zijn opgeschort (reset). Geïmplementeerd door NUSE_Queue_Reset() in Nucleus SE.

  • Geef informatie over een gespecificeerde wachtrij. Geïmplementeerd door NUSE_Queue_Information() in Nucleus SE.

  • Retourneer een telling van het aantal wachtrijen dat (momenteel) is geconfigureerd voor de toepassing. Geïmplementeerd door NUSE_Queue_Count() in Nucleus SE.

  • Voeg een nieuwe wachtrij toe aan de applicatie (maken). Niet geïmplementeerd in Nucleus SE.

  • Verwijder een wachtrij uit de applicatie (verwijderen). Niet geïmplementeerd in Nucleus SE.

  • Retour verwijzingen naar alle wachtrijen (momenteel) in de toepassing. Niet geïmplementeerd in Nucleus SE.

  • Stuur een bericht naar alle taken die in een wachtrij staan ​​(uitzending). Niet geïmplementeerd in Nucleus SE.

De implementatie van elk van deze service calls wordt in detail onderzocht.

Wachtrij schrijven en lezen

De fundamentele bewerkingen die op een wachtrij kunnen worden uitgevoerd, zijn het schrijven van gegevens ernaar - wat soms verzenden wordt genoemd – en er gegevens uit lezen – wat ook wel ontvangen wordt genoemd . Het is ook mogelijk om gegevens naar de voorkant van een wachtrij te schrijven - dit wordt ook wel jamming genoemd . Nucleus RTOS en Nucleus SE bieden elk drie basis-API-aanroepen voor deze bewerkingen, die hier worden besproken.

Schrijven naar een wachtrij

De Nucleus RTOS API-aanroep voor het schrijven naar een wachtrij is zeer flexibel, waardoor u voor onbepaalde tijd of met een time-out kunt opschorten als de bewerking niet onmiddellijk kan worden voltooid; d.w.z. u probeert naar een volledige wachtrij te schrijven. Nucleus SE biedt dezelfde service, behalve dat taakonderbreking optioneel is en time-out niet is geïmplementeerd.

Nucleus RTOS biedt ook de mogelijkheid om uit te zenden naar een wachtrij, maar dit wordt niet ondersteund door Nucleus SE. Het wordt beschreven onder Niet-geïmplementeerde API's in het volgende artikel.

Nucleus RTOS API-oproep voor verzending naar een wachtrij

Serviceoproep prototype:

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

Parameters:

wachtrij – verwijzing naar het door de gebruiker geleverde wachtrijcontroleblok

bericht – een verwijzing naar het te verzenden bericht

maat – het aantal UNSIGNED gegevenselementen in het bericht. Als de wachtrij berichten met een variabele lengte ondersteunt, moet deze parameter gelijk zijn aan of kleiner zijn dan de berichtgrootte die door de wachtrij wordt ondersteund. Als de wachtrij berichten met een vaste grootte ondersteunt, moet deze parameter exact hetzelfde zijn als de berichtgrootte die door de wachtrij wordt ondersteund.

opschorten – specificatie voor taakonderbreking; kan NU_NO_SUSPEND . zijn of NU_SUSPEND of een time-outwaarde

Retourneren:

NU_SUCCESS – het gesprek is succesvol afgerond

NU_INVALID_QUEUE – de wachtrijaanwijzer is ongeldig

NU_INVALID_POINTER – de berichtaanwijzer is NULL

NU_INVALID_SIZE – de berichtgrootte is niet compatibel met de berichtgrootte die door de wachtrij wordt ondersteund

NU_INVALID_SUSPEND – opschorten is geprobeerd vanuit een niet-taakthread

NU_QUEUE_FULL – de wachtrij is vol en opschorten is niet gespecificeerd

NU_TIMEOUT – de wachtrij is nog steeds vol, zelfs na onderbreking voor de opgegeven time-outwaarde

NU_QUEUE_DELETED – de wachtrij is verwijderd terwijl de taak was opgeschort

NU_QUEUE_RESET – de wachtrij is gereset terwijl de taak was opgeschort

Nucleus SE API-oproep voor verzending naar een wachtrij

Deze API-aanroep ondersteunt de belangrijkste functionaliteit van de Nucleus RTOS API.

Serviceoproep prototype:

STATUS NUSE_Queue_Send(NUSE_QUEUE wachtrij, ADDR *message,
                       U8 opschorten);

Parameters:

wachtrij – de index (ID) van de te gebruiken wachtrij

bericht – een verwijzing naar het te verzenden bericht, een enkele variabele van het type ADDR

opschorten – specificatie voor taakonderbreking; kan NUSE_NO_SUSPEND . zijn of NUSE_SUSPEND

Retourneren:

NUSE_SUCCESS – het gesprek is succesvol afgerond

NUSE_INVALID_QUEUE – de wachtrij-index is ongeldig

NUSE_INVALID_POINTER – de berichtaanwijzer is NULL

NUSE_INVALID_SUSPEND – er is geprobeerd om opschorting uit te voeren vanuit een niet-taakthread of wanneer het blokkeren van API-aanroepen niet was ingeschakeld

NUSE_QUEUE_FULL – de wachtrij is vol en opschorten is niet gespecificeerd

NUSE_QUEUE_WAS_RESET – de wachtrij is gereset terwijl de taak was opgeschort

Nucleus SE-implementatie van Queue ASend

Het grootste deel van de code van de NUSE_Queue_Send() API-functie – na parametercontrole – wordt geselecteerd door voorwaardelijke compilatie, afhankelijk van of ondersteuning voor het blokkeren (taakonderbreken) API-aanroepen is ingeschakeld. We zullen de twee varianten hier afzonderlijk bekijken.

Als blokkeren niet is ingeschakeld, is de code voor deze API-aanroep vrij eenvoudig:

if (NUSE_Queue_Items[queue] ==NUSE_Queue_Size[queue]) /* wachtrij vol */{ return_value =NUSE_QUEUE_FULL;}else /* wachtrij-element beschikbaar */{ NUSE_Queue_Data[queue][NUSE_Queue_Head[queue]++] =*bericht; if (NUSE_Queue_Head[wachtrij] ==NUSE_Queue_Size[wachtrij]) { NUSE_Queue_Head[wachtrij] =0; } NUSE_Queue_Items[wachtrij]++; return_value =NUSE_SUCCESS;}

De functie controleert eenvoudig of er ruimte is in de wachtrij en gebruikt de NUSE_Queue_Head[] index om het bericht op te slaan in het gegevensgebied van de wachtrij.

Als blokkeren is ingeschakeld, wordt de code complexer:

do{ if (NUSE_Queue_Items[queue] ==NUSE_Queue_Size[queue]) /* wachtrij vol */ { if (suspend ==NUSE_NO_SUSPEND) { return_value =NUSE_QUEUE_FULL; } else { /* block task */ NUSE_Queue_Blocking_Count[wachtrij]++; NUSE_Suspend_Task(NUSE_Task_Active, (wachtrij <<4) | NUSE_QUEUE_SUSPEND); return_value =NUSE_Task_Blocking_Return [NUSE_Task_Active]; if (return_value !=NUSE_SUCCESS) { opschorten =NUSE_NO_SUSPEND; } } } else { /* wachtrij-element beschikbaar */ NUSE_Queue_Data[wachtrij][NUSE_Queue_Head[wachtrij]++] =*bericht; if (NUSE_Queue_Head[wachtrij] ==NUSE_Queue_Size[wachtrij]) { NUSE_Queue_Head[wachtrij] =0; } NUSE_Queue_Items[wachtrij]++; if (NUSE_Queue_Blocking_Count[wachtrij] !=0) { U8 index; /* controleer of een taak in deze wachtrij is geblokkeerd */ NUSE_Queue_Blocking_Count[wachtrij]--; for (index=0; index 

Enige uitleg van de code kan nuttig zijn:

De code is ingesloten in een do…while loop, die doorgaat terwijl de parameter suspend de waarde NUSE_SUSPEND . heeft .

Als de wachtrij vol is en onderbreken is ingesteld op NUSE_NO_SUSPEND , de API-aanroep wordt afgesloten met NUSE_QUEUE_FULL . Als opschorten was ingesteld op NUSE_SUSPEND , wordt de taak opgeschort. Bij terugkeer (d.w.z. wanneer de taak wordt gewekt), als de geretourneerde waarde NUSE_SUCCESS is , wat aangeeft dat de taak is geactiveerd omdat een bericht is gelezen (in tegenstelling tot een reset van de wachtrij), keert de code terug naar boven.

Als de wachtrij niet vol is, wordt het aangeleverde bericht opgeslagen met de NUSE_Queue_Head[] index om het bericht op te slaan in het gegevensgebied van de wachtrij. Er wordt gecontroleerd of er taken in de wachtrij staan ​​(wacht op ontvangst). Als er nog taken wachten, wordt de eerste gewekt. De opschorten variabele is ingesteld op NUSE_NO_SUSPEND en de API-aanroep wordt afgesloten met NUSE_SUCCESS .


Ingebed

  1. Een inleiding tot Cam Locks en hoe ze werken
  2. Een inleiding tot oogschroeven en hoe ze werken
  3. Een inleiding tot doorvoertules en hoe ze werken
  4. Een inleiding tot roestvrij staal en hoe het wordt gemaakt
  5. C# Basisinvoer en -uitvoer
  6. Mailboxen:introductie en basisservices
  7. Semaphores:nutsvoorzieningen en datastructuren
  8. Semaphores:introductie en basisdiensten
  9. Event flag-groepen:nutsvoorzieningen en datastructuren
  10. Event flag-groepen:introductie en basisservices
  11. Oppervlakteslijpdiensten:proces en precisie