Toute la vérité sur RTOS. Article # 33. Utilisation du systÚme d'exploitation en temps réel Nucleus SE

Jusqu'Ă  prĂ©sent, dans cette sĂ©rie d'articles, nous avons examinĂ© les fonctionnalitĂ©s fournies par Nucleus SE. Il est maintenant temps de voir comment il peut ĂȘtre utilisĂ© dans une vĂ©ritable application de firmware.



Articles précédents de la série:
Article # 32. Migration de Nucleus SE: fonctionnalités et compatibilité non réalisées
Article # 31. Diagnostics et vérification des erreurs RTOS
Article # 30. Procédures d'initialisation et de démarrage de Nucleus SE
Article # 29. Interruptions dans Nucleus SE
Article # 28. Minuteries logicielles
Article # 27. Heure systĂšme
Article # 26. Canaux: services auxiliaires et structures de données
Article # 25. Canaux de données: introduction et services de base
Article # 24. Files d'attente: services auxiliaires et structures de données
Article # 23. Files d'attente: introduction et services de base
Article # 22. Boßtes aux lettres: services auxiliaires et structures de données
Article # 21. BoĂźtes aux lettres: introduction et services de base
Article # 20. Sémaphores: services auxiliaires et structures de données
Article # 19. Sémaphores: introduction et services de base
Article # 18. Groupes d'indicateurs d'événements: services d'assistance et structures de données
Article # 17. Groupes de drapeaux d'événements: introduction et services de base
Article # 16. Signaux
Article # 15. Partitions de mémoire: services et structures de données
Article # 14. Sections de mémoire: introduction et services de base
Article # 13. Structures de données de tùche et appels d'API non pris en charge
Article # 12. Services pour travailler avec des tĂąches
Article # 11. TĂąches: configuration et introduction Ă  l'API
Article # 10. Scheduler: fonctionnalités avancées et préservation du contexte
Article # 9. Scheduler: implémentation
Article # 8. Nucleus SE: conception interne et déploiement
Article # 7. Nucleus SE: Introduction
Article # 6. Autres services RTOS
Article # 5. Interaction et synchronisation des tĂąches
Article # 4. TĂąches, changement de contexte et interruptions
Article # 3. TĂąches et planification
Article # 2. RTOS: Structure et mode temps réel
Article # 1. RTOS: introduction.

Qu'est-ce que Nucleus SE?


Nous savons que Nucleus SE est le cƓur d'un systĂšme d'exploitation en temps rĂ©el, mais vous devez comprendre comment il s'intĂšgre dans le reste de l'application. Et cela convient, car contrairement Ă  un systĂšme d'exploitation de bureau (par exemple, Windows), l'application ne dĂ©marre pas sur Nucleus SE; le noyau fait simplement partie d'un programme exĂ©cutĂ© sur un pĂ©riphĂ©rique intĂ©grĂ©. Il s'agit du cas d'utilisation le plus courant pour RTOS.

D'un point de vue de haut niveau, une application intégrée est une sorte de code qui démarre au démarrage du CPU. Dans ce cas, l'environnement matériel et logiciel est initialisé, puis la fonction main () est appelée, ce qui lance le code d'application principal.

Lors de l'utilisation de Nucleus SE (et de nombreux autres noyaux similaires), la différence est que la fonction main () fait partie du code du noyau. Cette fonction initialise simplement les structures de données du noyau, puis appelle l'ordonnanceur, ce qui conduit au lancement du code d'application (tùches). L'utilisateur peut ajouter n'importe quel code d'initialisation natif à la fonction main () .

Nucleus SE comprend également un ensemble de fonctions - une interface de programmation d'application (API) qui fournit un ensemble de fonctions telles que la communication et la synchronisation des tùches, le travail avec des minuteries, l'allocation de mémoire, etc. Toutes les fonctions API ont été décrites plus haut dans les articles de cette série.

Tous les logiciels Nucleus SE sont fournis en tant que code source (principalement en C). Pour configurer le code conformément aux exigences d'une application particuliÚre, une compilation conditionnelle est utilisée. Ceci est décrit en détail dans cet article dans la section Configuration.

Une fois le code compilĂ©, les modules d'objet Nucleus SE rĂ©sultants sont associĂ©s aux modules de code d'application, rĂ©sultant en une seule image binaire, qui est gĂ©nĂ©ralement placĂ©e dans la mĂ©moire flash du pĂ©riphĂ©rique intĂ©grĂ©. Le rĂ©sultat de cette liaison statique est que toutes les informations symboliques restent disponibles Ă  la fois dans le code d'application et dans le code du noyau. Ceci est utile pour le dĂ©bogage, mais il faut ĂȘtre prudent pour Ă©viter une mauvaise utilisation des donnĂ©es Nucleus SE.

Prise en charge du processeur et des outils


Étant donnĂ© que Nucleus SE est fourni en tant que code source, il doit ĂȘtre portable. Cependant, le code s'exĂ©cutant Ă  un niveau aussi bas (lors de l'utilisation de planificateurs oĂč un changement de contexte est requis, c'est-Ă -dire autre chose que Run to Completion), ne peut pas ĂȘtre complĂštement indĂ©pendant du langage d'assembly. J'ai minimisĂ© cette dĂ©pendance, et pour le portage vers une nouvelle programmation de bas niveau CPU n'est presque pas nĂ©cessaire. L'utilisation d'un nouvel ensemble d'outils de dĂ©veloppement (compilateur, assembleur, Ă©diteur de liens, etc.) peut Ă©galement entraĂźner des problĂšmes de portage.

Configuration de l'application Nucleus SE


La clé d'une utilisation efficace de Nucleus SE est une configuration correcte. Cela peut sembler compliqué, mais en fait, tout est assez logique et ne nécessite qu'une approche systématique. Presque toute la configuration se fait en éditant deux fichiers: nuse_config.h et nuse_config.c .

ParamĂštre Nuse_config.h


Ce fichier n'est qu'un jeu de caractÚres de la directive #define , auquel sont affectées les valeurs appropriées pour obtenir la configuration de noyau nécessaire. Dans le fichier nuse_config.h, par défaut, tous les caractÚres sont présents, mais les paramÚtres minimaux leur sont attribués.

Compteurs d'objets
Le nombre d'objets noyau de chaque type est défini par des valeurs de symboles de la forme NUSE_SEMAPHORE_NUMBER . Pour la plupart des objets, cette valeur peut varier de 0 à 15. Les tùches sont une exception, il doit y en avoir au moins une. Les signaux, en fait, ne sont pas des objets indépendants, car ils sont associés à des tùches et sont activés en définissant NUSE_SIGNAL_SUPPOR T sur TRUE .

Activateurs de fonctions API
Chaque fonction d'API Nucleus SE peut ĂȘtre activĂ©e sĂ©parĂ©ment en affectant un symbole dont le nom correspond au nom de la fonction (par exemple, NUSE_PIPE_JAM ) Ă  TRUE . Cela conduit Ă  l'inclusion du code de fonction dans l'application.

Sélection et paramÚtres du planificateur
Nucleus SE prend en charge quatre types de planificateurs, comme décrit dans un article précédent. Le planificateur utilisé est défini en affectant NUSE_SCHEDULER_TYPE à l' une des valeurs suivantes: NUSE_RUN_TO_COMPLETION_SCHEDULER , NUSE_TIME_SLICE_SCHEDULER , NUSE_ROUND_ROBIN_SCHEDULER ou NUSE_PRIORITY_SCHEDULER .

Vous pouvez configurer d'autres paramĂštres du planificateur:
NUSE_TIME_SLICE_TICKS indique le nombre de ticks par slot pour le planificateur de tranche de temps. Si un autre ordonnanceur est utilisĂ©, ce paramĂštre doit ĂȘtre dĂ©fini sur 0.
NUSE_SCHEDULE_COUNT_SUPPORT peut ĂȘtre dĂ©fini sur TRUE ou FALSE pour activer / dĂ©sactiver le mĂ©canisme de compteur du planificateur.
NUSE_SUSPEND_ENABLE active le verrouillage des tĂąches (suspension) pour de nombreuses fonctions API. Cela signifie qu'un appel Ă  une telle fonction peut entraĂźner une suspension de la tĂąche appelante jusqu'Ă  ce que la ressource soit libĂ©rĂ©e. Pour sĂ©lectionner cette option, NUSE_SUSPEND_ENABLE doit Ă©galement ĂȘtre dĂ©fini sur TRUE .

Autres options
Plusieurs autres paramĂštres peuvent Ă©galement ĂȘtre affectĂ©s de valeurs VRAI ou FAUX pour activer / dĂ©sactiver d'autres fonctions du noyau:
NUSE_API_PARAMETER_CHECKING ajoute un code de vérification de paramÚtre d'appel d'appel de fonction API. Couramment utilisé pour le débogage.
NUSE_INITIAL_TASK_STATE_SUPPORT définit l'état initial de toutes les tùches comme NUSE_READY ou NUSE_PURE_SUSPEND . Si ce paramÚtre est désactivé, toutes les tùches auront l'état initial NUSE_READY .
NUSE_SYSTEM_TIME_SUPPORT - prise en charge de l'heure systĂšme.
NUSE_INCLUDE_EVERYTHING - un paramÚtre qui ajoute le nombre maximal de fonctions à la configuration de Nucleus SE. Il conduit à l'activation de toutes les fonctionnalités optionnelles et de chaque fonction API des objets configurés. Utilisé pour créer rapidement une configuration Nucleus SE pour vérifier un nouveau portage du code du noyau.

Définition de nuse_config.c


AprÚs avoir spécifié la configuration du noyau dans nuse_config.h, il est nécessaire d'initialiser les différentes structures de données stockées dans la ROM. Cela se fait dans le fichier nuse_config.c . La définition des structures de données est contrÎlée par une compilation conditionnelle, donc toutes les structures sont contenues dans une copie du fichier nuse_config.c par défaut.

Données de tùche
Le tableau NUSE_Task_Start_Address [] doit ĂȘtre initialisĂ© avec la valeur des adresses de dĂ©part de chaque tĂąche. Il s'agit gĂ©nĂ©ralement d'une liste de noms de fonction, sans parenthĂšses. Les prototypes des fonctions de saisie des tĂąches doivent Ă©galement ĂȘtre visibles. Dans le fichier par dĂ©faut, la tĂąche est configurĂ©e avec le nom NUSE_Idle_Task () , cela peut ĂȘtre changĂ© en tĂąche d'application.

Si vous utilisez n'importe quel planificateur sauf Run to Completion, chaque tĂąche nĂ©cessite sa propre pile. Pour chaque pile de tĂąches, vous devez crĂ©er un tableau en RAM. Ces tableaux doivent ĂȘtre de type ADDR et l'adresse de chacun d'eux doit ĂȘtre stockĂ©e dans NUSE_Task_Stack_Base [] . Il est difficile de prĂ©dire la taille du tableau, il est donc prĂ©fĂ©rable d'utiliser des mesures (voir la section «DĂ©bogage» plus loin dans cet article). La taille de chaque tableau (c'est-Ă -dire le nombre de mots sur la pile) doit ĂȘtre stockĂ©e dans NUSE_Task_Stack_Size [] .

Si une fonction a Ă©tĂ© activĂ©e pour indiquer l'Ă©tat initial de la tĂąche (Ă  l'aide du paramĂštre NUSE_INITIAL_TASK_STATE_SUPPORT ), le tableau NUSE_Task_Initial_State [] doit ĂȘtre initialisĂ© avec l'Ă©tat NUSE_READY ou NUSE_PURE_SUSPEND .

Données du pool de partitions
Si au moins un pool de partitions est configurĂ©, une baie (de type U8 ) doit ĂȘtre créée pour chacun d'eux dans la ROM. La taille de ces tableaux est calculĂ©e comme suit: (nombre de partitions * (taille de partition + 1)). Les adresses de ces sections (c'est-Ă -dire leurs noms) doivent ĂȘtre affectĂ©es aux Ă©lĂ©ments NUSE_Partition_Pool_Data_Address [] correspondants. Pour chaque pool, le nombre de partitions et leur taille doivent ĂȘtre placĂ©s respectivement dans NUSE_Partition_Pool_Partition_Number [] et NUSE_Partition_Message_Size [] .

Données de file d'attente
Si au moins une file d'attente est configurĂ©e, un tableau (de type ADDR ) doit ĂȘtre créé pour chacun d'eux dans la RAM. La taille de ces tableaux est le nombre d'Ă©lĂ©ments dans chaque file d'attente. Les adresses de ces tableaux (c'est-Ă -dire leurs noms) doivent ĂȘtre affectĂ©es aux Ă©lĂ©ments NUSE_Queue_Data [] correspondants. La taille de chaque file d'attente doit ĂȘtre affectĂ©e Ă  l'Ă©lĂ©ment NUSE_Queue_Size [] correspondant.

Données de liaison de données
Si au moins un canal de donnĂ©es est configurĂ©, un tableau (de type U8 ) doit ĂȘtre créé en RAM pour celui-ci (ou pour chacun d'eux). La taille de ces tableaux est calculĂ©e comme suit: (taille du canal * taille du message dans le canal). Les adresses de ces tableaux (c'est-Ă -dire leurs noms) doivent ĂȘtre attribuĂ©es aux Ă©lĂ©ments NUSE_Pipe_Data [] correspondants. Pour chaque canal, sa taille et sa taille de message doivent ĂȘtre attribuĂ©es aux Ă©lĂ©ments NUSE_Pipe_Size [] et NUSE_Pipe_Message_Size [] correspondants , respectivement.

Données de sémaphore
Si au moins un sĂ©maphore est configurĂ©, le tableau NUSE_Semaphore_Initial_Value [] doit ĂȘtre initialisĂ© avec les valeurs initiales du compte Ă  rebours.

Données du minuteur d'application
Si au moins un temporisateur est configurĂ©, le tableau NUSE_Timer_Initial_Time [] doit ĂȘtre initialisĂ© avec les valeurs initiales des compteurs. De plus, NUSE_Timer_Reschedule_Time [] doit recevoir des valeurs de redĂ©marrage. Ces valeurs de minuterie seront utilisĂ©es aprĂšs la fin du premier cycle de minuterie. Si les valeurs de redĂ©marrage sont dĂ©finies sur 0, le compteur s'arrĂȘte aprĂšs un cycle.

Si la prise en charge des mĂ©canismes d'achĂšvement de compte est configurĂ©e (en dĂ©finissant le paramĂštre NUSE_TIMER_EXPIRATION_ROUTINE_SUPPORT sur TRUE ), deux autres tableaux doivent ĂȘtre créés. Les adresses des mĂ©canismes de complĂ©tion (juste une liste de noms de fonction, sans parenthĂšses) doivent ĂȘtre placĂ©es dans NUSE_Timer_Expiration_Routine_Address [] . Le tableau NUSE_Timer_Expiration_Routine_Parameter [] doit ĂȘtre initialisĂ© avec les valeurs des paramĂštres d'achĂšvement.

Quelle API?


Tous les systÚmes d'exploitation sous une forme ou une autre ont une API (interface de programmation d'application). Nucleus SE ne fait pas exception, et les fonctions qui composent l'API ont été décrites en détail dans cette série d'articles.

Il peut sembler évident que lors de l'écriture d'une application à l'aide de Nucleus SE, vous devez utiliser l'API comme décrit dans les articles précédents. Mais ce n'est pas toujours le cas.

Pour la plupart des utilisateurs, l'API Nucleus SE sera quelque chose de nouveau, peut-ĂȘtre mĂȘme leur premiĂšre expĂ©rience d'utilisation de l'API du systĂšme d'exploitation. Et comme il est assez simple, il peut servir de bonne introduction au sujet. Dans ce cas, la procĂ©dure est claire.

