VladislavS 39 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 3 минуты назад, Arlleex сказал: фиктивное чтение из TIM3->SR или поставить барьер памяти DMB (если буфер записи есть). DMB вообще из другой оперы. Читать SR можно, но это бесполезная трата времени (а там 1М прерываний в секунду, если что). Надо всего лишь сброс флага сделать в начале прерывания, а за ним полезные действия. 2 минуты назад, Vladimir_T сказал: На выходе таймера, через PB4 сформирован нормальный, ожидаемый сигнал. Ну вот, что я и предполагал. Осталось подумать зачем вам 1М прерываний, можно ли от этого уйти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladimir_T 1 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 4 hours ago, Arlleex said: В отладочном модуле (периферия DBG), установите бит "заморозки" тактирования модуля TIM3, чтобы при остановке отладчиком таймер не считал. И еще: прерывания с частотой 1 МГц, это, конечно, сильно. Не знаю, есть ли буфер записи системного уровня в STM32F7, но по-хорошему, перед выходом из прерывания нужно сделать фиктивное чтение из TIM3->SR или поставить барьер памяти DMB (если буфер записи есть). Да, видать высокая частота. При снижении частоты хотя бы на 20%, процессор нормально выходит из прерывания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба Только что, VladislavS сказал: DMB вообще из другой оперы... Вполне из этой оперы. Цитата Читать SR можно, но это бесполезная трата времени. А какие аргументы будут? Почему чтение SR будет бесполезно? Цитата Надо всего лишь сброс флага сделать в начале прерывания, а за ним полезные действия. Вредный совет, ИМХО, уж простите за прямоту. Перетасует оптимизатор команды записи в регистры, и вполне может получиться, что финальная запись в SR будет в конце обработчика. ARM, между прочим, об этом прямо писал в своих рекомендациях по работе с прерываниями на Cortex-Mx. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladimir_T 1 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба Благодарю всех за помощь. Буду снижать частоту, хотя это будет очень серьезным моим просчетом и корректировке алгоритмов.... Пока удалось 952 кГц добиться - это уже хорошо. Процессор тактируется от генератора 50МГц, ядро и все шины настроил на предельные частоты 216 МГц. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 245 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 32 минуты назад, VladislavS сказал: При остановке в отладчике таймер продолжает работать. Вообще-то, по уму, при отладке таймеров полезно их останавливать посредством DBGMCU_APBx_FZ. По-крайней мере в CM4. Или в CM7 больше нет этих регистров? 33 минуты назад, Vladimir_T сказал: 1 МГц. Да уж.... а подумать? 15 минут назад, Vladimir_T сказал: хотя это будет очень серьезным моим просчетом и корректировке алгоритмов.... Интересно - для каких "алгоритмов" необходимы такие высокие частоты прерываний? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vladimir_T 1 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 4 hours ago, jcxz said: Да уж.... а подумать? Все думки свои исчерпал - на форум обратился... Много полезного узнал... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 1 час назад, Arlleex сказал: Почему чтение SR будет бесполезно? Потому что не является "полезным" действием. Вместо него можно было дрыгнуть ногой или ещё что-нибудь нужное для работы программы. Представляете, 1М бесполезных действий в секунду на ровном месте. 1 час назад, Arlleex сказал: Перетасует оптимизатор команды записи в регистры Компилятор не имеет права менять местами доступ к volatile сущностям, коими являются регистры периферии. 1 час назад, Arlleex сказал: Вполне из этой оперы. Таки нет. Уже даже надоело это обсуждать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 31 минуту назад, VladislavS сказал: Потому что не является "полезным" действием. Вместо него можно было дрыгнуть ногой или ещё что-нибудь нужное для работы программы. Здесь много тонкостей. В том числе нужно учитывать, висит ли регистр для дрыгания ногой на той же шине, что и регистры управления таймером, иначе дрыг ногой будет не таким уж и полезным действием (с точки зрения гарантии очистки pending-бита прерывания в TIM->SR). А вот чтение того же регистра, в который писали, однозначно будет заставлять процессор дожидаться реальной записи. Цитата Компилятор не имеет права менять местами доступ к volatile сущностям, коими являются регистры периферии. Это, конечно, да, только не факт, что в прерывании код действительно что-то будет писать в регистры периферии (кроме регистров таймера). Цитата Таки нет. Уже даже надоело это обсуждать. Ну, то есть аргументов нет. P.S. Только не DMB, а DSB, разумеется. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 39 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 2 часа назад, Arlleex сказал: только не факт, что в прерывании код действительно что-то будет писать в регистры периферии (кроме регистров таймера). Прерывание, которое не изменяет ни одной volatile сущности, не имеет смысла. Это не обязательно периферия, может просто флаг в памяти, например. Там не хватает задержки несколько тактов всего, её можно получить разными способами. 2 часа назад, Arlleex сказал: Ну, то есть аргументов нет. Барьеры работают на уровне ядра процессора, а сбрасываемый флаг гуляет по внешним шинам. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Arlleex 190 16 марта, 2022 Опубликовано 16 марта, 2022 · Жалоба 6 часов назад, VladislavS сказал: Надо всего лишь сброс флага сделать в начале прерывания, а за ним полезные действия. 6 часов назад, Arlleex сказал: Вредный совет, ИМХО, уж простите за прямоту. Перетасует оптимизатор команды записи в регистры, и вполне может получиться, что финальная запись в SR будет в конце обработчика. ARM, между прочим, об этом прямо писал в своих рекомендациях по работе с прерываниями на Cortex-Mx. Пожалуй, здесь я хотел бы уточнить, что флаг, конечно же, нужно сбрасывать при входе в прерывание, но еще при этом нужно гарантировать, что при любом уровне оптимизации команда фактической записи в регистр сброса активного прерывания не будет последней перед BX LR. Хотя и эта гарантия ни к чему не обязывает - большая разница в тактировании клоковых доменов (при прохождении данных через AHB-APB-мосты, например) уже может поставить крест на идее "пододвинуть сброс активного прерывания в начало обработчика", особенно в коротких по объему обработчиках. Также я не спроста написал, что нужно быть внимательным при изменении "фиктивного обратного чтения" на некое "полезное действие" вроде дергания ногой GPIO. Это как раз касается очень коротких прерываний (по объему инструкций). Реальный порядок завершения записи в память типа Device (а это в том числе регистры I/O согласно терминологии ARM в ARMv7-M) зависит от кучи внешних факторов, в числе которых и озвученные мною потенциальные возможности периферии GPIO и обсуждаемого таймера "сидеть" на разных AHB/APB, на входных интерфейсах которых могут находиться независимые system-level буферы записи. А еще не забываем уже указанную возможность разных частот этих самых шин. Из ARMv7-M Цитата Side effect completion in Strongly-ordered and Device memory The completion of a memory access in Strongly-ordered or Device memory is not guaranteed to be sufficient to determine that the side effects of the memory access are visible to all observers. The mechanism that ensures the visibility of side-effects of a memory access is IMPLEMENTATION DEFINED, for example provision of a status register that can be polled. В том же документе можно найти информацию (вполне логичную), что для этих типов памяти система памяти гарантирует, что доступ на чтение, следующий за доступом записи по одному и тому же адресу, будет дожидаться реального завершения доступа записи (да-да, сквозь все шины, с учетом всех буферов записи (ядра и system-level implemented)). Поэтому обратное чтение адреса, по которому ранее произвелась запись - есть гарантия применения результата операции записи (допустим, чистка бита прерывания). Но самое интересное, что между снятием бита прерывания на периферии и моментом, когда этот сигнал физически сбросится на соответствующем входе NVIC тоже есть время, очень маленькое, а может и вполне сопоставимое с долей такта CPU. Кто знает. Тут уж забота реализаторов конкретного чипа свести эту задержку к 0. Иначе никакие фиктивные чтения, барьеры и т.д. не будут гарантировать корректного поведения. Что касается барьеров. Если чип довольно простой по шинной архитектуре (т.е. в лучшем случае домен синхронизации один), то при наличии буфера записи ядра (вне зависимости от возможных буферов вне ядра) после команды записи на очистку бита прерывания следует дождаться применения реальной записи (о чем я только что и написал чуть выше), и в данном случае DSB сможет это гарантировать (DSB заставляет осуществить все буферизованные записи). В контексте STM32 я не находил информации, какие буферы записи там реализованы (но наверняка как минимум буфер записи ядра присутствует), соответственно сразу имеет смысл озадачиться применением барьеров. В этом контексте я и написал в прошлых постах - DMB/DSB. Но практически универсальным решением будет фиктивное обратное чтение. Вот и все. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться