|
STM32F407 + прерывание + время реакции, Меняется время реакции на внешнее событие |
|
|
|
Jul 26 2015, 19:07
|
Местный
  
Группа: Участник
Сообщений: 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 не используется)! В чём причина этого явления и как с ним бороться? Буду признателен за любые идеи или информацию.
|
|
|
|
|
 |
Ответов
|
Jul 28 2015, 15:45
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
вы в какой среде пишите? Если в Keil, то для переноса функций в РАМ, вам надо правой кнопкой в С файл с функциями тыкнуть, и сказать чтобы они запустились из РАМ, все остальное сделает кеил за вас сам.
Регистры FPU надо сохранять в стэк, только если в прерываниях вы будите использовать модуль FPU, если нет, то пусть они лежат где лежать, и вход будет быстрее в прерывание и проблем не будет.
Идея с ДМА вам видится не верно. Вам надо подготовить массив для вывода, так чтобы ДМА просто перекладывало данные на порт, с заданной частотой. Пусть ваша фоновая неспешная программа подготавливая файл делает его как раз того вида, чтобы ДМА осталось его только выплюнуть. ДМА сможет спокойно запускаться по таймеру с заданными интервалами и без каких либо плаваний времянки (если ему поставить приоритет повыше) все делать. А ядро в это время сможет продолжать заниматься своими делами....
|
|
|
|
|
Jul 29 2015, 15:54
|
Местный
  
Группа: Участник
Сообщений: 291
Регистрация: 11-04-14
Из: Саратов
Пользователь №: 81 335

|
Цитата(Golikov A. @ Jul 28 2015, 18:45)  вы в какой среде пишите? Если в Keil, то для переноса функций в РАМ, вам надо правой кнопкой в С файл с функциями тыкнуть, и сказать чтобы они запустились из РАМ, все остальное сделает кеил за вас сам. Регистры FPU надо сохранять в стэк, только если в прерываниях вы будите использовать модуль FPU, если нет, то пусть они лежат где лежать, и вход будет быстрее в прерывание и проблем не будет. Идея с ДМА вам видится не верно. Простите за долгое отсутствие - текучка и изучение мануала по наводке jcxz. Оказывается, я многое упустил в своё время... Среда у меня, к сожалению, CooCox. Keil прекрасная штука, но мне не по карману, а программа слишком велика для бесплатной версии. В прерываниях FPU нигде не используется, только в фоне. Ищу способ запретить сохранять FPU регистры в стек - а их там 32, если не ошибаюсь. Если даже по 1 такту на каждого - это уже масштаб моих флуктуаций! Идея с DMA мною не отброшена. Я её проработаю, но позже. А пока мне надо научиться отключать Lazy context save - я даже это ещё не могу заставить сделать свой кокос. Цитата(bugdesigner @ Jul 28 2015, 19:26)  А можно одно уточнение? У Вас таймер считает импульсы 84 МГц без прескалера? Я правильно понял? Не могли бы Вы показать в студию код обработчика прерывания и код инициализации таймера? Может что-то прояснится... И последнее, я присоединюсь к мнению коллег насчёт дернуть ногой при входе в обработчик. Может всё же какая-то логическая ошибка закралась. Да, таймер считает без прескалера. Инициализируеется так: Код /*------------------Инициализация TIM6 - строчный таймер-*/ RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE); //включаем тактирование //Частота шины APB1 42 МГц, на таймер - 84 Мгц TIM6->PSC = 0; //Настройка предделителя на 84 "такта" в микросекунду TIM6->ARR = 10080; //10080 период - почти две строки 120 мкс 5600 TIM6->DIER &= ~TIM_DIER_UIE; //запрет прерывания от таймера TIM6->CR1 |= TIM_CR1_CEN; //включаем таймер - пусть молотит непрерывно // прерывания от TIM6 не будет //TIM6_CNT — текущее значение счётчика для чтения/записи; Описал максимально подробно. Из обработчика приведу фрагмент, который, собственно и занимается выводом телевизионной строки Код Tim6_Count = TIM6->CNT; //длительность предыдущей строки TIM6->CNT = 0; //начало измерения строк - сбрасываем таймер //подготовимся к скоростному выводу данных Td = Tdelt; //1 шаг = 10 тактов TIM6 - шаг Ts = T_Nath - Td;//начальная задержка 10,5 мкс Kt = KolBytStr; //число байт в строке //Начали вывод активной строки. Пока не кончится активная строка, не выйдем отсюда if (Zerkalo) { //вывод "зеркально" - со старшего полубайта последнего байта массива строки Video_Adres_Th0 = (Nstr - NomerNath) * KolBytStr + KolBytStr + Video_Adres; //адрес первого байта //это адрес текущих 2 точек вывода - последний байт строки while (TIM6->CNT < Ts)continue;//ждём момента для вывода 1 точки GPIO_SetBits(PORT_OUT1_ON_OSD, OUT1_ON_OSD);//вкл. сигнала видео Vt = (uint32_t)(*--Video_Adres_Th0) << SDWIG_RGBT; //первые две точки while (Kt--) { Vt1 = Vt; Vt = Vt >> 4; //спустим старший полубайт Ts += Td; //время следующей точки while (TIM6->CNT < Ts) continue; //ждём момента для вывода точки PORT_RGBT->ODR = Vt; //вывод старшего полубайта Ts += Td; //время следующей четной точки Vt = (uint32_t)(*--Video_Adres_Th0) << SDWIG_RGBT; //следующий байт на разложение на точки while (TIM6->CNT < Ts)continue; //ждём момента для вывода точки PORT_RGBT->ODR = Vt1; //вывод младшего полубайта } } else { //вывод "прямо" Поясню, что строка, где "//ждём момента для вывода 1 точки" это и есть интервал от начала прерывания до начала вывода. Вот он то и "плавает". Кстати следующая строка и есть ваше "дернуть ногой".
Сообщение отредактировал IgorKossak - Jul 29 2015, 17:16
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!
|
|
|
|
|
Jul 30 2015, 03:15
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(ШСА @ Jul 29 2015, 21:54)  В прерываниях FPU нигде не используется, только в фоне. Ищу способ запретить сохранять FPU регистры в стек - а их там 32, если не ошибаюсь. Если даже по 1 такту на каждого - это уже масштаб моих флуктуаций! Идея с DMA мною не отброшена. Я её проработаю, но позже. А пока мне надо научиться отключать Lazy context save - я даже это ещё не могу заставить сделать свой кокос. Вы как-то странно мануал читаете.... Lazy context save Вам отключать не надо, он никак не увеличивает время входа, а наоборот - предназначен для уменьшения времени входа в ISR (резервирует место в стеке, но не пишет). Но так как у Вас FPU в фоне используется, а где-то не используется, то из-за Lazy context save у Вас в этих местах и будет разница во времени входа (но место в стеке при стэкинге всё равно будет выделяться одинаково!). А вот если Вы, как я советовал, вообще отключите автоматическое сохранение контекста FPU при входе в ISR, то всегда на стек будет сохраняться как в M3 только 8 регистров. Это можно сделать, если в ISR-ах у Вас не используется FPU. Но если есть операционка и FPU используется в разных задачах, то в переключателе задач ОС (программном) надо сделать сохранение контектса FPU ручками. У нас в наших изделиях я так и делаю, но не для уменьшения времени входа в ISR, а для экономии стеков задач (делаю FPCCR = 0, а потом сохраняю или не сохраняю контекст FPU в переключателе задач ручками, в зависимости от того - использует данная задача FPU или нет). И как это сделать - я Вам уже выше писал: FPCCR = 0. Вы как-то читаете выборочно  И от компилятора это никак не зависит, это Вам надо открыть мануал на ядро M4 и найти там FPCCR.
|
|
|
|
Сообщений в этой теме
ШСА STM32F407 + прерывание + время реакции Jul 26 2015, 19:07 aaarrr Цитата(ШСА @ Jul 26 2015, 22:07) ...никак... Jul 26 2015, 19:29 ШСА Цитата(aaarrr @ Jul 26 2015, 22:29) В нек... Jul 27 2015, 05:46  Огурцов а если умножить на 5 тактов ожидания, то получится... Jul 27 2015, 05:53 ViKo Может, нестабильную задержку создает перезапуск та... Jul 27 2015, 03:03 ШСА Цитата(ViKo @ Jul 27 2015, 06:03) Может, ... Jul 27 2015, 06:09  Огурцов Цитата(ШСА @ Jul 27 2015, 06:09) Не понял... Jul 27 2015, 08:36   ШСА Цитата(Огурцов @ Jul 27 2015, 11:36) флеш... Jul 27 2015, 09:02 AHTOXA Мне кажется, что самый здравый совет был вот этот:... Jul 27 2015, 08:35 aaarrr Попробуйте сделать следующее:
1. Внешнее прерывани... Jul 27 2015, 06:27 ШСА Цитата(aaarrr @ Jul 27 2015, 09:27) Попро... Jul 27 2015, 06:41  scifi Вот тут расписано про задержку на входе в обработч... Jul 27 2015, 06:49   ШСА Цитата(scifi @ Jul 27 2015, 09:49) Вот ту... Jul 27 2015, 07:12 aaarrr Интересно сравнить результаты при работе из флеш и... Jul 27 2015, 06:52 scifi Цитата(aaarrr @ Jul 27 2015, 09:52) 2. Пр... Jul 27 2015, 07:00  aaarrr Цитата(scifi @ Jul 27 2015, 10:00) Можно ... Jul 27 2015, 07:04 Timmy Цитата(ШСА @ Jul 26 2015, 22:07) Дорогие ... Jul 27 2015, 07:30 ШСА Цитата(Timmy @ Jul 27 2015, 10:30) Если в... Jul 27 2015, 08:04  scifi Цитата(ШСА @ Jul 27 2015, 11:04) Ну, собс... Jul 27 2015, 08:08   ШСА Цитата(scifi @ Jul 27 2015, 11:08) А нель... Jul 27 2015, 08:31 Golikov A. ЦитатаФлаги очищаются в конце обработчика, так что... Jul 27 2015, 07:49 ШСА [quote name='Golikov A.' date='Jul 27 ... Jul 27 2015, 08:18  scifi Цитата(ШСА @ Jul 27 2015, 11:18) Так прер... Jul 27 2015, 08:29   ШСА Цитата(scifi @ Jul 27 2015, 11:29) Неправ... Jul 27 2015, 08:40    scifi Цитата(ШСА @ Jul 27 2015, 11:40) Интересн... Jul 27 2015, 08:59    jcxz Выключите сохранение контекста FPU при стэкинге (и... Jul 28 2015, 02:43     aaarrr Цитата(jcxz @ Jul 28 2015, 05:43) Перенес... Jul 28 2015, 06:37     ШСА Цитата(jcxz @ Jul 28 2015, 05:43) Выключи... Jul 28 2015, 10:09      scifi Цитата(ШСА @ Jul 28 2015, 13:09) Ведь фаз... Jul 28 2015, 10:37       ШСА Цитата(scifi @ Jul 28 2015, 13:37) А это ... Jul 28 2015, 12:17      ViKo Цитата(ШСА @ Jul 28 2015, 13:09) Ребята... Jul 28 2015, 11:33       scifi Цитата(ViKo @ Jul 28 2015, 14:33) А вы та... Jul 28 2015, 12:27      jcxz Цитата(ШСА @ Jul 28 2015, 16:09) Я не зна... Jul 28 2015, 12:33       ШСА Цитата(jcxz @ Jul 28 2015, 15:33) Имхо - ... Jul 28 2015, 13:03        jcxz Цитата(ШСА @ Jul 28 2015, 19:03) Интересн... Jul 29 2015, 03:03        SasaVitebsk Цитата(ШСА @ Jul 28 2015, 16:03) вывод до... Jul 29 2015, 05:50         Сергей Борщ Цитата(SasaVitebsk @ Jul 29 2015, 08:50) ... Jul 29 2015, 07:38          jcxz Цитата(Сергей Борщ @ Jul 29 2015, 13:38) ... Jul 29 2015, 08:11          Tanya Цитата(Сергей Борщ @ Jul 29 2015, 10:38) ... Jul 29 2015, 08:33          ШСА Цитата(Сергей Борщ @ Jul 29 2015, 10:38) ... Jul 29 2015, 17:03           jcxz Цитата(ШСА @ Jul 29 2015, 23:03) А вот с ... Jul 30 2015, 05:09            ШСА Наконец сегодня дошли руки проверить хоть какие-то... Jul 30 2015, 17:13             jcxz Цитата(ШСА @ Jul 30 2015, 23:13) Мораль: ... Jul 31 2015, 02:35             SasaVitebsk Цитата(ШСА @ Jul 30 2015, 20:13) Мораль: ... Jul 31 2015, 04:46              ШСА Цитата(SasaVitebsk @ Jul 31 2015, 07:46) ... Jul 31 2015, 07:04               scifi Цитата(ШСА @ Jul 31 2015, 10:04) А вот то... Jul 31 2015, 08:05                jcxz Цитата(scifi @ Jul 31 2015, 14:05) Возьми... Jul 31 2015, 10:05                 scifi Цитата(jcxz @ Jul 31 2015, 13:05) Кстати ... Jul 31 2015, 10:26  LightElf QUOTE (ШСА @ Jul 27 2015, 11:18) Так прер... Jul 27 2015, 08:29 zltigo QUOTE (Golikov A. @ Jul 27 2015, 10:49) п... Jul 28 2015, 09:17 Golikov A. 1. Можно отключить флэщ акселератор и тогда время ... Jul 27 2015, 09:15 ШСА Цитата(Golikov A. @ Jul 27 2015, 12:15) 1... Jul 27 2015, 09:52 Golikov A. Справедливо... Jul 28 2015, 09:49 bugdesigner А можно одно уточнение? У Вас таймер считает импул... Jul 28 2015, 16:26 Golikov A. любой проц можно поставить на жесткую времянку, то... Jul 31 2015, 08:33 ШСА Цитата(Golikov A. @ Jul 31 2015, 11:33) А... Jul 31 2015, 19:00  aaarrr Цитата(ШСА @ Jul 31 2015, 22:00) Значит, ... Jul 31 2015, 19:11  jcxz Цитата(ШСА @ Aug 1 2015, 01:00) Но экспер... Aug 1 2015, 06:10  ШСА Цитата(ШСА @ Jul 31 2015, 22:00) Но экспе... Aug 2 2015, 18:05   jcxz Цитата(ШСА @ Aug 3 2015, 00:05) Чем больш... Aug 3 2015, 03:58    ШСА Спасибо. Но ведь и здесь пока есть варианты, напри... Aug 3 2015, 04:09 ШСА Цитата(Golikov A. @ Jul 31 2015, 11:33) л... Aug 1 2015, 15:39  aaarrr Цитата(ШСА @ Aug 1 2015, 18:39) Четыре та... Aug 1 2015, 16:56   ШСА Покажу, но уже не сегодня. Aug 1 2015, 17:04 Golikov A. набортная, на борту проца.... Jul 31 2015, 19:09 Golikov A. ЦитатаНо эксперимент (критерий истины) показал, чт... Jul 31 2015, 19:18 ШСА Цитата(Golikov A. @ Jul 31 2015, 22:18) о... Aug 1 2015, 16:47 Golikov A. ассемблер тут не причем, человека беспокоит не вре... Aug 1 2015, 07:10 jcxz Цитата(Golikov A. @ Aug 1 2015, 13:10) ас... Aug 1 2015, 18:44 Golikov A. Взять порт
Взять маску
Если ноль прыгнуть
Прыгнуть... Aug 1 2015, 18:05 aaarrr Цитата(Golikov A. @ Aug 1 2015, 21:05) Ма... Aug 1 2015, 18:14  ViKo Цитата(aaarrr @ Aug 1 2015, 21:14) Загруз... Aug 2 2015, 07:42   aaarrr Цитата(ViKo @ Aug 2 2015, 10:42) Кейл пок... Aug 2 2015, 08:30 ШСА Цитата(Golikov A. @ Aug 1 2015, 21:05) Вз... Aug 1 2015, 18:29 Golikov A. Не вижу возможности вам не верить), а почему загру... Aug 1 2015, 18:28 aaarrr Цитата(Golikov A. @ Aug 1 2015, 21:28) Не... Aug 1 2015, 18:50  GetSmart Цитата(aaarrr @ Aug 1 2015, 22:50) Одиноч... Sep 10 2015, 23:41 Golikov A. Ваша правда, другое дело пока лдр искал, нашел что... Aug 1 2015, 19:16 jcxz Когда дело доходит до подсчёта тактов при работе с... Aug 1 2015, 21:18 Golikov A. Мы же не знаем куда у вас там подключены ножки, и ... Aug 3 2015, 05:50 ШСА Цитата(Golikov A. @ Aug 3 2015, 08:50) Мы... Aug 3 2015, 07:32 Golikov A. если 4 биты порта в памяти рядом (в пределах байта... Aug 3 2015, 07:36 ШСА Ну да, а как иначе? В STM32F4 нет никаких видеосре... Aug 3 2015, 07:46 Golikov A. Ну ДМА может гнать по кругу, и оно имеет прерывани... Aug 3 2015, 07:55 ШСА Цитата(Golikov A. @ Aug 3 2015, 10:55) Де... Aug 3 2015, 08:22 Golikov A. ДМА запускается по таймеру, таймер запускается по ... Aug 3 2015, 08:57 ШСА Отлично. Спасибо. Aug 3 2015, 09:08 aaarrr Цитата(GetSmart @ Sep 11 2015, 02:41) Под... Sep 11 2015, 10:22 GetSmart Цитата(aaarrr @ Sep 11 2015, 14:22) Corte... Sep 11 2015, 14:26  aaarrr Цитата(GetSmart @ Sep 11 2015, 17:26) Дру... Sep 11 2015, 14:54 GetSmart Время до сих пор не нашёл для полноценного тестиро... Sep 21 2015, 12:25 ШСА Цитата(GetSmart @ Sep 21 2015, 15:25) Вре... Sep 23 2015, 19:32  GetSmart Цитата(ШСА @ Sep 23 2015, 23:32) Тестиров... Sep 23 2015, 19:39 GetSmart Потестил на LPC4357 и LPC11U37/501. У обоих ядра M... Oct 25 2015, 08:54 GetSmart Цитата(GetSmart @ Oct 25 2015, 12:54) У п... Oct 26 2015, 11:57 GetSmart Проверил ещё на LPC1227 (M0+ r0p0). Этого эффекта ... Oct 29 2015, 19:20 GetSmart Цитата(GetSmart @ Oct 29 2015, 23:20) Про... Nov 5 2015, 17:22
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|