2020-10-02 01:30 PM
Hi I am starting to do some basics with register operations and came across with this situation.
The board I am using is a STM32L031k6 nucleo.
Code is the following
#include "stm32l031xx.h"
// Green led is at PB3
static void delay_ms(uint32_t delay);
int main(void)
{
// Enable clock for GPIOB
RCC->IOPENR |= RCC_IOPENR_GPIOBEN;
// Set Gpio B3 as output, default mode is analog mode
GPIOB->MODER = (GPIOB->MODER & ~(GPIO_MODER_MODE3)) | (GPIO_MODER_MODE3_0);
while (1)
{
GPIOB->BSRR |= 0x8;
delay_ms(20);
GPIOB->BRR |= 0x8;
delay_ms(20);
}
}
void delay_ms(uint32_t delay)
{
for (; delay > 0; delay--)
{
for (uint16_t i = 0; i < 2000; i++)
{
/* code */
}
}
}
if function is not declared as static, it never works.
If declared as static, it works most of the times that I do clean-build-transfer ( I don' t understand when it doesn' t)
if declared as __INLINE code takes like extra 60 B of space and works.
As IDE I am using VSCode with stm32-for-vscode extension, which sets the makefile based on a CubeMx proy.
Is the compiler doing some optimization and removing the function ? Is the MCU hanging for some reason ?
2020-10-02 02:23 PM
That's a bad delay function. The compiler can optimize it out entirely. It is probably doing so in certain cases.
A better (but still bad) delay would use volatile variables to prevent them from being optimized out. A good delay would be based on actual time, such as systick or timer counts.
2020-10-03 01:06 AM
Thanks for the answer, what will change in this case calling it static or inline? I am aware that the way to go would've been as you said, timmer count or systick. I wanted something fast for the sake of blinking the led I will change it.
2020-10-03 03:08 AM
For an active delay function based on the cycle counter have a look at:
https://community.st.com/s/question/0D53W00000BJ7KdSAL/is-haldelay1-quaranteed-to-be-close-to-1ms
2020-10-03 03:40 AM
For your quick test to work, add volatile qualifier for both - delay and i variables.
2020-10-03 04:02 AM
Adding volatile to i and neither of static nor inline for the function declaration made it work. Thanks a lot.
2020-10-03 05:09 AM
You shouldn't need to RMW against BRR/BSRR, the whole point is you can do a single write at a bit level.
Review the code output by the compiler, and run in the debugger.
For the cases that dont work, inspect the listing file, and show that code.
Use the counter in a freerunning TIM to mark time.
Use a scope to see signals faster than the human eye.