cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_gpio driver switching speed

gerhard
Associate II
Posted on August 09, 2016 at 19:29

Is the HAL_gpio driver slow compared to driving a pin in another fashion?

If I use

HAL_GPIO_WritePin(GPIOA, ANA_IN_J1_02_Pin, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOA, ANA_IN_J1_02_Pin, GPIO_PIN_SET);

At 16MHz I would expect the pin to toggle at 8MHz but the highest it does is about 600KHz, so High/Low for about 700nS

Any help appreciated

6 REPLIES 6
Posted on August 09, 2016 at 19:48

At 16MHz I would expect the pin to toggle at 8MHz...

Why, because one line of C equates to a single CPU instruction? Look at a disassembly/listing of the code output by the compiler.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
gerhard
Associate II
Posted on August 09, 2016 at 20:37

clive1

I guess I should have asked the question differently.

Is there any other way of using the HAL libraries so there is less delay in the transition time of the pin.

Posted on August 09, 2016 at 21:02

If the real question is how do I generate an 8 MHz signal, the answer is to use a timer.

You'd have to determine how thickly wrapped your abstraction is, if it goes to a function you've got to load 3 registers and a call/return penalty. Your distance between 600 KHz and 8 MHz is 13 cycles. Can the optimizer recognize the case?

You could be more explicit so it doesn't call a function.

GPIOA->BSRR = 0x00000001;

GPIOA->BSRR = 0x00010000;

Using preloaded pointers and constants, the compiler might do a better job optimizing.

If this is some test of CPU performance, and it's a poor metric, I'd use assembler to repeatedly STR into the BSRR register in an unwound loop. At some point you'd get limited by the write buffers, and the slowness of the peripheral buses.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
gerhard
Associate II
Posted on August 09, 2016 at 22:34

clive1

Thanks. I will try this.

I'm trying to use the HAL libraries / Drivers as much as possible to avoid using ASM.

The only thing I was realizing is the response time is slow, so if an interrupt needs to toggle a pin, it looses 700nS or so.

I know other guys may suggest using the old STM libraries, but if I can use the STMCubeMX generated output sufficiently, (with some tweaks like you suggested), it beats re-inventing the wheel.

Regards

Chris1
Senior III
Posted on August 09, 2016 at 23:42

If the HAL Library for the device you are using has low-level files, you could use those.

 

For example, if you include stm32l4xx_ll_gpio.h in your project, you can call functions like LL_GPIO_SetOutputPin(), which should be essentially equivalent to directly writing to registers like GPIOA->BSRR.

LL_GPIO_SetOutputPin() code from stm32l4xx_ll_gpio.h:

__STATIC_INLINE void LL_GPIO_SetOutputPin(GPIO_TypeDef *GPIOx, uint32_t PinMask)

{

  WRITE_REG(GPIOx->BSRR, PinMask);

}

Posted on August 09, 2016 at 23:47

You don't specify a specific STM32 or Cortex-Mx core, but  you're going to burn ~12 cycles every time you enter and exit interrupt context. So you are generally going to want to avoid MHz, or >100's KHz interrupt frequencies. Where possible you'd want to decimate the load as much as possible, ie use DMA to do 10 or 100 operations between the need to poke the hardware directly with an interrupt service.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..