Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум разработчиков электроники ELECTRONIX.ru _ ARM _ Cortex-Mx

Автор: dimka76 Sep 14 2018, 17:03

Здравствуйте.

Возник такой вопрос.

Можно ли из обработчиков исключительных ситуаций вызывать функции ?
Не возникнет ли проблем со стеком ?

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

Автор: Forger Sep 14 2018, 17:19

Цитата(dimka76 @ Sep 14 2018, 20:03) *
Можно ли из обработчиков исключительных ситуаций вызывать функции ?
Не возникнет ли проблем со стеком ?

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

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

Да, не могут, поскольку приоритет обработчиков исключительных ситуаций имеют наивысший приоритет. Ведь в этом весь смысл таких прерываний ))

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

Автор: dimka76 Sep 14 2018, 17:37

Цитата(Forger @ Sep 14 2018, 20:19) *
но есть НО:
Если такое исключение возникло именно из-за проблем со стеком, то логично предположить, что сразу пользоваться стеком не стоит (точнее, таким указателем стека).


Вот этот вариант и навел на вопрос. Спасибо, что подтвердили мои опасения.
У меня план такой. При попадании в исключительную ситуацию перевести некоторые ноги МК в определенное состояние.
И после этого зависнуть в этом прерывании навсегда.
А вот для управления нужными ногами у меня есть свои функции. Можно конечно прямо в прерывании
через регистры переключить ноги. Но мне кажется, что с точки зрения архитектуры программы это не правильно.

Думаю перед вызовом функции заново проинициализировать указатель стека значением из нулевого адреса.

Цитата(Forger @ Sep 14 2018, 20:19) *
Также нужно учесть, что для прерываний обычно используют другой стек (точнее, указатель стека), особенно если применяется RTOS.


RTOS не используется и режим работы не меняется. Поэтому указатель один, если я не ошибаюсь конечно )))

Автор: Forger Sep 14 2018, 17:50

Цитата(dimka76 @ Sep 14 2018, 20:37) *
Вот этот вариант и навел на вопрос. Спасибо, что подтвердили мои опасения.
У меня план такой. При попадании в исключительную ситуацию перевести некоторые ноги МК в определенное состояние.
И после этого зависнуть в этом прерывании навсегда.

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

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

С "точки зрения архитектуры" в обработчике прерывания нужно сделать все, чтобы сделать девайс безопасным. Как можно быстрее!
Как именно это будет сделано - вопрос второстепенный.
Самое простое - тупо вызвать принудительный сброс всего проца.

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

Автор: scifi Sep 14 2018, 18:09

Цитата(dimka76 @ Sep 14 2018, 20:37) *
У меня план такой. При попадании в исключительную ситуацию перевести некоторые ноги МК в определенное состояние.
И после этого зависнуть в этом прерывании навсегда.
А вот для управления нужными ногами у меня есть свои функции. Можно конечно прямо в прерывании
через регистры переключить ноги. Но мне кажется, что с точки зрения архитектуры программы это не правильно.

Думаю перед вызовом функции заново проинициализировать указатель стека значением из нулевого адреса.

Предлагаю другой план. Устанавливаем некий флаг "перевести ноги и зависнуть", вызываем программный сброс. Программа при старте проверяет условие "сброс == программный && флаг == установлен". Ну и при выполнении условия делает что надо. Так проще.

Автор: Forger Sep 14 2018, 18:24

Цитата(scifi @ Sep 14 2018, 21:09) *
Предлагаю другой план. Устанавливаем некий флаг "перевести ноги и зависнуть", вызываем программный сброс.

Увы, на некоторых процах программный сброс != аппаратному сбросу.


Автор: scifi Sep 14 2018, 18:29

Цитата(Forger @ Sep 14 2018, 21:24) *
Увы, на некоторых процах программный сброс != аппаратному сбросу.

Это уж пусть ТС разбирается. Во всяком случае, на STM32 команда программного сброса физически дёргает ногу RST. И даже не сбросится, если ногу подтянуть так, что дёргание не осилит.

Автор: Forger Sep 14 2018, 18:33

Цитата(scifi @ Sep 14 2018, 21:29) *
Это уж пусть ТС разбирается.

Да вся эта тема - по сути баян, но раз уж подняли муть со дна, то не грех и чуток погундеть, благо пятница rolleyes.gif

Цитата
Во всяком случае, на STM32 команда программного сброса физически дёргает ногу RST.

Не совсем - содержимое ОЗУ все же сохраняется. Но это даже к лучшему ))



Автор: aaarrr Sep 14 2018, 18:53

Цитата(Forger @ Sep 14 2018, 21:33) *
Не совсем - содержимое ОЗУ все же сохраняется. Но это даже к лучшему ))

А что, POR сбрасывает ОЗУ?

Автор: Forger Sep 14 2018, 18:55

Цитата(aaarrr @ Sep 14 2018, 21:53) *
А что, POR сбрасывает ОЗУ?

У STM32 - не сбрасывает, просто в этом случае там будет "каша".

Автор: aaarrr Sep 14 2018, 18:58

Цитата(Forger @ Sep 14 2018, 21:55) *
У STM32 - не сбрасывает, просто в этом случае там "каша".

Честно говоря, не знаю семейств, где бы сброс обнулял содержимое ОЗУ. Хотя вполне допускаю, что и такое встречается.

Автор: scifi Sep 14 2018, 19:00

Цитата(Forger @ Sep 14 2018, 21:33) *
Не совсем - содержимое ОЗУ все же сохраняется. Но это даже к лучшему ))

Ага, лишь бы возразить. У ОЗУ не бывает сигнала сброса. Ну или это какое-то чудесатое ОЗУ.

Автор: Forger Sep 14 2018, 19:02

Цитата(aaarrr @ Sep 14 2018, 21:58) *
Честно говоря, не знаю семейств, где бы сброс обнулял содержимое ОЗУ. Хотя вполне допускаю, что и такое встречается.

Честно говоря тоже, но в свете http://electronix.ru/redirect.php?https://lenta.ru/news/2018/09/14/zashity/ обнуление ОЗУ при сбросе становится уже необходимостью laughing.gif


Цитата(scifi @ Sep 14 2018, 22:00) *
У ОЗУ не бывает сигнала сброса.

ОЗУ бывают разные, в том числе внешние

Автор: scifi Sep 14 2018, 19:04

Цитата(Forger @ Sep 14 2018, 22:02) *
Честно говоря тоже, но в свете http://electronix.ru/redirect.php?https://lenta.ru/news/2018/09/14/zashity/ обнуление ОЗУ при сбросе становится уже необходимостью laughing.gif

Сенсация. Обнаружен способ стащить деньги из кошелька. Для этого нужен физический доступ к кошельку.

Автор: Forger Sep 14 2018, 19:05

Цитата(scifi @ Sep 14 2018, 22:04) *
Сенсация. Обнаружен способ стащить деньги из кошелька. Для этого нужен физический доступ к кошельку.

Цитата(scifi)
Ага, лишь бы возразить.


rolleyes.gif

Автор: scifi Sep 14 2018, 19:05

Цитата(Forger @ Sep 14 2018, 22:02) *
ОЗУ бывают разные, в том числе внешние

Будьте любезны, дайте ссылочку на внешнее ОЗУ с сигналом сброса.

Автор: Forger Sep 14 2018, 19:20

Цитата(scifi @ Sep 14 2018, 22:05) *
Будьте любезны, дайте ссылочку на внешнее ОЗУ с сигналом сброса.

http://electronix.ru/redirect.php?https://www.maximintegrated.com/en/products/digital/memory-products/DS1200.html

Автор: dimka76 Sep 14 2018, 19:45

Цитата(scifi @ Sep 14 2018, 21:09) *
Предлагаю другой план. Устанавливаем некий флаг "перевести ноги и зависнуть", вызываем программный сброс. Программа при старте проверяет условие "сброс == программный && флаг == установлен". Ну и при выполнении условия делает что надо. Так проще.


По-моему проще в обработчике исключения
Код
__set_MSP(TOP_RAM_ADDR);


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

Автор: aaarrr Sep 14 2018, 19:52

Цитата(Forger @ Sep 14 2018, 22:20) *
http://electronix.ru/redirect.php?https://www.maximintegrated.com/en/products/digital/memory-products/DS1200.html

Сказали бы тогда, что любая DDR3+ подходит под определение "внешнее ОЗУ с сигналом сброса", чем людей экзотикой пугать.

Автор: dimka76 Sep 14 2018, 19:52

Цитата(Forger @ Sep 14 2018, 21:33) *
Да вся эта тема - по сути баян,


Тема не как реализовывать обработчик исключений, а насколько безопасно просто так из него вызывать функции ))))

Автор: Forger Sep 14 2018, 20:29

Цитата(aaarrr @ Sep 14 2018, 22:52) *
чем людей экзотикой пугать.

Ну, какой был вопрос, такой же и вышел ответ wink.gif

Экзотика - это нужда в бытовых МК в обнулении содержимого ОЗУ после сброса.

Вот есть мысля: при исключении писать в определенную область ОЗУ отладочную информацию, делать программный сброс (в STM32 типа NVIC Reset), а в коде при старте каждый раз проверять содержимое этой области.
Отличить полезную инфу от мусора в ОЗУ можно с помощью примитивных "маркеров" или элементарной контрольной суммы. Разумеется, эти данные нужно объявлять с соотв. квалификаторами или в соотв. не стираемой при старте секции.
Если есть "чё", то писать это уже в реальный энергонезависимый журнал (на флэшку, sd-карточкуи т.п.) и жить дальше до очередного HF ))

Автор: aaarrr Sep 14 2018, 20:37

Цитата(Forger @ Sep 14 2018, 23:29) *
Вот есть мысля: при исключении писать в определенную область ОЗУ отладочную информацию, делать программный сброс (в STM32 типа NVIC Reset), а в коде при старте каждый раз проверять содержимое этой области.

Много лет использую именно такой механизм. Хорошее, годное решение.

Автор: AlexandrY Sep 15 2018, 04:24

Цитата(dimka76 @ Sep 14 2018, 22:52) *
Тема не как реализовывать обработчик исключений, а насколько безопасно просто так из него вызывать функции ))))

Периферия после сбоя может быть в отключенном из адресного пространства состоянии.
Обычными "функциями" я бы пользоваться не рисковал.
Некоторые прерывания, например от WDOG, в принципе вам дают всего сотню тактов до сброса.
Поэтому только прямое обращение к регистрам.
Кстати, сбой и последующий reset может привести и к переходу на код в Bootloader-е, тогда и на RAM надеяться нельзя.
Практичней думать о таких ситуациях учитывая бутлодер. А он может быть и в ROM-е и даже не документирован.

Автор: jcxz Sep 15 2018, 05:18

Цитата(dimka76 @ Sep 14 2018, 20:37) *
У меня план такой. При попадании в исключительную ситуацию перевести некоторые ноги МК в определенное состояние.
И после этого зависнуть в этом прерывании навсегда.
А вот для управления нужными ногами у меня есть свои функции.

Выполняете CPSID I, CPSID F и после этого спокойно вызываете свои функции и зависаете. Только эти "свои функции" должны быть реентерабельны.

Цитата(aaarrr @ Sep 14 2018, 21:58) *
Честно говоря, не знаю семейств, где бы сброс обнулял содержимое ОЗУ. Хотя вполне допускаю, что и такое встречается.

Не обнуляется, но затирается часть - у многих.

Цитата(dimka76 @ Sep 14 2018, 22:52) *
Тема не как реализовывать обработчик исключений, а насколько безопасно просто так из него вызывать функции ))))

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

Цитата(dimka76 @ Sep 14 2018, 22:45) *
По-моему проще в обработчике исключения
Код
__set_MSP(TOP_RAM_ADDR);

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

Цитата(AlexandrY @ Sep 15 2018, 07:24) *
Периферия после сбоя может быть в отключенном из адресного пространства состоянии.

Это на каком-же из МК (соответствующих заголовку темы) такое делается? wacko.gif

Цитата(Forger @ Sep 14 2018, 23:29) *
Вот есть мысля: при исключении писать в определенную область ОЗУ отладочную информацию, делать программный сброс (в STM32 типа NVIC Reset), а в коде при старте каждый раз проверять содержимое этой области.
Отличить полезную инфу от мусора в ОЗУ можно с помощью примитивных "маркеров" или элементарной контрольной суммы. Разумеется, эти данные нужно объявлять с соотв. квалификаторами или в соотв. не стираемой при старте секции.

Лучше использовать соответствующий периферийный регистр, где флажками указан тип сброса (POR, внешняя нога, WDT, программный, ...) и не возиться с флагами в ОЗУ, которые нужно ещё и правильно расположить.

Автор: DASM Sep 15 2018, 06:29

жирные вы тут.. скомпилировал с -fexception, получил 86К кода хелло ворд на О3, приуныл и забил

Автор: Forger Sep 15 2018, 06:42

Цитата(jcxz @ Sep 15 2018, 08:18) *
Лучше использовать соответствующий периферийный регистр, где флажками указан тип сброса (POR, внешняя нога, WDT, программный, ...) и не возиться с флагами в ОЗУ, которые нужно ещё и правильно расположить.

Аппаратные флажки-то - это само собой.
Но имелось ввиду проверять валидность (актуальность) самих данных, дабы не спутать их с мусором в ОЗУ и не записать это мусор в журнал.

Автор: dimka76 Sep 16 2018, 16:38

Цитата(jcxz @ Sep 15 2018, 08:18) *
Сам вызов безопасен. А почему он должен быть не безопасен?

Например, как писали выше, вот поэтому

Цитата(Forger @ Sep 14 2018, 20:19) *
Если такое исключение возникло именно из-за проблем со стеком, то логично предположить, что сразу пользоваться стеком не стоит (точнее, таким указателем стека).


Цитата(jcxz @ Sep 15 2018, 08:18) *
Выполняете CPSID I, CPSID F и после этого спокойно вызываете свои функции и зависаете

Я так понимаю это команды запрещения прерываний и исключительных ситуаций.
А зачем они в обработчике исключений ?
Их же и так никто прервать не может.

Цитата(jcxz @ Sep 15 2018, 08:18) *
Только функция обязательно должна быть реентерабельной.

Мои функции дергания норкой таковыми и являются. Просто запись в регистр порта ввода вывода.

Цитата(jcxz @ Sep 15 2018, 08:18) *
Если уж и переустанавливать указатель стека, то на вершину существующего выделенного статически стека.

Я в своем сообщении это и имел ввиду, просто наверное некорректно изъяснился.

Автор: jcxz Sep 17 2018, 06:25

Цитата(dimka76 @ Sep 16 2018, 19:38) *
Например, как писали выше, вот поэтому

В Cortex-M при вызове функции стек не используется. Внутри функции он конечно может быть использован, но только если она вызывает другие функции или имеет много локальных переменных. Но Вы пишете, что внутри только - дёргание ногой. Тогда - о каком стеке вообще речь?

Цитата(dimka76 @ Sep 16 2018, 19:38) *
Я так понимаю это команды запрещения прерываний и исключительных ситуаций.
А зачем они в обработчике исключений ?
Их же и так никто прервать не может.

Это - запрет и разрешение прерываний. Не могут прервать только исключения с приоритетом ниже.

Цитата(dimka76 @ Sep 16 2018, 19:38) *
Мои функции дергания норкой таковыми и являются. Просто запись в регистр порта ввода вывода.

А если это исключение произошло до того как сконфигурили ногу (которой хотите дёрнуть) на вывод? Просто повиснете навсегда?

Автор: dimka76 Sep 18 2018, 19:13

Цитата(jcxz @ Sep 17 2018, 09:25) *
А если это исключение произошло до того как сконфигурили ногу (которой хотите дёрнуть) на вывод? Просто повиснете навсегда?


Это ножка включает/выключает внешнее устройство. Если ножка не сконфигурирована, то устройство выключено. А в обработчике исключения я хочу это внешнее устройство выключать. Значит все нормально будет )))

В принципе, я получил ответ на свои вопросы.
Все откликнувшимся спасибо !!!

Автор: DASM Sep 20 2018, 15:09

Цитата(jcxz @ Sep 17 2018, 09:25) *
В Cortex-M при вызове функции стек не используется.

а как он вызовет он передаст ,к примеру 35 аргументов в нее?

Автор: jcxz Sep 20 2018, 18:38

Цитата(DASM @ Sep 20 2018, 18:09) *
а как он вызовет он передаст ,к примеру 35 аргументов в нее?

Хотя бы прочитайте на что отвечаете:
Цитата(jcxz @ Sep 17 2018, 09:25) *
Внутри функции он конечно может быть использован, но только если она вызывает другие функции или имеет много локальных переменных. Но Вы пишете, что внутри только - дёргание ногой. Тогда - о каком стеке вообще речь?

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)