FreeRTOS计时器在SAM L21 Xplained Pro中速度过快

时间:2017-11-15 13:36:19

标签: timer embedded atmel freertos atmelstudio

当我调用vTaskDelay时,延迟持续一半的假设时间。我已经追溯了问题,我发现Tick rate值是configTICK_RATE_HZ中定义的两倍。我使用勾勾来检查这个,以便用示波器切换LED并测量频率。

我正在使用Atmel Studio 7和FreeRTOS v8.0.1配置Atmel SAM L21 Xplained pro A板(ATSAML21J18A),基于ASF示例的文件“使用OLED1 Xplained的FreeRTOS无滴答演示”。

我的CPU时钟从SYSTEM_CLOCK_SOURCE_OSC16M以12MHz运行。配置的滴答速率为100 Hz,来自GLCK_O(CPU时钟)的定时器。但是,当我将CPU时钟频率改为4MHz而不是12 MHz时,Tick速率是正确的,所以我想我在运行操作系统滴答的定时器某处缺少某些配置。

以下是我使用不同CPU时钟速率得到的操作系统滴答率的一些值:

  • CPU:4 MHz - 滴答率:100 Hz
  • CPU:8 MHz - 刻度:548 Hz
  • CPU:12 MHz - 滴答率:218 Hz
  • CPU:16 MHz - 滴答率:548 Hz
  • CPU:48 MHz - 刻度:2,25 kHz

此外,当我将OS定时器时钟源配置为以32kHz运行的内部超低功耗振荡器ULPOSC32k时,滴答速率是正确的,与CPU时钟频率(100Hz)无关。

此外,当我选择无滴答模式(1或2)时,即使配置在刻度模式下运行良好,CPU为4MHz并且从Systick定时器生成滴答中断,我也有同样的问题,dalay持续一半的时间。

在FreeRTOSConfig中我有:

#define configUSE_PREEMPTION                    1
#define configUSE_TICKLESS_IDLE                 0
#define configUSE_IDLE_HOOK                     0
#define configUSE_TICK_HOOK                     1
#define configPRIO_BITS                         2
#define configCPU_CLOCK_HZ                      ( system_gclk_gen_get_hz(GCLK_GENERATOR_0) )
#define configTICK_RATE_HZ                      ( ( portTickType ) 100 )

滴答计时器配置为:

void vPortSetupTimerInterrupt(void)
{
    // Struct for configuring TC
    struct tc_config tcconf;
    // Set up configuration values
    tc_get_config_defaults(&tcconf);
    tcconf.clock_source    = GCLK_GENERATOR_0;
    tcconf.counter_size    = TC_COUNTER_SIZE_32BIT;
    tcconf.run_in_standby  = true;
    tcconf.clock_prescaler = TC_CLOCK_PRESCALER_DIV1;
    tcconf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;

    // Initialize the TC
    tc_init(&tc, TICK_TC, &tcconf);

    // Register and enable callback for freeRTOS tick handler
    tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
    tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);

    // Set top value equal to one os tick
    tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);

    // Enable the timer
    tc_enable(&tc);
}

TIMER_RELOAD_VALUE_ONE_TICK来自:

//! Frequency of timer
#define TIMER_HZ                            ( configCPU_CLOCK_HZ )

//! Value per os tick of timer
#define TIMER_RELOAD_VALUE_ONE_TICK         ( TIMER_HZ / configTICK_RATE_HZ )

//!  Maximum value of timer
#define TIMER_MAX_COUNT                     ( 0xffffffff )

//! Maximum possible suppressed ticks with timer
#define TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS ( TIMER_MAX_COUNT / TIMER_RELOAD_VALUE_ONE_TICK )

我非常感谢有关此计时器问题的任何见解,这让我陷入困境。我已经检查了两个与此相关的类似问题:

STM32 SysTick counting twice as fast as it should

freertos tick factor 2 too fast on stm32f4xx

2 个答案:

答案 0 :(得分:1)

saml21有5个定时器/计数器TC0-TC4。计数寄存器是16位。您可以将TC0和TC1(或TC2和TC3)一起使用,使其为32位。 TC4是PDO中唯一的计时器,没有与之配对的另一个计时器。它不能用作32位定时器(虽然它可以让你尝试)。

将TIMER_MAX_COUNT更改为0xffff,将tcconf.counter_size更改为TC_COUNTER_SIZE_16BIT,您将能够使用TC4而不是TC2。

答案 1 :(得分:0)

将Timer实例从TC4更改为TC2可解决此问题。

  // Initialize the TC
    tc_init(&tc, TICK_TC, &tcconf);

  //! Timer/Counter instance to use as tick timer
  //#define TICK_TC TC4
  #define TICK_TC TC2

现在它生成一个正确的100 Hz滴答,与配置的CPU时钟频率无关。

但是,当我激活低功耗模式时,我仍然需要看到它的含义,因为看起来TC4是Power Domain 0中唯一有效的定时器  (PD0)(最低功率域)。