Global variable is set to zero without updating

Dear Community members!

I have declared a global variable as flag and initialized by 0. This flag is only written by a function MosfetSwitch(), when this function calls first it set mosfetFlag = 1, but after this fn. is over mosfetFlag is being set to 0 again during other functions call.
Hence it always executing if(!mosfetFlag) block at mosfetFlag is kept toggling as observed in live expression view.

uint8_t mosfetFlag = 0;
void MosfetSwitch(void)
{
	if ( clBMS.clIO.IoGPIO_vGetLevel(GPI_Ext_HVIL) )  //always true
        {
		if(!mosfetFlag){
               /*some function to set pin*/
		mosfetFlag =1;
		}
	}
	else{                         //this block is intentionaly kept unreachable for hw testing
	        /*function to reset pin*/
		mosfetFlag = 0;
	}
}


void StartTask03(void *argument)
{
  /******/
  for(;;)
  {
    fn1();
    fn2();
    MosfetSwitch();
  }
}

**In another scenario when initialized mosfetFlag = 1**

uint8_t mosfetFlag = 1;
void MosfetSwitch(void)
{
	if ( clBMS.clIO.IoGPIO_vGetLevel(GPI_Ext_HVIL) )  //always true
        {
		if(mosfetFlag){      //modified to make reachable
               /*some function to set pin*/
		mosfetFlag =2; 
               .
               .
               .
               .
       }
     else(){
      .
      . 
      mosfetFlag = 0;
      }
}

in this case mosfetFlag is not being set to 0 again.

I kept tried to kept mosfetFlag as volatile or static to see some compiler issue. but the variable 'mosfetFlag ’ is always showing exact behaviour when initialised with 0 and 1 seperatly.

total heap size used 32768
heap still available 10180
memory management scheme heap_4/ heap_5
compiler optimization level -O0

configured by stm32 CubeIDE for stm32g474xx controller.
I am not sure is this the issue of gcc or freeRTOS.

Are you sure MosfetSwitch() is not called by more than 1 FreeRTOS task? Does any ISRs directly update mosfetFlag or call MosfetSwitch()? If it can get updated by more than 1 execution context, you need to protect access to mosfetFlag maybe with a mutex.

If its just one task only updating mosfetFlag and you are still seeing the issue, then probably its due to a memory overwrite. I would try putting a hardware breakpoint [eclipse example] in the address at which mosfetFlag is stored to figure out how is it getting modified without any explicit calls to modify it.

1 Like

One possible explanation of the different behaviour is that this variable is placed in different sections (bss and data) depending on whether it is initialized to 0 or 1 and you have a memory corruption in bss section. As @tony-josi-aws suggested, use data breakpoints to catch memory corruption.

The issue i found is an array is going out of bound, and overlapping location of mosfeFlag.

Thanks Toni : )

sorry for confusion, the exact behaviour with 0/1 is compared to when mosfetFlag variable is declared extern, static and volatile. Issue is fixed now.

another question is,
any variable if not initialized then only it goes in bss, or does it also take space in bss if explicitly initialized with zero?

Thanks for reporting back.

any variable if not initialized then only it goes in bss, or does it also take space in bss if explicitly initialized with zero?

Any global or static variable, if not initialized, goes in BSS. Those that are explicitly initialized to zero can be either in the BSS or data section, depending on the compiler.

You can take a look at -fno-zero-initialized-in-bss if using GCC.

1 Like

Hint: You have to declare this kind of global variable used in multiple tasks resp. ISRs and task(s) volatile (as you finally did ?). Otherwise (compiler optimized) code may or may not work as expected.

1 Like