Кто любит RISC в жизни, заходим, не стесняемся.
Ответить

STM32F407 + прерывание + время реакции

Вс июл 26, 2015 22:15:12

Дорогие собратья!
Сталкивался ли кто нибудь с такой тонкой и непонятной мне проблемой - значительным изменением времени входа в обработчик прерывания по внешнему событию в зависимости от команд, выполняемых в этот момент в основной программе?
Конкретная ситуация: В микроконтроллере 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 не используется)! :shock:

В чём причина этого явления и как с ним бороться?
Буду признателен за любые идеи или информацию.

Re: STM32F407 + прерывание + время реакции

Вс июл 26, 2015 23:50:51

Точно с приоритетами все ок? Если это возможно (я не знаю специфики вашего устройства), назначьте этому прерыванию наивысший приоритет и посмотрите что это даст в плане стабильности времени "Событие-выдача первого импульса"

MPU задействован?

Re: STM32F407 + прерывание + время реакции

Пн июл 27, 2015 03:31:27

А согласно описанию на Cortex-3 время вызова обработчика прерывания составляет от 6 до 11 тактов ядра.

Двенадцать, вообще-то.

Изображение

И от того, чем процессор был занят в момент возникновения прерывания, момент входа в обработчик, как раз таки зависит:

"In may processors, the exact interrupt latency depends on what the processor is executing at the time the interrupt occurs. For example, in many processor architectures, the processor starts to respond to a interrupt request only when the current executing instruction completes, which can add a number of extra clock cycles. As a result, the interrupt latency value can contain a best case and a worst case value. This variation can results in jitters of interrupt responses, which could be problematic in certain applications like audio processing (with the introduction of signal distortions) and motor control (which can result in harmonics or vibrations)."

Еще шесть тактов добавятся, если внешнее прерывание возникло во время выполнения кода в обработчике другого прерывания, с более низким приоритетом. Так оно по копеечке и набегает где-то.

Re: STM32F407 + прерывание + время реакции

Пн июл 27, 2015 07:00:30

Cat писал(а):Если это возможно (я не знаю специфики вашего устройства), назначьте этому прерыванию наивысший приоритет и посмотрите

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


MPU задействован?

Судя по тому, что я глубоко задумался, что такое MPU, наверное, его не трогал. MPU - Memory Protection Unit? Какое оно имеет отношение к моей программе, и что с ним вообще можно делать?

Re: STM32F407 + прерывание + время реакции

Пн июл 27, 2015 07:46:09

Двенадцать, вообще-то.
И от того, чем процессор был занят в момент возникновения прерывания, момент входа в обработчик, как раз таки зависит:
Еще шесть тактов добавятся, если внешнее прерывание возникло во время выполнения кода в обработчике другого прерывания, с более низким приоритетом. Так оно по копеечке и набегает где-то.[/quote]

Конечно - двенадцать. Вообще в STM32F4, если верить описанию, время отклика на событие прерывания составляет 12 тактов - если прерывается фоновая программа, 6 тактов - если прерывается другое низкоприоритетное прерывание, 18 тактов - если прерывание произошло в момент выхода из другого прерывания (выход из прерывания занимает 12 тактов). В итоге имеем максимально возможный шум (или биения) на выходе до: 18 - 6 = 12 тактов. Для тактовой частоты 168 МГц это составит 0,072 мкс. И это максимум! А у меня в реале - 0,2 мкс. Причём даже с отключёнными другими прерываниями.
Что касается зависимости от фоновой программы. В этом микроконтроллере выборка и выполнение команды занимают 1 такт. Ну, может быть, ещё загрузка 1 - 2 аргументов - по такту. Но учитывая, что в нём организован аппаратный конвейер, влияние фоновой программы на обработчик, вернее на время его вызова, не должно быть вообще! А у меня оно есть, да ещё какое сильное!
Я уж даже думал, что столь короткий цикл в фоновой программе так меняет ток потребления МК, что не выдерживает стабилизатор питания, и поэтому сбивается PLL в STM32F4. Но это не подтвердилось - обвешанный большими ёмкостями МК ведёт себя точно также, как и в стандартном включении.

Re: STM32F407 + прерывание + время реакции

Вт июл 28, 2015 05:38:23

ШСА писал(а):Но учитывая, что в нём организован аппаратный конвейер, влияние фоновой программы на обработчик, вернее на время его вызова, не должно быть вообще!

Текущая команда, во время выполнения которой случилось прерывание, должна завершиться. А это может занять не один такт. Так что от джиттера тут никуда не деться.

Re: STM32F407 + прерывание + время реакции

Вт июл 28, 2015 06:57:39

Текущая команда, во время выполнения которой случилось прерывание, должна завершиться. А это может занять не один такт. Так что от джиттера тут никуда не деться.[/quote]

Без сомнения, это так. Но какой он будет, этот фазовый шум?
В STM32F4 команда без аргументов выполняется за 3 такта: выборка - расшифровка - исполнение. Но, поскольку там организован на микропрограммном уровне конвейер команд, то в на каждом такте одна команда исполняется, следующая расшифровывается, а будущая выбирается. В результате каждый такт исполняется 1 команда, и прервать этот процесс можно на любом такте.
А вот что сделать нельзя, так это влезть "внутрь" такта. Отсюда и неизбежность фазового шума. Его величина должна быть при отсутствии других прерываний - 1 такт, при наличии других конкурирующих событий - от 6+1 до 12+1 тактов.
А у меня, во первых, фазовые сдвиги достигают 34 тактов (т.е. в три раза больше!), а во вторых, явственно прослеживается зависимость времени реакции от содержания фоновой программы. Причем, интересно, во время длительного короткого цикла очистки памяти в фоновой программе время реакции на событие УМЕНЬШАЕТСЯ! Более того, в этот период уменьшается и мелкий фазовый шум (поскольку цикл очистки длительный, то за это время проходит много прерываний). Ну, и в третьих - Это явление не зависит от наличия других прерываний, и происходит даже тогда, когда других событий нет, а фазовые сдвиги такие же = 34 такта.

Re: STM32F407 + прерывание + время реакции

Ср июл 29, 2015 02:35:03

ШСА писал(а):А у меня, во первых, фазовые сдвиги достигают 34 тактов (т.е. в три раза больше!), а во вторых, явственно прослеживается зависимость времени реакции от содержания фоновой программы.

Судя по всему, виноват кеш инструкций. Каждый промах с предсказанием выливается в пять тактов ожидания поступления данных из флеша. При возникновении внешнего прерывания, промахи кеша неизбежны. Вот здесь довольно подробно эту проблему описывают и даже кой-какие методы ее обхода предлагают. Ну и гуглом по "STM32F4 interrupt jitter" пройтись тоже не лишним будет.

Re: STM32F407 + прерывание + время реакции

Ср июл 29, 2015 20:40:29

a5021 писал(а):
ШСА писал(а):А у меня, во первых, фазовые сдвиги достигают 34 тактов (т.е. в три раза больше!), а во вторых, явственно прослеживается зависимость времени реакции от содержания фоновой программы.

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


Согласен, промах неизбежен, и это обязательно приведёт к некоторой задержке входа в обработчик.
Здесь возможен интересный эффект: если в перерывах между событиями фоновая программа выполнит 1024 шага (длина кэша в STM32F407), то гарантированно в кэше не сохранится точка входа в обработчик. Тогда при его вызове будет этот "промах". А вот когда фон долго находится в коротком цикле очистки памяти, точка входа обработчика сохраниться может, что приведёт к уменьшению времени реакции на внешнее событие на эти 5 тактов. Это согласуется с экспериментом за исключением одного - у меня задержка (фазовый сдвиг выходного сигнала) значительно больше - порядка 34 тактов.
Появилась ещё одна гипотеза, которая, честно сказать, меня потрясла.
Дело в том, что у меня включён аппаратный FPU (Float Point Unit). А у него есть свои регистры (кажется 32 шт), которые по умолчанию МК загоняет в стек при прерывании в добавок к тем, которые он сохраняет при выключенном FPU. В фоне FPU используется очень широко, а вот при очистке памяти - нет. И если МК прерывается событием в момент, когда работает FPU, то в стек запишется на 32 слова больше, чем обычно. А если FPU не используется - время реакции уменьшится на 32 такта!!!
Запись регистров FPU можно запретить с помощью Lazy context save. Но как это сделать в CooCox я пока никак не соображу.

За ссылочку большое спасибо.

Re: STM32F407 + прерывание + время реакции

Чт июл 30, 2015 20:46:29

Наконец сегодня дошли руки проверить хоть какие-то гипотезы. Собственно, рабочих гипотез осталось две.
Первая: что причиной влияния фоновой программы на время реакции обработчика и является сохранение в стеке регистров FPU и предложил его запретить. Такой запрет не помешал бы работе системы, поскольку FPU в обработчиках прерываний не используется, а значит и состояние FPU от прерывания не изменилось бы.
В STM32F4 это делается просто: FPU->FPCCR &= ~((1U << FPU_FPCCR_ASPEN_Pos) | (1U << FPU_FPCCR_LSPEN_Pos));
В результате явление не исчезло, ну существенно уменьшилось. Т.е влияние фоновой программы на прерывания осталось, но флуктуации времени запуска обработчика прерываний снизились не менее чем в два раза.
Мораль: Количество сохраняемых в стеке регистров ЦП при прерывании зависит не от того, выполняло или нет в этот момент FPU какую нибудь команду, а от того, что записано в регистре CONTROL с помощью FPU->FPCCR.
Поэтому запрещая сохранение регистров FPU можно изменить среднее время реакции обработчиков на внешние события и изменить интенсивность использования стека. Но к флуктуациям времени вызова обработчика в зависимости от команды, выполняемой в этот момент фоновой программой, это не имеет отношения.

Осталась вторая гипотеза, что время реакции обработчика зависит от длины кэша команд МК. Т.е. механизм такой: если фоновая программа выполняет длительный короткий цикл, в течение которого происходит несколько прерываний, то после первого прерывания из кэша не вытесняется начало обработчика прерывания и все последующие прерывания происходят быстрее.
Чтобы проверить эту идею нужно было очистить кэш команд перед выходом из обработчика.
Я не нашёл (да пока и не искал) такой команды, но чтобы проверить эту идею в фоновой программе внутри короткого цикла вставил вызов небольшой функции, которая ничего полезного не делала, но и ничего не портила. Фактически, цикл перестал быть коротким. Результат - эти флуктуации исчезли!
Мораль сногсшибательная: кэш команд в STM32F4, который так здорово "разгоняет" ЦП, может быть причиной непредсказуемых флуктуаций времени реакции обработчиков на внешние события. Причём флуктуаций весьма чувствительных - до 400 нс, когда используется FPU и включено сохранение его регистров в стеке (это происходит по умолчанию при включении FPU)!

Re: STM32F407 + прерывание + время реакции

Пн янв 08, 2024 21:12:03

Прошу прощения, что старую тему поднимаю, но если рассматривать не 407, а 103 STM, то кто какие получал задержки выхода в прерывание? Что-то у меня получаются вообще запредельно большие - аж под 3мкс. Да программа конечно большая, многое могло влиять, но не на столько же? Частота 72МГц жешь.
Ответить