|
|
  |
STM32F407 + прерывание + время реакции, Меняется время реакции на внешнее событие |
|
|
|
Jul 28 2015, 10:09
|
Местный
  
Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335

|
Цитата(jcxz @ Jul 28 2015, 05:43)  Выключите сохранение контекста FPU при стэкинге (и резервирование места для него): FPCCR = 0;
Зачем его чистить? Перенесите ISR в ОЗУ как уже советовали. Причём начало его выровняйте на адрес, кратный размеру строки выборки команд CPU (вроде STM407 выбирает команды строками по 128байт). И таблицу векторов - тоже в ОЗУ. Лучше - в CCM.
Но самое правильное решение - конечно использовать DMA, выставив ему приоритет доступа к шине выше чем CPU. Вы меня своим заявлением слегка контузили. Я не знаю что такое контекст FPU и стэкинг. Аппаратный FPU (Floating Point Unit) у меня включён, и выключать его нельзя. Это всё, что я знаю про FPU. Использовать DMA - что я выиграю, и главное - сколько? Ведь фаза выходного импульса плавает аж на 34 такта! Перенести ISR в ОЗУ мне кажется здравой идеей, сейчас я продумываю как её осуществить, чтобы себе не сильно напортить. Ребята! Давайте договоримся - если у кого есть идея, излагайте в таком порядке: 1. Гипотеза, объясняющая природу этого явления, а именно - каким образом фоновая программа может влиять на время реакции на внешнее событие, да ещё в таких масштабах; 2. Способ или механизм исключения или компенсации этих задержек; 3. Конкретные рекомендации; В противном случае я вынужден по вашим рекомендациям гадать, в чём же заключается идея. А это плохо потому, что я не настолько глубоко знаю STM32F4, чтобы по намёку понять всё, что имелось в виду. Кстати, если есть примеры как оформить ISR в ОЗУ, а тем более таблицу векторов в CCM, дайте ссылочку, чтобы мне поменьше пришлось наступать на грабли.
|
|
|
|
|
Jul 28 2015, 10:37
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(ШСА @ Jul 28 2015, 13:09)  Ведь фаза выходного импульса плавает аж на 34 такта! А это хорошо или плохо? Сколько надо? 10 хватит? А 30? Телепаты в отпуске. Цитата(ШСА @ Jul 28 2015, 13:09)  Использовать DMA - что я выиграю, и главное - сколько? Не очень понятно, что вы там ваяете, но суть предложения такова: сделать так, чтобы фазу формировал контроллер DMA, а не процессор с его неопределённым временем входа в обработчик прерывания. В общем, надеемся, и не без оснований, что у DMA джиттер поменьше, чем 34 такта. Предвидя вопрос "как?", отвечаю: только вам ведомо, как работает эта ваша адская машина.
|
|
|
|
|
Jul 28 2015, 12:17
|
Местный
  
Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335

|
Цитата(scifi @ Jul 28 2015, 13:37)  А это хорошо или плохо? Сколько надо? 10 хватит? А 30? Чтобы у вас не рисовались монстры в голове, расскажу, что это за машина. Эта штучка получает изображение от видеокамеры. Фоновая программа, никуда не спеша, рассматривает его, выявляет в нём разные особенности, а потом формирует своё изображение, которое, по её мнению, и должно появиться на экране. А выводом изображения как раз и занимается мой обработчик. И он очень спешит - его работа запускается телевизионными синхроимпульсами. Сама по себе начальная задержка не критична, а вот её "плавание" недопустимо. Допуск на фазовый шум планировался на уровне 4 тактов. По результатам испытаний стало ясно, что 10, от силы 12 тактов ещё можно терпеть. В процессе борьбы с шумами мы и выявили эту странную взаимосвязь фоновой программы и обработчика. Кстати, стало ясно, что и происхождение других мелких шумов, скорее всего имеют ту же природу. А вот с природой-то и пошли непонятки. Цитата(ViKo @ Jul 28 2015, 14:33)  А вы так и не попробовали дергать ногой в прерывании? Гипотеза в том, что у таймера есть предделитель и счетчик, которые (оба или один из них - вам читать в руководстве) могут перегружаться сразу, а могут, только, когда досчитают до конца. У вас как? Мой обработчик, сообразуясь со таймером, пересылает данные на выходной порт. Так что дёрганья ног здесь более чем достаточно. Таймер сбрасывается в самом начале прерывания, чтобы "синхронизироваться" с внешним событием (в этом-то и ахиллесова пята алгоритма). До следующего события таймер перезагрузиться не успеет, а если это случилось, значит входной сигнал исчез, и можно "уснуть". Так что во время работы таймер никогда не может перезагружаться сам.
|
|
|
|
|
Jul 28 2015, 12:33
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ШСА @ Jul 28 2015, 16:09)  Я не знаю что такое контекст FPU и стэкинг. Аппаратный FPU (Floating Point Unit) у меня включён, и выключать его нельзя. Это всё, что я знаю про FPU. Откройте мануал на CortexM, там есть описание что такое stacking. Это собственно - сохранение некоторых регистров CPU при входе в прерывание. M4, в отличие от M3, умеет сохранять (или резервировать место для сохранения) также регистры FPU. Если у Вас выключено Lazy context save или МК посчитает что по каким-то причинам контекст FPU тоже надо сохранить, то в стек вместо 8 слов запишется гораздо больше. Т.е. - если как я понимаю Вы где-то в фоне использовали FPU, то это и произойдёт. Цитата(ШСА @ Jul 28 2015, 16:09)  Использовать DMA - что я выиграю, и главное - сколько? Ведь фаза выходного импульса плавает аж на 34 такта! Не знаю какой выходной импульс Вы имеете в виду, но Вашу задачу - прерывание на входной импульс и сброс таймера в обработчике этого прерывания, может сделать DMA: делаете запуск DMA-транзакции по этому самому импульсу, этой транзакцией обнуляете таймер. Задержка запуска DMA-транзакции будет неизмеримо меньше времени реакции на прерывание. Не знаю правда - поддерживает ли такое DMA-контроллер STM32F407? Но в LPC17xx такое возможно. STM32F407 думаю тоже должен уметь. Цитата(ШСА @ Jul 28 2015, 18:17)  Мой обработчик, сообразуясь со таймером, пересылает данные на выходной порт. Так что дёрганья ног здесь более чем достаточно. Таймер сбрасывается в самом начале прерывания, чтобы "синхронизироваться" с внешним событием (в этом-то и ахиллесова пята алгоритма). До следующего события таймер перезагрузиться не успеет, а если это случилось, значит входной сигнал исчез, и можно "уснуть". Так что во время работы таймер никогда не может перезагружаться сам. Имхо - в таком случае вообще программно ничего делать не нужно. Всё должен делать DMA, получающий синхрособытия от таймера, который по этим событиям будет класть данные в порт.
|
|
|
|
|
Jul 28 2015, 13:03
|
Местный
  
Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335

|
Цитата(jcxz @ Jul 28 2015, 15:33)  Имхо - в таком случае вообще программно ничего делать не нужно. Всё должен делать DMA, получающий синхрособытия от таймера, который по этим событиям будет класть данные в порт. Интересная идея, но её надо обсчитать: вывод должен происходить каждые 20 тактов ( для таймера от 84 МГц - 10 тактов). Но выводиться должна только половина байта по очереди старший - младший, или младший - старший. Т.о. за двадцать тактов нужно успеть: "достать" нужный байт, "перевернуть" его как надо, выделить нужную половинку и отправить на выходной порт. Да, ещё следить, когда включить-выключить таймер. А вот ваша идея насчёт FPU меня потрясла. Действительно, во время короткого цикла очистки памяти в фоне FPU не используется и время реакции на прерывание уменьшается. А в остальных местах программы FPU занято на всю катушку, и время реакции увеличивается. Я посмотрю свои настройки, надеюсь, уж если не решить проблему, то хотя бы уменьшить.
|
|
|
|
|
Jul 28 2015, 15:45
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
вы в какой среде пишите? Если в Keil, то для переноса функций в РАМ, вам надо правой кнопкой в С файл с функциями тыкнуть, и сказать чтобы они запустились из РАМ, все остальное сделает кеил за вас сам.
Регистры FPU надо сохранять в стэк, только если в прерываниях вы будите использовать модуль FPU, если нет, то пусть они лежат где лежать, и вход будет быстрее в прерывание и проблем не будет.
Идея с ДМА вам видится не верно. Вам надо подготовить массив для вывода, так чтобы ДМА просто перекладывало данные на порт, с заданной частотой. Пусть ваша фоновая неспешная программа подготавливая файл делает его как раз того вида, чтобы ДМА осталось его только выплюнуть. ДМА сможет спокойно запускаться по таймеру с заданными интервалами и без каких либо плаваний времянки (если ему поставить приоритет повыше) все делать. А ядро в это время сможет продолжать заниматься своими делами....
|
|
|
|
|
Jul 29 2015, 03:03
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ШСА @ Jul 28 2015, 19:03)  Интересная идея, но её надо обсчитать: вывод должен происходить каждые 20 тактов ( для таймера от 84 МГц - 10 тактов). Но выводиться должна только половина байта по очереди старший - младший, или младший - старший. Т.о. за двадцать тактов нужно успеть: "достать" нужный байт, "перевернуть" его как надо, выделить нужную половинку и отправить на выходной порт. Да, ещё следить, когда включить-выключить таймер. Вы видно плохо представляете как работает DMA... Я не очень хорошо знаю периферию STM32, но для LPC17xx сделал бы так: Таймер1 программирую в режим счётчика импульсов на ноге МК (Ваши стартовые импульсы подаю на эту ногу). Предел счёта для него ==1. По этому пределу программирую стоп таймера1 и выдачу события на DMA-канал1. DMA-канал1 программирует Таймер2, запускает его с периодом ==10 тактов. Таймер2 по достижении величины периода (10) перезапускается и выдаёт событие на DMA-канал2. DMA-канал2 выполняет пересылки из заранее подготовленного массива тетрад в порт каждые 10 тактов таймера2 (по каждому его перезапуску). Это - первый блок пересылки DMA-канала2 (он находится в режиме передачи свЯзных списков (linked list)). Размер первого блока linked list равен размеру пересылаемого массива тетрад. После завершения первого блока, DMA-канал2 вторым блоком пересылки выключает таймер2. Третьим блоком пересылки DMA-канал2 включает и программрует таймер1 на ожидание след. входного импульса. После этого DMA-канал2 переходит на начало связного списка своих блоков передач (готов к обработке след. входного импульса). Если STM32 позволяет запускать DMA от перепада на внешнем пине, то можно обойтись без таймера, а запускать DMA-канал1 от пина. Цитата(ШСА @ Jul 28 2015, 19:03)  А вот ваша идея насчёт FPU меня потрясла. Действительно, во время короткого цикла очистки памяти в фоне FPU не используется и время реакции на прерывание уменьшается. А в остальных местах программы FPU занято на всю катушку, и время реакции увеличивается. Я посмотрю свои настройки, надеюсь, уж если не решить проблему, то хотя бы уменьшить. Достаточно просто выключить это сохранение контекста FPU раз у Вас FPU не используется в ISR. Это надо делать всегда, хотя-бы для того, чтобы уменьшить расход стека. Но по уму надо делать через DMA, раз у Вас такие требования к временным интервалам, что всё в тактах считаете. DMA более детерминирован по времени чем выполнение кода в CPU.
|
|
|
|
|
Jul 29 2015, 05:50
|
Гуру
     
Группа: Свой
Сообщений: 2 712
Регистрация: 28-11-05
Из: Беларусь, Витебск, Строителей 18-4-220
Пользователь №: 11 521

|
Цитата(ШСА @ Jul 28 2015, 16:03)  вывод должен происходить каждые 20 тактов ( для таймера от 84 МГц - 10 тактов). Любопытно конечно послушать продолжение, так как многие сообщают подробности, которых в мануале сразу и не заметишь. Такие вещи выясняются, когда конкретную задачу решаешь. )) Но если по теме, то раз речь идёт о 20 тактах, то всё же задачу требуется решать аппаратно. То есть фоновая задача может отсчитываться процессором, а, этот Ваш вывод, должен выполняться аппаратно. Аппаратно либо средствами процессора, либо внешними аппаратными средствами. На мой взгляд, это очевидно. Данный процессор, как раз не предназначен для формирования временных диаграмм. Для этих целей требуются процессора с чётко определённым временем выполнения команд, то есть без кэш, без механизмов предвыборки и так далее. Типа AVR, PIC, а так как они по быстродействию не укладываются, то плисину какую-нибудь применить. А процессор должен выполнять свою задачу асинхронно к данному событию. Чем раньше Вы это осмыслите, переделаете железо, тем быстрее решите задачу. Иначе всё равно к этому вернётесь. Моё мнение.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|