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