Добрый день.
Есть платка stm32f4discovery с процессором ARMv7-M. В процессоре есть nested vectored interrupt controller (NVIC) . Никак не могу разобраться, как правильно обрабатывать прерывания на ассемблере(thumbv2). Как я понимаю NVIC аппаратно сохраняет часть регистров на стек MSP. Допустим мне надо дополнительно сохранить еще несколько регистров через команду stm. опять же насколько я понял команда stm может быть прервана обработчиком прерывания (допустим прерыванием более высокого приоритета) и продолжена по завершению обработки прерывания. Тогда непонятно как гарантированно сохранить регистры при входе в прерывание?? Так же непонятно нужно ли использовать инструкции DMB DSB ISB при входе или возврате из прерывания??
помогите разобрать nested vectored interrupt controller arm7
- Реклама
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Re: помогите разобрать nested vectored interrupt controller
Просто сохраняете регистры на входе в каждый обработчик и восстанавливаете перед выходом, никаких проблем прерываемость STM/LDM не создаёт.
Барьеры при прерываниях не нужны.
Барьеры при прерываниях не нужны.
Re: помогите разобрать nested vectored interrupt controller
Спасибо.
Только я все-таки решил пользоваться командами типа push/pop для сохранения восстановления регистров на стек. Еще возникло несколько вопросов. Должен ли я пользоваться для возврата из прерывания командой pop, чтобы восстановить все регистры, которые положил на стек NVIC, или он аппаратно считывает регистры при выходе из прерывания и мне достаточно выполнить команду bx lr?? И еще предположим после reset я занес в оба указателя стека ( psp msp ) нужные адреса и переключился на psp. Правильно ли я понимаю что при входе в первое прерывание NVIC сохранит регистры на psp, а при входе во все вложенные прерывания будет сохранять регистры на стек msp??
Только я все-таки решил пользоваться командами типа push/pop для сохранения восстановления регистров на стек. Еще возникло несколько вопросов. Должен ли я пользоваться для возврата из прерывания командой pop, чтобы восстановить все регистры, которые положил на стек NVIC, или он аппаратно считывает регистры при выходе из прерывания и мне достаточно выполнить команду bx lr?? И еще предположим после reset я занес в оба указателя стека ( psp msp ) нужные адреса и переключился на psp. Правильно ли я понимаю что при входе в первое прерывание NVIC сохранит регистры на psp, а при входе во все вложенные прерывания будет сохранять регистры на стек msp??
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Re: помогите разобрать nested vectored interrupt controller
1) PUSH/POP -- те же самые STM/LDM, разницы никакой нет.
2) NVIC ничего не кладёт ни на стек, ни даже в стек (по-русски всё ж "в стек", "на стек" -- это прямая калька с английского), кладёт само процессорное ядро. Соответственно, обратные действия тоже выполняет процессорное ядро, а не NVIC. Единственная функция NVIC -- это обрабатывать поступающие запросы прерываний и выдавать процессорному ядру соответствующие сигналы, когда это требуется.
3) Вы отвечаете за откат Ваших действий, процессор -- за откат своих действий. Так что, получив приказ на переход на EXC_RETURN (псевдоадрес, помещаемый при входе в обработчик прерывания в LR; переход на него не обязательно выполняется с помощью BX, можно использовать и ряд других команд), он восстановит сохранённые в стеке восемь значений, а заодно выполнит все прочие действия по возврату из прерывания. Ваша задача -- перед передачей управления на EXC_RETURN восстановить то, что сохраняли Вы, и обеспечить правильное значение соответствующего указателя стека (если по каким-то причинам Вы его меняли) и содержимого самого стека.
4) Насчёт использования стеков понимаете правильно. Но помните, что это относится лишь к аппаратному сохранению регистров, производимому самим процессором; когда Вы будете сохранять что-либо с помощью STM/PUSH, значения будут записываться всегда в текущий стек.
Вообще, обработка прерываний на русском описана, например, здесь: http://ru.osdev.wikia.com/wiki/%D0%9E%D ... 0%BB%D0%B5.
2) NVIC ничего не кладёт ни на стек, ни даже в стек (по-русски всё ж "в стек", "на стек" -- это прямая калька с английского), кладёт само процессорное ядро. Соответственно, обратные действия тоже выполняет процессорное ядро, а не NVIC. Единственная функция NVIC -- это обрабатывать поступающие запросы прерываний и выдавать процессорному ядру соответствующие сигналы, когда это требуется.
3) Вы отвечаете за откат Ваших действий, процессор -- за откат своих действий. Так что, получив приказ на переход на EXC_RETURN (псевдоадрес, помещаемый при входе в обработчик прерывания в LR; переход на него не обязательно выполняется с помощью BX, можно использовать и ряд других команд), он восстановит сохранённые в стеке восемь значений, а заодно выполнит все прочие действия по возврату из прерывания. Ваша задача -- перед передачей управления на EXC_RETURN восстановить то, что сохраняли Вы, и обеспечить правильное значение соответствующего указателя стека (если по каким-то причинам Вы его меняли) и содержимого самого стека.
4) Насчёт использования стеков понимаете правильно. Но помните, что это относится лишь к аппаратному сохранению регистров, производимому самим процессором; когда Вы будете сохранять что-либо с помощью STM/PUSH, значения будут записываться всегда в текущий стек.
Вообще, обработка прерываний на русском описана, например, здесь: http://ru.osdev.wikia.com/wiki/%D0%9E%D ... 0%BB%D0%B5.
- Мяукните!
- Открыл глаза
- Сообщения: 63
- Зарегистрирован: Пн апр 20, 2015 14:00:32
- Контактная информация:
Re: помогите разобрать nested vectored interrupt controller
За много лет программирования на ассемблере для F4, я не встречал ситуаций, где могли бы работать барьерные инструкции. Они там просто не нужны. Поэтому нигде не ставлю.
Впервые с этой штукой я столкнулся, начав работать с настоящим процессором, у которого есть кэши данных и инструкций. Который умеет выполнять несколько инструкций за один цикл. Может загружать в регистры по 16 байт за цикл и выгружать с такой же скоростью. Естественно, все эти данные зависают в L1/L2. И что бы они отобразились на реальную физическую память, их нужно туда проталкивать силой, командой DSB.
Что бы процессор не начал загружать и анализировать последующий код, НЕ перепрыгивал через голову, и дожидался выполнения предыдущей команды ассемблера, вставляется барьер DMB. Все эти барьеры останавливают работу процессора на 150-300 машинных циклов, как минимум.
Команда ISB нужна только при смене режимов процессора, когда вы что-то так наменяли в его системных регистрах, что весь последующий код, находящийся в кеше, становится недействительным, может привести к неправильной работе процессора и его кеш нужно перезагрузить, обновить. Для этого используется команда ISB. Даже страшно представить, сколько циклов уйдёт на выполнение такой безобидной на вид командочки... Выполнится она быстро, инвалидировав все данные в кеше. Но вот последующий за ISB код начнёт выполняться в ~20 раз медленней. Да, кеши это страшная штука....
Если вы не меняете на ходу режимы процессора и не генерируете динамически собственный исполняемый код, команда ISB вряд ли пригодится.
Вот так вот. Разбирайтесь потихоньку!
Впервые с этой штукой я столкнулся, начав работать с настоящим процессором, у которого есть кэши данных и инструкций. Который умеет выполнять несколько инструкций за один цикл. Может загружать в регистры по 16 байт за цикл и выгружать с такой же скоростью. Естественно, все эти данные зависают в L1/L2. И что бы они отобразились на реальную физическую память, их нужно туда проталкивать силой, командой DSB.
Что бы процессор не начал загружать и анализировать последующий код, НЕ перепрыгивал через голову, и дожидался выполнения предыдущей команды ассемблера, вставляется барьер DMB. Все эти барьеры останавливают работу процессора на 150-300 машинных циклов, как минимум.
Команда ISB нужна только при смене режимов процессора, когда вы что-то так наменяли в его системных регистрах, что весь последующий код, находящийся в кеше, становится недействительным, может привести к неправильной работе процессора и его кеш нужно перезагрузить, обновить. Для этого используется команда ISB. Даже страшно представить, сколько циклов уйдёт на выполнение такой безобидной на вид командочки... Выполнится она быстро, инвалидировав все данные в кеше. Но вот последующий за ISB код начнёт выполняться в ~20 раз медленней. Да, кеши это страшная штука....
Если вы не меняете на ходу режимы процессора и не генерируете динамически собственный исполняемый код, команда ISB вряд ли пригодится.
Вот так вот. Разбирайтесь потихоньку!
NXP i.MX7D на чистом ассемблере
- Реклама
Re: помогите разобрать nested vectored interrupt controller
Всем спасибо за подробный ответ. Вроде бы разобрался с контроллером прерываний. Все работает.
По поводу барьерных инструкций интересно разобраться все таки зачем они нужны. Мяукните! если у вам есть материалы на эту тему был бы признателен за ссылку.
По поводу барьерных инструкций интересно разобраться все таки зачем они нужны. Мяукните! если у вам есть материалы на эту тему был бы признателен за ссылку.
-
SII
- Вымогатель припоя
- Сообщения: 635
- Зарегистрирован: Пт янв 30, 2009 14:50:35
- Откуда: Солнечногорск
Re: помогите разобрать nested vectored interrupt controller
Уже ж ответили: они нужны процессорам, имеющим кэши, суперскалярное исполнение и прочие интересные вещи. В простых процессорах этих вещей нет, поэтому и соответствующие инструкции реального применения не находят.


