Tick Rate Problem

k3nt00 wrote on Tuesday, December 23, 2014:

Hello,

I’m having some trouble with the tick rate. I am using the CORTEX_STM32F107_GCC_Rowley demo, but on a different board with the same exact chip and crystal clock frequency of 25MHz. The prvSetupHardware() func sets the clock up for 62.5MHz. I have I2C and UART working at the correct rates. What I can can’t seem to get working at the expected timing is the tick rate. My tick rate is set for 1000Hz. When I run a single and simple task that simply toggles a pin and then vTaskDelayUntil for 1 tick, it ends up being ~30ms when it should be 1ms. I’ve been trying to figure out what I’m doing wrong, but haven’t. Any help is greatly appreciated!

Thank you
I am using:
Chip: STM32F107VC (Cortex-M3)
Compiler: arm-none-eabi-gcc
Version: FreeRTOS V8.0.1

edwards3 wrote on Tuesday, December 23, 2014:

You have set your tick to give you a resolution of 1ms, so if you try and block for 1ms I would expect to block for between 0.00001 and 0.99999ms, so you will get odd results, but you should not get longer than 1ms. If you are getting 30ms then likely the SysTick clock in your STM32 is not running at the frequency you think it is. The SysTick is part of the core of the STM32.

k3nt00 wrote on Wednesday, December 24, 2014:

I actually get ~30ms when using 1-10 delay ticks. If I use greater than 10, the actual blocking delay is (ticks x 3).

my hardware setup func


static void prvSetupHardware( void )
{
    /* Start with the clocks in their expected state. */
  RCC_DeInit();

  /* Enable HSE (high speed external clock). */
  RCC_HSEConfig( RCC_HSE_ON );

  /* Wait till HSE is ready. */
  while( RCC_GetFlagStatus( RCC_FLAG_HSERDY ) == RESET )
  {
  }

  /* 2 wait states required on the flash. */
  *( ( unsigned long * ) 0x40022000 ) = 0x02;

  /* HCLK = SYSCLK */
  RCC_HCLKConfig( RCC_SYSCLK_Div1 );

  /* PCLK2 = HCLK */
  RCC_PCLK2Config( RCC_HCLK_Div1 );

  /* PCLK1 = HCLK/2 */
  RCC_PCLK1Config( RCC_HCLK_Div2 );

  /* PLLCLK = (25MHz / 2 ) * 5 = 62.5 MHz. */
  RCC_PLLConfig( RCC_PLLSource_HSI_Div2, RCC_PLLMul_5 );

  /* Enable PLL. */
  RCC_PLLCmd( ENABLE );

  /* Wait till PLL is ready. */
  while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
  {
  }

  /* Select PLL as system clock source. */
  RCC_SYSCLKConfig( RCC_SYSCLKSource_PLLCLK );

  /* Wait till PLL is used as system clock source. */
  while( RCC_GetSYSCLKSource() != 0x08 )
  {
  }

  /* Enable GPIOA, GPIOB, GPIOC, GPIOD, GPIOE and AFIO clocks */
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB |RCC_APB2Periph_GPIOC
              | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_AFIO, ENABLE );

  /* Set the Vector Table base address at 0x08000000 */
  NVIC_SetVectorTable( NVIC_VectTab_FLASH, 0x0);

  NVIC_PriorityGroupConfig( NVIC_PriorityGroup_4 );

  /* Configure HCLK clock as SysTick clock source. */
  SysTick_CLKSourceConfig( SysTick_CLKSource_HCLK );
}

freertos config


#ifndef FREERTOS_CONFIG_H
#define FREERTOS_CONFIG_H

#define configUSE_PREEMPTION		1
#define configUSE_IDLE_HOOK			0
#define configUSE_TICK_HOOK			0
#define configCPU_CLOCK_HZ			( ( unsigned long ) 62500000 )
#define configTICK_RATE_HZ			( ( TickType_t ) 1000 )
#define configMAX_PRIORITIES		( 6 )
#define configMINIMAL_STACK_SIZE	( ( unsigned short ) 128 )
#define configTOTAL_HEAP_SIZE		( ( size_t ) ( 30 * 1024 ) )
#define configMAX_TASK_NAME_LEN		( 16 )
#define configUSE_16_BIT_TICKS		0
#define configIDLE_SHOULD_YIELD		1

/* Co-routine definitions. */
#define configUSE_CO_ROUTINES 		0
#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )

 
#define configUSE_MUTEXES				1
#define configUSE_COUNTING_SEMAPHORES 	0
#define configUSE_ALTERNATIVE_API 		0
#define configCHECK_FOR_STACK_OVERFLOW	2
#define configUSE_RECURSIVE_MUTEXES		1
#define configQUEUE_REGISTRY_SIZE		0


/* Set the following definitions to 1 to include the API function, or zero
to exclude the API function. */

#define INCLUDE_vTaskPrioritySet		1
#define INCLUDE_uxTaskPriorityGet		1
#define INCLUDE_vTaskDelete				1
#define INCLUDE_vTaskCleanUpResources	0
#define INCLUDE_vTaskSuspend			1
#define INCLUDE_vTaskDelayUntil			1
#define INCLUDE_vTaskDelay				1

/* This demo makes use of one or more example stats formatting functions.  These
format the raw data provided by the uxTaskGetSystemState() function in to human
readable ASCII form.  See the notes in the implementation of vTaskList() within 
FreeRTOS/Source/tasks.c for limitations. */
#define configUSE_STATS_FORMATTING_FUNCTIONS	1
#define configUSE_TRACE_FACILITY                1
#define configGENERATE_RUN_TIME_STATS  0

/* This is the raw value as per the Cortex-M3 NVIC.  Values can be 255
(lowest) to 0 (1?) (highest). */
#define configKERNEL_INTERRUPT_PRIORITY 		255
/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!!
See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */
#define configMAX_SYSCALL_INTERRUPT_PRIORITY 	191 /* equivalent to 0xb0, or priority 11. */


/* This is the value being used as per the ST library which permits 16
priority values, 0 to 15.  This must correspond to the
configKERNEL_INTERRUPT_PRIORITY setting.  Here 15 corresponds to the lowest
NVIC value of 255. */
#define configLIBRARY_KERNEL_INTERRUPT_PRIORITY	15

#define configASSERT( x ) if( ( x ) == 0 ) { taskDISABLE_INTERRUPTS(); for( ;; ); }
/*-----------------------------------------------------------
 * Macros required to setup the timer for the run time stats.
 *-----------------------------------------------------------*/
/* The run time stats time base just uses the existing high frequency timer
test clock.  All these macros do is clear and return the high frequency
interrupt count respectively. */
extern unsigned long ulRunTimeStatsClock;
#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() ulRunTimeStatsClock = 0
#define portGET_RUN_TIME_COUNTER_VALUE() ulRunTimeStatsClock

//NEED THESE!!
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler
#define xPortSysTickHandler SysTick_Handler


#endif /* FREERTOS_CONFIG_H */

toggle task


static void prvTOGGLETask( void *pvParameters )
{
  
  char bit = 0;

  portTickType xLastWakeTime;

  xLastWakeTime = xTaskGetTickCount();

  /* Block for 10ms. */
  const TickType_t xDelay = 10 / portTICK_PERIOD_MS;

  for(;;)
  {

      if(bit)
        GPIOC->BSRR = 1 << 6;
      else
        GPIOC->BRR  = 1 << 6;
      bit = !bit;

      vTaskDelayUntil( &xLastWakeTime, xDelay);
  }
}

rtel wrote on Wednesday, December 24, 2014:

It is out of scope to look at hardware set up here, but looking at your
FreeRTOSConfig.h settings:

Where did the value 62500000 come from in your configCPU_CLOCK_HZ
setting? From your description it is most likely that the frequency of
the clock feeding the SysTick timer is different from this value.

Regards.

k3nt00 wrote on Wednesday, December 24, 2014:

Thank you very much for your responses!

I found the problem.

Apologies for the lack of relevance to FreeRTOS.

In the demo program, the prvSetupHardware() function sets the clock as so:


  /* PLLCLK = (25MHz / 2 ) * 5 = 62.5 MHz. */
  RCC_PLLConfig( RCC_PLLSource_HSI_Div2, RCC_PLLMul_5 );

But in the most recent stm32f10x_rcc.h, RCC_PLLSource_HSE_Div2 is not defined for STM32F10X_CL, which is this chip.


/** @defgroup PLL_entry_clock_source 
  * @{
  */

#define RCC_PLLSource_HSI_Div2           ((uint32_t)0x00000000)

#if !defined (STM32F10X_LD_VL) && !defined (STM32F10X_MD_VL) && !defined (STM32F10X_HD_VL) && !defined (STM32F10X_CL)
 #define RCC_PLLSource_HSE_Div1           ((uint32_t)0x00010000)
 #define RCC_PLLSource_HSE_Div2           ((uint32_t)0x00030000)
 #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \
                                   ((SOURCE) == RCC_PLLSource_HSE_Div1) || \
                                   ((SOURCE) == RCC_PLLSource_HSE_Div2))
#else
 #define RCC_PLLSource_PREDIV1            ((uint32_t)0x00010000)
 #define IS_RCC_PLL_SOURCE(SOURCE) (((SOURCE) == RCC_PLLSource_HSI_Div2) || \
                                   ((SOURCE) == RCC_PLLSource_PREDIV1))
#endif /* STM32F10X_CL */ 

I used the value ((uint32_t)0x00030000), and I am now getting ~10ms.