Я пытаюсь измерить производительность некоторого кода с помощью таймера TIM2 на STM32L031K6 (Cortex-M0 +).
Поскольку M0 + предлагает только 16-битные счетчики, я хочу настроить предварительный масштабировщик TIM2 для более медленного счета. Тем не менее, это, кажется, не показывает никакого эффекта вообще. Таймер все еще работает на максимальной скорости, что нежелательно для моего случая использования.
Раньше я использовал libopencm3, но теперь я пишу в регистры напрямую через указатели, потому что впоследствии у меня не будет доступа к libopencm3.
Я просмотрел таблицу данных серии STM32L0 и прочитал, как установить таймеры напрямую. Настройка таймера и измерение небольшого кода (для цикла с nops) работает отлично. Но настройка прескалера не будет работать. Я записал значение (например, 0x1234) в регистр предварительной шкалы и снова прочитал его, чтобы убедиться, что запись действительно работает. Я попытался вызвать событие обновления, потому что похоже, что с теневыми регистрами происходит некоторая буферизация, но она также не работает.
void __attribute__ ((noinline)) timer_setup()
{
*( (uint32_t*) 0x40021038 ) |= 1; //Enable Timer in RCC_APB1ENR (Bit 0)
*( (uint32_t*) 0x40000028 ) = 0x1234; //Some prescaler
*( (uint32_t*) 0x4000002C ) = 0xFFFF; //Auto-Reload to max 2**16
// *( (uint32_t*) 0x40000000 ) ^= 2; //I tried triggering an update here
// *( (uint32_t*) 0x40000014 ) ^= 1; //But it also didn't work
*( (uint32_t*) 0x40000000 ) ^= 1; //Enable the timer
}
void __attribute__ ((noinline)) timer_stop()
{
*( (uint32_t*) 0x40000000 ) ^= 1; //Stop the timer
}
int __attribute__ ((noinline)) timer_value()
{
return *( (uint32_t*) 0x40000024 ); //Read the counter
}
Я ожидал, что число будет ниже, если я установлю прескалер. Тем не менее, я всегда получаю одно и то же значение. Например, 1326 для цикла nops.