【问题标题】:FreeRTOS timer Tick too fast in SAM L21 Xplained ProSAM L21 Xplained Pro 中的 FreeRTOS 计时器滴答速度太快
【发布时间】:2018-04-28 18:18:17
【问题描述】:

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

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

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

以下是我在不同 CPU 时钟频率下获得的一些 OS 滴答率值:

  • 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

【问题讨论】:

  • 我投票结束这个问题作为题外话,因为:你有调试器 - 是什么阻止你检查定时器 o systick 寄存器值?自己做一些调试。如果你付出一些努力,很容易回答问题。
  • 是的,我完全同意。我一直在使用调试器并尽我所能检查定时器和频率变量,我已经尝试了所有不同的组合来改变 CPU 时钟源和频率,以及定时器时钟源。我还检查了滴答和无滴答模式。我已经检查了几天能找到的所有寄存器,但找不到原因,可能我遗漏了一些明显的东西。在尝试了我能想到的一切之后,询问是我最后的手段。如果有任何建议可以继续我的努力,我将不胜感激。
  • 你确定你定义的时钟频率对你的硬件是正确的吗?您的处理器似乎能够以 48 MHz 运行,可能使用来自外部时钟的 PLL 乘法器。
  • 我想是的,我使用 SYSTEM_CLOCK_SOURCE_OSC16M 通过 GLCK_0 为 CPU 提供时钟,在 SAM L21 中它允许 4、8、12 和 16 MHz 模式。也可以使用 DFLL 或 DPLL 获得 48 MHz。我也尝试过这个 CPU 频率,滴答频率是 2.25 kHz。我已经编辑了问题,添加了一些结果。

标签: timer embedded atmel freertos atmelstudio


【解决方案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。

【讨论】:

    【解决方案2】:

    将 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
    

    现在它会独立于配置的 CPU 时钟频率生成正确的 100 Hz 滴答声。

    但是,当我激活低功耗模式时,我仍然需要了解这将产生的影响,因为 TC4 似乎是电源域 0 中唯一处于活动状态的定时器 (PD0)(最低功率域)。

    【讨论】:

      猜你喜欢
      • 2018-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-26
      • 2013-10-15
      相关资源
      最近更新 更多