=Zap= 0 15 декабря, 2012 Опубликовано 15 декабря, 2012 · Жалоба Выполняю перезагрузку с помощью прыжка по адресу ResetISR, хранящемуся во флэше 0x4: ((void (*)(void))HWREG(0x00000004))(); Всё перезагружается нормально, проходит __iar_program_start, main, вообще всё работает кроме прерываний SysTick. При этом SysTick работает, считает его счётчик, он ставит бит пендинг прерывания, если бит снять, то SysTick его опять ставит. Другие прерывания происходят. Да и вообще ошибки в коде инициализации нет, так как при аппаратном ресете всё работает. А при софтварном ресете вот такое чудо. Такое ощущение, что я чего-то не знаю про инициализацию Cortex-M3 ядра. Есть советы куда копать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aaarrr 63 15 декабря, 2012 Опубликовано 15 декабря, 2012 · Жалоба Выполняю перезагрузку с помощью прыжка по адресу ResetISR, хранящемуся во флэше 0x4: При такой "перезагрузке" не будет сброшена периферия и NVIC. Почему не хотите выполнить её штатными средствами? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 15 декабря, 2012 Опубликовано 15 декабря, 2012 · Жалоба Выполняю перезагрузку с помощью прыжка по адресу ResetISR, хранящемуся во флэше 0x4: ((void (*)(void))HWREG(0x00000004))(); Всё перезагружается нормально, проходит __iar_program_start, main, вообще всё работает кроме прерываний SysTick. При этом SysTick работает, считает его счётчик, он ставит бит пендинг прерывания, если бит снять, то SysTick его опять ставит. Другие прерывания происходят. Странный способ... А SP загружаете? сброс через запрос: NVIC_SystemReset(); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Slash 0 15 декабря, 2012 Опубликовано 15 декабря, 2012 · Жалоба Как вариант сбрасывать через Watchdog Timer. Завели его на несколько миллисекунд и дальше while(1); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Гость MALLOY2 16 декабря, 2012 Опубликовано 16 декабря, 2012 · Жалоба Если это Cortex-M3, надо использовать встроенную возможность софтвеерной перегрузки, в регистре SCB_AIRCR установить бит SYSRESETREQ. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=Zap= 0 21 декабря, 2012 Опубликовано 21 декабря, 2012 · Жалоба Спасибо за рекомендации. Перезагружал таким способом так как по-быстрому это когда-то работало и с тех пор не трогал. А потом вдруг сломалось и было непонятно почему. Тем не менее, разгадку я, видимо, нашёл. Поделюсь опытом: в перезагрузку я ухожу из прерывания SysTick (использовал его для счёта задержки времени перед перезагрузкой), таким образом NVIC не чувствует возврата из SysTick и новые прерывания больше не вызывает. Вызывает только более высокоприоритетные. С SP (stack pointer) проблем нет: его нормально переинициализирует стартовый код IAR. Кроме перезагрузки мы используем переход из бутлоадера в основную прошивку, что NVIC_SystemReset() или SYSRESETREQ уже не помогает сделать. Там были те же проблемы и придётся использовать прыжок на адрес. Теперь понятно, что его надо сделать не из прерывания. Watchdog timer хорошая мысль. Как раз подойдёт для отсчёта той задержки, которая нужна перед перезагрузкой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 21 декабря, 2012 Опубликовано 21 декабря, 2012 · Жалоба Кроме перезагрузки мы используем переход из бутлоадера в основную прошивку, что NVIC_SystemReset() или SYSRESETREQ уже не помогает сделать. Там были те же проблемы и придётся использовать прыжок на адрес. Теперь понятно, что его надо сделать не из прерывания. Для перехода на основную прошивку из загрузчика делаю следующее: - Выставляю флаг "запуск основной прошивки" (переменная в ОЗУ, записываю туда сигнатуру типа 0xCAFEBABE). - Делаю software reset. - Загрузчик в самом начале (low_level_init()) проверяет регистр причины сброса. Если "software reset", то проверяем сигнатуру, и если есть совпадение, то затираем сигнатуру нулями и прыгаем на основную прошивку. В противном случае продолжаем исполнять код загрузчика. Таким образом основная прошивка запускается до того, как началась инициализация загрузчика. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vlad_new 1 21 декабря, 2012 Опубликовано 21 декабря, 2012 · Жалоба // Программный RESET - Эквивалент дерганья лапы RESET. *(u32*)(0xE000ED0C)=0x05FA0004; Дергаем откуда угодно и когда угодно :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sysel 0 22 декабря, 2012 Опубликовано 22 декабря, 2012 · Жалоба // Программный RESET - Эквивалент дерганья лапы RESET. *(u32*)(0xE000ED0C)=0x05FA0004; Дергаем откуда угодно и когда угодно :) Т.е. Вы предлагаете сделать ресет через регистр "AIRCR". Автор не написал, что у него за МК. К сожалению, у NXP семейства LPC175x, LPC176x не поддерживают данный способ (см. UM10360, "34.4.3.6 Application Interrupt and Reset Control Register"). Поэтому приходится делать ресет через Watchdog Timer. Как обстоят дела с этим регистром у других МК - я не знаю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=Zap= 0 23 декабря, 2012 Опубликовано 23 декабря, 2012 · Жалоба Проверил свою гипотезу про прыжок изнутри прерывания. Она-то подтвердилась, но после прыжка извне прерываний таблицу векторов стартовый код IAR из флэша уже не копирует в оперативку. Видимо он видит, что таблица уже в оперативке... Так как обработчики я ставлю динамически, то всё заработало. Для перехода на основную прошивку из загрузчика делаю следующее: - Выставляю флаг "запуск основной прошивки" (переменная в ОЗУ, записываю туда сигнатуру типа 0xCAFEBABE). - Делаю software reset. - Загрузчик в самом начале (low_level_init()) проверяет регистр причины сброса. Если "software reset", то проверяем сигнатуру, и если есть совпадение, то затираем сигнатуру нулями и прыгаем на основную прошивку. В противном случае продолжаем исполнять код загрузчика. Таким образом основная прошивка запускается до того, как началась инициализация загрузчика. Я делаю почти так же: сигнатура в памяти, перезагрузка и проверка и затирание сигнатуры. Еще проверяю CRC прошивки перед тем как на неё перейти, а то мало ли что. low_level_init() происходит до копирования таблицы векторов прерываний в RAM. Это значит, что стартовый код основной прошивки скопирует таблицу сам, взяв её из стартового сектора. Не достанется ли ему в таком случае таблица от бутлоадера? Автор не написал, что у него за МК. К сожалению, у NXP семейства LPC175x, LPC176x не поддерживают данный способ (см. UM10360, "34.4.3.6 Application Interrupt and Reset Control Register"). Поэтому приходится делать ресет через Watchdog Timer. У меня Texas Instruments контроллер семейства Stellaris LM3S5Rхх. Довольно глючная штука. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться