STM32 functions are passed and not executed during debugging

My Environment:
1- Mac Os
2- STM32 Bluepill flashed with Blackmagic Prob firmware and acts as a Black magic probe
3- Stm32 Bluepill as a development board
4- CMSIS Frameworks

My Problem:
I am trying to program my STM32 blue pill and debugging it using a Blackmagic probe (a bluepill with BMP firmware)

I wrote the following code and when debugging it using BMP it starts getting executed but when reaching the delay1() function line of code, control just passes it and doesn’t execute it therefore the LED connected to the pin PB11 is always ON but dimmed because it gets switched ON and Off so fast and the delay function is not executed!

My question is:
What is going on? Why would control just jump and not execute a line of code?

 * ! Green LED -> PB11
 * * Blue LED  -> PB10
 * * Red LED   -> PB1
 * * Pot.      -> PA0
 * * Push Btn. -> PB9

//? ========= INCLUEDS =+=========
#include "STM32F1xx.h"

//? ========= PROTOTYPES ===========
void portsInit(void);
void delay1(void);

int main(void)

        //GPIOB->ODR ^= GPIO_ODR_ODR11_Msk;

void portsInit(void)
    //* Enable clock to port "A" and "B" (Default SysCLK = 8Mhz ext. OSC):
    RCC->APB2ENR |= ((1<<2) | (1<<3));

    //* Set Pin Modes and Pin Configuration. (Reset Value = 0x4444 4444)
    //! Setting Mode for Pin PB11 MODE[1:0], "Bit1" of the MODE register = 1 and "Bit0" = 1
    GPIOB->CRH |= GPIO_CRH_MODE11_Msk;           // Set PB11 MODE as Output @ 50Mhz (max).  
    //! Setting Configuration for Pin PB11 CNF[1:0]
    GPIOB->CRH &= ~(GPIO_CRH_CNF11_Msk);
        * Final GPIOB->CRH register must equal 0b 0011 0100 0100 0100 or 0x3444,
        * to set pb11 pin as an Output MODE @ 50Mhz configured as General purpose
        * output push-pull configuration.
}// End portsInit() Function.

void delay1(void)
    for(uint32_t i = 0; i < 10000000; i++)

/**     ============= Registers Can be used as well such as: ==================    
    //RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;       // Enable PortA Clock
    //RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;       // Enable PortB Clock
    Set pin "PB11" as output push-pull (Green LED)
    GPIOB->CRH |= ((1<<12) | (1<<13));        //Set Pin to Output 50Mhz max speed
    GPIOB->CRH &= ~((1<<14) | (1<<15));       //Configure Pin as Push-Pull


PS. I am using an extension for commenting!

The compiler optimizes this away completely since the function has no effects.

Just add asm("nop"); inside the loop or use the propper SysTick interrupts for timekeeping.

Thank you. It worked now. But I still do have some questions:

1- Is there any way I can control the optimization for the Debugged version and one for the Release version? (I am new to platformIO so please bear with me).
2- What could a proper SysTick be? can you please give me an example?

Thanks in advance.

Yes, see documentation. By writing build_type = debug you will turn off optimizations. You can also do the same (again see docs) by doing a build_unflags = -Os and build_flags = -O0 to remove the optimize size flag and set the optimize none flag.

If you look into the implementations of e.g. the STM32HAL with HAL_IncTick() and HAL_Delay() you’ll notice that it’s very simple. Configure the SysTick to fire every 1 millisecond and increment a variable there. To wait, reset that variable to 0 and wait until the value reaches the desired millisecond value.

Working tested example for a Bluepill and its builtin LED on PC13:

#include "stm32f1xx.h"
#define LED1 (13)
#define _MODER CRH

// Counter for millisecond Interval
//must be volatile to indicate to the compiler 
//that this variable is changed during an ISR and cannot be optimized
uint32_t volatile msTicks = 0; 

void SysTick_Handler(void)
  // SysTick Interrupt Handler. called every millisec
  msTicks++; // Increment Counter

void Device_Initialization(void)
  // update system core clock variable from current state
  // configure SysTick to fire every 1mSec
  if (SysTick_Config(SystemCoreClock / 1000))
    //error handler..

void ms_delay(uint32_t ms)
  //reset counter variable to 0
  msTicks = 0;
  //wait until interrupt has increased the
  //variable again after some time
  while (msTicks < ms)

//Alternates blue and green LEDs quickly
int main(void)
  ENABLE_GPIO_CLOCK;            // enable the clock to GPIO
  LEDPORT->_MODER |= GPIOMODER; // set pins to be general purpose output
  for (;;)
    LEDPORT->ODR ^= (1 << LED1); // toggle diodes

  return 0;

as src\main.c.

This works with all optimizations enabled.