This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

CMSIS-RTOS2 and CMSIS perpherial code HAL timeout

Folks
Looking for a sanity check and perhaps looking to see how others are dealing with this issue

So I had fault with a peripheral on a stm32F1xx where basically it would never timed out
so that the PC would end up caught in a while() loop it effectively killed an RTOS task and caused the system to
fail in a bad way.

Looking at the ST provided CMSIS HAL Driver code eg SPI transmit receive code
you see references to

  /* Init tickstart for timeout management*/
  tickstart = HAL_GetTick();

and its used later in

      if((Timeout != HAL_MAX_DELAY) && ((HAL_GetTick()-tickstart) >=  Timeout))
      {
        errorcode = HAL_TIMEOUT;
        goto error;
      }

so in stm32f1xx_hal.c you find the systick timer code e.g.

/**
  * @brief Provides a tick value in millisecond.
  * @note  This function is declared as __weak  to be overwritten  in case of other
  *       implementations in user file.
  * @retval tick value
  */
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

I started my project using ST MXCube and in the stm32f1xx_it.c because I knew
I was be going to use an RTOS eg from the Keil runtime commented out the
SysTick_Handler because its also declared in the rtx libraries

/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
  /* USER CODE BEGIN SysTick_IRQn 0 */

  /* USER CODE END SysTick_IRQn 0 */
  HAL_IncTick();
  HAL_SYSTICK_IRQHandler();
  /* USER CODE BEGIN SysTick_IRQn 1 */

  /* USER CODE END SysTick_IRQn 1 */
}

So going back to the HAL_GetTick() function I quickly wrote this in main.c of the ST MxCube produced code


#include "RTX_Config.h"
static osKernelState_t mosKernalState = osKernelInactive;
static uint32_t mlFakeTick = 0;
static uint32_t muwTick = 0;
static uint32_t muwTickTarget = 0;

uint32_t HAL_GetTick(void)
{
  if(osKernelRunning == mosKernalState)
  {
    muwTick = osKernelGetTickCount();
    return muwTick;
  }
  else
  {
    if(0 == muwTickTarget)
    {
      muwTickTarget = (SystemCoreClock/OS_TICK_FREQ);
      mlFakeTick = 20; // give 10 cycles or so for first starting off
    }
    else
    {
      mlFakeTick + =20;  // swag at cycle count from being here last time
      if(mlFakeTick > muwTickTarget)
      {
        muwTick ++;
        mlFakeTick = 0;
      }
    }
  }
  return muwTick;
}

extern SystemCoreClock in declared in system_stm32f1xx.c

OS_TICK_FREQ is declared in "RTX_Config.h"

then in the main() function

  if (osKernelReady == osKernelGetState())
  {
    mosKernalState = osKernelRunning;
    osKernelStart(); // Start thread execution
  }

So now the Perpherials now timeout if theres a fault.

Has anyone else come across this problem when using HAL CMSIS code and an RTOS where the
system tick interrupt has been redirected from the HAL CMSIS code?

Anyone got any suggestions for a better work around ?
eg using pointer to functions for things like osKernelGetTickCount()

Parents Reply Children