Всем привет! Столкнулся с довольно любопытным косяком. И так, контроллер 1986ВЕ1Т, ядро Cortex-M1. Настроено прерывание от SysTick таймера, в обработчике дрыгается нога. В основном цикле программы вызывается виртуальный метод класса. Сам класс простой, это реализация программного таймера. Работает он всего с 3мя переменными типа uint32_t, одна из которых объявлена как volatile (счетчик) никакие регистры при этом не трогает. И теперь самое интересное, если функция которая вызывается в main в цикле виртуальная, то уплывает частота прерываний таймера SysTick в большую сторону. Стоит закоментить virtual в объявлении функции, как все начинает работать как и должно. Будут у кого нибудь гипотезы как вообще такое возможно? П.С.: Если закоментить volatile у переменной счетчика, но при этом оставить virtual у функции, то все так же работает :) Если что, значения всех регистров, которые хоть как - то могут повлиять на частоты таймера я сравнивал, они не меняются в рабочем варианте по сравнению с косячным.

Комментарии: 8

  1. Voron63

    Обработка и выполнение вызова виртуального метода занимает больше времени, чем обработка и выполнение вызова обычного метода. Кроме того, компилятор также должен выделять один дополнительный указатель для каждого объекта класса, который имеет одну или несколько виртуальных функций.

    • Anton

      Верно, вот только вызов виртуального метода происходит в основном цикле программы, а не в обработчике прерывания.

      • Voron63

        пример кода если можно сюда напишите, а то на пальцах не оче понятно

  2. Anton

    Всем привет! Как - то давно, я писал об интересном эффекте, наблюдаемом на 1986ВЕ1Т (cortex-m1). Когда вызов функции в основном цикле программы приводил к "пропуску прерываний" таймера SysTick. После довольно продолжительных разборок удалось докопаться до истины, которой и хочу поделиться. На самом деле пропуска преываний небыло, замедляется сам таймер. Связано это с тем, что таймер считает импульсы только тогда, когда процессор выполняет инструкции, а инструкция BL (вызов подпрограммы) сбрасывает кэш процессора и ему приходиться заново зачитывать их из FLASH. На это время исполнение инструкций прекращается и соответственно приостанавливается SysTick. Косвенным подтверждением тому, явился эксперимент. Я настроил TIMER1 с прерыванием и смотрел частоту, с которым оно выполняется. Вызов функции в основном цикле никак не оказывал влияния на него.

    • Voron63

      а работа с флеш через дма была?

      • Anton

        под FLASH я имею ввиду память в которой хранится прошивка МК...

        • Voron63

          ясно,интересное наблюдение

Не нашли ответ?

Вам также может быть интересно