ШСА 0 26 июля, 2015 Опубликовано 26 июля, 2015 · Жалоба Дорогие коллеги! Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе? Конкретная ситуация: В микроконтроллере 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 не используется)! В чём причина этого явления и как с ним бороться? Буду признателен за любые идеи или информацию. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 26 июля, 2015 Опубликовано 26 июля, 2015 · Жалоба ...никак не должно зависеть от содержания прерываемой программы (DMA не используется)! В некоторой степени все же зависит. В чём причина этого явления и как с ним бороться? Буду признателен за любые идеи или информацию. Непредсказуемую задержку может вносить работа кэш контроллера флеш-памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Может, нестабильную задержку создает перезапуск таймера, а не вход в прерывание. Задайте в прерывании дергание ножкой порта, для проверки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ШСА 0 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба В некоторой степени все же зависит. Непредсказуемую задержку может вносить работа кэш контроллера флеш-памяти. Интересная мысль - а сколько может вносить, и чем можно на эту задержку влиять? Вообще в STM32F4, если верить описанию, время отклика на событие прерывания составляет 12 тактов - если прерывается фоновая программа, 6 тактов - если прерывается другое низкоприоритетное прерывание, 18 тактов - если прерывание произошло в момент выхода из другого прерывания (выход из прерывания занимает 12 тактов). В итоге имеем максимально возможный шум (или биения) на выходе до: 18 - 6 = 12 тактов. Для тактовой частоты 168 МГц это составит 0,072 мкс. И это максимум! А у меня в реале - 0,2 мкс. Причём даже с отключёнными другими прерываниями. Что касается зависимости от фоновой программы. Учитывая, что в STM32F407 организован аппаратный конвейер, влияние фоновой программы на обработчик, вернее на время его вызова, не должно быть вообще! А у меня оно есть, да ещё какое сильное! Я уж даже думал, что столь короткий цикл в фоновой программе так меняет ток потребления МК, что не выдерживает стабилизатор питания, и поэтому сбивается PLL в STM32F4. Но это не подтвердилось - обвешанный большими ёмкостями МК ведёт себя точно также, как и в стандартном включении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VCucumber 0 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ШСА 0 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Может, нестабильную задержку создает перезапуск таймера, а не вход в прерывание. Задайте в прерывании дергание ножкой порта, для проверки. Нет, это исключено. Период внешнего события - 64 мкс, а период перезапуска таймера вдвое больше (я по нему идентифицирую исчезновение внешнего сигнала). Сброс таймера в единственном месте - вторая команда обработчика прерывания. Да и потом - даже если таймер что-то там делает, влияние на задержку реакции оказывает именно содержание фоновой программы. Это проверено: когда я закомментировал цикл очистки памяти в фоновой программе, это явление исчезло! а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем Не понял кто кого ждёт. Все команды фоновой программы занимают по 1 такту. DMA нет. Реакция на внешнее событие определяется укладкой в стек информации о возврате и занимает от 6 до 18 тактов. Я отключал все другие прерывания, в этом случае реакция должна быть максимально стабильной - 12-13 тактов. Т.е. нестабильность реакции - 1 такт! А у меня в реальности ничего не меняется - фоновая программа непостижимым образом изменяет время реакции на прерывания до 34 тактов! а если умножить на 5 тактов ожидания, то получится даже хуже вашего, или ваше в среднем Не понял кто кого ждёт. Все команды фоновой программы занимают по 1 такту. DMA нет. Реакция на внешнее событие определяется укладкой в стек информации о возврате и занимает от 6 до 18 тактов. Я отключал все другие прерывания, в этом случае реакция должна быть максимально стабильной - 12-13 тактов. Т.е. нестабильность реакции - 1 такт! А у меня в реальности ничего не меняется - фоновая программа непостижимым образом изменяет время реакции на прерывания до 34 тактов! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Попробуйте сделать следующее: 1. Внешнее прерывание замените на прерывание от таймера с высокой тактовой частотой (84МГц). При входе в прерывание считывайте CNT. Так получите значительно более точное измерение времени входа. 2. Перенесите обработчик в RAM, сравните результаты. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ШСА 0 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Попробуйте сделать следующее: 1. Внешнее прерывание замените на прерывание от таймера с высокой тактовой частотой (84МГц). При входе в прерывание считывайте CNT. Так получите значительно более точное измерение времени входа. 2. Перенесите обработчик в RAM, сравните результаты. Маленькое уточнение - эти два пункта надо сделать одновременно или по одному? Пункт 1, я понял, нужен, чтобы исключить биения внешней частоты и источника тактирования МК. Я это попробую сегодня сделать. А вот пункт 2 - поясните. Я такого никогда не делал и не знаю (пока) как это сделать. Но главное - зачем, ведь в описании на Cortex, насколько я помню, программа из RAM выполняется медленнее, чем из FLASH. А у меня и так МК едва успевает выполнять нужную работу, причём только после оптимизации компилятором. Если замедлить работу обработчика, работа программы развалится и уже ничего невозможно будет измерить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Вот тут расписано про задержку на входе в обработчик прерывания у Cortex-M3 и Cortex-M4: "between eight and 32 cycles if the floating point context in a Cortex-M4 with FPU is stacked immediately". Кстати, у вас нигде прерывания не запрещаются? Атомарные операции и всё такое. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Интересно сравнить результаты при работе из флеш и RAM. Про пункты: 1. Чтобы исключить осциллограф прежде всего :) 2. Программа из RAM выполняется примерно с той же скоростью, что из "ускоренной" флеш. Немного медленнее, зато гораздо более предсказуемо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба 2. Программа из RAM выполняется примерно с той же скоростью, что из "ускоренной" флеш. Немного медленнее, зато гораздо более предсказуемо. Всё не так просто. Можно разогнать программу в ОЗУ. Для этого код должен сидеть в куске ОЗУ 112 КБ (начинается с адреса 0x20000000), подключенном к I-bus, ОЗУ надо замапить на адрес 0, а данные расположить в CCM (64 КБ). В этом случае всё должно работать с нулевыми задержками. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Можно разогнать программу в ОЗУ. Можно, просто для проверки предположения о влиянии "ускорителя" флеш это не нужно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ШСА 0 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Вот тут расписано про задержку на входе в обработчик прерывания у Cortex-M3 и Cortex-M4: "between eight and 32 cycles if the floating point context in a Cortex-M4 with FPU is stacked immediately". Кстати, у вас нигде прерывания не запрещаются? Атомарные операции и всё такое. Спасибо за ссылочку: на первый же взгляд вижу намёк на причину - на возможные такты ожидания при обращении к слову по частям. А ведь у меня этого много. Буду разбираться. Прерывания не запрещаются. Флаги очищаются в конце обработчика, так что вложенные прерывания исключены. Атомарные операции... Наверное, вы правы! Для экономии памяти я сплошь работаю с невыровненными данными в ОЗУ, а ведь это может приводить к аппаратным задержкам! Это похоже на правду, ведь цикл очистки массива у меня идёт по байтовому указателю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Timmy 1 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Дорогие коллеги! Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе? Конкретная ситуация: В микроконтроллере STM32F407 в main-е крутится некая большая программа. Когда наступает внешнее событие, а именно - отрицательный фронт на EXTI_Line1, вызывается обработчик прерывания void EXTI1_IRQHandler(void). В нём обнуляется таймер TIM6, тактируемый частотой 84 МГц, и начинается вывод информации в виде набора импульсов, привязанных к значениям TIM6. Когда вывод закончен - выходим из обработчика (TIM6 оставляем молотить впустую). Если вам надо обеспечить постоянное время реакции на фронт входного сигнала, то следует защёлкнуть этот фронт в capture unit, и привязать выходные сигналы к защёлкнутому времени таким образом, чтобы процессор всегда успевал среагировать. Правда, время реакции получится по-максимуму, зато стабильно. Если нужно совсем быструю реакцию, лучше использовать FPGA. Время входа в прерывание можно сократить, если использовать FIQ, а не IRQ, но его на большинстве кортексов нет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 июля, 2015 Опубликовано 27 июля, 2015 · Жалоба Флаги очищаются в конце обработчика, так что вложенные прерывания исключены. Вроде это как раз гарантия создания повторного прерывания:) Вложенные прерывания у вас исключает NVIC, а вот очищенный в конце флаг может вызвать прерывание повторно из-за конвейеров, нужны будут барьеры на выходе. Опять же ускоритель флешь, если вы попадаете не на 16 на 32 битные команды то ему больше 4 команд не выбрать, а частота выборки команд у него в почти 8 раз меньше, так что скакнув прерыванием в не закишированную область, да еще и попав на 32 битную команду, у вас все здорово притормозится, а в след раз вы можете попасть уже в область выбранную и сохраненную в ускорителе, а потом вы ее можете почистить и так по кругу, так что у вас там есть где набрать нестабильность ИМХО... ремя входа в прерывание можно сократить, если использовать FIQ, а не IRQ, но его на большинстве кортексов нет. Я могу ошибаться, но вроде как в кортексах уже NVIC, и потому деления на быстрое и медленное уже нет ни в большинстве, а во всех кортексах... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться