реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> После софтварной перезагрузки не работает прерывание SysTick, ((void (*)(void))HWREG(0x00000004))();
=Zap=
сообщение Dec 15 2012, 11:39
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 7-01-09
Пользователь №: 42 985



Выполняю перезагрузку с помощью прыжка по адресу ResetISR, хранящемуся во флэше 0x4:
Код
((void (*)(void))HWREG(0x00000004))();

Всё перезагружается нормально, проходит __iar_program_start, main, вообще всё работает кроме прерываний SysTick. При этом SysTick работает, считает его счётчик, он ставит бит пендинг прерывания, если бит снять, то SysTick его опять ставит. Другие прерывания происходят. Да и вообще ошибки в коде инициализации нет, так как при аппаратном ресете всё работает. А при софтварном ресете вот такое чудо.
Такое ощущение, что я чего-то не знаю про инициализацию Cortex-M3 ядра.
Есть советы куда копать?
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 15 2012, 11:44
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(=Zap= @ Dec 15 2012, 15:39) *
Выполняю перезагрузку с помощью прыжка по адресу ResetISR, хранящемуся во флэше 0x4:

При такой "перезагрузке" не будет сброшена периферия и NVIC. Почему не хотите выполнить её штатными средствами?
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Dec 15 2012, 11:47
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(=Zap= @ Dec 15 2012, 13:39) *
Выполняю перезагрузку с помощью прыжка по адресу ResetISR, хранящемуся во флэше 0x4:
Код
((void (*)(void))HWREG(0x00000004))();

Всё перезагружается нормально, проходит __iar_program_start, main, вообще всё работает кроме прерываний SysTick. При этом SysTick работает, считает его счётчик, он ставит бит пендинг прерывания, если бит снять, то SysTick его опять ставит. Другие прерывания происходят.

Странный способ...
А SP загружаете?

сброс через запрос:
Код
NVIC_SystemReset();
Go to the top of the page
 
+Quote Post
Slash
сообщение Dec 15 2012, 16:48
Сообщение #4


Местный
***

Группа: Участник
Сообщений: 202
Регистрация: 10-04-05
Из: Санкт-Петербург
Пользователь №: 4 011



Как вариант сбрасывать через Watchdog Timer. Завели его на несколько миллисекунд и дальше while(1);
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Dec 16 2012, 07:31
Сообщение #5


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Если это Cortex-M3, надо использовать встроенную возможность софтвеерной перегрузки, в регистре SCB_AIRCR установить бит SYSRESETREQ.
Go to the top of the page
 
+Quote Post
=Zap=
сообщение Dec 21 2012, 07:36
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 7-01-09
Пользователь №: 42 985



Спасибо за рекомендации. Перезагружал таким способом так как по-быстрому это когда-то работало и с тех пор не трогал. А потом вдруг сломалось и было непонятно почему.
Тем не менее, разгадку я, видимо, нашёл. Поделюсь опытом: в перезагрузку я ухожу из прерывания SysTick (использовал его для счёта задержки времени перед перезагрузкой), таким образом NVIC не чувствует возврата из SysTick и новые прерывания больше не вызывает. Вызывает только более высокоприоритетные.
С SP (stack pointer) проблем нет: его нормально переинициализирует стартовый код IAR.
Кроме перезагрузки мы используем переход из бутлоадера в основную прошивку, что NVIC_SystemReset() или SYSRESETREQ уже не помогает сделать. Там были те же проблемы и придётся использовать прыжок на адрес. Теперь понятно, что его надо сделать не из прерывания.
Watchdog timer хорошая мысль. Как раз подойдёт для отсчёта той задержки, которая нужна перед перезагрузкой.
Go to the top of the page
 
+Quote Post
scifi
сообщение Dec 21 2012, 15:09
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(=Zap= @ Dec 21 2012, 11:36) *
Кроме перезагрузки мы используем переход из бутлоадера в основную прошивку, что NVIC_SystemReset() или SYSRESETREQ уже не помогает сделать. Там были те же проблемы и придётся использовать прыжок на адрес. Теперь понятно, что его надо сделать не из прерывания.

