2017-08-13 7 views
0

Comment obtenir la valeur réelle de SP s'enregistrer?GCC ARM: obtenir la valeur réelle du registre SP

Je souhaite remplir toute la mémoire SRAM avec certaines valeurs initiales, mais je n'ai pas voulu remplacer le contenu réel de la pile.

mon code de démarrage (qui remplace également le contenu réel de la pile):

void RESET_handler() { 
    unsigned *src, *dst; 
    // initialize memory 
    // ..... 

    // fill SRAM 
    dst = &_bss_end; 
    while (dst < &_stacktop) { 
     *dst++ = 0x55555555; 
    } 
} 

_bss_end est fin de mémoire utilisée pour les variables statiques et _stacktop pointe vers la fin de la mémoire SRAM ou également en haut de la pile.

Bien que cette fonction soit réinitialisée, le gestionnaire gcc la rend sûre et commence par pousser certains registres dans la pile (more info). Oui à ce stade, le contenu réel de la pile n'est pas pertinent et l'écrasement est sûr, mais pour l'autorisation je voudrais arrêter de remplir avant la pile en remplaçant &_stacktop par la valeur réelle de SP.

Toutes les autres idées sont également les bienvenues sauf suggestion de réécrire le code de démarrage en assembleur.

+0

Les personnes défendant les normes C ne seront pas aimées votre question et mon commentaire. Qu'en est-il de 'char * approximativeStackTop (char x) {return (&x);}'? – Marian

+0

Je me demande quel est le but de tout l'exercice? Vous essayez de déboguer des problèmes de mémoire de cette façon? –

+0

@Felix pendant le développement est agréable de voir à quelle hauteur est la pile en cours, combien de mémoire libre avez-vous, est mieux que le calcul ou toute analyse statique – vlk

Répondre

1

Cela ne peut être fait de manière fiable que par la modification du fichier de démarrage.

Je se concentrer uniquement sur pile unique (pour fil * privilégié) exemple pour le démarrage de type openSTM32:

/* Call the clock system intitialization function.*/ 
    bl SystemInit 
/* Call static constructors */ 

    bl fillStack // <------------ add this 

    bl __libc_init_array 
/* Call the application's entry point.*/ 
    bl main 

Puis, dans l'un de vos fichiers C implémenter la fonction fillStack. utiliser instructions intrinsèques CMSIS comme __get_MSP()

+0

Merci pour votre avis, mais il y a un problème que mon modèle nu n'utilise pas CMSIS et j'évite complètement d'utiliser il. Mais j'ai inspiré comment CMSIS implémente la fonction '__get_MSP()' et c'est assez simple. Voici ma lecture msp modifiée: 'register unsigned * msp_reg; __asm__ volatile ("mrs% 0, msp \ n": "= r" (msp_reg)); 'qui fonctionne comme prévu dans mon démarrage. – vlk

+0

Une raison de ne pas utiliser le CMSIS? C'est juste un tas de définitions pratiques, typedefs, intrinsèques et inline. Ce n'est pas une bibliothèque - pas de frais généraux, pas de données ajoutées. CMSIS est le métal le plus dépouillé - rien que du matériel ordinaire. –

+0

Dans mes projets, j'ai des périphériques réécrits en classes ou structures C++ avec des champs de bits. J'évite complètement l'utilisation de '# define' mais j'utilise tous les biens de C++ 11/14 comme' namespace', 'class',' template', 'enum class',' auto', bitfields, fonctions 'inline', ...Le code est maintenant plus propre, mieux lisible et aussi les optimisations fonctionnent bien (le code est petit et aussi rapide) – vlk