Перейти к содержанию
    

ADuC702x и обработчик прерывания FIQ

Здравствуйте форумчане!

 

Посоветуйте способ выхода из прерывания FIQ в микроконтроллере ADuC702x (ядро ARM7TDMI) на адрес нужной функции.

Из прерывания FIQ вызывать эту функцию не хочу, так как она по времени выполнения занимает порядка 30 мс, к тому же в процессе ее выполнения

может произойти прерывание от монитора напряжения питания в случае возникновения которого необходимо корректное остановка работы микроконтроллера.

Если у кого-то есть такой опыт, прошу поделиться примером кода. Использую в проекте Keil.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посоветуйте способ выхода из прерывания FIQ в микроконтроллере

 

А что, разрешение прерывания в обработчике и мутекс для запрета повтороного входа в ту же функцию не помогает?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А что, разрешение прерывания в обработчике и мутекс для запрета повтороного входа в ту же функцию не помогает?

Я так понимаю, что в случае вызова нужной мне функции из FIQ, работа контроллера прерываний будет восстановлена только после выхода из FIQ.

Мне необходимо максимальная реакция микроконтроллера на прерывание, поэтому установка флага в прерывании с последующей его проверкой в основном цикле программы не устраивает. Хотелось бы завершить прерывание переходом не в точку, предшествующую его возникновению, а на адрес нужной мне функции. Когда-то давно еще на архитектуре 8051 это было возможно путем манипуляции со стеком при помощи ассемблерных инструкций. Я думаю, что и на архитектуре ARM7TDMI это возможно....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как вы вернетесь то в точку где было прерывание, если вы из него улетите в вашу функцию...

вам предется в функцию передавать точку возврата, делать там непонятный переход... а если опять будет прерывание?

 

Когда вы попадает в FIQ прерывание, у вас снимается флажок реакции на прерывания, по выходу из FIQ он ставиться снова. Никто вам не мешает, при переходе в вашу функцию из FIQ опять поставить этот флажок.

 

тогда если ваша функция отработает до конца, вы выйдите из FIQ в точку остановки программы.

А если же у вас пока вы будите в функции возникнет прерывание, вы политите отработаете его и вернетесь в свою функцию, а когда ее закончите выйдите из FIQ в точку остановки программы.

 

Одна сложность вам надо сделать так чтобы повторно вы опять в FIQ не полетели, за этим просто надо следить.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Одна сложность вам надо сделать так чтобы повторно вы опять в FIQ не полетели, за этим просто надо следить.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

мне помниться что для FIQ был свой флаг, нет? То есть можно просто обычные прерывания разрешить, а FIQ не разрешать. или он все равно забьет обычные и пока он стоит, обычные не вызовутся?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мне необходимо максимальная реакция микроконтроллера на прерывание, поэтому установка флага в прерывании с последующей его проверкой в основном цикле программы не устраивает. Хотелось бы завершить прерывание переходом не в точку, предшествующую его возникновению, а на адрес нужной мне функции. Когда-то давно еще на архитектуре 8051 это было возможно путем манипуляции со стеком при помощи ассемблерных инструкций. Я думаю, что и на архитектуре ARM7TDMI это возможно....

Берёте любую RTOS. Например: uCOS. ЗавОдите высокоприоритетную задачу, которая ждёт события на каком-то мэйлбоксе.

В ISR посылаете сообщение в этот мэйлбокс. Задача просыпается, делает работу и опять уходит на ожидание мэйлбокса. Всё.

Стандартный подход построения задач-обработчиков событий.

 

мне помниться что для FIQ был свой флаг, нет? То есть можно просто обычные прерывания разрешить, а FIQ не разрешать. или он все равно забьет обычные и пока он стоит, обычные не вызовутся?

В ARM7 всего два внешних прерывания: FIQ и IRQ. У каждого свой флаг и свой бит разрешения.

При срабатывании одного из них, процессор переключается в соотв. контекст (FIQ или IRQ) со своим стеком. При входе в FIQ, насколько помню, автоматом запрещается IRQ.

Как правило - прерывание от любой периферии можно направить на любой из входов: FIQ или IRQ. Так что - прерывание любой периферии может быть как FIQ так и IRQ (по крайней мере в LPC23xx).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как вы вернетесь то в точку где было прерывание, если вы из него улетите в вашу функцию...

вам предется в функцию передавать точку возврата, делать там непонятный переход... а если опять будет прерывание?

 

Когда вы попадает в FIQ прерывание, у вас снимается флажок реакции на прерывания, по выходу из FIQ он ставиться снова. Никто вам не мешает, при переходе в вашу функцию из FIQ опять поставить этот флажок.

 

тогда если ваша функция отработает до конца, вы выйдите из FIQ в точку остановки программы.

А если же у вас пока вы будите в функции возникнет прерывание, вы политите отработаете его и вернетесь в свою функцию, а когда ее закончите выйдите из FIQ в точку остановки программы.

 

