当我调用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时钟速率得到的操作系统滴答率的一些值:
此外,当我将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 )
我非常感谢有关此计时器问题的任何见解,这让我陷入困境。我已经检查了两个与此相关的类似问题:
答案 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)(最低功率域)。