STM32HAL need HAL_gettick() but CMSIS_OS2 without os_time how do i ... ( ¯¨̯ ¯̥̥ )
Hi,
here is the solution for CMSIS-RTOS2.
#include "cmsis_os2.h" /** * Override default HAL_GetTick function */ uint32_t HAL_GetTick (void) { static uint32_t ticks; uint32_t i; if (osKernelGetState() == osKernelRunning) { return ((uint32_t)osKernelGetTickCount ()); } /* If Kernel is not running wait approximately 1 ms then increment and return auxiliary tick counter value */ for (i = (SystemCoreClock >> 4U); i > 0U; i--) { __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); } return ++ticks; }
Best regards, Milorad
Interesting. I tried something similar a while back but I found that osKernelGetState() didn't always return osKernelRunning as one would expect once the system was up and running.
Can't remember exactly, but I'm sure it sometimes returned osKernelError which caused the function to use the manually incremented tick (as in the above example). This in turn plays havoc with any HAL library calls that use HAL_GetTick(). I suspected that the problems I was seeing were as a result of the occasional osKernelError, and then the manual tick++ was very different to the values returned by osKernelGetTickCount().
I gave up investigating why I was seeing osKernelError (It was a while ago).
Now I just use a simple version which works for me:
uint32_t HAL_GetTick (void) {
return (uint32_t)osKernelGetTickCount();
}
If you could duplicate situation in which osKernelGetState() would return osKernelError it would be usefull to find the root cause.
Anyways, your implementation does not take into account that usually HAL_Init is done while RTOS is not running, and there are some delays there which depend on tick incrementing, so it might be that some time dependant operations are not executed with required delays thus it could cause improper initialization.
Also, your implementation on F7 would cause Hard Fault as osKernelGetTickCount() is not allowed if RTOS is not running.
Thank you for that info.
It was a while ago and much has changed in my system since then, but if I am able to reproduce the problem I will definitely open a ticket.
Excellent, thank you!
Despite multiple attempts over the past few days, I have not been able to reproduce the above osKernelError problem. Your delay works perfectly, as does my original one.
Most likely case is that I must have been doing something stupid.
Hi Milorad,
I use your nops delay exactly and I get a delay of 1 sec !!!! I use STM32F4 and Keil compiler and my SystemCoreClock is 72MHz. What is your SystemCoreClock?
Hi Julio,
I guess you are right, the SystemCoreClock should be also divided by 1000, so to not use integer math we should divide it by 1024 (it is close enough for this usage case) which is same as shifting to right for 10 bits, so the "for" loop should be corrected as follows:
for (i = (SystemCoreClock >> 14U); i > 0U; i--) { __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); }