Одна сложность вам надо сделать так чтобы повторно вы опять в FIQ не полетели, за этим просто надо следить.

У меня алгоритм работы устройства довольно простой - после возникновения прерывания FIQ максимально быстро перейти к функции регистрации данных с АЦП (записать данные в массив), затем записанный массив данных перезаписать в FLASH память и выключить прибор. Но в процессе регистрации возможна ситуации срабатывания монитора напряжения питания (из-за разряда батареи). В этом случае мне необходимо остановить процесс регистрации и завершит программу с установленным флагом в FLASH 'сбой напряжения питания'. В данный момент функцию регистрации я вызываю из FIQ, поэтому если происходит сбой по напряжению питания я теряю зарегистрированные данные и флаг с информацией о сбое напряжения питания тоже не устанавливается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В данный момент функцию регистрации я вызываю из FIQ, поэтому если происходит сбой по напряжению питания я теряю зарегистрированные данные и флаг с информацией о сбое напряжения питания тоже не устанавливается.

Зачем всё на FIQ повесили??? Прикладные ISR - расположите на IRQ, а монитор питания - на FIQ. Тогда он прервёт любой обработчик IRQ.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Зачем всё на FIQ повесили??? Прикладные ISR - расположите на IRQ, а монитор питания - на FIQ. Тогда он прервёт любой обработчик IRQ.

Выбрал FIQ потому, что фоновая задача выполняется на низкой тактовой частоте ядра, а FIQ в ADUC702x обеспечивает аппаратное переключение на максимальную частоту тактирования ядра при возникновении прерывания FIQ. У прерывания IRQ такой возможности нет, а значит реакция на прерывание гораздо медленнее происходит.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Нужные биты в PLL устанавливаются аппаратно, после выхода из FIQ устанавливаются в исходное состояние. Ждать выхода PLL на режим не нужно. Может стоит попробовать ваше предложение на практике. Спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня алгоритм работы устройства довольно простой - после возникновения прерывания FIQ максимально быстро перейти к функции регистрации данных с АЦП (записать данные в массив), затем записанный массив данных перезаписать в FLASH память

 

Т.е. во флеш пишите из прерывания?? Знаете, сколь по длительности запись идет?? А прерывать запись флеши далеко не в каждом контроллере разрешается.

 

Ждать выхода PLL на режим не нужно.

Странно, почти везде требуется время...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Там может быть стоит переход с PLL клока на внутренний и обратно, оба из которых стабильно работают все время, то есть PLL настроился и держит его. Но вроде переход то же какое-то время занимает.

 

Запись во внутреннюю флэш это вещь такая... но с другой стороны для нее все равно надо прерывания запрещать в 90% так что можно и из прерывания это делать:) они будут автоматом запрещены... без запрета проц вроде не просто флэш запорит, а вообще повиснуть может, нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Выбрал FIQ потому, что фоновая задача выполняется на низкой тактовой частоте ядра, а FIQ в ADUC702x обеспечивает аппаратное переключение на максимальную частоту тактирования ядра при возникновении прерывания FIQ. У прерывания IRQ такой возможности нет, а значит реакция на прерывание гораздо медленнее происходит.

Что мешает в обработчике IRQ сделать то же самое программно?

И что именно там делается с частотой аппаратно?: включается и разгоняется PLL или меняется источник тактирования (PLL/внутренний RC) или просто меняется делитель тактовой перед CPU?

Если первое - то время стабилизации PLL довольно велико и много больше времени входа в любой ISR.

Если второе или третье - то программно переключить источник (при условии, что он уже работает и готов) или изменить делитель тактовой CPU дело одной-двух записей в регистры на входе в обработчик IRQ.

Если Вы не вынесете монитор питания в FIQ, а прочие прерывания - в IRQ, а всё повесите на FIQ, то новый FIQ монитора у Вас не вызовется никак до окончания обработки текущего ISR

(у Вас наверное и другие ISR в системе есть?). Ну если только не предпринять каких-то хитрых манипуляций с режимами работы CPU.

 

Да и вообще - говорить о скорости реакции на прерывание, учитывая какую Вам работу на сделать по его обслуживанию (работа с ADC, запись флешь) смешно.

Она будет несравнима мала по сравнению со временем доступа к флешь.

Флешь у Вас кстати какая? SPI или ...?

А учитываете, что если сработал монитор, а у вас уже идёт, не дай бог, операция стирания, сколько придётся ждать?

Может всё-таки Вам лучше для записи событий монитора поставить батарейное ОЗУ или FRAM?

 

Запись во внутреннюю флэш это вещь такая... но с другой стороны для нее все равно надо прерывания запрещать в 90% так что можно и из прерывания это делать:) они будут автоматом запрещены... без запрета проц вроде не просто флэш запорит, а вообще повиснуть может, нет?

Заменить на MSP430 из серии с FRAM-памятью ;)

Там что запись в ОЗУ, что во FRAM - никакой разницы. Не хватает ОЗУ - отрезал от памяти программ скока надо ;)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...