реклама на сайте
подробности

 
 
7 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> STM32F407 + прерывание + время реакции, Меняется время реакции на внешнее событие
ШСА
сообщение Jul 26 2015, 19:07
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Дорогие коллеги!
Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе?
Конкретная ситуация: В микроконтроллере STM32F407 в main-е крутится некая большая программа. Когда наступает внешнее событие, а именно - отрицательный фронт на EXTI_Line1, вызывается обработчик прерывания void EXTI1_IRQHandler(void). В нём обнуляется таймер TIM6, тактируемый частотой 84 МГц, и начинается вывод информации в виде набора импульсов, привязанных к значениям TIM6. Когда вывод закончен - выходим из обработчика (TIM6 оставляем молотить впустую).
Замечено следующее: Время от момента внешнего события до появления первого импульса на выходе нестабильно и меняется (по осциллографу) более чем на 0,2 мкс при тактировании ядра 168 МГц. Иными словами, время вызова обработчика может увеличиваться (или уменьшаться) аж на 34 такта! Причём меняется оно в зависимости от кода, выполняемого в данный момент в main-е. Самое большое изменение этого времени (в сторону уменьшения) происходит при выполнении (в main-е) цикла очистки области памяти:
for(i = 0; i < 60768; i++) *j++ = Сonst;

А согласно описанию на Cortex-3 время вызова обработчика прерывания составляет от 6 до 11 тактов ядра. И уж никак не должно зависеть от содержания прерываемой программы (DMA не используется)! wacko.gif

В чём причина этого явления и как с ним бороться?
Буду признателен за любые идеи или информацию.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 26 2015, 19:29
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(ШСА @ Jul 26 2015, 22:07) *
...никак не должно зависеть от содержания прерываемой программы (DMA не используется)! wacko.gif

В некоторой степени все же зависит.

Цитата(ШСА @ Jul 26 2015, 22:07) *
В чём причина этого явления и как с ним бороться?
Буду признателен за любые идеи или информацию.

Непредсказуемую задержку может вносить работа кэш контроллера флеш-памяти.
Go to the top of the page
 
+Quote Post
ViKo
сообщение Jul 27 2015, 03:03
Сообщение #3


Универсальный солдатик
******

Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362



Может, нестабильную задержку создает перезапуск таймера, а не вход в прерывание. Задайте в прерывании дергание ножкой порта, для проверки.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 05:46
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(aaarrr @ Jul 26 2015, 22:29) *
В некоторой степени все же зависит.


Непредсказуемую задержку может вносить работа кэш контроллера флеш-памяти.


Интересная мысль - а сколько может вносить, и чем можно на эту задержку влиять?
Вообще в STM32F4, если верить описанию, время отклика на событие прерывания составляет 12 тактов - если прерывается фоновая программа, 6 тактов - если прерывается другое низкоприоритетное прерывание, 18 тактов - если прерывание произошло в момент выхода из другого прерывания (выход из прерывания занимает 12 тактов). В итоге имеем максимально возможный шум (или биения) на выходе до: 18 - 6 = 12 тактов. Для тактовой частоты 168 МГц это составит 0,072 мкс. И это максимум! А у меня в реале - 0,2 мкс. Причём даже с отключёнными другими прерываниями.
Что касается зависимости от фоновой программы. Учитывая, что в STM32F407 организован аппаратный конвейер, влияние фоновой программы на обработчик, вернее на время его вызова, не должно быть вообще! А у меня оно есть, да ещё какое сильное!
Я уж даже думал, что столь короткий цикл в фоновой программе так меняет ток потребления МК, что не выдерживает стабилизатор питания, и поэтому сбивается PLL в STM32F4. Но это не подтвердилось - обвешанный большими ёмкостями МК ведёт себя точно также, как и в стандартном включении.
Go to the top of the page
 
+Quote Post
Огурцов
сообщение Jul 27 2015, 05:53
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 3 928
Регистрация: 28-03-07
Из: РФ
Пользователь №: 26 588



а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 06:09
Сообщение #6


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(ViKo @ Jul 27 2015, 06:03) *
Может, нестабильную задержку создает перезапуск таймера, а не вход в прерывание. Задайте в прерывании дергание ножкой порта, для проверки.


