AlexeyT 0 May 30, 2017 Posted May 30, 2017 · Report post Уважаемые коллеги, помогите разобраться: Есть процессор на базе Cortex-M4, с FPU. У него есть встроенный загрузчик, но нет ПЗУ - только ОЗУ. Есть подключенные к нему внешняя флэш-память и программатор JTAG. Есть тестовая прошивка - настройка тактовой частоты, СОМ-порта и пока всё, дальше бесконечный цикл while(1) {}. Раньше было больше, но при уменьшении до нынешнего варианта косяк не исчез. Принципиальный момент - NVIC в тестовой прошивке не настраивается, обработчики исключений не переопределены. Последовательность работы: При подаче питания процессор начинает исполнять код заводского загрузчика, анализирует линии задания режима загрузки и переходит в режим исполнения программы из внешней флэш-памяти. Она успешно исполняется, используя прерывания - одно от периферийного блока СнК (контроллер МКИО) и одно внешнее. После чего в какой-то момент надо передать управление другой программе. Имитирую передачу управления. Для этого я выполняю останов (команда "h") процессора через J-Link Commander. А вот дальше есть два варианта развития событий: 1) не_выполняя_сброса, заливаю в ОЗУ инструкций образ тестовой прошивки, пишу во VTOR новый адрес таблицы, указываю новую вершину стека (первое слово прошивки), пишу в PC адрес вектора сброса (второе слово прошивки) и запускаю (команда "g"). После чего снова останавливаю ядро и вижу, что упал в исключение NMI. 2) выполняю сброс (команда "R"), и выполняю те же действия, что и ранее, над той же тестовой прошивкой. После чего останавливаю ядро и вижу, что что ядро спокойно остановлено (NoException). В чем может быть принципиальное отличие этих режимов? Какие регистры SCB нужно сбросить в начале п.1, чтобы состояние стало близким к идеальному, т.е. после Reset? Чем сброс через JTAG отличается от сброса через NVIC_SystemReset() с точки зрения системных процедур, выполняемых перед main? Quote Share this post Link to post Share on other sites More sharing options...
jcxz 124 May 30, 2017 Posted May 30, 2017 · Report post Есть процессор на базе Cortex-M4, с FPU. У него есть встроенный загрузчик, но нет ПЗУ - только ОЗУ. Это нонсенс. :laughing: Если нет ПЗУ, то где тогда находится загрузчик? ПЗУ не может не есть. :laughing: Какие регистры SCB нужно сбросить в начале п.1, чтобы состояние стало близким к идеальному, т.е. после Reset? Очевидно что нужно сбросить и всю периферию. Использовать WDT. Quote Share this post Link to post Share on other sites More sharing options...
Forger 16 May 31, 2017 Posted May 31, 2017 · Report post Уважаемые коллеги, помогите разобраться: Есть процессор на базе Cortex-M4, с FPU. У него есть встроенный загрузчик, но нет ПЗУ - только ОЗУ. Вообще, под ПЗУ понимается куча разной энергонезависимой памяти. Вангую, что в вашем процессоре есть некая ROM с загрузчиком, но нету FLASH-памяти. Так? У процессора есть маркировка? не_выполняя_сброса, заливаю в ОЗУ инструкций образ тестовой прошивки После чего снова останавливаю ядро и вижу, что упал в исключение NMI. Неужели после подобного "вандализма" вы ожидали другого поведения проца? :) Чем сброс через JTAG отличается от сброса через NVIC_SystemReset() с точки зрения системных процедур, выполняемых перед main? А при чем тут некие магические "системные процедуры"? Сброс - есть сброс, иначе он назывался бы иначе: например, передача управления в начало программы или типа того. Quote Share this post Link to post Share on other sites More sharing options...
AlexeyT 0 May 31, 2017 Posted May 31, 2017 (edited) · Report post Если нет ПЗУ, то где тогда находится загрузчик? ПЗУ не может не есть. laughing.gif Вангую, что в вашем процессоре есть некая ROM с загрузчиком, но нету FLASH-памяти. Так? Есть 4 кБ ПЗУ с загрузчиком, зашитым на заводе (намертво, не Flash). Пользователю оно доступно только на чтение. Процессор стартует из него. Для пользователя есть 128 кБ ОЗУ под инструкции и 64 кБ ОЗУ под данные. Пользовательская программа может появиться в ОЗУ двумя способами: через JTAG или в результате работы заводского загрузчика. После чего управление передается на нее способом, описанным в первом посте, т.е. без сброса. Неужели после подобного "вандализма" вы ожидали другого поведения проца? sm.gif Именно потому, что раньше проблем не было, ожидал - это способ, используемый заводским загрузчиком. А при чем тут некие магические "системные процедуры"? Сброс - есть сброс, иначе он назывался бы иначе: например, передача управления в начало программы или типа того. "Магические процедуры" - типа __main, которая вызывается в векторе RESET. Собственно, и вопрос - в чем отличие? NVIC_SystemReset() - это таки "сброс" или "Передача управления в начало программы"? Очевидно что нужно сбросить и всю периферию. Использовать WDT. Периферия - блоки на шинах AHB/APB? Или все-таки регистры SCB? Мысль с WDT проработаю, спасибо. Edited May 31, 2017 by AlexeyT Quote Share this post Link to post Share on other sites More sharing options...
Forger 16 May 31, 2017 Posted May 31, 2017 · Report post NVIC_SystemReset() - это таки "сброс" или "Передача управления в начало программы"? Работает аналогично аппаратному сбросу, RTFM. В своем коде использую его уже давно, работает практически также, как и аппаратный сброс. Собственно для этого он был задуман. System reset request bit ..... This is intended to force a large system reset of all major components except for debug. Мысль с WDT проработаю, спасибо.WDT приходится использовать для программного сброса в тех камнях, где нет соотв. регистров, в PIC/AVR например. В ARMах же WDT все же лучше использовать как WDT, а для сброса юзать NVIC_SystemReset или напрямую регистр AIRCR (ссылка выше). Почитайте содержимое NVIC_SystemReset (см. CMSIS на ваш секретный камень). Также в ответственных приложения полезно использовать внешний контроллер сброса со встроенным WDT. В этом случае для железного (аппаратного) сброса камня достаточно лишь какое-то время прекратить дергать соотв. пин для "кормления" этого внешнего WDT. это способ, используемый заводским загрузчиком. Заводской загрузчик не будет затирать в ОЗУ собственный стек и область хранения собственных переменных. Также заводской загрузчик перед настройкой векторов и передачей управления запрещает все прерывания. Поэтому ваш способ "в лоб" всегда будет вызывать exception, а заводской - не будет ))) зы. Как я понял, процессор секретный, маркировка стерта... Quote Share this post Link to post Share on other sites More sharing options...
Сергей Борщ 78 May 31, 2017 Posted May 31, 2017 · Report post 1) не_выполняя_сброса, заливаю в ОЗУ инструкций образ тестовой прошивки, пишу во VTOR новый адрес таблицы, указываю новую вершину стека (первое слово прошивки), пишу в PC адрес вектора сброса (второе слово прошивки)За это время могли прийти запросы на прерывания от какой-то периферии. Когда вы запускаете выполнение, ядро бросается обработать эти запросы, но обрабочиков для них в таблице векторов уже нет. Вы не пробовали на каждый неиспользуемый вектор повесить свой обработчик с пустым циклом? Если попадете в один из таких обработчиков - сразу станет понятно, на какой из запросов нет обработчика. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 124 May 31, 2017 Posted May 31, 2017 · Report post Есть 4 кБ ПЗУ с загрузчиком, зашитым на заводе (намертво, не Flash). Пользователю оно доступно только на чтение. Процессор стартует из него. Вы не поверите, но почти все ARM-ы стартуют из такого ПЗУ. Даже те, где есть flash программ. :laughing: Периферия - блоки на шинах AHB/APB? Или все-таки регистры SCB? Всю. Что как раз и делает WDT. Работает аналогично аппаратному сбросу Если вы про AIRCR ядра Cortex, то это не так. В некоторых Cortex - работает, в других - сбрасывает только ядро. Что совсем не эквивалентно аппаратному ресету МК. Так что - или другие средства (специфичные для данного МК регистры периферии), или универсально - WDT. В ARMах же WDT все же лучше использовать как WDT, а для сброса юзать NVIC_SystemReset или напрямую регистр AIRCR (ссылка выше). Это не так (см. выше). И во-вторых - не во всех ARM-ах есть этот регистр. За это время могли прийти запросы на прерывания от какой-то периферии. Когда вы запускаете выполнение, ядро бросается обработать эти запросы, но обрабочиков для них в таблице векторов уже нет Запрет всех прерываний и исключений. Затем - очистка всех запросов от всей использованной периферии. Затем - очистка всех флагов запросов в NVIC Quote Share this post Link to post Share on other sites More sharing options...
Forger 16 May 31, 2017 Posted May 31, 2017 · Report post Это не так (см. выше). И во-вторых - не во всех ARM-ах есть этот регистр. Этот регистр есть во всех Cortex-M, а тут речь про Cortex-M4, но ТС по неизвестным причинам упорно скрывает маркировку камня, поэтому дальнейшие гадания в этом направлении лишены всякого смысла :) К слову, я использую тока STM (подсел). Так вот в них во всех NVIC_SystemReset сбрасывает весь камень (ядро, шины, память, периферию). Quote Share this post Link to post Share on other sites More sharing options...
scifi 1 May 31, 2017 Posted May 31, 2017 · Report post К слову, я использую тока STM (подсел). Так вот в них во всех NVIC_SystemReset сбрасывает весь камень (ядро, шины, память, периферию). У STM32 сделано следующим образом: Software Reset дёргает линию RST вниз. Если эта линия хорошо подтянута вверх, то ничего не произойдёт. Никакого сброса :laughing: Этот регистр есть во всех Cortex-M, а тут речь про Cortex-M4, но ТС по неизвестным причинам упорно скрывает маркировку камня, поэтому дальнейшие гадания в этом направлении лишены всякого смысла :) Соответственно, во всяких экзотических камнях может быть всё что угодно. Вплоть до того, что NVIC_SystemReset не делает совсем ничего :laughing: Quote Share this post Link to post Share on other sites More sharing options...
Forger 16 May 31, 2017 Posted May 31, 2017 · Report post У STM32 сделано следующим образом: Software Reset дёргает линию RST вниз. Если эта линия хорошо подтянута вверх, то ничего не произойдёт. Никакого сброса :laughing: Гы, вот почему я на RST оставлял лишь один кондер 0.1мк, "притянутый" к GND (если нету внешнего контроллера сброса) :) Соответственно, во всяких экзотических камнях может быть всё что угодно. Вплоть до того, что NVIC_SystemReset не делает совсем ничего :laughing: Во всяких экзотических камнях наверно даже WDT может напрочь отсутствовать Quote Share this post Link to post Share on other sites More sharing options...
AlexeyT 0 May 31, 2017 Posted May 31, 2017 · Report post Этот регистр есть во всех Cortex-M, а тут речь про Cortex-M4, но ТС по неизвестным причинам упорно скрывает маркировку камня, поэтому дальнейшие гадания в этом направлении лишены всякого смысла :) К слову, я использую тока STM (подсел). Так вот в них во всех NVIC_SystemReset сбрасывает весь камень (ядро, шины, память, периферию). Никакого секрета. Используем свой камень 1914ВА018 (http://mvc-nn.ru/продукция/микропроцессоры-и-микроконтроллеры/), очень стойкий ко всякой гадости (проверено испытаниями). Еще раз спасибо всем за ответы Quote Share this post Link to post Share on other sites More sharing options...
Forger 16 May 31, 2017 Posted May 31, 2017 · Report post 1914ВА018 А что в его даташите написано по поводу различных схем сброса? Quote Share this post Link to post Share on other sites More sharing options...
Edit2007 3 May 31, 2017 Posted May 31, 2017 · Report post А что в его даташите написано по поводу различных схем сброса? гораздо интереснее, что написано в ERRATA. Quote Share this post Link to post Share on other sites More sharing options...