
Dans cet article, nous continuons à passer en revue les sections de mémoire du RTOS.
Nucleus RTOS dispose de trois appels d'API qui fournissent des fonctions utilitaires liées aux pools de partitions de mémoire: renvoyer des informations sur les pools de partitions, renvoyer le nombre de pools de partitions dans une application et renvoyer des pointeurs vers tous les pools de partitions dans une application. Les deux premiers défis sont implémentés dans Nucleus SE.
Articles précédents de la série:
Article # 14. Sections de mémoire: introduction et services de baseArticle # 13. Structures de données de tâche et appels d'API non pris en chargeArticle # 12. Services pour travailler avec des tâchesArticle # 11. Tâches: configuration et introduction à l'APIArticle # 10. Scheduler: fonctionnalités avancées et préservation du contexteArticle # 9. Scheduler: implémentationArticle # 8. Nucleus SE: conception interne et déploiementArticle # 7. Nucleus SE: IntroductionArticle # 6. Autres services RTOSArticle # 5. Interaction et synchronisation des tâchesArticle # 4. Tâches, changement de contexte et interruptionsArticle # 3. Tâches et planificationArticle # 2. RTOS: Structure et mode temps réel
Article # 1. RTOS: introduction.
Récupération des informations du pool de partitions
Cet appel de service fournit des informations partielles sur le pool de partitions. L'implémentation de Nucleus SE diffère de Nucleus RTOS en ce qu'elle renvoie moins d'informations car les noms des objets et les demandes de pause ne sont pas pris en charge et la tâche ne peut pas être interrompue.
Appel des informations du pool de partitions dans Nucleus RTOS
Prototype d'appel:
STATUS NU_Partition_Pool_Information (pool NU_PARTITION_POOL *, nom CHAR *, VOID ** start_address, UNSIGNED * pool_size, UNSIGNED * partition_size, UNSIGNED * disponible, UNSIGNED * alloué, OPTION * suspend_type, UNSIGNED * tasks_waiting ** first_task; first_task; first_task; first_task; first_task;Paramètres:
pool - un pointeur vers le pool de partitions sur lequel des informations sont demandées;
nom - pointeur vers la zone de destination à 8 caractères pour le nom du pool de partitions; comprend un endroit pour terminer zéro;
start_address - un pointeur vers une variable qui reçoit un pointeur vers le début de la zone de données du pool de partitions;
pool_size - un pointeur sur une variable qui reçoit la taille du pool de partitions (en octets);
partition_size - pointeur vers une variable qui obtient la taille des partitions dans un pool donné;
available - un pointeur sur une variable qui reçoit le nombre de partitions actuellement disponibles dans ce pool;
alloué - un pointeur vers une variable qui reçoit le nombre de partitions actuellement utilisées dans un pool donné;
suspend_type - pointeur vers une variable pour obtenir le type de suspension de tâche; types de suspension valides:
NU_FIFO et
NU_PRIORITY ;
tasks_waiting - un pointeur sur une variable qui reçoit le nombre de tâches suspendues dans un pool de partitions donné;
first_task - pointeur vers le pointeur de tâche dans lequel se trouve le pointeur de la première tâche suspendue.
Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_POOL - pointeur non valide vers le pool de partitions.
Appel des informations du pool de partitions dans Nucleus SE
Prototype d'appel:
STATUS NUSE_Partition_Pool_Information (pool NUSE_PARTITION_POOL, ADDR * start_address, U32 * pool_size, U16 * partition_size, U8 * disponible, U8 * alloué, U8 * tasks_waiting, NUSE_TASK * first_task)Paramètres:
pool - l'index du pool de partitions pour lequel des informations sont demandées;
start_address - un pointeur vers une variable qui reçoit un pointeur vers le début de la zone de données du pool de partitions;
pool_size - un pointeur sur une variable qui reçoit la taille du pool de partitions (en octets);
partition_size - pointeur vers une variable qui obtient la taille des partitions dans un pool donné;
available - un pointeur sur une variable qui reçoit le nombre de partitions actuellement disponibles dans ce pool;
alloué - un pointeur vers une variable qui reçoit le nombre de partitions actuellement utilisées dans un pool donné;
tasks_waiting - un pointeur vers une variable qui reçoit le nombre de tâches suspendues dans ce pool de partitions (si la suspension des tâches est désactivée, 0 est renvoyé);
first_task - un pointeur vers une variable de type
NUSE_TASK , qui reçoit l'index de la première tâche suspendue (si la suspension de la tâche est désactivée, 0 est renvoyé).
Valeur de retour:
NUSE_SUCCESS - l'appel s'est terminé avec succès;
NUSE_INVALID_POOL - index de pool de partitions non valide;
NUSE_INVALID_POINTER - un ou plusieurs des pointeurs transmis ne sont pas valides.
Implémentation de la récupération d'informations et du regroupement de partitions dans Nucleus SE
La mise en œuvre d'un tel appel d'API est simple à exécuter:

La fonction renvoie l'état du pool de partitions. Ensuite, si le blocage des appels API est activé, le nombre de tâches en attente et l'index de la première d'entre elles sont renvoyés (sinon, ces paramètres sont définis sur 0).
Obtention du nombre de pools de partitions
Cet appel renvoie des informations sur le nombre de pools de partitions configurés dans l'application. Alors que dans Nucleus RTOS, ce nombre change au fil du temps et que la valeur de retour représentera le nombre actuel de pools, dans Nucleus SE, la valeur de retour est définie lors de l'assemblage et reste inchangée.
Le défi d'obtenir le nombre de pools de partitions dans Nucleus RTOS
L'appel prend en charge la fonctionnalité de base de l'API RTOS Nucleus.
Prototype d'appel:
UNSIGNED NU_Established_Partition_Pools (VOID);Paramètres:
Sont absents.
Valeur de retour:
Nombre de pools de partitions créés dans l'application.
Le défi d'obtenir le nombre de pools de partitions dans Nucleus SE
Cet appel d'utilitaire prend en charge la fonctionnalité principale de l'API RTOS Nucleus.
Prototype d'appel:
U8 NUSE_Partition_Pool_Count (void);Paramètres:
Sont absents
Valeur de retour:
Nombre de pools de partitions créés dans l'application.
Implémentation
L'implémentation de cet appel d'API est extrêmement simple: la valeur
#define du symbole
NUSE_PARTITION_POOL_NUMBER est
retournée .
Structures de données
Comme tous les autres objets Nucleus SE, les pools de partitions utilisent des tableaux de structure à la fois dans la ROM et la RAM, dont le nombre dépend du nombre de pools spécifiés dans les paramètres.
Je recommande fortement que le code d'application accède à ces structures de données via des fonctions API, et non directement. Cela évite l'incompatibilité avec les futures versions de Nucleus SE et les effets secondaires indésirables, et simplifie également le portage de l'application vers Nucleus RTOS. Ce qui suit est une description détaillée des structures de données pour faciliter la compréhension du code d'appel de service et le débogage.
Structure des données du noyau placées dans la RAM
Ces structures de données comprennent:
NUSE_Partition_Pool_Partition_Used [] - un tableau de type
U8 , ayant une entrée pour chaque pool de partitions configuré, contenant le compteur des pools actuellement utilisés;
NUSE_Partition_Pool_Blocking_Count [] - un tableau de type
U8 contenant un compteur de tâches bloquées dans chaque pool de partitions. Ce tableau existe si le blocage de l'appel d'API est possible.
Ces structures de données sont initialisées en zéros à l'aide de
NUSE_Init_ Partition_Pool () lors du démarrage de Nucleus SE. C'est logique car cela rend chaque partition de chaque pool inutilisée (gratuite). L'article suivant fournira une description complète des procédures de démarrage dans Nucleus SE.
Voici les descriptions des structures de données dans le fichier
nuse_init.c .

Données utilisateur RAM
L'utilisateur doit allouer une zone en RAM pour stocker les données de chaque pool de partitions. La quantité d'espace dans la RAM doit correspondre au volume des partitions configurées (voir «Données dans la ROM» ci-dessous) avec un octet supplémentaire pour chaque partition du pool. Chaque section de la zone de données est précédée d'un octet d'état.
Données ROM
Cela comprend:
NUSE_Partition_Pool_Data_Address [] - un tableau de type
ADDR , avec une entrée pour chaque pool de partitions configuré, contenant l'adresse du début de la zone de stockage des données;
NUSE_Partition_Pool_Partition_Number [] - un tableau de type
U8 avec une entrée pour chaque pool de partitions configuré contenant des informations sur le nombre de partitions dans le pool;
NUSE_Partition_Pool_Partition_Size [] - un tableau de type
U16 avec une entrée pour chaque pool de partitions configuré, contenant la taille des partitions pour les pools.
Ces structures de données sont déclarées et initialisées (statiquement) dans
nuse_config.c :

Empreinte des données pour le pool de partitions
Comme pour tous les objets principaux de Nucleus SE, la quantité de mémoire requise pour les pools de partitions est prévisible.
La taille de la ROM (en octets) pour tous les pools de partitions d'application peut être calculée comme suit:
NUSE_PARTITION_POOL_NUMBER * (taille de (ADDR) + 2)La quantité de données du noyau dans la RAM pour tous les pools de partitions d'application lorsque le blocage d'appels API est activé ne prend que 2 octets par pool de partitions, et lorsque le blocage n'est pas activé, cela prend 1 octet.
La quantité de mémoire pour stocker les données utilisateur dans la RAM varie pour chaque pool de partitions, bien que, comme déjà mentionné, pour un pool avec l'index n, elle puisse être calculée comme suit:
NUSE_Partition_Pool_Partition_Number [n] *(NUSE_Partition_Pool_Partition_Size [n] + 1)Appels d'API non réalisés
Trois appels d'API pour les pools de partitions implémentés dans Nucleus RTOS ne sont pas pris en charge dans Nucleus SE.
Créer un pool de partitions
Cet appel d'API crée un pool de partitions. Nucleus SE n'en a pas besoin car les tâches sont créées statiquement.
Prototype d'appel:
STATUS NU_Create_Partition_Pool (pool NU_PARTITION_POOL *, nom CHAR *, VOID * start_address, UNSIGNED pool_size, UNSIGNED partition_size, OPTION suspend_type);Paramètres:
pool - un pointeur vers une unité de contrôle de
pool de partitions définie par l'utilisateur; utilisé comme descripteur du pool de partitions dans d'autres appels d'API;
nom - un pointeur sur le nom du pool de partitions, une chaîne de 7 caractères avec un zéro de fin;
start_address - définit l'adresse de début de la zone mémoire du pool de partitions;
pool_size - quantité totale de mémoire en octets;
partition_size - la quantité de mémoire en octets pour chaque partition du pool. En plus de cela, une petite quantité supplémentaire de mémoire est allouée associée à chaque section, ce qui est réalisé grâce aux deux pointeurs de données utilisés.
suspend_type - détermine comment les tâches sont suspendues dans le pool de partitions; Les options de paramètre valides sont
NU_FIFO et
NU_PRIORITY .
Valeur de retour:
NU_SUCCESS - indique la réussite de l'appel;
NU_INVALID_POOL - indique la valeur zéro de l'unité de contrôle du pool de partitions (
NULL );
NU_INVALID_MEMORY - indique la valeur zéro de la zone mémoire définie par l'
adresse start_ (
NULL );
NU_INVALID_SIZE - indique que la taille de la partition est soit 0, soit supérieure à la mémoire allouée à la partition;
NU_INVALID_SUSPEND - valeur
suspend_type non
valide .
Suppression du pool de partitions
Cet appel d'API supprime un pool de partitions créé précédemment. Nucleus SE n'en a pas besoin car les objets sont créés statiquement et ne peuvent pas être supprimés.
Prototype d'appel:
STATUS NU_Delete_Partition_Pool (pool NU_PARTITION_POOL *);Paramètres:
pool - pointeur vers l'unité de contrôle du pool de partitions;
Valeur de retour:
NU_SUCCESS - indique la réussite de l'appel;
NU_INVALID_POOL - indique une valeur non valide pour le pointeur du pool de partitions;
Pointeurs de pool de partition
Cet appel d'API crée une liste séquentielle de pointeurs vers tous les pools de partitions du système. Nucleus SE n'en a pas besoin car les objets sont identifiés par un index et non par un pointeur.
Prototype d'appel:
UNSIGNED NU_Partition_Pool_Pointers (NU_PARTITION_POOL ** pointer_list, UNSIGNED maximum_pointers);Paramètres:
pointer_list - pointeur vers un tableau de pointeurs
NU_PARTITION_POOL ; la baie est remplie de pointeurs vers des pools configurés dans le système;
maximum_pointers - le nombre maximum de pointeurs pouvant être placés dans le tableau.
Valeur de retour:
Nombre de pointeurs
NU_PARTITION_POOL placés dans le tableau.
Compatible avec Nucleus RTOS
Lors du développement de Nucleus SE, l'une des principales tâches consistait à garantir un haut niveau de compatibilité du code avec Nucleus RTOS. Les pools de partition ne faisaient pas exception et, du point de vue du développeur, ils sont implémentés de la même manière que dans Nucleus RTOS. Certaines zones d'incompatibilité existantes sont acceptables, même s'il convient de considérer que le code final est plus facile à comprendre et plus efficace en termes de mémoire. Cependant, les appels d'API Nucleus RTOS peuvent être utilisés presque directement comme appels Nucleus SE. À l'avenir, un article est prévu avec des informations sur l'utilisation de Nucleus SE par les utilisateurs de Nucleus RTOS.
Identificateurs d'objet
Dans Nucleus RTOS, tous les objets sont décrits par des structures de données (unités de contrôle) d'un type spécifique. Un pointeur vers ce bloc de contrôle est utilisé comme identifiant pour le pool de partitions. J'ai décidé que Nucleus SE nécessitait une approche différente pour une utilisation plus efficace de la mémoire. Tous les objets du noyau sont décrits par plusieurs tables en RAM et / ou ROM. Les tailles de ces tables sont déterminées par le nombre de types configurables de tous les objets. L'identifiant d'un objet particulier est l'index de ces tables. Par conséquent, j'ai déterminé que
NUSE_PARTITION_POOL était équivalent à
U8 , après quoi une variable (pas un pointeur) de ce type sert d'identifiant de la tâche. Cette légère incompatibilité est facile à déterminer si le code est porté depuis ou vers Nucleus RTOS. Les identifiants d'objets sont généralement stockés et transmis inchangés.
Nucleus RTOS prend également en charge la dénomination des pools de partitions. Ces noms sont utilisés uniquement pour le débogage. Je les ai exclus de Nucleus SE pour économiser de la mémoire.
Nombre de sections et leur volume
Dans Nucleus RTOS, le pool de partitions est configuré en fonction du volume total du pool et du volume des partitions (qui contiennent 2 pointeurs supplémentaires). Ces paramètres sont définis comme UNSIGNED (environ 32 bits). Dans Nucleus SE, le pool de partitions est configuré en fonction de la taille de la partition (pour laquelle un octet supplémentaire a été ajouté) et du nombre total de partitions. Ces paramètres sont définis comme U16 et U8, respectivement.
Appels d'API non réalisés
Nucleus RTOS prend en charge 7 appels pour travailler avec des pools de partitions, dont 3 ne sont pas implémentés dans Nucleus SE. Plus de détails sur ces défis et les raisons de leur exclusion sont décrits ci-dessus.
Le prochain article portera sur les signaux.
À propos de l'auteur: Colin Walls travaille dans l'industrie électronique depuis plus de trente ans, consacrant la majeure partie de son temps au micrologiciel. Il est maintenant ingénieur firmware chez Mentor Embedded (une division de Mentor Graphics). Colin Walls intervient souvent lors de conférences et séminaires, auteur de nombreux articles techniques et de deux livres sur le firmware. Vit au Royaume-Uni.
Blog professionnel
de Colin , e-mail: colin_walls@mentor.com.