This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problem on debugger with extern variable

Hello everybody,
I have a problem with a global variable. This variable is declared as extern.
It is reset to 0 automatically inside the Keil µVisionb 4 debugger when used in a function written in different C file.
I make deeper reference.

I declared variable in a header like this

#ifdef __VAR_G
        #define __DEF
#else
        #define __DEF extern
#endif

__DEF uint32_t SystemCoreClock;
__DEF   uint32_t Init_OK;

I use this variable twice :
Firstly in a.c file

#define __VAR_G
#include "stm32f4xxiut.h"
void SystemInit()
{
    Init_OK = Init_OK | HSE_FAIL;
    SystemCoreClock=16000000;
}

Secondly in b.c file

#include "stm32f4xxiut.h"
void main()
{
    int b=0;
    if (Init_OK==1)
        b=2;
}

My problem is the following.
In the keil debugger, with STM32F4XX, first, system init is executed. The both variable are declared as global and a value is assigned to them. Then, the core branch to main and the both variable are reset to zero in spite of the extern keyword used inside the definition.

Do you know why there is this strange behaviour.

Thank you.

Parents
  • System_Init() initializes clock.

    Exactly. And that's all you're supposed to do in there. Writing normal C variables is stricly outside the set of things you're allowed to do in there.

    These two variables are to save clock frequency

    And why on earth would you need a variable to store this in, although it is beyond all reasonable doubt a compile-time constant?

    and the second is a kind of register to know what is working or not inside initialization without checking every register.

    Except that it's not any kind of register. It's a C variable.

    It is not classical C variable for my program which them will be declare and initialize inside main.

    Now you're being ridiculous. Well, either that, or you have not the slightest idea what the words you're using actually mean.

    Because, in contrast to what you say now, that's exactly what those things are: plain ordinary C variables. Your own code treats them every bit as if it were one: you set the variable to some value in one place, and expect it to keep that value until modified by an assignment later.

Reply
  • System_Init() initializes clock.

    Exactly. And that's all you're supposed to do in there. Writing normal C variables is stricly outside the set of things you're allowed to do in there.

    These two variables are to save clock frequency

    And why on earth would you need a variable to store this in, although it is beyond all reasonable doubt a compile-time constant?

    and the second is a kind of register to know what is working or not inside initialization without checking every register.

    Except that it's not any kind of register. It's a C variable.

    It is not classical C variable for my program which them will be declare and initialize inside main.

    Now you're being ridiculous. Well, either that, or you have not the slightest idea what the words you're using actually mean.

    Because, in contrast to what you say now, that's exactly what those things are: plain ordinary C variables. Your own code treats them every bit as if it were one: you set the variable to some value in one place, and expect it to keep that value until modified by an assignment later.

Children
  • The following is straight from ST's system_stm32f0xx.c (my emphasis added) - I imagine that the OP's STM32F4xx would be similar:

    /**
      ******************************************************************************
      * @file    system_stm32f0xx.c
      * @author  MCD Application Team
      * @version V1.0.0
      * @date    23-March-2012
      * @brief   CMSIS Cortex-M0 Device Peripheral Access Layer System Source File.
      *          This file contains the system clock configuration for STM32F0xx devices,
      *          and is customized for use with STM32F0-DISCOVERY Kit.
      *          The STM32F0xx is configured to run at 48 MHz, following the three
      *          configuration below:
      *            - PLL_SOURCE_HSI (default): HSI (~8MHz) used to clock the PLL, and
      *                                        the PLL is used as system clock source.
      *            - PLL_SOURCE_HSE          : HSE (8MHz) used to clock the PLL, and
      *                                        the PLL is used as system clock source.
      *            - PLL_SOURCE_HSE_BYPASS   : HSE bypassed with an external clock
      *                                        (8MHz, coming from ST-Link) used to clock
      *                                        the PLL, and the PLL is used as system
      *                                        clock source.
      *
      *
      * 1.  This file provides two functions and one global variable to be called from
      *     user application:
      *      - SystemInit(): Setups the system clock (System clock source, PLL Multiplier
      *                      and Divider factors, AHB/APBx prescalers and Flash settings),
      *                      depending on the configuration selected (see above).
      *                      This function is called at startup just after reset and
      *                      before branch to main program. This call is made inside
      *                      the "startup_stm32f0xx.s" file.
      *
      *      - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
      *                                  by the user application to setup the SysTick
      *                                  timer or configure other parameters.
      *
      *      - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
      *                                 be called whenever the core clock is changed
      *                                 during program execution.
    

    So they do seem to be suggesting that the user code can just read this global?!

    This will work provided you call SystemCoreClockUpdate() before the user code first uses the SystemCoreClock variable - but the documentation above certainly doesn't make that clear!