Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Over opmisation in STM32F407 blinking LED

Status
Not open for further replies.

yefj

Advanced Member level 5
Advanced Member level 5
Joined
Sep 12, 2019
Messages
1,505
Helped
1
Reputation
2
Reaction score
5
Trophy points
38
Activity points
9,113
Hello, I wrote a blinking LED program for my SRM32F407 descovery.
but i got to the conclution that my KEIL compiler optimises away the FOR loop.
My KEIL uses -O1
In the internet i read that its about the local I vaiable in the for loop and that i should try to make it volotile.
But my video manual didnt use volotile.
What could be done?
Thanks.

Code:
#include "stm32f407xx.h"

int main()
{
    
    
    RCC->AHB1ENR|=(1uL<<3); //set thirdbit
    //GPIOD->MODER&=~(1uL<<31);//reset 0 on 31 01 to gpio_moder 31,30 bits in register
    //GPIOD->MODER|=(1uL<<30);//set 1 on 30 output mode for pin 15 port D
    GPIOD->MODER=0x55000000;
    
    
    GPIOD->OTYPER=0; //all register is push pull
    GPIOD->OSPEEDR=0;//speed low
     //GPIOD->ODR|=(1<<15); //Sets pin 15


    while(1)
        
    {
         GPIOD->BSRR=(1uL<<15);
            for(uint32_t i=0;i<500000;i++){}
     GPIOD->BSRR=(1uL<<(15+16));       


    }
}

1612452489364.png
 

I'm not even a software programmer, but this statement doesn't do anything.
for(uint32_t i=0;i<500000;i++){}

It makes perfect sense that the compiler will remove it. Doing nothing once is the same as doing nothing 500,000 times.
 
  • Like
Reactions: yefj

    yefj

    Points: 2
    Helpful Answer Positive Rating
This is a common situation people find themselves in when they try to create a small delay loop for themselves, even with a compiler that has little (or no) optimisation turned on.
as @ADS-e says, the compiler sees that nothing happens inside the loop and so removes it.
I've not used the Keil compiler but check to see if it has any built-in delay functions/macros and use those if you can.
There are other alternatives. Try creating a 'volatile' global variable and assign the 'i' value to that. Volatile is a signal to the compiler that the current compilation unit may not be the only thing that us updating the variable and therefore do not optimise it away.
Depending on how long you want the delay, you could use one of the timers in the MCU - set it up and then poll its flag (which will be declared volatile in the supplied files for the reason mentioned above.
Susan
 
  • Like
Reactions: yefj

    yefj

    Points: 2
    Helpful Answer Positive Rating
Hi,

I generally tend to say that "busy wait" just consumes all the processing power.

In your case - independent how powerful your processor is - the simple task "blinking a LED" consumes 100% of processing power.

Thus I just use "busy wait" for setup before the main loop.
During normal operation (within main loop) I avoid it as good as possible.
I use interrupts and hardware periferals instead.
* Using interrupt it will counsume less than 0.1% of processing power.
* Using hardware it will consume 0% (really zero) processing power.

Both solutions are not difficult and need just a couple of lines of code.
But you (the programmer) needs to leave the idea, that all things happen according code in a straight line. You need to learn that the hardware actively makes things beside your code ... or that your (main) code us interrupted ..and the ISR is processed.
A cleanly written ISR will not alter your main() behaviour. So once you have written your "blink LED" in ISR style you just enable/disable the LED in main via a global variable ... and forget about it.

In main() you may use (different approaches)
* blinkLed = false // to disable blinking
* blinkLed = true // to enable blinking
Or
blinkLed = 5 // to make the LED flash 5 times, then automatically stop LED (by downcounting blinkLed variable in ISR)
blinkLed = 0 // to immediately stop blinking

Again: with ISR method you just set the "blinkLed" variable, then forget about it. Do whatever you want in main() ... your LED will blink as desired.

Klaus
 
  • Like
Reactions: yefj

    yefj

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top