Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: STM32: сброс всей периферии перед переходом из загрузчика в основную прошивку
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Страницы: 1, 2
k000858
Достаточно ли отключить тактирование определенной шины, что бы сбросить всю периферию, сидящую на этой шине?

К примеру как это предлагается делать в HAL библиотеках:
RCC->APB1RSTR = 0xFFFFFFFF; // FORCE_RESET
RCC->APB1RSTR = 0x00; // RELEASE_RESET
adnega
Цитата(k000858 @ May 21 2014, 11:53) *
Достаточно ли отключить тактирование определенной шины, что бы сбросить всю периферию, сидящую на этой шине?

К примеру как это предлагается делать в HAL библиотеках:
RCC->APB1RSTR = 0xFFFFFFFF; // FORCE_RESET
RCC->APB1RSTR = 0x00; // RELEASE_RESET

Есть регистр, отвечающий за тактирование, а есть регистр, отвечающий за сброс периферии. Вы их не путаете?
k000858
Цитата(adnega @ May 21 2014, 11:57) *
Есть регистр, отвечающий за тактирование, а есть регистр, отвечающий за сброс периферии. Вы их не путаете?

да. все верно. затупил.
выше описанный регистр как раз относится к регистру сброса.

т.е. записав в эти регистры, сбросится вся периферия, сидящая на шине?
scifi
Самый кошерный способ - это сбросить МК полностью и сразу после сброса перейти в основную прошивку. Собственно, так я всегда и делаю.
Axel
Отключение тактирования точно ничего не сбрасывает. Так что - или регистры RSTR, или общий ресет.
k000858
Цитата(scifi @ May 21 2014, 12:03) *
Самый кошерный способ - это сбросить МК полностью и сразу после сброса перейти в основную прошивку. Собственно, так я всегда и делаю.

тогда попутный вопрос: при сбросе мк с помощью функции NVIC_SystemReset (из core_cm4.h CMSIS библиотеки) происходит полный сброс контроллера, включая сброс периферии (особенно интересуют прерывания) ?
scifi
Цитата(k000858 @ May 21 2014, 12:08) *
тогда попутный вопрос: при сбросе мк с помощью функции NVIC_SystemReset (из core_cm4.h CMSIS библиотеки) происходит полный сброс контроллера, включая сброс периферии (особенно интересуют прерывания) ?

Да.
k000858
а есть способ запретить все прерывания, а не одно какое то конкретное?
Golikov A.
глобальным флагом?
#define INTERRUPT_DISABLE_STORE(flag1, flag2) (flag1) = __disable_irq(); (flag2) = __disable_fiq()
#define INTERRUPT_RESTORE(flag1, flag2) if(!(flag1)) __enable_irq(); if(!(flag2)) __enable_fiq()
k000858
Цитата(Golikov A. @ May 21 2014, 13:45) *
глобальным флагом?
#define INTERRUPT_DISABLE_STORE(flag1, flag2) (flag1) = __disable_irq(); (flag2) = __disable_fiq()
#define INTERRUPT_RESTORE(flag1, flag2) if(!(flag1)) __enable_irq(); if(!(flag2)) __enable_fiq()

а. т.е. функция __disable_irq(); запрещает все прерывания?
Golikov A.
не все, а только обычные
__disable_fiq() - остальные
но есть не маскируемые типа ресета, которые никак не запретишь...
и это в кейле, в других средах, могут быть переопределены по другому, там битики в регистре устанавливаются...

scifi
Цитата(Golikov A. @ May 21 2014, 15:26) *
__disable_fiq() - остальные

Какой такой fiq? Это же Cortex-M, нет там никакого fiq. Уважаемый, не вводите общественность в заблуждение.
Golikov A.
я просто не в курсе, неужели STM32 - это только кортексы М? ну нет фик, и нет, плохого ничего не будет, можете запрещать, можете не запрещатьsm.gif
A. Fig Lee
Цитата(k000858 @ May 21 2014, 03:08) *
тогда попутный вопрос: при сбросе мк с помощью функции NVIC_SystemReset (из core_cm4.h CMSIS библиотеки) происходит полный сброс контроллера, включая сброс периферии (особенно интересуют прерывания) ?

А каким образом по ресету Вы собираетесь переходить в основную программу?
Загрузчик разве не по начальному аддрессу?
Так Вы туда опять и попадете
scifi
Цитата(A. Fig Lee @ May 21 2014, 15:59) *
А каким образом по ресету Вы собираетесь переходить в основную программу?
Загрузчик разве не по начальному аддрессу?
Так Вы туда опять и попадете

Это же совсем просто: в самом начале загрузчика проверять специальный флаг и прыгать в основную прошивку или продолжать выполнять загрузчик.
adnega
Цитата(scifi @ May 21 2014, 16:17) *
Это же совсем просто: в самом начале загрузчика проверять специальный флаг и прыгать в основную прошивку или продолжать выполнять загрузчик.

При этом не тронув никакой периферии.
Golikov A.
специальный флаг, целостность прошивки, и какие - либо коды безопасности....
_Артём_
Цитата(scifi @ May 21 2014, 15:29) *
Какой такой fiq? Это же Cortex-M, нет там никакого fiq.

Как же нет? А это что:
Код
/** \brief  Disable FIQ

    This function disables FIQ interrupts by setting the F-bit in the CPSR.
    Can only be executed in Privileged modes.
*/
#define __disable_fault_irq               __disable_fiq

?
scifi
Цитата(_Артём_ @ May 21 2014, 16:39) *
Как же нет? А это что:

А это какая-то чушь (очевидно, перекочевала из кода для других процессоров ARM). Просто подтверждает, что этот код пишут простые смертные, вполне способные ошибаться.
A. Fig Lee
Цитата(scifi @ May 21 2014, 07:17) *
Это же совсем просто: в самом начале загрузчика проверять специальный флаг и прыгать в основную прошивку или продолжать выполнять загрузчик.

Флаг в EEPROM?
А почему сразу не прыгнуть? К чему эти танцы с бубном, если и так ясно что прыгать будем?

Цитата(Golikov A. @ May 21 2014, 07:26) *
специальный флаг, целостность прошивки, и какие - либо коды безопасности....

А при чем здесь reset?
Программа бутлоадер стартанула, все проверила, теперь выставляет флаг, чтобы прыгнуть и делает ресет?
Бессмыслица
ViKo
Это какой-то "мудрец" переименовал fast_interrupt от ARM в fault_interrupt для Cortex-M.
Golikov A.
поглядел доки на кортекс - м
http://infocenter.arm.com/help/index.jsp?t...b/CHDBIBGJ.html
нашел только
PM
Prioritizable interrupt mask:
0 = no effect.
1 = prevents the activation of all exceptions with configurable priority.

то есть Reset, NMI, HardFault задушить этим битиком нельзя...

HardFault душиться егойным регистром
http://infocenter.arm.com/help/index.jsp?t...a/Cihieffb.html

Reset понятно никак не душиться,

_Артём_
Цитата(scifi @ May 21 2014, 16:55) *
А это какая-то чушь (очевидно, перекочевала из кода для других процессоров ARM).

Почему чушь? Код вполне имеет смысл:
Код
__attribute__( ( always_inline ) ) static __INLINE void __enable_fault_irq(void)
{
  __ASM volatile ("cpsie f");
}


/** \brief  Disable FIQ

    This function disables FIQ interrupts by setting the F-bit in the CPSR.
    Can only be executed in Privileged modes.
*/
__attribute__( ( always_inline ) ) static __INLINE void __disable_fault_irq(void)
{
  __ASM volatile ("cpsid f");
}
Golikov A.
Цитата
А при чем здесь reset?
Программа бутлоадер стартанула, все проверила, теперь выставляет флаг, чтобы прыгнуть и делает ресет?
Бессмыслица


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


Цитата
Почему чушь? Код вполне имеет смысл:

http://infocenter.arm.com/help/index.jsp?t...ch02s08s01.html

это от 7 арма...

в кортаксах - м только
CPSID i
http://infocenter.arm.com/help/index.jsp?t...a/BABHBAAB.html
_Артём_
Цитата(Golikov A. @ May 21 2014, 17:17) *
поглядел доки на кортекс - м
http://infocenter.arm.com/help/index.jsp?t...b/CHDBIBGJ.html
нашел только
PM
Prioritizable interrupt mask:
0 = no effect.
1 = prevents the activation of all exceptions with configurable priority.

Не там смотрите: нужно в описании Cortex-M3 или M4 смотреть.
Цитата
2.8. FAULTMASK register bit assignmentsBits Name Function
[31:1] - Reserved
[0] FAULTMASK
0 = no effect
1 = prevents the activation of all exceptions except for NMI.
The processor clears the FAULTMASK bit to 0 on exit from any exception handler except the NMI handler.
Golikov A.
все там
просто ссылки криво вставляются... я постом выше поправил ссылки...

в кортаксах - м только

CPSID i
http://infocenter.arm.com/help/index.jsp?t...a/BABHBAAB.html

отключает все крмое NMI и RESET, странно что про HardFault не упомянуто...

О прошу прощения. Чет криво у них написано, если взять набор инструкций кортекса м3

Examples
CPSID i ; Disable interrupts and configurable fault handlers (set PRIMASK)
CPSID f ; Disable interrupts and all fault handlers (set FAULTMASK)
CPSIE i ; Enable interrupts and configurable fault handlers (clear PRIMASK)
CPSIE f ; Enable interrupts and fault handlers (clear FAULTMASK).
adnega
Цитата
Биты состояния прерывания (I и F) были заменены новым регистром PRIMASK (однобитный регистр, который будучи установлен в 1, разрешает генерацию только немаскируемого прерывания и исключения HardFault; все остальные прерывания и исключения маскируются).

Читаем Джозефа Ю.
scifi
Цитата(_Артём_ @ May 21 2014, 17:18) *
Почему чушь? Код вполне имеет смысл:

Код имеет смысл, а вот комментарий не имеет:
Цитата
This function disables FIQ interrupts by setting the F-bit in the CPSR.

Про комментарий я и написал - это чушь.
Golikov A.
вот хрень какая-то, что же их официальный сайт то никак не определиться:?

ну то есть надо понимать что осталось одно
__disable_irq();
которое глушит все кроме ресета и NMI?
A. Fig Lee
Цитата(Golikov A. @ May 21 2014, 08:21) *
а может так
старт - проверка - режим обновления прошивки - обновил прошивку, поставил флаг нормального старта - ресет
и по первому пути... в таком случае вы точно ничего не забудите, и ваша основная программа начнется как после ресета, со всеми регистрами в правильных состояниях

Не будет "со всеми регистрами".
Флаг надо както передать. EEPROM?
Его надо будет както прочтать, значит инициализировать регистры, сделать какието действия,
то есть все равно ни как про ресете.
Golikov A.
ножка? Одна единственная на кнопке? Которая и в основной программе остается такой же?

Ну вообще да флаг через EEPROM, Еще PLL настроить, но это делается и в основной проге, просто данный момент пропускается...
scifi
Цитата(A. Fig Lee @ May 21 2014, 17:35) *
Флаг надо както передать. EEPROM?

Зачем EEPROM? При "теплом" сбросе содержимое ОЗУ на чипе сохраняется.
A. Fig Lee
Цитата(Golikov A. @ May 21 2014, 08:37) *
ножка? Одна единственная на кнопке? Которая и в основной программе остается такой же?

Ну вообще да флаг через EEPROM, Еще PLL настроить, но это делается и в основной проге, просто данный момент пропускается...

Не только ножка. Состояние прерываний остается тем же.
То есть, если они запрещены, то в основной программе надо explicitly разрешать.
По прежнему не вижу большого смысла в выполенении ресета

Цитата(scifi @ May 21 2014, 08:41) *
Зачем EEPROM? При "теплом" сбросе содержимое ОЗУ на чипе сохраняется.

А в чем разница?
Разве не по офному и тому же аддрессу переход происходит пристарте?
Каким волшебным образом при холодном старте обнуляется RAM, если
не самой программой?
Golikov A.
от ресета внутренне спокойно...