Для перехода на основную прошивку из загрузчика делаю следующее:
- Выставляю флаг "запуск основной прошивки" (переменная в ОЗУ, записываю туда сигнатуру типа 0xCAFEBABE).
- Делаю software reset.
- Загрузчик в самом начале (low_level_init()) проверяет регистр причины сброса. Если "software reset", то проверяем сигнатуру, и если есть совпадение, то затираем сигнатуру нулями и прыгаем на основную прошивку. В противном случае продолжаем исполнять код загрузчика.
Таким образом основная прошивка запускается до того, как началась инициализация загрузчика.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Dec 21 2012, 17:08
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127




// Программный RESET - Эквивалент дерганья лапы RESET.
*(u32*)(0xE000ED0C)=0x05FA0004;
Дергаем откуда угодно и когда угодно sm.gif
Go to the top of the page
 
+Quote Post
sysel
сообщение Dec 22 2012, 07:33
Сообщение #9


Знающий
****

Группа: Свой
Сообщений: 601
Регистрация: 3-07-07
Пользователь №: 28 852



Цитата(vlad_new @ Dec 21 2012, 21:08) *
// Программный RESET - Эквивалент дерганья лапы RESET.
*(u32*)(0xE000ED0C)=0x05FA0004;
Дергаем откуда угодно и когда угодно sm.gif

Т.е. Вы предлагаете сделать ресет через регистр "AIRCR".

Автор не написал, что у него за МК. К сожалению, у NXP семейства LPC175x, LPC176x не поддерживают данный способ (см. UM10360, "34.4.3.6 Application Interrupt and Reset Control Register"). Поэтому приходится делать ресет через Watchdog Timer.

Как обстоят дела с этим регистром у других МК - я не знаю.
Go to the top of the page
 
+Quote Post
=Zap=
сообщение Dec 23 2012, 17:53
Сообщение #10


Участник
*

Группа: Участник
Сообщений: 29
Регистрация: 7-01-09
Пользователь №: 42 985



Проверил свою гипотезу про прыжок изнутри прерывания. Она-то подтвердилась, но после прыжка извне прерываний таблицу векторов стартовый код IAR из флэша уже не копирует в оперативку. Видимо он видит, что таблица уже в оперативке... Так как обработчики я ставлю динамически, то всё заработало.
Цитата(scifi @ Dec 21 2012, 19:09) *
Для перехода на основную прошивку из загрузчика делаю следующее:
- Выставляю флаг "запуск основной прошивки" (переменная в ОЗУ, записываю туда сигнатуру типа 0xCAFEBABE).
- Делаю software reset.
- Загрузчик в самом начале (low_level_init()) проверяет регистр причины сброса. Если "software reset", то проверяем сигнатуру, и если есть совпадение, то затираем сигнатуру нулями и прыгаем на основную прошивку. В противном случае продолжаем исполнять код загрузчика.
Таким образом основная прошивка запускается до того, как началась инициализация загрузчика.

Я делаю почти так же: сигнатура в памяти, перезагрузка и проверка и затирание сигнатуры. Еще проверяю CRC прошивки перед тем как на неё перейти, а то мало ли что. low_level_init() происходит до копирования таблицы векторов прерываний в RAM. Это значит, что стартовый код основной прошивки скопирует таблицу сам, взяв её из стартового сектора. Не достанется ли ему в таком случае таблица от бутлоадера?
Цитата(sysel @ Dec 22 2012, 11:33) *
Автор не написал, что у него за МК. К сожалению, у NXP семейства LPC175x, LPC176x не поддерживают данный способ (см. UM10360, "34.4.3.6 Application Interrupt and Reset Control Register"). Поэтому приходится делать ресет через Watchdog Timer.

У меня Texas Instruments контроллер семейства Stellaris LM3S5Rхх. Довольно глючная штука.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 07:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01426 секунд с 7
ELECTRONIX ©2004-2016