
Cet article examinera les signaux, qui sont les mécanismes d'interaction les plus simples entre les tâches dans Nucleus SE. Ils offrent un moyen peu coûteux de transférer des messages simples entre les tâches.
Articles précédents de la série:
Article # 15. Partitions de mémoire: services et structures de donnéesArticle # 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.
Utiliser des signaux
Les signaux diffèrent de tous les autres types d'objets du noyau en ce qu'ils ne sont pas autonomes: les signaux sont associés à des tâches et ne peuvent exister sans eux. Si l'application est configurée pour utiliser des signaux, chaque tâche possède un ensemble de huit indicateurs de signal.
Toute tâche peut définir des signaux pour une autre tâche. Les signaux ne peuvent être lus que par le propriétaire du signal. Pendant la lecture, les signaux sont réinitialisés. Les tâches ne peuvent pas lire ou réinitialiser les signaux d'autres tâches.
Nucleus RTOS dispose d'un outil qui permet aux tâches d'attribuer des fonctions qui s'exécutent lorsqu'une autre tâche définit un ou plusieurs indicateurs de signal. Cela rappelle quelque peu une routine de traitement d'interruption. Cette fonctionnalité n'est pas prise en charge dans Nucleus SE; ici, les tâches doivent demander explicitement des indicateurs de signal.
Configuration du signal
Comme pour la plupart des objets Nucleus SE, le réglage du signal est déterminé par les directives
#define dans
nuse_config.h . Le paramètre principal est
NUSE_SIGNAL_SUPPORT , qui active la prise en charge des fonctionnalités (pour toutes les tâches de l'application). La question d'indiquer le nombre de signaux n'en vaut pas la peine: 8 drapeaux sont alloués pour chaque tâche.
La définition de ce paramètre d'activation sert d'activateur de signal principal. Cela fournit une structure de données bien définie ayant une taille appropriée. De plus, cette option active les paramètres de l'API.
Activer les appels API
Chaque fonction API (appel d'utilitaire) dans Nucleus SE est activée par la directive
#define dans
nuse_config.h . Pour les signaux, ceux-ci comprennent:
NUSE_SIGNALS_SEND NUSE_SIGNALS_RECEIVE
Par défaut, ils sont définis sur
FALSE , désactivant ainsi chaque appel de service et empêchant le code qui les implémente d'être activé. Pour configurer les signaux dans l'application, vous devez sélectionner les appels d'API nécessaires et définir les directives correspondantes sur
TRUE .
Ce qui suit est un extrait du fichier
nuse_config.h par défaut:
#define NUSE_SIGNAL_SUPPORT FALSE #define NUSE_SIGNALS_SEND FALSE #define NUSE_SIGNALS_RECEIVE FALSE
Une fonction API activée avec le support de signalisation désactivé entraînera une erreur de compilation. Si votre code utilise un appel d'API qui n'a pas été activé, une erreur de mise en page se produira car le code d'implémentation n'a pas été inclus dans l'application. Bien sûr, l'inclusion de deux fonctions API est quelque peu inutile, car il est inutile d'activer la prise en charge du signal en l'absence de ces API. Des activateurs ont été ajoutés pour assurer la compatibilité avec d'autres fonctionnalités de Nucleus SE.
Signaux d'appel
Nucleus RTOS prend en charge quatre appels supplémentaires liés au signal qui offrent les fonctionnalités suivantes:
- Envoi de signaux à une tâche donnée. Nucleus SE est implémenté dans la fonction NUSE_Signals_Send () .
- Réception des signaux. Nucleus SE est implémenté dans la fonction NUSE_Signals_Receive () .
- Enregistrement du gestionnaire de signaux. Non implémenté dans Nucleus SE.
- Activez / désactivez les signaux (de contrôle). Non implémenté dans Nucleus SE.
La mise en œuvre de chacun de ces défis est discutée en détail ci-dessous.
Services de signalisation et de réception
Les opérations fondamentales qui peuvent être effectuées sur un ensemble de signaux de tâche sont l'envoi de données (peut être effectué par n'importe quelle tâche) et la lecture de données (par conséquent, l'effacement des données ne peut être effectué que par la tâche propriétaire). Nucleus RTOS et Nucleus SE fournissent deux appels d'API de base pour ces opérations, qui seront décrits ci-dessous.
Comme les signaux sont des bits, ils sont mieux visualisés sous forme de nombres binaires. Étant donné que la norme C n'a historiquement pas pris en charge la représentation des constantes binaires (uniquement octales et hexadécimales), Nucleus SE possède un fichier d'en-tête utile
nuse_binary.h qui contient des caractères
#define comme
b01010101 pour les 256 valeurs 8 bits. Ce qui suit est un extrait du fichier
nuse_binary.h :
#define b00000000 ((U8) 0x00) #define b00000001 ((U8) 0x01) #define b00000010 ((U8) 0x02) #define b00000011 ((U8) 0x03) #define b00000100 ((U8) 0x04) #define b00000101 ((U8) 0x05)
Envoi de signaux
Toute tâche peut envoyer des signaux à toute autre tâche de l'application. L'envoi de signaux implique de définir un ou plusieurs drapeaux de signal. Il s'agit d'une opération OU qui n'affecte pas les indicateurs définis précédemment.
Appel pour envoyer des signaux à Nucleus RTOSPrototype d'appel de service:
STATUS NU_Send_Signals (tâche NU_TASK *, signaux UNSIGNED);Paramètres:
tâche - pointeur vers l'unité de commande de tâche à laquelle appartiennent les drapeaux de signal définis;
signaux - la valeur des indicateurs de signal définis.
Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_TASK - pointeur non valide vers la tâche;
Appel pour envoyer des signaux à Nucleus SECet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus RTOS.
Prototype d'appel de service:
STATUS_NUSE_Signals_Send (tâche NUSE_TASK, signaux U8);Paramètres:
tâche - index (ID) de la tâche à laquelle appartiennent les indicateurs de signal définis;
signaux - la valeur des indicateurs de signal définis.
Valeur de retour:
NUSE_SUCCESS - l'appel de service s'est terminé avec succès;
NUSE_INVALID_TASK - index de tâche non valide.
Implémentation de la signalisation dans Nucleus SEVoici le code complet de la fonction NUSE_Signals_Send ():
STATUS NUSE_Signals_Send(NUSE_TASK task, U8 signals) { #if NUSE_API_PARAMETER_CHECKING if (task >= NUSE_TASK_NUMBER) { return NUSE_INVALID_TASK; } #endif NUSE_CS_Enter(); NUSE_Task_Signal_Flags[task] |= signals; NUSE_CS_Exit(); return NUSE_SUCCESS; }
Le code est très simple. Après toute vérification des paramètres, les valeurs du signal passent par l'opération OU sur les drapeaux de signal de la tâche spécifiée. Les tâches de verrouillage n'affectent pas les signaux.
Réception de signaux
Une tâche ne peut lire que son propre ensemble d'indicateurs de signal. Pendant la lecture, les valeurs des drapeaux sont réinitialisées.
Appel pour recevoir des signaux dans Nucleus RTOSPrototype d'appel de service:
UNSIGNED NU_Receive_Signals (VOID);Paramètres: aucun.
Valeur de retour:
Valeurs d'indicateur de signal.
Appel pour recevoir des signaux dans Nucleus SECet appel d'API prend en charge la fonctionnalité principale de l'API Nucleus RTOS.
Prototype d'appel de service:
U8 NUSE_Signals_Receive (void);Paramètres: aucun.
Valeur de retour:
Valeurs d'indicateur de signal.
Implémentation de la réception du signal Nucleus SEVoici le code complet de la fonction
NUSE_Signals_Receive () :
U8 NUSE_Signals_Receive(void) { U8 signals; NUSE_CS_Enter(); Signals = NUSE_Task_Signal_Flags[NUSE_Task_Active]; NUSE_Task_Signal_Flags[NUSE_Task_Active] = 0; NUSE_CS_Exit(); return signals; }
Le code est très simple. La valeur des indicateurs est copiée, la valeur initiale est réinitialisée et la copie est renvoyée par la fonction API. Les tâches de verrouillage n'affectent pas les signaux.
Structures de données
Les signaux n'étant pas des objets indépendants, l'utilisation de la mémoire dépend des tâches auxquelles ils appartiennent. Voici quelques informations pour une compréhension complète. Les signaux utilisent une structure de données (en RAM) qui, comme les autres objets Nucleus SE, est une table dont les dimensions correspondent au nombre de tâches dans l'application. Cette structure de données n'est utilisée que si la prise en charge du signal est activée.
Je recommande fortement que le code d'application n'accède pas directement à cette structure de données, mais utilise les fonctions API disponibles. Cela évite l'incompatibilité avec les futures versions de Nucleus SE, les effets secondaires indésirables et simplifie également le portage de l'application vers Nucleus RTOS. La structure des données est discutée en détail ci-dessous pour simplifier la compréhension des principes d'appel de service et de débogage.
La structure des données placées en RAM
Structure des données:
NUSE_Task_Signal_Flags [] - un tableau de type U8 avec une entrée pour chaque tâche configurée, les indicateurs de signal sont stockés dans ce tableau.
Cette structure de données est initialisée à
zéro par la fonction
NUSE_Init_Task () lors du chargement de Nucleus SE.
Structure des données placées dans la ROM
Les signaux manquent de structures de données dans la ROM.
Quantité de mémoire pour stocker les données de signal
Comme pour tous les objets principaux Nucleus SE, la quantité de mémoire requise pour les signaux est prévisible.
La quantité de données dans la ROM pour tous les signaux de l'application est de 0.
La quantité de mémoire pour stocker des données dans la RAM (en octets) pour tous les signaux dans l'application est égale au nombre de tâches configurées (
NUSE_TASK_NUMBER ). Mais en fait, ces données appartiennent aux tâches et sont décrites dans l'article précédent sur les tâches.
Appels d'API non réalisés
Deux appels de signalisation de l'API Nucleus RTOS ne sont pas implémentés dans Nucleus SE:
Enregistrement du gestionnaire de signaux
Cet appel API définit la procédure (fonction) de traitement du signal pour la tâche en cours. Nucleus SE n'en a pas besoin car les gestionnaires de signaux ne sont pas pris en charge.
Prototype d'appel de service:
STATUS NU_Register_Signal_Handler (VOID (* signal_handler) (UNSIGNED));Paramètres:
signal_handler - une fonction qui doit être appelée lors de la réception de signaux
Valeur de retour:
NU_SUCCESS - l'appel s'est terminé avec succès;
NU_INVALID_POINTER - pointeur nul vers le gestionnaire de signal (
NULL )
Contrôle (activation / désactivation) des signaux
Ce service active et / ou désactive les signaux pour la tâche en cours. Pour chaque tâche, 32 signaux sont disponibles. Chaque signal est représenté par un bit dans
signal_enable_mask . L'ajout d'un bit à
signal_enable_mask active le signal correspondant et la suppression d'un bit le désactive.
Prototype d'appel de service:
UNSIGNED NU_Control_Signals (UNSIGNED enable_signal_mask);Paramètres:
enable_signal_mask - motif binaire représentant les signaux corrects.
Valeur de retour:
Masque pour activer / désactiver le signal précédent.
Compatible avec Nucleus RTOS
Lors du développement de Nucleus SE, mon objectif était de maintenir le niveau de code compatible avec Nucleus RTOS. Les signaux ne font 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. Il y a quelques incompatibilités que j'ai considérées comme valides, étant donné que le code final est beaucoup plus facile à comprendre et peut utiliser la mémoire plus efficacement. Sinon, les appels de l'API Nucleus RTOS peuvent être transférés presque directement vers les appels Nucleus SE.
Gestionnaires de signaux
Dans Nucleus SE, les gestionnaires de signaux ne sont pas implémentés pour simplifier la structure globale.
Disponibilité et quantité du signal
Dans Nucleus RTOS, les tâches peuvent avoir 32 drapeaux de signal. Dans Nucleus SE, j'ai décidé de réduire leur nombre à huit, car cela suffira pour des applications plus simples et économisera des ressources RAM. Si nécessaire, les signaux peuvent être complètement désactivés.
Appels d'API non réalisés
Nucleus RTOS prend en charge quatre appels de service de signalisation. Parmi ceux-ci, deux n'ont pas été implémentés dans Nucleus SE. Leur description peut être trouvée ci-dessus dans la section «Appels d'API non réalisés».
À 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.