вот что кеил написал в хелпе
Цитата
__disable_fiq

Typically, this intrinsic disables FIQ interrupts by setting the F-bit in the CPSR. However, for v7-M it sets the fault mask register (FAULTMASK). FIQ interrupts are not supported in v6-M.


то есть на самом деле это от 7 армов тянется, и несмотря что FIQ сменилось с быстрых на ошибочные, это все равно не для кортексов М
_Артём_
Цитата(Golikov A. @ May 21 2014, 17:35) *
ну то есть надо понимать что осталось одно
__disable_irq();
которое глушит все кроме ресета и NMI?

Почему? __disable_irq() это :
Код
CPSID i ; Disable interrupts and configurable fault handlers (set PRIMASK)

HardFault не запрещается после __disable_irq.
HardFault запретится после CPSID f.
Вроде так выходит...

Цитата(A. Fig Lee @ May 21 2014, 17:44) *
А в чем разница?
Разве не по офному и тому же аддрессу переход происходит пристарте?
Каким волшебным образом при холодном старте обнуляется RAM, если
не самой программой?

Обнуляется программой...Можно зарезервировать ячейку в ОЗУ и проверять её на старте и в зависимости от её значения решать что делать дальше - запускать программу, запускать бут или ещё что-то.
ViKo
Из User Guide на Cortex-M
Golikov A.
путано написано, в описании на проц LPC1768, в части про кортекс м3 есть запись про HARDFAULTMASK, в наборе инструкций кортекса м3 есть такое... В описании на серию кортексов М0-4, нету... даже нет HardFaule Mask регистра....

и как это понимать?
поправочка-------------

http://infocenter.arm.com/help/index.jsp?t...a/CHDBIBGJ.html
у М3, и М4 есть, называется FAULTMASK, и флажочек тоже есть

Цитата
The FAULTMASK register prevents activation of all exceptions except for Non-Maskable Interrupt (NMI). See the register summary in Table 2.2 for its attributes. The bit assignments are:

получается его одного достаточно чтобы все выключить? даже примаск?
_Артём_
Цитата(Golikov A. @ May 21 2014, 17:57) *
путано написано, в описании на проц LPC1768, в части про кортекс м3 есть запись про HARDFAULTMASK, в наборе инструкций кортекса м3 есть такое...

В каком пункте мануала про HARDFAULTMASK написано?

Цитата(Golikov A. @ May 21 2014, 17:57) *
получается его одного достаточно чтобы все выключить? даже примаск?

Получается достаточно - кроме NMI и Reset.
A. Fig Lee
Цитата(_Артём_ @ May 21 2014, 08:50) *
Обнуляется программой...Можно зарезервировать ячейку в ОЗУ и проверять её на старте и в зависимости от её значения решать что делать дальше - запускать программу, запускать бут или ещё что-то.

Это значит надо писать собственный startup файл.
Тоже можно, конечно.. Но по мне так это уже извращения пошли.
scifi
Цитата(A. Fig Lee @ May 21 2014, 18:23) *
Это значит надо писать собственный startup файл.
Тоже можно, конечно.. Но по мне так это уже извращения пошли.

Стартапа бояться - загрузчик не писать. Ну что за цирк, ей-богу :-)
A. Fig Lee
Цитата(scifi @ May 21 2014, 09:30) *
Стартапа бояться - загрузчик не писать. Ну что за цирк, ей-богу :-)

А мы без всяких самодельных стартапов и ресетов обошлись.
Чем больше меняешь, тем больше багов.
_Артём_
Цитата(A. Fig Lee @ May 21 2014, 18:23) *
Это значит надо писать собственный startup файл.
Тоже можно, конечно.. Но по мне так это уже извращения пошли.

Можно отредактировать startup, который есть: всего-то несколько строк добавить.
Код
               if ((FlashCrcOk()) && (StartType==START_APPLICATION)) {
        __disable_irq();
        __set_MSP(*(uint32_t *)0x1008);
        ISRPtr application_reset_handler=(ISRPtr)(*(uint32_t *)0x100C);
        goto *application_reset_handler;
              
                }