Нет, это исключено. Период внешнего события - 64 мкс, а период перезапуска таймера вдвое больше (я по нему идентифицирую исчезновение внешнего сигнала). Сброс таймера в единственном месте - вторая команда обработчика прерывания.
Да и потом - даже если таймер что-то там делает, влияние на задержку реакции оказывает именно содержание фоновой программы. Это проверено: когда я закомментировал цикл очистки памяти в фоновой программе, это явление исчезло!

Цитата(Огурцов @ Jul 27 2015, 08:53) *
а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем


Не понял кто кого ждёт.
Все команды фоновой программы занимают по 1 такту. DMA нет. Реакция на внешнее событие определяется укладкой в стек информации о возврате и занимает от 6 до 18 тактов. Я отключал все другие прерывания, в этом случае реакция должна быть максимально стабильной - 12-13 тактов. Т.е. нестабильность реакции - 1 такт! А у меня в реальности ничего не меняется - фоновая программа непостижимым образом изменяет время реакции на прерывания до 34 тактов!


Цитата(Огурцов @ Jul 27 2015, 08:53) *
а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем


Не понял кто кого ждёт.
Все команды фоновой программы занимают по 1 такту. DMA нет. Реакция на внешнее событие определяется укладкой в стек информации о возврате и занимает от 6 до 18 тактов. Я отключал все другие прерывания, в этом случае реакция должна быть максимально стабильной - 12-13 тактов. Т.е. нестабильность реакции - 1 такт! А у меня в реальности ничего не меняется - фоновая программа непостижимым образом изменяет время реакции на прерывания до 34 тактов!
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2015, 06:27
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Попробуйте сделать следующее:
1. Внешнее прерывание замените на прерывание от таймера с высокой тактовой частотой (84МГц). При входе в прерывание считывайте CNT. Так получите значительно более точное измерение времени входа.
2. Перенесите обработчик в RAM, сравните результаты.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 06:41
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(aaarrr @ Jul 27 2015, 09:27) *
Попробуйте сделать следующее:
1. Внешнее прерывание замените на прерывание от таймера с высокой тактовой частотой (84МГц). При входе в прерывание считывайте CNT. Так получите значительно более точное измерение времени входа.
2. Перенесите обработчик в RAM, сравните результаты.


Маленькое уточнение - эти два пункта надо сделать одновременно или по одному?
Пункт 1, я понял, нужен, чтобы исключить биения внешней частоты и источника тактирования МК. Я это попробую сегодня сделать. А вот пункт 2 - поясните. Я такого никогда не делал и не знаю (пока) как это сделать. Но главное - зачем, ведь в описании на Cortex, насколько я помню, программа из RAM выполняется медленнее, чем из FLASH. А у меня и так МК едва успевает выполнять нужную работу, причём только после оптимизации компилятором. Если замедлить работу обработчика, работа программы развалится и уже ничего невозможно будет измерить.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 06:49
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Вот тут расписано про задержку на входе в обработчик прерывания у Cortex-M3 и Cortex-M4: "between eight and 32 cycles if the floating point context in a Cortex-M4 with FPU is stacked immediately".
Кстати, у вас нигде прерывания не запрещаются? Атомарные операции и всё такое.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2015, 06:52
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Интересно сравнить результаты при работе из флеш и RAM.
Про пункты:
1. Чтобы исключить осциллограф прежде всего sm.gif
2. Программа из RAM выполняется примерно с той же скоростью, что из "ускоренной" флеш. Немного медленнее, зато гораздо более предсказуемо.
Go to the top of the page
 
+Quote Post
scifi
сообщение Jul 27 2015, 07:00
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(aaarrr @ Jul 27 2015, 09:52) *
2. Программа из RAM выполняется примерно с той же скоростью, что из "ускоренной" флеш. Немного медленнее, зато гораздо более предсказуемо.

Всё не так просто. Можно разогнать программу в ОЗУ. Для этого код должен сидеть в куске ОЗУ 112 КБ (начинается с адреса 0x20000000), подключенном к I-bus, ОЗУ надо замапить на адрес 0, а данные расположить в CCM (64 КБ). В этом случае всё должно работать с нулевыми задержками.
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Jul 27 2015, 07:04
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(scifi @ Jul 27 2015, 10:00) *
Можно разогнать программу в ОЗУ.

