Comment faire pour déterminer le maximum de l'utilisation des piles?
Quelles méthodes sont disponibles pour la détermination de l'optimum de la taille de la pile pour l'embarqué et de contrainte de mémoire système? Si elle est trop grande alors la mémoire est perdu qui pourrait être utilisé ailleurs. Toutefois, si elle est trop petite alors nous obtenons ce site homonyme du...
Pour essayer de sauter démarrer les choses: Jack Ganssle états L'Art de la Conception de Systèmes Embarqués que, "Avec l'expérience, on apprend à la norme scientifique de calculer la taille appropriée pour une pile: Choisir une taille au hasard et de l'espoir." Quelqu'un peut-il faire mieux que ça?
Un exemple plus spécifique a été demandé. Alors, comment faire un programme en C, en ciblant un MSP430 MCU avec 2 ko de RAM à l'aide de la IAR Embedded Workbench de la chaîne sans un système d'exploitation? Cette IDE peut afficher le contenu de la pile et l'utilisation tout en utilisant un JTAG débogueur.
- dépend du chipset / OS / langage de programmation que vous utilisez.
- Content de voir que cette question n'a de réponses à certaines questions, à la différence de stackoverflow.com/questions/177516/...
- J'ai vu que la question lors de la demande, mais la pensée intégré à l'inclinaison séparés...
- Jack Ganssle dit plus que cela. Je pense que c'était juste son intro one-liner. De son livre, 2e édition, p. 250: "Depuis quelques programmeurs ont, d'une manière raisonnable afin de déterminer maximale de la pile exigences, toujours assumer vos devis sera incorrect. Pour chaque pile dans le système, assurez-vous que le code d'initialisation remplit l'ensemble de la quantité de mémoire allouée à la pile avec la valeur 0x55. Plus tard, lors du débogage, vous pouvez afficher la pile et de détecter les débordements de pile en le voyant aucun des blocs de 0x55 dans cette région..."
- Je sais que ce n'est pas tout, dit-il, mais j'ai essayé d'utilisé de la même manière qu'il a fait: susciter l'intérêt pour le sujet. 😉
Vous devez vous connecter pour publier un commentaire.
La façon la plus courante pour déterminer la plus profonde de l'utilisation des piles est d'initialiser la pile de la mémoire avec certains connus, mais une valeur inhabituelle, puis périodiquement (ou à la fin d'un grand test) voir où ce modèle s'arrête.
C'est exactement comment le RAP IDE détermine le montant de pile utilisé.
Vous tagged votre question avec d'analyse statique, mais c'est un problème qui est difficile à résoudre par le biais d'analyse statique. L'utilisation des piles dépend du programme du profil d'exécution, en particulier, si vous êtes en utilisant la récursivité ou alloca. Étant donné que c'est une plate-forme intégrée, je suppose que c'est aussi difficile à exécuter quelque chose comme ps ou haut et de voir combien la pile de votre application utilise.
Une approche intéressante consiste à utiliser l'adresse de l'actuel cadre de la pile afin de déterminer combien de pile est utilisé. Vous pouvez le faire en prenant l'adresse d'une fonction est un argument ou d'une variable locale. Que faire pour les principal fonction et pour les fonctions que vous pensez sont à l'aide de la plupart de la pile. La différence va vous dire le montant de la pile de votre application. Voici un exemple (en supposant coutumier de faible à élevée, croissance de la pile).
Si votre compilateur permet de spécifier une fonction personnalisée prologue (beaucoup de le faire pour permettre à base de graphe programme de profilage), vous pouvez même organiser pour toutes les fonctions à appeler un tel code de mesurage. Ensuite, votre fonction de mesure mecomes quelque chose comme
J'ai utilisé une approche similaire à ce que j'ai décrit pour générer ces cartes.
Avec une bonne source code outil d'analyse statique, vous pouvez produire un graphe d'appel pour votre application. Étant donné que, et des estimations de la quantité de gens du pays/temporaires produites par votre compilateur, vous pouvez carrément calculer une estimation prudente de la pile de la demande.
Ce que j'entends par "bon" outil d'analyse est celui qui peut lire toutes les unités de compilation possible de déterminer directement les appels de fonction, peut déterminer indirecte des pointeurs, dans le compilaiton unité, peuvent calculer un conservateur des points à l'analyse sur l'ensemble du système, permet de construire un graphe d'appel de prendre en compte les points à l'analyse. Ceci élimine beaucoup d'outils, c'est pourquoi l'on voit des méthodes ad hoc tels que le "remplissage de la pile lors de l'exécution et de voir ce qui se passe". Vous avez également besoin d'estimations de la pile des demandes le compilateur place sur la pile; vous pouvez vous rapprocher d'un lot de ce par le simple fait de savoir comment grand les exigences de stockage de tous les types, ce qui est généralement assez facile à déterminer pour les systèmes embarqués C programmes. Enfin, vous devez croire que vous application n'a pas d'appels récursifs, ou que l'outil a une idée de la plus profonde de la récursivité (probablement par vous dire.
Le Logiciel DMS Réingénierie Toolkit répond à toutes ces exigences pour les programmes en C.
Voir http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html
Vous avez encore le configurer pour le calcul de la pile de la demande par l'analyse du graphe d'appel et d'utilisation des diverses estimations de la taille.
Si vous voulez une réponse rapide, l'utilisation de la pile de remplissage de truc. Si vous voulez une réponse que vous pouvez recalculer après chaque source de changement de code, vous aurez besoin de l'analyse statique approche.
Je suis en train de travailler sur ce problème dès maintenant - c'est à dire le calcul analytique de stacksize.
Il est de toute évidence un très récursive morceau de code, en raison d'un appel de fonction pourrait avoir un tableau indexé, ou un ou plusieurs de ses arguments et un ou plusieurs des indices de tableau pourrait impliquer des appels de fonction!!
Cependant, un couple de réalisations permettent un certain soulagement de la complexité:
(1) Lors de l'utilisation d'un langage de haut niveau du compilateur, le stackpointer à la fin de l'exécution de chaque instruction/la ligne de code doit être à la même place, comme il l'était au début.
(Au moins, ce serait une bonne règle à respecter, sinon vous allez avoir des problèmes!)
(2)Le stackpointer après le retour de chaque fonction ou une sous-routine d'appel doit être la même qu'elle était avant l'appel. Par conséquent, le maximum de la taille de la pile est le maximum, plus que toutes les instructions du programme, de la pointe stacksize atteint dans chaque état.
(Au moins, ce serait une bonne règle à respecter, sinon vous allez avoir des problèmes!)
De cours d'une instruction peut inclure le récursive problèmes que j'ai mentionnés ci-dessus, mais au moins le problème de trouver le maximum d'stacksize exigence de tout un programme, puis revient à trouver le maximum d'stacksize exigence de chaque énoncé, puis ramasser le maximum de personnes.
Ce ne peut être complété jusqu'à ce que toutes les fonctions appelées ont été compilés. J'ai donc générer un fichier pour chaque module compilé qui enregistre un certain nombre de stacksizes pour chaque énoncé
(en gros la valeur de crête avant chaque appel de la fonction et de la valeur immmediately avant chaque appel de fonction (à l'exclusion de toute encore inconnu des ajouts à stacksize causés par l'appel de la fonction), et les noms de fonction en cause. Ensuite, j'ai rétrospectivement traiter ces fichiers à l'aide d'une routine récursive, une fois que toutes les fonctions ont été compilés, pour déterminer les pics stacksize.
La chance, c'est que, fonctions récursives outre, le maximum possible stacksize exigence ne dépend alors de flux de programme, bien que dans un flux typique (qui sont des données dépendantes) ce maximum possible stacksize ne peut jamais être atteint.
Exemple: Supposons que la fonction 1 les appels de fonction 2 et le déroulement du programme, à la fois dépend de la valeur de données de X. Supposons qu'il y est une gamme de X qui provoque de fonction 1 à l'exécution de ses pires déclaration, qui comprend un appel à la fonction 2, qui n'exécute pas son pire des cas, la déclaration pour la même gamme de X. Puisque nous avons calculé le maximum possible stacksize en utilisant le pire des cas pour les deux fonction 1 et la fonction 2 en même temps, nous pouvons avoir surestimé la taille de la pile. Au moins nous avons commis une erreur sur le côté sécuritaire.
J'aime faire des routines d'interruption de leur propre stackspace sur un OS de la pile si elle a besoin, afin de ne pas ajouter à la pile de programme exigences, à part le retour de l'interruption de l'adresse
Puis examiner à la main la portion de code, où la recherche de l'utilisation des piles est probablement le plus élevé (souvenez-vous je n'en dit pas des tableaux)