scifi
Цитата(A. Fig Lee @ May 21 2014, 18:32) *
А мы без всяких самодельных стартапов и ресетов обошлись.
Чем больше меняешь, тем больше багов.

На самом деле бывает полезно разбираться в стартапе. Тем более на Cortex-M минимальный стартап - это всего несколько строчек:
CODE
#include <string.h>

extern char __etext, __data_start__, __data_end__, __bss_start__, __bss_end__;
extern int main();

void __attribute((used))
Reset_Handler(void)
{
/* copy-init variables */
memcpy(&__data_start__, &__etext, &__data_end__ - &__data_start__);
/* zero-init variables */
memset(&__bss_start__, 0, &__bss_end__ - &__bss_start__);
(void)main();
}
A. Fig Lee
Это не стартап, это ресет хэндлер.
Никто не спорит про разобратся, но переделывать не вижу смысла.

В любом случае, как обслуживать ситуацию,
когда в данной ячейке при холодном старте флаг случайно совпал с тем, который выставляется
для прыгания в главную программу?
Может еще один флаг добавим?
Может, CRC считать начнем?
_Артём_
Цитата(A. Fig Lee @ May 21 2014, 18:53) *
Это не стартап, это ресет хэндлер.

Ну так стартап состоит из двух частей - таблицы векторов и Reset_Handler-а. Таблица у каждого МК своя и её менять не надо.

Цитата(A. Fig Lee @ May 21 2014, 18:53) *
В любом случае, как обслуживать ситуацию,
когда в данной ячейке при холодном старте флаг случайно совпал с тем, который выставляется
для прыгания в главную программу?

Маловероятно...

Цитата(A. Fig Lee @ May 21 2014, 18:53) *
Может еще один флаг добавим?
Может, CRC считать начнем?

К тому же CRC прошивки посчитать всё равно желательно, а то вдруг там пусто.
A. Fig Lee
Цитата(_Артём_ @ May 21 2014, 09:58) *
Маловероятно...

Ну.. Если так программировать..
Программирование должно быть детерминистик как возможно.
В общем, с ресетом больше граблей, дольше и выгоды не вижу.
Проще прыгнуть сразу, без всяких вероятностей
_Артём_
Цитата(A. Fig Lee @ May 21 2014, 19:39) *
Ну.. Если так программировать..
Программирование должно быть детерминистик как возможно.

Согласен - не дело это. Хотя и каких-то нежелательных эффектов тоже сразу не видно. Хотя наверное можно придумать.

Цитата(A. Fig Lee @ May 21 2014, 19:39) *
В общем, с ресетом больше граблей, дольше и выгоды не вижу.
Проще прыгнуть сразу, без всяких вероятностей

Согласен, так и лучше и проще.
Golikov A.
а мне понравилась идея)

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

получается я могу сделать флаг в RAM, и переходить через ресет на бут если в флаге стоит кодовое слово, иначе уходить в основную прогу. И оставить EEPROM в покое, интересно...
Сергей Борщ
Цитата(Golikov A. @ May 21 2014, 20:21) *
получается я могу сделать флаг в RAM, и переходить через ресет на бут если в флаге стоит кодовое слово, иначе уходить в основную прогу. И оставить EEPROM в покое, интересно...
Не плодите сущностей. Вы сбрасываться как собираетесть? Программно? Вот и проверяйте флаг программного сброса в соответствующем регистре ядра. И не нужно ни EEPROM, ни ячейки в ОЗУ резервировать. А еще лучше сбрасываться после прошивки собакой и по отсутствию флага программного сброса делать проверку целостности прошивки и прыжок в нее. А по флагу программного сброса или при ошибке целостности уходить в загрузчик. Тогда вы получите возможность запуска загрузчика из основной программы программным сбросом и загрузчик при этом будет запускаться тоже со сброшенной периферией.
Я делаю именно так и нахожу это очень простым и удобным.
Golikov A.
Сбрасывать собакой - чтобы сброс был железным?
Если любой программный сброс - уход в загрузчик, то для удаленной перезагрузки устройства тоже делать фокус с вачдогом?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.