Pour certains utilisateurs, une autre API peut ĂȘtre une option plus attrayante. Il y a trois situations Ă©videntes oĂč cela est possible.
  1. Nucleus SE n'est qu'une partie d'un systÚme qui utilise d'autres systÚmes d'exploitation pour d'autres composants. Par conséquent, la portabilité du code et, plus important encore, l'expérience de l'utilisation de divers systÚmes d'exploitation semblent trÚs tentantes.
  2. L'utilisateur possÚde une vaste expérience de l'utilisation de l'API d'un autre systÚme d'exploitation. L'utilisation de cette expérience est également trÚs recommandée.
  3. L'utilisateur souhaite réutiliser du code écrit pour l'API d'un autre systÚme d'exploitation. La modification des appels API est possible, mais prend du temps.


Étant donnĂ© que le code source complet de Nucleus SE est disponible pour tout le monde, rien ne vous empĂȘche de modifier chaque fonction API afin qu'elle ressemble Ă  son Ă©quivalent d'un autre systĂšme d'exploitation. Cependant, cela prendra beaucoup de temps et sera trĂšs improductif. Une approche plus correcte serait d'Ă©crire un «wrapper». Il existe plusieurs façons de procĂ©der, mais la plus simple consiste Ă  crĂ©er un fichier d'en-tĂȘte ( #include ) contenant un ensemble de macros #define qui mapperont les fonctions d'API tierces aux fonctions d'API Nucleus SE.

Un wrapper qui transfĂšre (partiellement) les fonctions de l'API RTOS Nucleus Ă  Nucleus SE est distribuĂ© avec Nucleus SE. Il peut ĂȘtre utile aux dĂ©veloppeurs ayant une expĂ©rience de l'utilisation de Nucleus RTOS, ou oĂč Ă  l'avenir il sera possible de passer Ă  ce RTOS. Ce wrapper peut Ă©galement servir d'exemple lors du dĂ©veloppement de choses similaires.

Débogage des applications Nucleus SE


L'Ă©criture d'une application embarquĂ©e Ă  l'aide d'un noyau multitĂąche est une tĂąche complexe. S'assurer que le code fonctionne et dĂ©tecter les erreurs peut ĂȘtre une tĂąche intimidante. MalgrĂ© le fait qu'il ne s'agit que de code qui s'exĂ©cute sur un processeur, l'exĂ©cution simultanĂ©e de plusieurs tĂąches rend assez difficile de se concentrer sur un thread d'exĂ©cution spĂ©cifique. Cela est encore plus compliquĂ© lorsque plusieurs tĂąches partagent un code commun. Pire encore, lorsque deux tĂąches ont exactement le mĂȘme code (mais fonctionnent avec des donnĂ©es diffĂ©rentes). La complication des structures de donnĂ©es utilisĂ©es pour implĂ©menter les objets du noyau afin de voir des informations significatives est Ă©galement compliquĂ©e.

Pour dĂ©boguer des applications construites Ă  l'aide de Nucleus SE, aucune bibliothĂšque ou autre service supplĂ©mentaire n'est requis. Tout le code du noyau est lisible par le dĂ©bogueur. Par consĂ©quent, toutes les informations symboliques sont disponibles pour Ă©tude. Lorsque vous travaillez avec des applications Nucleus SE, tout outil de dĂ©bogage moderne peut ĂȘtre utilisĂ©.

Utiliser un débogueur


Les outils de dĂ©bogage conçus spĂ©cifiquement pour les systĂšmes embarquĂ©s sont devenus trĂšs puissants au cours des 30 derniĂšres annĂ©es. La principale caractĂ©ristique d'une application embarquĂ©e, par rapport Ă  un programme de bureau, est que tous les systĂšmes embarquĂ©s sont diffĂ©rents (et tous les ordinateurs personnels sont assez similaires les uns aux autres). Un bon dĂ©bogueur intĂ©grĂ© doit ĂȘtre flexible et avoir suffisamment de paramĂštres pour correspondre Ă  la variĂ©tĂ© de systĂšmes intĂ©grĂ©s et aux besoins des utilisateurs. La personnalisation du dĂ©bogueur s'exprime sous diverses formes, mais il existe gĂ©nĂ©ralement la possibilitĂ© de crĂ©er des scripts. C'est cette fonctionnalitĂ© qui permet au dĂ©bogueur de bien fonctionner avec une application au niveau du noyau. Ci-dessous, je vais discuter de quelques cas d'utilisation du dĂ©bogueur.

Il convient de noter qu'en général, un débogueur est une famille d'outils, pas seulement un programme. Le débogueur peut avoir différents modes de fonctionnement, grùce auxquels il aide lors du développement de code sur un systÚme virtuel ou sur du matériel réel.

Points d'arrĂȘt sensibles aux tĂąches


Si le programme a un code commun Ă  plusieurs tĂąches, l'utilisation de points d'arrĂȘt conventionnels lors du dĂ©bogage est compliquĂ©e. Il est fort probable que le code ne s'arrĂȘte que lorsqu'un point d'arrĂȘt est atteint dans le contexte d'une tĂąche spĂ©cifique que vous dĂ©boguez actuellement. Pour ce faire, vous avez besoin d'un point d'arrĂȘt qui tiendra compte de la tĂąche.

Heureusement, la possibilitĂ© de crĂ©er des scripts sur des dĂ©bogueurs modernes et la disponibilitĂ© des donnĂ©es de caractĂšres Nucleus SE rendent l'implĂ©mentation de points d'arrĂȘt spĂ©cifiques Ă  une tĂąche assez simple. Il suffit d'Ă©crire un script simple qui sera associĂ© Ă  un point d'arrĂȘt que vous souhaitez enseigner pour distinguer les tĂąches. Ce script prendra le paramĂštre: index (ID) de la tĂąche qui vous intĂ©resse. Le script compare simplement cette valeur avec l'index de la tĂąche en cours ( NUSE_Task_Active ). Si les valeurs correspondent, le programme s'arrĂȘte. S'ils sont diffĂ©rents, l'exĂ©cution continue. Il est Ă  noter que l'exĂ©cution de ce script affectera l'exĂ©cution de l'application en temps rĂ©el ( note du traducteur: cela signifie que l'exĂ©cution du programme ralentira son fonctionnement normal ). Cependant, si le script n'est pas dans une boucle qui sera exĂ©cutĂ©e trĂšs souvent, cet effet sera minime.

Informations sur les objets du noyau


Le besoin évident de déboguer l'application Nucleus SE est la possibilité d'obtenir des informations sur les objets du noyau: quelles sont leurs caractéristiques et quel est leur statut actuel. Cela vous permet d'obtenir des réponses à des questions telles que: "Quelle est la taille de cette file d'attente et combien de messages y figurent maintenant?"

Cela peut ĂȘtre utilisĂ© en ajoutant du code de dĂ©bogage supplĂ©mentaire Ă  votre application, qui utilisera les appels d'API "informatifs" (tels que NUSE_Queue_Information ). Bien sĂ»r, cela signifie que votre application contient maintenant du code supplĂ©mentaire, qui ne sera plus nĂ©cessaire aprĂšs la mise en Ɠuvre de l'application. L'utilisation de #define pour activer et dĂ©sactiver ce code Ă  l'aide de la compilation conditionnelle serait une dĂ©cision logique.

Certains dĂ©bogueurs peuvent effectuer un appel de fonction ciblĂ©, c'est-Ă -dire appeler directement une fonction API pour rĂ©cupĂ©rer des informations.Cela Ă©limine le besoin de code supplĂ©mentaire, mais cette fonction API doit ĂȘtre configurĂ©e pour que le dĂ©bogueur puisse l'utiliser.

Une approche alternative, plus flexible, mais moins «non vieillissante» est l'accĂšs direct aux structures de donnĂ©es des objets du noyau. TrĂšs probablement, il est prĂ©fĂ©rable de le faire en utilisant des scripts de dĂ©bogage. Dans notre exemple, la taille de la file d'attente peut ĂȘtre obtenue Ă  partir de NUSE_Queue_Size [] , et son utilisation actuelle Ă  partir de NUSE_Queue_Data [] . De plus, les messages dans la file d'attente peuvent ĂȘtre affichĂ©s en utilisant l'adresse de la zone de donnĂ©es de la file d'attente (Ă  partir de NUSE_Queue_Data [] ).

Valeurs de retour d'appel API


De nombreuses fonctions API renvoient une valeur d'Ă©tat indiquant le succĂšs de l'appel. Il serait utile de garder une trace de ces valeurs et de marquer les cas dans lesquels elles ne sont pas Ă©gales Ă  NUSE_SUCCESS (c'est-Ă -dire qu'elles ont une valeur de zĂ©ro). Étant donnĂ© que ce suivi est uniquement destinĂ© au dĂ©bogage, la compilation conditionnelle est tout Ă  fait appropriĂ©e. La dĂ©finition d'une variable globale (par exemple, NUSE_API_Call_Status ) peut ĂȘtre compilĂ©e conditionnellement (sous le contrĂŽle du symbole de directive #define). Ensuite, une partie de la dĂ©finition des appels d'API, Ă  savoir NUSE_API_Call_Status = , peut Ă©galement ĂȘtre compilĂ©e conditionnellement. Par exemple, Ă  des fins de dĂ©bogage, un appel qui ressemble gĂ©nĂ©ralement Ă  ceci:

NUSE_Mailbox_Send (mbox, msg, NUSE_SUSPSEND);

prendra la forme suivante:

NUSE_API_Call_Status = NUSE_Mailbox_Send (mbox, msg, NUSE_SUSPEND);

Si le verrouillage des tùches est activé, de nombreux appels de fonction API peuvent uniquement renvoyer des informations sur la réussite d'un appel ou sur la réinitialisation de l'objet. Cependant, si la vérification des paramÚtres d'API est activée, les appels d'API pourront renvoyer de nombreuses autres valeurs.

Définition de la taille de la pile de tùches et du débordement de pile


Le sujet de la protection contre le débordement de pile a été abordé dans un article précédent (# 31). Il existe plusieurs autres possibilités lors du débogage.

La zone mĂ©moire de la pile peut ĂȘtre remplie d'une valeur caractĂ©ristique: autre chose que tous les uns ou tous les zĂ©ros. AprĂšs cela, le dĂ©bogueur peut ĂȘtre utilisĂ© pour surveiller les zones de mĂ©moire et combien les valeurs seront modifiĂ©es, ce qui permettra de comprendre le degrĂ© de saturation de la pile. Si toutes les zones de mĂ©moire ont Ă©tĂ© modifiĂ©es, cela ne signifie pas que la pile Ă©tait pleine, mais cela peut signifier que sa taille est Ă  peine suffisante, ce qui est dangereux. Elle devrait ĂȘtre augmentĂ©e et les tests poursuivis.

Comme dĂ©crit dans l' article # 31, lors de la mise en Ɠuvre des diagnostics, des zones supplĂ©mentaires, des «mots de protection», peuvent ĂȘtre situĂ©es sur l'un des bords de la zone de mĂ©moire de la pile. Le dĂ©bogueur peut ĂȘtre utilisĂ© pour suivre l'accĂšs Ă  ces mots, car toute tentative de les Ă©crire signifie un dĂ©bordement ou un Ă©puisement de la pile.

Liste de contrĂŽle de configuration de Nucleus SE


Étant donnĂ© que Nucleus SE a Ă©tĂ© conçu comme un systĂšme hautement flexible et personnalisable pour rĂ©pondre aux exigences des applications, il nĂ©cessite un nombre important de paramĂštres personnalisables. C'est pourquoi l'intĂ©gralitĂ© de cet article est en fait consacrĂ©e Ă  la configuration de Nucleus SE. Pour vous assurer de ne rien manquer, voici une liste de contrĂŽle de toutes les Ă©tapes clĂ©s que vous devez suivre pour crĂ©er l'application intĂ©grĂ©e Nucleus SE.
  1. Nucleus SE. , Nucleus SE , Nucleus SE .
  2. CPU/. .
  3. . , , .
  4. . . . , . 16 .
  5. . - main() ?
  6. . 4 , .
  7. , .
  8. .
  9. . , .
  10. . , .
  11. . , . . — 16 .
  12. . , .
  13. . , (, ).
  14. API. API, .


Le prochain article (le dernier de cette série) résumera toute l'histoire avec Nucleus SE et fournira également des informations pour vous aider à créer et à utiliser des implémentations Nucleus SE.

À 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.

Source: https://habr.com/ru/post/fr467763/


All Articles