Можно, просто для проверки предположения о влиянии "ускорителя" флеш это не нужно.
Go to the top of the page
 
+Quote Post
ШСА
сообщение Jul 27 2015, 07:12
Сообщение #13


Местный
***

Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335



Цитата(scifi @ Jul 27 2015, 09:49) *
Вот тут расписано про задержку на входе в обработчик прерывания у Cortex-M3 и Cortex-M4: "between eight and 32 cycles if the floating point context in a Cortex-M4 with FPU is stacked immediately".
Кстати, у вас нигде прерывания не запрещаются? Атомарные операции и всё такое.


Спасибо за ссылочку: на первый же взгляд вижу намёк на причину - на возможные такты ожидания при обращении к слову по частям. А ведь у меня этого много. Буду разбираться.
Прерывания не запрещаются. Флаги очищаются в конце обработчика, так что вложенные прерывания исключены.
Атомарные операции... Наверное, вы правы! Для экономии памяти я сплошь работаю с невыровненными данными в ОЗУ, а ведь это может приводить к аппаратным задержкам! Это похоже на правду, ведь цикл очистки массива у меня идёт по байтовому указателю.
Go to the top of the page
 
+Quote Post
Timmy
сообщение Jul 27 2015, 07:30
Сообщение #14


Знающий
****

Группа: Участник
Сообщений: 835
Регистрация: 9-08-08
Из: Санкт-Петербург
Пользователь №: 39 515



Цитата(ШСА @ Jul 26 2015, 22:07) *
Дорогие коллеги!
Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе?
Конкретная ситуация: В микроконтроллере STM32F407 в main-е крутится некая большая программа. Когда наступает внешнее событие, а именно - отрицательный фронт на EXTI_Line1, вызывается обработчик прерывания void EXTI1_IRQHandler(void). В нём обнуляется таймер TIM6, тактируемый частотой 84 МГц, и начинается вывод информации в виде набора импульсов, привязанных к значениям TIM6. Когда вывод закончен - выходим из обработчика (TIM6 оставляем молотить впустую).

Если вам надо обеспечить постоянное время реакции на фронт входного сигнала, то следует защёлкнуть этот фронт в capture unit, и привязать выходные сигналы к защёлкнутому времени таким образом, чтобы процессор всегда успевал среагировать. Правда, время реакции получится по-максимуму, зато стабильно. Если нужно совсем быструю реакцию, лучше использовать FPGA.
Время входа в прерывание можно сократить, если использовать FIQ, а не IRQ, но его на большинстве кортексов нет.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Jul 27 2015, 07:49
Сообщение #15


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата
Флаги очищаются в конце обработчика, так что вложенные прерывания исключены.

Вроде это как раз гарантия создания повторного прерыванияsm.gif Вложенные прерывания у вас исключает NVIC, а вот очищенный в конце флаг может вызвать прерывание повторно из-за конвейеров, нужны будут барьеры на выходе.

Опять же ускоритель флешь, если вы попадаете не на 16 на 32 битные команды то ему больше 4 команд не выбрать, а частота выборки команд у него в почти 8 раз меньше, так что скакнув прерыванием в не закишированную область, да еще и попав на 32 битную команду, у вас все здорово притормозится, а в след раз вы можете попасть уже в область выбранную и сохраненную в ускорителе, а потом вы ее можете почистить и так по кругу, так что у вас там есть где набрать нестабильность ИМХО...

Цитата
ремя входа в прерывание можно сократить, если использовать FIQ, а не IRQ, но его на большинстве кортексов нет.

Я могу ошибаться, но вроде как в кортексах уже NVIC, и потому деления на быстрое и медленное уже нет ни в большинстве, а во всех кортексах...
Go to the top of the page
 
+Quote Post

7 страниц V   1 2 3 > » 
Reply to this topicStart new topic
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 19th July 2025 - 20:09
Рейтинг@Mail.ru


Страница сгенерированна за 0.01508 секунд с 7
ELECTRONIX ©2004-2016