реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Программные прерывания разного приоритета
amaora
сообщение Jun 24 2016, 16:02
Сообщение #1


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Один из таймеров задает базовую частоту, в его обработчике прерывания запускается опрос датчиков и забираются результаты предыдущего опроса. Надо обрабатывать данные одновременно на разных частотах. Для примера конкретные числа, приходит 400 Гц, в первом же обработчике все преобразуется к 100 Гц, далее обработка на 100 Гц. Одновременно с этим 100 Гц преобразуются в 10 Гц и обрабатываются вторым способом, формируются поправки, которые идут на входы первой процедуры обработки.

То есть на временной диаграмме будет долгая работа 10 Гц процедуры, которую несколько раз прерывает 100 Гц процедура, и в 4 раза чаще прерывание для чтения измерений датчиков, которое перебивает всех но занимает мало времени.

Как это сделать на прерываниях? Из первого каждые 4 такта можно запускать второе прерывание с меньшим приоритетом. А из второго каждые 10 тактов третье с еще меньшим приоритетом. Но где взять программные прерывания? Занять неиспользуемые IRQ? Красивее вариантов нет?

Можно было бы обойтись одним прерыванием, если было бы можно разрешить одному IRQ вытеснять самого себя, менять приоритет исполняемого в данный момент прерывания. Но почитав внимательнее про регистр BASEPRI я понял, что так не получится.

МК - stm32f4xx.

Спасибо.
Go to the top of the page
 
+Quote Post
SII
сообщение Jun 26 2016, 16:35
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



А почему не сделать нормальные потоки и спокойно не обрабатывать в них данные, используя прерывания лишь для опроса датчиков?
Go to the top of the page
 
+Quote Post
amaora
сообщение Jun 26 2016, 17:43
Сообщение #3


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Этот вариант рассматривается.
Go to the top of the page
 
+Quote Post
gerber
сообщение Jun 26 2016, 21:48
Сообщение #4


Знающий
****

Группа: Участник
Сообщений: 750
Регистрация: 1-11-11
Пользователь №: 68 088



Выделите 2 свободные ноги (пустые), сконфигурируйте их как выход, и зарядите от них прерывания с разным (пониженным) приоритетом относительно 400 Гц. После чего в обработчике 400 Гц каждый 4-й раз дёргаете одну ногу, каждый 40-й раз - другую. Наслаждаетесь эффектом.


--------------------
"... часами я мог наблюдать, как люди работают." (М. Горький)
Go to the top of the page
 
+Quote Post
esaulenka
сообщение Jun 27 2016, 07:52
Сообщение #5


Профессионал
*****

Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877



Идея, в принципе, верная - использовать какие-нибудь "лишние" аппаратные прерывания (благо их в современных камнях с избытком).
Даже на ноги ничего выводить не надо (разве что для отладки будет полезно).

Но, по хорошему, требуемый функционал хорошо ложится на RTOS. Я тоже когда-то велосипеды строил - низкоприоритетные прерывания, длинные процедуры которые выполняются за несколько заходов (чтоб в паузах можно было что-то ещё сделать).
В очередной раз порекламирую scmRTOS - компактно, наглядно, хорошо документировано.
По функционалу до "больших" ОСей бесконечно далеко, но этого никто и не обещал.

PS вроде б можно крутить приоритет текущего прерывания. Надо б внимательно прочитать, в какой момент оно в контроллере прерываний сравнивается. Но зачем подкладывать себе же такие очевидные грабли?!


--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 27 2016, 14:37
Сообщение #6


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(amaora @ Jun 24 2016, 20:02) *
Красивее вариантов нет?

Это, наверное, самый простой, когда проект без ОС и не хочется самому писать на асме подмену контекстов выходов из IRQ. Но могут попасться недокументированные вектора на месте якобы свободных. Паранойю можно сгладить передачей сигналов подтверждений вызова между своими уровнями. Если при влёте в нижеприоритетное прерывание нет флага от более приоритетного, то сразу выходить из обработчика.

Но можно добавить паранойи. Если вдруг разрешить якобы свободный вектор и что-то недокументированное запросит прерывание, то произойдёт зависание в обработчике IRQ. Так что вариант использовать вектор периферии, которая в проекте не используется смотрится тоже неплохо. Обязательно ли нужно запитывать этот блок для корректной работы NVIC должно быть написано в документации. Если не написано, то скорее всего придётся запитывать и внутри обработчика сбрасывать все возможные запросы от этого блока периферии, несмотря на то, что блок не используется.

Цитата(esaulenka @ Jun 27 2016, 11:52) *
PS вроде б можно крутить приоритет текущего прерывания.

Поделитесь информацией, если что-то узнаете. Логика NVIC может быть заточена на отработку инструкции BX со служебными значениями (паттерн 0xffffffxx).

Сообщение отредактировал GetSmart - Jun 27 2016, 21:22


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
amaora
сообщение Jun 27 2016, 17:20
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 421
Регистрация: 2-01-08
Пользователь №: 33 778



Если переходит на rtos, то я надолго закопаюсь в переписывание всего кода под нее. Наловлю проблем с синхронизацией потоков. Это останавливает. Хотя код во многих прикладных местах может стать более простым, но для этого надо будет отладить сложный низкоуровневый код.

Цитата
PS вроде б можно крутить приоритет текущего прерывания. Надо б внимательно прочитать, в какой момент оно в контроллере прерываний сравнивается. Но зачем подкладывать себе же такие очевидные грабли?!


Да в документах arm об этом, что-то было. Только подразумевается смена приоритета для прерываний которые возникнут после этой смены. А не смена приоритета того, что выполняется в данный момент.

На стеке хранится значение регистра PSR в котором номер ISR, по которому похоже определяется приоритет прерывания после, например выхода из вложенного. А приоритеты хранятся в регистрах NVIC, может случится нехорошо если после выхода из вложенного прерывания окажется, что приоритет уже другой.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 27 2016, 21:04
Сообщение #8


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(amaora @ Jun 27 2016, 21:20) *
На стеке хранится значение регистра PSR в котором номер ISR, по которому похоже определяется приоритет прерывания после, например выхода из вложенного.

Предположений можно сделать несколько. Нужны документальные подтверждения.
Предположить можно, что эти младшие биты PSR просто информационные для программера. То есть процессором это значение создаётся, но потом им не читается и ни на что не влияет.


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 28 2016, 04:09
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(amaora @ Jun 27 2016, 23:20) *
Если переходит на rtos, то я надолго закопаюсь в переписывание всего кода под нее.
...
Да в документах arm об этом, что-то было. Только подразумевается смена приоритета для прерываний которые возникнут после этой смены. А не смена приоритета того, что выполняется в данный момент.

Берёте любой неиспользуемый в программе вектор аппаратного прерывания и используете его (возбуждаете это прерывание программно).
Никаких изменений приоритета на ходу делать конечно не надо. Если нужно чтобы управление попало в этот, программно возбуждаемый вектор, после завершения инициировавшего прерывания, то его приоритет делаете ниже чем у инициировавшего прерывания. Лучше даже ниже чем у любого настоящего аппаратного прерывания. Получается что-то типа задачи ОС, получающей управление по событию в инициирующем ISR.
Делал так не раз в разных проектах (и в давно работающих) на разных МК, там где и ОС при этом работает - всё прекрасно работает без проблем. Да и почему не должно работать?

Цитата(amaora @ Jun 27 2016, 23:20) *
На стеке хранится значение регистра PSR в котором номер ISR, по которому похоже определяется приоритет прерывания после, например выхода из вложенного. А приоритеты хранятся в регистрах NVIC, может случится нехорошо если после выхода из вложенного прерывания окажется, что приоритет уже другой.

На стеке сохраняется предыдущее значение PSR (и поле IPSR его в том числе) сохранённое при стэкинге. При выходе из прерывания оно будет просто восстановлено в PSR.
Текущее содержимое IPSR имхо просто маскирует содержмое регистра запросов NVIC (маскируются все прерывания с приоритетом ниже указанного в IPSR).

Цитата(GetSmart @ Jun 28 2016, 03:04) *
То есть процессором это значение создаётся, но потом им не читается и ни на что не влияет.

Не может быть. Если более приоритетный ISR (номер N) прервал выполнение менее приоритетного (номер K), то после возврата из ISR N, что CPU должен записать в IPSR? Откуда он это определит? Вот как раз со стека он это считывает и заносит в PSR.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 28 2016, 15:14
Сообщение #10


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(jcxz @ Jun 28 2016, 08:09) *
Не может быть. Если более приоритетный ISR (номер N) прервал выполнение менее приоритетного (номер K), то после возврата из ISR N, что CPU должен записать в IPSR? Откуда он это определит? Вот как раз со стека он это считывает и заносит в PSR.

Документальные подтверждения где?
На уровне предположений - может. Как говорится мухи отдельно, котлеты отдельно. Номера векторов могут "гулять" по стеку и IPSR. А приоритеты этих активированных векторов могут жить своей (невидимой программисту) жизнью внутри NVIC. При этом можно в стеке эти номера менять (сбивать), оттуда значение грузится в IPSR, а на котлеты (приоритеты принятых прерываний/исключений) это не повлияет.

Вопрос стоит в том, насколько подробно ARM этот вопрос задокументировал. Чтобы масоны эту логику в дальнейшем не смогли переиначить.

Сообщение отредактировал GetSmart - Jun 28 2016, 17:06


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 29 2016, 03:48
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(GetSmart @ Jun 28 2016, 21:14) *
Документальные подтверждения где?

Вам письмо за подписью директора ARM нужно?

Цитата(GetSmart @ Jun 28 2016, 21:14) *
При этом можно в стеке эти номера менять (сбивать), оттуда значение грузится в IPSR, а на котлеты (приоритеты принятых прерываний/исключений) это не повлияет.

И где тогда посмотреть текущий уровень приоритета прерывания по Вашему? В каком регистре?
Фантазировать можно как угодно, но как правило, разработчики ядер действуют соответствуясь с логикой и здравым смыслом и не городят ненужных сущностей когда без них можно обойтись.
Если такие регистры уже есть и они хранят нечто нужное, на кой придумывать некие "невидимые программисту" сущности?
О том же говорит и правило Бритвы Оккама.

Цитата(GetSmart @ Jun 28 2016, 21:14) *
Вопрос стоит в том, насколько подробно ARM этот вопрос задокументировал. Чтобы масоны эту логику в дальнейшем не смогли переиначить.

Открываете описание ядра с http://www.arm.com, читаете про регистр IPSR и про регистр Interrupt Control State Register (в числе регистров NVIC), в котором есть поле VECTACTIVE.
Пишете простейший код, в котором изнутри одного ISR вызываете другой, более приоритетный.
Трассируете:
вход в первый ISR - содержимое IPSR и VECTACTIVE - совпадают (например ==0x24);
вход во второй ISR (вложенный) - содержимое IPSR и VECTACTIVE - совпадают (например ==0x0B); в стеке содержимое IPSR из первого ISR (0x24), LR=0xFFFFFFF1;
меняете на стеке содержимое IPSR на какое-либо другое (например ==0x25);
выполняете BX LR и убеждаетесь, что теперь IPSR и VECTACTIVE становятся раными значению, записанному Вами в стек (0x25), а не тому значению, что было в первом ISR (0x24).
Обратите внимание - оба регистра IPSR и VECTACTIVE установились в значение, записанное Вами в стек (0x25), а не в значение из первого ISR (0x24), которое могло быть получено из неких "невидимых программисту" субстанций.
Go to the top of the page
 
+Quote Post
ar__systems
сообщение Jun 29 2016, 07:02
Сообщение #12


self made
****

Группа: Свой
Сообщений: 855
Регистрация: 7-03-09
Из: Toronto, Canada
Пользователь №: 45 795



У вас простейшая задача с минимальными скоростями, зачем городить огород с вложенными прерываниями? Делайте как все нормальные люди, одно прерывание 100гц, все медленное в бесконечном цикле вне прерываний.
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 29 2016, 11:59
Сообщение #13


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(jcxz @ Jun 29 2016, 07:48) *
Обратите внимание - оба регистра IPSR и VECTACTIVE установились в значение, записанное Вами в стек (0x25), а не в значение из первого ISR (0x24), которое могло быть получено из неких "невидимых программисту" субстанций.

Вы невнимательны. Описанные мной детали не противоречили этому. <Номера> векторов можно менять на стеке. И оттуда они будут браться при возвратах из обработчиков. Я именно это и имел ввиду. Но номера это не приоритеты. Приоритеты для (как минимум ожидаемых) прерываний задаются программистом в регистрах NVIC.IPR[]. Для исключений есть жёсткие приоритеты, есть тоже настраиваемые. Штука в том, что можно в IPSR загрузить, к примеру для CM0, значение 63 (у него 6-битный IPSR). Но для этого вектора у CM0 нет соответствующего регистра NVIC.IPR[] и вопрос: откуда будет браться приоритет? В то же время, приоритет активированного NVIC-ом вектора всегда существует и такой коллизии там нет.

Уточню свои же слова
Цитата
То есть процессором это значение создаётся, но потом им не читается и ни на что не влияет.

= aka "Номер вектора перекладывается с места на место", но приоритетом не управляет.

Ещё в описании ARMv6-M (где и описан NVIC) есть такая цитата
Цитата
If software changes the priority of an exception when it is active or enabled, the effect is UNPREDICTABLE in ARMv6-M.

из которой тоже не очень понятно, что за "огород" там организован.

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

Сообщение отредактировал GetSmart - Jun 30 2016, 01:11


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post
jcxz
сообщение Jun 30 2016, 08:50
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(GetSmart @ Jun 29 2016, 17:59) *
Вы невнимательны. Описанные мной детали не противоречили этому. <Номера> векторов можно менять на стеке. И оттуда они будут браться при возвратах из обработчиков. Я именно это и имел ввиду.

Это ещё неизвестно кто невнимателен.
На мою фразу:
Если более приоритетный ISR (номер N) прервал выполнение менее приоритетного (номер K), то после возврата из ISR N, что CPU должен записать в IPSR? Откуда он это определит? Вот как раз со стека он это считывает и заносит в PSR.
Вы потребовали документальное подтверждение, а теперь сами пишете что "номера векторов будут браться со стека".
И Вы же утверждали, что:
Цитата(GetSmart @ Jun 28 2016, 03:04) *
То есть процессором это значение создаётся, но потом им не читается и ни на что не влияет.

На что я Вам указал что оно влияет - заносится в регистры IPSR и в поле VECTACTIVE регистра "Interrupt Control State Register".

А как узнать приоритет текущего прерывания - я не знаю, возможно он программно недоступен и может быть определён только косвенно, считав регистр приоритета для соответствующего номера прерывания. Поэтому и не рекомендуют изменять приоритет для текущего активного или разрешённого прерывания.
Возможно в момент регистрации нового запроса прерывания, его приоритет считывается из регистров приоритета и заносится в поле VECTPENDING регистра "Interrupt Control State Register".
Go to the top of the page
 
+Quote Post
GetSmart
сообщение Jun 30 2016, 19:06
Сообщение #15


.
******

Группа: Участник
Сообщений: 4 005
Регистрация: 3-05-06
Из: Россия
Пользователь №: 16 753



Цитата(jcxz @ Jun 30 2016, 12:50) *
Это ещё неизвестно кто невнимателен.
На мою фразу:
Если более приоритетный ISR (номер N) прервал выполнение менее приоритетного (номер K), то после возврата из ISR N, что CPU должен записать в IPSR? Откуда он это определит? Вот как раз со стека он это считывает и заносит в PSR.

Вы ерунду написали и даже не поняли этого. По номеру в IPSR и сохранённой копии этого номера в стеке НИКАК не определить кто кого приоритетней. Если в документации чёрным по белому не написано, что <в любой момент времени> или <в моменты переходов между векторами> номер ассоциируется с приоритетом по какой-то таблице. Даже при этой логике про ограниченность таблицы я уже написал. Если же <в момент вызова> ассоциируется, то NVIC вызвать может только допустимый вектор, имеющий (табличный) приоритет. И эта версия уже ближе к тому, что я пытался донести.

Цитата(jcxz @ Jun 30 2016, 12:50) *
На что я Вам указал что оно влияет - заносится в регистры IPSR и в поле VECTACTIVE регистра "Interrupt Control State Register".

Я уже уточнил, что имел ввиду: "Номер вектора перекладывается с места на место", но приоритетом не управляет. Точнее может не управлять. Т.к. ясно это не описано. Вполне рабочее предположение. Можно ещё точнее выразить её: приоритет вектора КЭШИРУЕТСЯ в момент вызова и пока обработчик этого вектора не завершится, то подменами IPSR или регистров NVIC.IPR[] приоритет этого активного вектора не изменить. Для этого кэширования не нужен второй стек. Т.к. все прерывания и исключения испольняются строго с возрастающим приоритетом, то достаточно битовой карты приоритетов, на которой взводятся биты. Это версия. В документации я не вижу противоречий с ней. Но может я что-то ещё не прочитал.

Цитата(jcxz @ Jun 30 2016, 12:50) *
А как узнать приоритет текущего прерывания - я не знаю
...возможно...
Возможно ...

Вы так уверенно спорили, что казалось всё знаете.
Повторюсь. Предположить можно несколько вариантов. И это будут только предположения. А в норме ясность должна следовать из документации.
Можно поковыряться в реальном процессоре. Но нет гарантии, что во всех v6-M это будет одинаково. И в документации неполнота всё-равно будет (если есть).

Сообщение отредактировал GetSmart - Jul 1 2016, 04:14


--------------------
Заблуждаться - Ваше законное право :-)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 23:35
Рейтинг@Mail.ru


Страница сгенерированна за 0.01446 секунд с 7
ELECTRONIX ©2004-2016