jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Назрела необходимость (уже давно), разрешить прерывания более низкого приоритета в обработчике высокого приоритета. Способ в лоб - подкорректировав стек и сделать фиктивный возврат из прерывания. С помощью MRS/MSR как я понял этого не сделать - в документации написано что запись в IPSR игнорируется. Есть ли какое-то более человеческое решение чем через формирование стека возврата и возврат из прерывания? Собственно, зачем это нужно - в случае аварии вызывается определенный irq. В обработчике нужно сделать некую аварийную последовательность действий, но для этого нужны рабочие обработчики другиз, в т.ч. низкоприоритетных прерываний. Можно конечно приоритеты нужных irq повысить. Но есть вторая задача - сделать софтовый ресет (разумеется с обнулением стека), в нужную функцию и с разблокированными прерываниями. Например, в bootolader для перепрошивки. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Назрела необходимость (уже давно), разрешить прерывания более низкого приоритета в обработчике высокого приоритета. Это противоречит самому принципу приоритетов прерываний. Странная необходимость ... Способ в лоб - подкорректировав стек и сделать фиктивный возврат из прерывания. С помощью MRS/MSR как я понял этого не сделать - в документации написано что запись в IPSR игнорируется. В режиме handler (обработка прерываний) автоматом включается привилегированный режим, т.е. при остром желании можно влезть в любой стек и нагадить там как положено )) Обычно это используют лишь в портах RTOS. Есть ли какое-то более человеческое решение чем через формирование стека возврата и возврат из прерывания? Можно форсить более высокоприоритетное прерывание прямо из текущего обработчика. В зависимости от его приоритета оно будет вызвано сразу или лишь после выхода из текущего обработчика. Для этой цели хорошо подойдет NMI, у него самый высокий приоритет (после Reset). Можно даже извратиться - вызывать hardfault, например, обращаясь к несуществующей памяти :smile3046: Собственно, зачем это нужно - в случае аварии вызывается определенный irq. А в чем проблема вызывать некую функцию? К чему городить огород с отдельным прерыванием? Например, в bootolader для перепрошивки. А вот эта задача реализуется уже несколько иначе. Тут неоднократно поднималась эта тема. Пройдитесь поиском )) зы. Подобную задачу я реализую просто: вызываю в случае аварии System Reset (нужно смотреть на его реализацию в каждом семействе МК). Однако, не во всех задачах полный сброс допустим. Аппаратно само устройство делаю так, что в сброшенном состоянии все силовые цепи отключаются, автоматом снимаются все сигналы готовности (если используются внешние силовые модули). Это реализована подтяжками соотв. портов МК внешними резисторами. Остальные обработчики типа HardFault у меня тоже в итоге вызывают System Reset (после анализа и фиксации в журнале событий причины сбоя). Т.е. любое зависание, срабатывание вотчдога и т. д. всегда сбрасывают проц, что автоматом вырубает все силовые цепи. Это удобно при отладке и прошивке - пока шьется проц, вырубается всякая опасная "сила", скажем силовые ключи привода мощного мотора, гасится мощной источник для "силы". В таком решении гарантировано, что ничего никуда не поедет и не сожжет никакие "пробки" ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Собственно в мягком ресете есть необходимость именно из-за сброса gpio - например, обрывается питание и bluetooth подвисает перед прошивкой. Плюс, все переменные переинициализируются и нельзя точку входа выбрать, неудобно. То что колхоз это понятно, но без него не вижу простых решений. Хотя не сильный колхоз. Единственное неудобство - повторный вход в оборванные обработчики прерываний, но это не сильно пугает. Сброс состояний - дело несложное. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Единственное неудобство - повторный вход в оборванные обработчики прерываний, но это не сильно пугает. Сброс состояний - дело несложное. Все-таки не пойму, чем не годится обычная функция, которая делает всю эту инициализацию? например, обрывается питание и bluetooth подвисает перед прошивкойЯ бы в таком случае поставил ключ на питание блютуса - какой нить подходящий p-mosfet. Управление им от соотв. gpio. Так и питание батарейки проще экономить (если девайс батарейный). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба п.с. irq вызывается, поскольку авария может прилететь извне в любой момент и независимо от режима работы нужно немедленно выполнить аварийные процедуры. Проще всего это сделать с чистого листа - заново принудительно с нуля переинициализировать нужную периферию (чтоб наверняка) в нужный режим, отключить все лишнее и сделать несколько действий. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба п.с. irq вызывается, поскольку авария может прилететь извне в любой момент и независимо от режима работы нужно немедленно выполнить аварийные процедуры. Проще всего это сделать с чистого листа - заново принудительно с нуля переинициализировать нужную периферию (чтоб наверняка) в нужный режим, отключить все лишнее и сделать несколько действий. Так все-таки, чем не годится вызов некой функции, где все это делается? Она же вызывается при запуске проца однократно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Я бы в таком случае поставил ключ на питание блютуса - какой нить подходящий p-mosfet. как вариант, только с RC цепочкой. Чтоб вырубался, но не сразу. Но честно не думал что проблемы такого характера могут возникнуть, думаю все-таки правильнее программно решить. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба как вариант, только с RC цепочкой. Чтоб вырубался, но не сразу. Но честно не думал что проблемы такого характера могут возникнуть, думаю все-таки правильнее программно решить. Правильно - как можно надежнее )) Блютус тоже может зависнуть программно и перестать отвечать по каналу обмена, тут единственный вариант - передернуть его питание, но только его питание. В идеале хорошо бы еще мониторить потребляемый ток, чтобы вовремя вырубать мертвые узлы, но такое нужно очень редко .... В одном моем проекте стояла ESP-ка, которая любила иногда подвисать по usart-у. Зная это, я сразу поставил для нее отдельный стабилизатор 3.3В со входом EN. Это позволило включать ESP-ку только тогда, когда это было нужно, чисто программно. Зависла - передергиваем питание стабилизаатора и начинаем все по-новой. Фактически производился сброс только модуля, отвечающего за обмен под wifi, а все остальные модули (программные модули) работали в штатном режиме. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Так все-таки, чем не годится вызов некой функции, где все это делается? Она же вызывается при запуске проца однократно. Ей нужно по хорошему передать несколько параметров. Плюс как определить что на ребут для определенной цели ушел? В память записать определенную сигнатуру? Но это то же колхоз. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Ей нужно по хорошему передать несколько параметров.Зачем? Сделайте разные функции для разных задач. Дайте им соотв. имена. Плюс как определить что на ребут для определенной цели ушел? Я использую модульную структура проекта, каждый модуль нужно инициализировать индивидуально при старте. Но ничто не мешает принудительно его переинициализировать (скажем, вызвав соотв. SWI). Каждый модуль у меня "владеет" своими пинами и своими аппаратными узлами (таймеры, цапы и т.п.). Никто не обращается к одному и тому же аппаратному узлу из разных модулей. Т. е. у всех аппаратных сущностей есть владелец в единственном числе. Так я точно могу управлять всей системой. Т. е. на этапе проектировки закладывается строгая и очень жесткая иерархия. Она неизменна в процессе работы всей железки. Каждый модуль обязан самостоятельно инициализировать "свое" железо (в т.п. числе и пины!). Общая пока что только инициализация системного таймера и тактовой частоты, но и она скоро "уйдет" в свой модуль (SystemController). В память записать определенную сигнатуру? Но это то же колхоз. Я совсем запутался ... Какую еще сигнатуру? Что же на самом деле вы хотите реализовать? Распишите конкретный пример, а то, может оказаться, что мы толкуем о разных вещах ))) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Сейчас я в одном из девайсов делаю примерно так. Т.е. делаю софт-ресет из основного цикла (где контроллер irq не замаскирован), а в AHBENR ставлю флаг, который в загрузчике анализируется и после железного ресета гарантированно сброшен. RCC->AHBENR=1;// marker for software reset SysTick->CTRL=0; uint32_t* ptr=(uint32_t*)(0x08000000); SCB->VTOR=(uint32_t)ptr; __set_MSP(*(ptr++)); __set_BASEPRI(0); __set_CONTROL(0); NVIC->ICER[0]=0xFFFFFFFF; NVIC->ICER[1]=0xFFFFFFFF; NVIC->ICER[2]=0xFFFFFFFF; NVIC->ICER[3]=0xFFFFFFFF; NVIC->ICER[4]=0xFFFFFFFF; NVIC->ICER[5]=0xFFFFFFFF; NVIC->ICER[6]=0xFFFFFFFF; NVIC->ICER[7]=0xFFFFFFFF; NVIC->ICPR[0]=0xFFFFFFFF; NVIC->ICPR[1]=0xFFFFFFFF; NVIC->ICPR[2]=0xFFFFFFFF; NVIC->ICPR[3]=0xFFFFFFFF; NVIC->ICPR[4]=0xFFFFFFFF; NVIC->ICPR[5]=0xFFFFFFFF; NVIC->ICPR[6]=0xFFFFFFFF; NVIC->ICPR[7]=0xFFFFFFFF; void (*start)()=(void(*)())(*ptr); start(); Вполне доволен таким софтовым ресетом без сброса железа. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Вполне доволен таким софтовым ресетом без сброса железа. А приведите пример, когда действительно нужен такой "софтовый ресет"? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Я совсем запутался ... Какую еще сигнатуру? Что же на самом деле вы хотите реализовать? Распишите конкретный пример, а то, может оказаться, что мы толкуем о разных вещах ))) Мы видимо по разному думаем. Я про то, как передать загрузчику после железного ресета параметры. Это некий квест и тоже с колхозом. Работает примерно так: работает девайс в обычном режиме. Приходит кодограмма на перепрошивку, с дополнительными данными. Независимо от режима он должен ребутнуться, продолжить обмен по этому протоколу (без обрыва и без переинициализации протокола обмена) и прошиться. При этом в этой кодограмме содержатся данные, которые надо передать загрузчику. То есть загрузчик должен получить содержимое кодограммы и все состояния протокола обмена. После перепрошивки также без переинициализации протокола обмена запустить основную программу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Forger 17 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба После перепрошивки также без переинициализации протокола обмена запустить основную программу. Имхо, очень сомнительная и где-то даже опасная необходимость ... Обычно, всякая смена прошивки софта предполагает сброс всего проца. Мне никогда не попадалось обратное. Но, может быть, вы имеете ввиду некие настройки конкретного экземпляра девайса? У меня такие настройки храняться в внешней EEPROM/FRAM или во внутреннем EEPROM (или FLASH, если нету EEPROM). При перезапуске приложения все настройки загружаются в ОЗУ и оттуда все работает до очередного сброса. Также предусмотрены настройки по дефолту, позволяет вернуть девайс соотв. командами к заводским настройкам. За все это отвечает отдельный модуль Settings, он хранит все изменяемые параметры системы, которые могут быть разные для разных девайсов (в т. ч. серийны номер). Мы видимо по разному думаем.Это вообще-то справедливо для всех, иначе вообще не были бы нужны форумы :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jeka 0 12 июля, 2017 Опубликовано 12 июля, 2017 · Жалоба Специфика такая. Не хочется протокол обмена обрывать, т.к. это вызывает проблемы на главном устройстве, а их решить сложнее чем протокол поддерживать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться