2012-07-04 6 views
3

I - un débutant intégré - je me fraye un chemin dans le monde de la magie noire de la programmation embarquée. Jusqu'à présent, j'ai déjà gagné beaucoup de combats, mais ce nouveau bug semble difficile.Impossible de déboguer après avoir utilisé SysTick_Config

D'abord, mon embarqué configuration:

  • Olimex STM32-P207 (STM32F207)
  • Olimex ARM-USB-TOC-H JTAG
  • OpenOCD
  • Eclipse (avec le débogage matériel CDT et GDB
  • Codesourcery Toolchain
  • Fichier de démarrage et script de liaison (carte mémoire adaptée pour le STM32F207) pour RIDE (ce qui utilise GCC)
  • STM32F2xx_StdPeriph_Lib_V1.1.0

En utilisant les nombreux tutoriels et Q & Comme là-bas, j'ai pu mettre en place makefile, le code de liaison et démarrage et obtenu quelques exemples simples en cours d'exécution en utilisant la bibliothèque standard (le Blinky classique de la STM, en utilisant boutons et interruptions etc.). Cependant, une fois que j'ai commencé à jouer avec les interruptions de SysTick, les choses se sont mal passées.

Si ajoutez le SysTick_Config() appeler à mon code (même avec un SysTick_Handler vide), ...

int main(void) 
{ 
    /*!< At this stage the microcontroller clock setting is already configured, 
     [...] 
    */ 
    if (SysTick_Config(SystemCoreClock/120000)) 
    { 
    // Catch config error 
    while(1); 
    } 
[...] 

... alors mon débogueur commence à la (ligne) fonction NVIC_SetPriority() et une fois Je frappe "run" Je me retrouve dans le HardFault_Handler(). Cela ne se produit que lorsque vous utilisez le débogueur. Dans le cas contraire, le code fonctionne normalement (à partir des voyants clignotants). J'ai déjà beaucoup lu et essayé beaucoup (modification des options du compilateur, éditeur de liens, démarrage, essai d'autres codes avec des appels SysTick_Config()), mais rien n'a résolu ce problème. Une chose pourrait être un indice: Le compilateur démarre dans les deux cas (avec et sans l'appel SysTick_Config) à 0x00000184. Dans le cas sans l'appel SysTick_Config cela pointe au début de main(). En utilisant SysTick_Config cela pionts à NVIC_SetPriority().

Quelqu'un a-t-il une idée de ce qui se passe? Un indice sur où je pourrais continuer ma recherche d'une solution?

Je ne sais pas quelles autres informations seraient utiles pour résoudre cette énigme. S'il vous plaît faites le moi savoir et je serai heureux de fournir les pièces manquantes.

Merci beaucoup!

/edit1: Ajout des résultats de arm-none-eabi-readelf, -objdump et -size.

/edit2: J'ai supprimé les informations de code pour faire de la place pour le code réel. Avec cette nouvelle version simplifiée de débogage commence à

08000184: stmdaeq r0, {r4, r6, r8, r9, r10, r11, sp} 

readelf:

[ 2] .text    PROGBITS  08000184 008184 002dcc 00 AX 0 0 4 
... 
2: 08000184  0 SECTION LOCAL DEFAULT 2 
... 
46: 08000184  0 NOTYPE LOCAL DEFAULT 2 $d 
principale

.c

/* Includes ------------------------------------------------------------------*/ 
#include "stm32f2xx.h" 

/* Private typedef -----------------------------------------------------------*/ 
/* Private define ------------------------------------------------------------*/ 
/* Private macro -------------------------------------------------------------*/ 
/* Private variables ---------------------------------------------------------*/ 
uint16_t counter = 0; 

/* Private function prototypes -----------------------------------------------*/ 
/* Private functions ---------------------------------------------------------*/ 
void assert_failed(uint8_t* file, uint32_t line); 
void Delay(__IO uint32_t nCount); 
void SysTick_Handler(void); 
/** 
    * @brief Main program 
    * @param None 
    * @retval None 
    */ 
int main(void) 
{ 
    if (SysTick_Config(SystemCoreClock/12000)) 
    { 
    // Catch config error 
    while(1); 
    } 
    /* 
    * Configure the LEDs 
    */ 
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); // LEDs 

    GPIO_InitTypeDef GPIO_InitStructure; 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9; 
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; 
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; 
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; 
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; 
    GPIO_Init(GPIOF, &GPIO_InitStructure); 

    GPIOF->BSRRL = GPIO_Pin_6; 

    while (1) 
    { 
    if (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_9) == SET) 
    { 
     GPIOF->BSRRH = GPIO_Pin_9; 
    } 
    else 
    { 
     GPIOF->BSRRL = GPIO_Pin_9; 
    } 
    Delay(500000); 
    } 
    return 0; 
} 

#ifdef USE_FULL_ASSERT 

/** 
    * @brief Reports the name of the source file and the source line number 
    *   where the assert_param error has occurred. 
    * @param file: pointer to the source file name 
    * @param line: assert_param error line source number 
    * @retval None 
    */ 
void assert_failed(uint8_t* file, uint32_t line) 
{ 
    /* User can add his own implementation to report the file name and line number, 
    ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ 

    /* Infinite loop */ 
    while (1) 
    { 
    } 
} 
#endif 

/** 
* @brief Delay Function. 
* @param nCount:specifies the Delay time length. 
* @retval None 
*/ 
void Delay(__IO uint32_t nCount) 
{ 
    while (nCount > 0) 
    { 
    nCount--; 
    } 
} 

/** 
    * @brief This function handles Hard Fault exception. 
    * @param None 
    * @retval None 
    */ 
void HardFault_Handler(void) 
{ 
    /* Go to infinite loop when Hard Fault exception occurs */ 
    while (1) 
    { 
    } 
} 

/** 
    * @brief This function handles SysTick Handler. 
    * @param None 
    * @retval None 
    */ 
void SysTick_Handler(void) 
{ 
    if (counter > 10000) 
    { 
    if (GPIO_ReadInputDataBit(GPIOF, GPIO_Pin_8) == SET) 
    { 
     GPIOF->BSRRH = GPIO_Pin_8; 
    } 
    else 
    { 
     GPIOF->BSRRL = GPIO_Pin_8; 
    } 
    counter = 0; 
    } 
    else 
    { 
    counter++; 
    } 
} 

/EDIT3:

soultion: Parce que la solution est enfouit dans un commentaire, je l'ai mis ici:

Mon fichier de linker était absent ENTRY(your_function_of_choice); (par exemple Reset_Handler). Ajoutant ceci a fait mon travail de débogueur de nouveau (il commence maintenant au bon moment).

Merci à tous!

+0

Avez-vous ou pouvez-vous obtenir un fichier de carte contenant les adresses de toutes les fonctions non-statiques et les variables globales et l'adresse du point d'entrée? Je me demande si votre code ne compile pas correctement. –

+0

J'ai ajouté ci-dessus les résultats de bras-aucun-eabi-readelf, -objdump (petit fragment dû à la limite de caractères) et -size. Est-ce que cela contient ce que vous cherchez? –

+0

Essayez de simplifier votre code autant que possible et publiez le tout ici –

Répondre

2

J'ai un fort sentiment que le point d'entrée est pas correctement spécifié dans les options du compilateur ou script éditeur de liens ...

Et quel que soit le code vient d'abord à l'heure du lien dans la section ".text", il arrive à avoir la point d'accès.

Le point d'entrée, cependant, doit pointer vers une fonction spéciale « initialisation » qui fixerait la pile, initialiser la section ".bss" (et peut-être quelques autres sections aussi bien), initialiser tout matériel qui est nécessaire pour le fonctionnement de base (par exemple, le contrôleur d'interruption et peut-être une minuterie du système) et toutes les parties restantes des bibliothèques standard et avant de transférer le contrôle à main().

Je ne suis pas familier avec les outils et votre matériel, donc je ne peux pas dire exactement ce que la fonction spéciale "init" est, mais c'est à peu près le problème. Ce n'est pas indiqué par le point d'entrée du programme compilé. NVIC_SetPriority() n'a aucun sens là-bas.

+0

Je suppose que cette fonction init dont vous parlez est la fonction _SystemInit_ fournie par la bibliothèque standard. Voici un extrait du fichier de démarrage que j'utilise (celui de RIDE7): '/ * Appel de la fonction d'initialisation du système d'horloge. */ bl SystemInit /* Appelle le point d'entrée de l'application. */ bl main bx lr .size Reset_Handler,.-Reset_Handler' –

+0

Y a-t-il un moyen d'influencer ce point d'entrée? Et pourquoi mon code fonctionne-t-il correctement tant que je ne démarre pas avec mon débogueur? –

+0

Je ne sais pas comment fonctionne votre débogueur. Il peut s'agir d'une manière ou d'une autre d'utiliser ou d'affecter le matériel et les interruptions de manière à affecter votre code. En ce qui concerne le point d'entrée, vous devriez lire la documentation de votre compilateur/éditeur de liens et regarder les exemples de programmes fournis avec celui-ci et voir en quoi ils diffèrent des vôtres. –

Questions connexes