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

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

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

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

тогда попутный вопрос: при сбросе мк с помощью функции NVIC_SystemReset (из core_cm4.h CMSIS библиотеки) происходит полный сброс контроллера, включая сброс периферии (особенно интересуют прерывания) ?
Да.
k000858
May 21 2014, 04:07
а есть способ запретить все прерывания, а не одно какое то конкретное?
Golikov A.
May 21 2014, 05:35
глобальным флагом?
#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
May 21 2014, 05:43
Цитата(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.
May 21 2014, 07:16
не все, а только обычные
__disable_fiq() - остальные
но есть не маскируемые типа ресета, которые никак не запретишь...
и это в кейле, в других средах, могут быть переопределены по другому, там битики в регистре устанавливаются...
Цитата(Golikov A. @ May 21 2014, 15:26)

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

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

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

Это же совсем просто: в самом начале загрузчика проверять специальный флаг и прыгать в основную прошивку или продолжать выполнять загрузчик.
При этом не тронув никакой периферии.
Golikov A.
May 21 2014, 08:16
специальный флаг, целостность прошивки, и какие - либо коды безопасности....
_Артём_
May 21 2014, 08:29
Цитата(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
?
Цитата(_Артём_ @ May 21 2014, 16:39)

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

Это же совсем просто: в самом начале загрузчика проверять специальный флаг и прыгать в основную прошивку или продолжать выполнять загрузчик.
Флаг в EEPROM?
А почему сразу не прыгнуть? К чему эти танцы с бубном, если и так ясно что прыгать будем?
Цитата(Golikov A. @ May 21 2014, 07:26)

специальный флаг, целостность прошивки, и какие - либо коды безопасности....
А при чем здесь reset?
Программа бутлоадер стартанула, все проверила, теперь выставляет флаг, чтобы прыгнуть и делает ресет?
Бессмыслица
Это какой-то "мудрец" переименовал fast_interrupt от ARM в fault_interrupt для Cortex-M.
Golikov A.
May 21 2014, 09:07
поглядел доки на кортекс - м
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.htmlReset понятно никак не душиться,
_Артём_
May 21 2014, 09:08
Цитата(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.
May 21 2014, 09:11
Цитата
А при чем здесь 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
_Артём_
May 21 2014, 09:12
Цитата(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.
May 21 2014, 09:21
все там
просто ссылки криво вставляются... я постом выше поправил ссылки...
в кортаксах - м только
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
May 21 2014, 09:22
Цитата
Биты состояния прерывания (I и F) были заменены новым регистром PRIMASK (однобитный регистр, который будучи установлен в 1, разрешает генерацию только немаскируемого прерывания и исключения HardFault; все остальные прерывания и исключения маскируются).
Читаем Джозефа Ю.
Цитата(_Артём_ @ May 21 2014, 17:18)

Почему чушь? Код вполне имеет смысл:
Код имеет смысл, а вот комментарий не имеет:
Цитата
This function disables FIQ interrupts by setting the F-bit in the CPSR.
Про комментарий я и написал - это чушь.
Golikov A.
May 21 2014, 09:25
вот хрень какая-то, что же их официальный сайт то никак не определиться:?
ну то есть надо понимать что осталось одно
__disable_irq();
которое глушит все кроме ресета и NMI?
A. Fig Lee
May 21 2014, 09:25
Цитата(Golikov A. @ May 21 2014, 08:21)

а может так
старт - проверка - режим обновления прошивки - обновил прошивку, поставил флаг нормального старта - ресет
и по первому пути... в таком случае вы точно ничего не забудите, и ваша основная программа начнется как после ресета, со всеми регистрами в правильных состояниях
Не будет "со всеми регистрами".
Флаг надо както передать. EEPROM?
Его надо будет както прочтать, значит инициализировать регистры, сделать какието действия,
то есть все равно ни как про ресете.
Golikov A.
May 21 2014, 09:27
ножка? Одна единственная на кнопке? Которая и в основной программе остается такой же?
Ну вообще да флаг через EEPROM, Еще PLL настроить, но это делается и в основной проге, просто данный момент пропускается...
Цитата(A. Fig Lee @ May 21 2014, 17:35)

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

ножка? Одна единственная на кнопке? Которая и в основной программе остается такой же?
Ну вообще да флаг через EEPROM, Еще PLL настроить, но это делается и в основной проге, просто данный момент пропускается...
Не только ножка. Состояние прерываний остается тем же.
То есть, если они запрещены, то в основной программе надо explicitly разрешать.
По прежнему не вижу большого смысла в выполенении ресета
Цитата(scifi @ May 21 2014, 08:41)

Зачем EEPROM? При "теплом" сбросе содержимое ОЗУ на чипе сохраняется.
А в чем разница?
Разве не по офному и тому же аддрессу переход происходит пристарте?
Каким волшебным образом при холодном старте обнуляется RAM, если
не самой программой?
Golikov A.
May 21 2014, 09:36
от ресета внутренне спокойно...
вот что кеил написал в хелпе
Цитата
__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 сменилось с быстрых на ошибочные, это все равно не для кортексов М
_Артём_
May 21 2014, 09:40
Цитата(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, если
не самой программой?
Обнуляется программой...Можно зарезервировать ячейку в ОЗУ и проверять её на старте и в зависимости от её значения решать что делать дальше - запускать программу, запускать бут или ещё что-то.
Из User Guide на Cortex-M
Golikov A.
May 21 2014, 09:47
путано написано, в описании на проц 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:
получается его одного достаточно чтобы все выключить? даже примаск?
_Артём_
May 21 2014, 10:08
Цитата(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, 10:13
Цитата(_Артём_ @ May 21 2014, 08:50)

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

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

Стартапа бояться - загрузчик не писать. Ну что за цирк, ей-богу :-)
А мы без всяких самодельных стартапов и ресетов обошлись.
Чем больше меняешь, тем больше багов.
_Артём_
May 21 2014, 10:23
Цитата(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;
}
Цитата(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
May 21 2014, 10:43
Это не стартап, это ресет хэндлер.
Никто не спорит про разобратся, но переделывать не вижу смысла.
В любом случае, как обслуживать ситуацию,
когда в данной ячейке при холодном старте флаг случайно совпал с тем, который выставляется
для прыгания в главную программу?
Может еще один флаг добавим?
Может, CRC считать начнем?
_Артём_
May 21 2014, 10:48
Цитата(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, 11:29
Цитата(_Артём_ @ May 21 2014, 09:58)

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

Ну.. Если так программировать..
Программирование должно быть детерминистик как возможно.
Согласен - не дело это. Хотя и каких-то нежелательных эффектов тоже сразу не видно. Хотя наверное можно придумать.
Цитата(A. Fig Lee @ May 21 2014, 19:39)

В общем, с ресетом больше граблей, дольше и выгоды не вижу.
Проще прыгнуть сразу, без всяких вероятностей
Согласен, так и лучше и проще.
Golikov A.
May 21 2014, 13:11
а мне понравилась идея)
у меня сейчас
запуск в бутлоадер проверка флага в еепром, переход в бут или в основную программу...
получается я могу сделать флаг в RAM, и переходить через ресет на бут если в флаге стоит кодовое слово, иначе уходить в основную прогу. И оставить EEPROM в покое, интересно...
Сергей Борщ
May 21 2014, 14:32
Цитата(Golikov A. @ May 21 2014, 20:21)

получается я могу сделать флаг в RAM, и переходить через ресет на бут если в флаге стоит кодовое слово, иначе уходить в основную прогу. И оставить EEPROM в покое, интересно...
Не плодите сущностей. Вы сбрасываться как собираетесть? Программно? Вот и проверяйте флаг программного сброса в соответствующем регистре ядра. И не нужно ни EEPROM, ни ячейки в ОЗУ резервировать. А еще лучше сбрасываться после прошивки собакой и по отсутствию флага программного сброса делать проверку целостности прошивки и прыжок в нее. А по флагу программного сброса или при ошибке целостности уходить в загрузчик. Тогда вы получите возможность запуска загрузчика из основной программы программным сбросом и загрузчик при этом будет запускаться тоже со сброшенной периферией.
Я делаю именно так и нахожу это очень простым и удобным.
Golikov A.
May 21 2014, 14:53
Сбрасывать собакой - чтобы сброс был железным?
Если любой программный сброс - уход в загрузчик, то для удаленной перезагрузки устройства тоже делать фокус с вачдогом?
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.