vn821202 0 26 апреля, 2015 Опубликовано 26 апреля, 2015 · Жалоба Здравствуйте форумчане! Посоветуйте способ выхода из прерывания FIQ в микроконтроллере ADuC702x (ядро ARM7TDMI) на адрес нужной функции. Из прерывания FIQ вызывать эту функцию не хочу, так как она по времени выполнения занимает порядка 30 мс, к тому же в процессе ее выполнения может произойти прерывание от монитора напряжения питания в случае возникновения которого необходимо корректное остановка работы микроконтроллера. Если у кого-то есть такой опыт, прошу поделиться примером кода. Использую в проекте Keil. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 26 апреля, 2015 Опубликовано 26 апреля, 2015 · Жалоба Посоветуйте способ выхода из прерывания FIQ в микроконтроллере А что, разрешение прерывания в обработчике и мутекс для запрета повтороного входа в ту же функцию не помогает? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vn821202 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба А что, разрешение прерывания в обработчике и мутекс для запрета повтороного входа в ту же функцию не помогает? Я так понимаю, что в случае вызова нужной мне функции из FIQ, работа контроллера прерываний будет восстановлена только после выхода из FIQ. Мне необходимо максимальная реакция микроконтроллера на прерывание, поэтому установка флага в прерывании с последующей его проверкой в основном цикле программы не устраивает. Хотелось бы завершить прерывание переходом не в точку, предшествующую его возникновению, а на адрес нужной мне функции. Когда-то давно еще на архитектуре 8051 это было возможно путем манипуляции со стеком при помощи ассемблерных инструкций. Я думаю, что и на архитектуре ARM7TDMI это возможно.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба А как вы вернетесь то в точку где было прерывание, если вы из него улетите в вашу функцию... вам предется в функцию передавать точку возврата, делать там непонятный переход... а если опять будет прерывание? Когда вы попадает в FIQ прерывание, у вас снимается флажок реакции на прерывания, по выходу из FIQ он ставиться снова. Никто вам не мешает, при переходе в вашу функцию из FIQ опять поставить этот флажок. тогда если ваша функция отработает до конца, вы выйдите из FIQ в точку остановки программы. А если же у вас пока вы будите в функции возникнет прерывание, вы политите отработаете его и вернетесь в свою функцию, а когда ее закончите выйдите из FIQ в точку остановки программы. Одна сложность вам надо сделать так чтобы повторно вы опять в FIQ не полетели, за этим просто надо следить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба Одна сложность вам надо сделать так чтобы повторно вы опять в FIQ не полетели, за этим просто надо следить. Вот для этого и нужен мутекс, чтоб вновь не попасть в функцию, из которой еще не вышли в предидущий раз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба мне помниться что для FIQ был свой флаг, нет? То есть можно просто обычные прерывания разрешить, а FIQ не разрешать. или он все равно забьет обычные и пока он стоит, обычные не вызовутся? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба Мне необходимо максимальная реакция микроконтроллера на прерывание, поэтому установка флага в прерывании с последующей его проверкой в основном цикле программы не устраивает. Хотелось бы завершить прерывание переходом не в точку, предшествующую его возникновению, а на адрес нужной мне функции. Когда-то давно еще на архитектуре 8051 это было возможно путем манипуляции со стеком при помощи ассемблерных инструкций. Я думаю, что и на архитектуре ARM7TDMI это возможно.... Берёте любую RTOS. Например: uCOS. ЗавОдите высокоприоритетную задачу, которая ждёт события на каком-то мэйлбоксе. В ISR посылаете сообщение в этот мэйлбокс. Задача просыпается, делает работу и опять уходит на ожидание мэйлбокса. Всё. Стандартный подход построения задач-обработчиков событий. мне помниться что для FIQ был свой флаг, нет? То есть можно просто обычные прерывания разрешить, а FIQ не разрешать. или он все равно забьет обычные и пока он стоит, обычные не вызовутся? В ARM7 всего два внешних прерывания: FIQ и IRQ. У каждого свой флаг и свой бит разрешения. При срабатывании одного из них, процессор переключается в соотв. контекст (FIQ или IRQ) со своим стеком. При входе в FIQ, насколько помню, автоматом запрещается IRQ. Как правило - прерывание от любой периферии можно направить на любой из входов: FIQ или IRQ. Так что - прерывание любой периферии может быть как FIQ так и IRQ (по крайней мере в LPC23xx). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vn821202 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба А как вы вернетесь то в точку где было прерывание, если вы из него улетите в вашу функцию... вам предется в функцию передавать точку возврата, делать там непонятный переход... а если опять будет прерывание? Когда вы попадает в FIQ прерывание, у вас снимается флажок реакции на прерывания, по выходу из FIQ он ставиться снова. Никто вам не мешает, при переходе в вашу функцию из FIQ опять поставить этот флажок. тогда если ваша функция отработает до конца, вы выйдите из FIQ в точку остановки программы. А если же у вас пока вы будите в функции возникнет прерывание, вы политите отработаете его и вернетесь в свою функцию, а когда ее закончите выйдите из FIQ в точку остановки программы. Одна сложность вам надо сделать так чтобы повторно вы опять в FIQ не полетели, за этим просто надо следить. У меня алгоритм работы устройства довольно простой - после возникновения прерывания FIQ максимально быстро перейти к функции регистрации данных с АЦП (записать данные в массив), затем записанный массив данных перезаписать в FLASH память и выключить прибор. Но в процессе регистрации возможна ситуации срабатывания монитора напряжения питания (из-за разряда батареи). В этом случае мне необходимо остановить процесс регистрации и завершит программу с установленным флагом в FLASH 'сбой напряжения питания'. В данный момент функцию регистрации я вызываю из FIQ, поэтому если происходит сбой по напряжению питания я теряю зарегистрированные данные и флаг с информацией о сбое напряжения питания тоже не устанавливается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба В данный момент функцию регистрации я вызываю из FIQ, поэтому если происходит сбой по напряжению питания я теряю зарегистрированные данные и флаг с информацией о сбое напряжения питания тоже не устанавливается. Зачем всё на FIQ повесили??? Прикладные ISR - расположите на IRQ, а монитор питания - на FIQ. Тогда он прервёт любой обработчик IRQ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vn821202 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба Зачем всё на FIQ повесили??? Прикладные ISR - расположите на IRQ, а монитор питания - на FIQ. Тогда он прервёт любой обработчик IRQ. Выбрал FIQ потому, что фоновая задача выполняется на низкой тактовой частоте ядра, а FIQ в ADUC702x обеспечивает аппаратное переключение на максимальную частоту тактирования ядра при возникновении прерывания FIQ. У прерывания IRQ такой возможности нет, а значит реакция на прерывание гораздо медленнее происходит. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба А если в фик поставить флаг новые данные, а данные пихнуть в буффер, а всю обработку дальше в основном цикле? Или опять беда с малой тактовой вне?. Кстати переход с частоты на частоту разьве не требует ожидания плл? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vn821202 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба А если в фик поставить флаг новые данные, а данные пихнуть в буффер, а всю обработку дальше в основном цикле? Или опять беда с малой тактовой вне?. Кстати переход с частоты на частоту разьве не требует ожидания плл? Нужные биты в PLL устанавливаются аппаратно, после выхода из FIQ устанавливаются в исходное состояние. Ждать выхода PLL на режим не нужно. Может стоит попробовать ваше предложение на практике. Спасибо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
mantech 53 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба У меня алгоритм работы устройства довольно простой - после возникновения прерывания FIQ максимально быстро перейти к функции регистрации данных с АЦП (записать данные в массив), затем записанный массив данных перезаписать в FLASH память Т.е. во флеш пишите из прерывания?? Знаете, сколь по длительности запись идет?? А прерывать запись флеши далеко не в каждом контроллере разрешается. Ждать выхода PLL на режим не нужно. Странно, почти везде требуется время... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба Там может быть стоит переход с PLL клока на внутренний и обратно, оба из которых стабильно работают все время, то есть PLL настроился и держит его. Но вроде переход то же какое-то время занимает. Запись во внутреннюю флэш это вещь такая... но с другой стороны для нее все равно надо прерывания запрещать в 90% так что можно и из прерывания это делать:) они будут автоматом запрещены... без запрета проц вроде не просто флэш запорит, а вообще повиснуть может, нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 242 27 апреля, 2015 Опубликовано 27 апреля, 2015 · Жалоба Выбрал 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 - никакой разницы. Не хватает ОЗУ - отрезал от памяти программ скока надо ;) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться