Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: TI AM1808 Program Reset
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
doom13
Приветствую!
Хочу реализовать программный сброс процессора, но не могу подобрать нужную команду.

Можно сделать что-то типа:
Код
asm(" .ref Entry");
asm(" b Entry");

программа должна перезапуститься, но в моём случае не работает (только перейдёт на Entry и куда-то улетит), как понимаю надо ещё что-то почистить или сбросить, сделать аналог "System Reset" из CCS и перезапустить программу.

А как сделать, чтобы программа перешла на адреса встроенного ROM загрузчика и уже в соответствии с выбранным режимом загрузки перезагрузила прошивку и стартанула её?
Пока что-то не получаетсяsad.gif
jcxz
Используйте встроенный сторожевик для сброса.
doom13
Цитата(jcxz @ Nov 18 2014, 06:39) *
Используйте встроенный сторожевик для сброса.

Это можно, но хочется чтобы была команда, которая приходит, например, по ethernet. Как-то ведь можно, используя ассм, это сделать (всегда делал для других процов от TI). Нужно только описать переход на адрес, думаю, адрес ROM загрузчика 0xFFFD0000 должен подойти, но пока не могу разобраться, какую команду (или несколько команд) использовать.
Например для с28346 было:
Код
int restart()
{
    DINT;

    asm(" .ref _c_int00\n\t LB _c_int00");

    return 0;
}

int reset()
{
    DINT;
    PieCtrlRegs.PIECTRL.bit.ENPIE = 0;

    asm(" LB 0x003FFFC0");

    return 0;
}

Вопрос, как сделать для данного процессора нечто подобное?
jcxz
Цитата(doom13 @ Nov 18 2014, 12:25) *
Это можно, но хочется чтобы была команда, которая приходит, например, по ethernet. Как-то ведь можно

Пришла команда - пишете в WD недопустимую последовательность - сразу получаете аппаратный RESET.
В чём проблема?
Обратите внимание на выделенное жирным. Это в 100 раз надёжнее и достовернее любых программных рестартов, так как заведомо переводит весь МК в начальное состояние.
Чего Вы своим программным переходом не делаете.
doom13
Цитата(jcxz @ Nov 18 2014, 11:27) *
Пришла команда - пишете в WD недопустимую последовательность - сразу получаете аппаратный RESET.
В чём проблема?
Обратите внимание на выделенное жирным. Это в 100 раз надёжнее и достовернее любых программных рестартов, так как заведомо переводит весь МК в начальное состояние.
Чего Вы своим программным переходом не делаете.

Попробую такой вариант, спасибо, но всё же интересно, как ассмом можно его перенаправить на ROM загрузчик?
Пока делаю так:
Код
// reset.c
int reset()
{
    asm(" .ref RstHandler");
    asm(" b RstHandler");
    return 0;
}

попадаем:
Код
;reset.asm
    .global RstHandler
    .global ADDR_BOOTROM

ADDR_BOOTROM .word 0xFFFD0000

RstHandler:
;    LDR      r0, ADDR_BOOTROM
;    LDR      r1, [r0]
;    LDR      pc, [r0]

Как правильно написать то, что после RstHandler: ?

Да, мне кажется (возможно ошибаюсь), если перейти на код и заставить выполниться встроенный ROM-загрузчик, то это и будет аналог аппаратного сброса???
jcxz
Цитата(doom13 @ Nov 18 2014, 14:55) *
Попробую такой вариант, спасибо, но всё же интересно, как ассмом можно его перенаправить на ROM загрузчик?

Восстановить состояние регистров управления процессором в исходное состояние (такое, какое должно быть после подачи сигнала RESET).
Восстановить состояние периферии на исходное (прерывание, управление питанием, PLL, MPU/MMU, кеши и т.п.).
...(что-то ещё восстановить).
И только после этого можно делать RESET.

Я уже Вам написал что это в 100 раз сложнее чем 2 строчки которые у Вас, а Вы не верите....
doom13
Цитата(jcxz @ Nov 18 2014, 12:07) *
Восстановить состояние регистров управления процессором в исходное состояние (такое, какое должно быть после подачи сигнала RESET).
Восстановить состояние периферии на исходное (прерывание, управление питанием, PLL, MPU/MMU, кеши и т.п.).
И только после этого можно делать RESET.

Тут понятно, что это должно быть сделано. Поэтому мой переход на Entry и не запускается, что что-то там (всё) не очищено и не сброшено в начальное состояние.

Цитата(jcxz @ Nov 18 2014, 12:07) *
Я уже Вам написал что это в 100 раз сложнее чем 2 строчки которые у Вас, а Вы не верите....

Тут я понял, что использовать WD - это проще, но вот пока ещё хочется понять как его загнать на адреса встроенного загрузчика.
Две строчки - это рестарт того, что уже лежит в RAM, а вот две строчки, которые перенаправят его на встроенный загрузчик, думаю, спасли бы ситуацию, но пока не пойму какие команды и как использовать.
jcxz
Цитата(doom13 @ Nov 18 2014, 15:16) *
Тут я понял, что использовать WD - это проще, но вот пока ещё хочется понять как его загнать на адреса встроенного загрузчика.

Это несложно.
Для Thumb-2 системы команд (Cortex-M):
Код
typedef void (* EntryTyp)();
#define Entry ((EntryTyp)0xFFFD0001)  
Entry();

Для ARM-системы команд - с ноликом в мл. бите.
doom13
Цитата(jcxz @ Nov 18 2014, 12:34) *

Спасибо, то что надо. Это работает (прошивку перезаливает), но надо ему ещё что-то "обнулить", а то не стартанёт нормально загруженную прошивку. Не подскажете, что конкретно?


Нашёл кусок кода, что ему мешает после перезагрузки прошивки с внешней SPI-флэшки нормально работать. Проблема старая (спрашивал тут(сообщение №69), но никто не ответил), во всём оказывается виноват McBSP и его прерывания. Пробовал чистить все его регистры (McBSP), но не помогает, ещё что-то надо стереть. Что? Если убрать настройку прерываний от McBSP, то приведённый выше код перезальёт прошивку и она нормально запустится.

Ещё хочу спросить, что неправильно в моём коде и почему он не хочет компилиться?
Выше приводил переход на RstHandler: , это работает. Далее пытался сделать:
Код
RstHandler:
    B    0xFFFD0000

, но это компилиться не хочет, пишет
Цитата
Illegal operand
B 0xFFFD0000
.
Почему так? Если нажму кнопку Reset на плате, процессор станет на адрес 0xFFFF0000.
Смотрю дизассм и вижу:
Цитата
ffff0000: EAFF7FFE B 0xFFFD0000

, т.е. что я и пытался сделать, используется та же инструкция, почему в моём случае не захотело компилиться?
Если далее нажму "F5" в CCS, то перейдёт на адрес 0xFFFD0000, где ещё один бранч на следующий адрес.
Где может быть проблема?
jcxz
B - это прямой переход. В команде адрес назначения кодируется как смещение к PC.
А Вам нужен косвенный (BX):
LDR R0, p1
BX R0

для IAR:
p1 DC32 0xFFFD0000
для CCS:
p1 .long 0xFFFD0000
(если Thumb-2 - не забываем про мл. бит)

PS: Что ещё надо проинитить я не знаю. Не знаком с данным МК.
SM
Цитата(doom13 @ Nov 18 2014, 14:17) *
Где может быть проблема?


Проблема в расстоянии от команды перехода до точки назначения. Для далеких переходов следует использовать нечто типа:

LDR PC, JmpAddr

JmpAddr: .word 0xFFFD0000

или, если предполагается переключение ARM <=> THUMB, то

LDR R0, JmpAddr
BX R0
JmpAddr: .word 0xFFFD0000



UPD:
А вообще, я бы покопал на тему захода в SwRstDisable ARM-а (PSC0/LPSC14) - это было бы пожестче, если реализуемо.
doom13
Цитата(jcxz @ Nov 18 2014, 14:31) *
B - это прямой переход. В команде адрес назначения кодируется как смещение к PC.
А Вам нужен косвенный (BX):
LDR R0, p1
BX R0

для IAR:
p1 DC32 0xFFFD0000
для CCS:
p1 .long 0xFFFD0000
(если Thumb-2 - не забываем про мл. бит)

PS: Что ещё надо проинитить я не знаю. Не знаком с данным МК.


Спасибо, почитал, кто такой
Цитата
BX{cond} Rm
, получается - это и есть переход на адрес, который содержится в Rm (затупил, несколько раз просматривал все бранчи, но не нашёл нужную инструкцию).
Тогда не понимаю почему после ресета по адресу 0xFFFF0000 лежит просто
Цитата
B 0xFFFD0000
(согласно дизассму CCS), ведь это НЕПРАВИЛЬНАЯ инструкция!!?? Ведь B - это переход на label, а константа 0xFFFD0000 и будет для него illegal operand??? Или здесь он уже пересчитал адрес label и показал куда будет переходить?

Остаётся "старый" вопрос, что нужно почистить/занулить/сбросить, чтобы программа нормально стартовала после перезагрузки? Пытаюсь разобраться, если кто подскажет, буду благодарен.
SM
Цитата(doom13 @ Nov 18 2014, 15:04) *
Ведь B - это переход на label, а константа 0xFFFD0000 и будет для него illegal operand???

Я выше написал - весь вопрос в расстоянии от команды перехода до точки, куда переходить. На "короткие" расстояния - дотягивает команда B/BX label. На длинные - уже B/BX Rx нужна, или LDR PC,xxxx
doom13
Цитата(SM @ Nov 18 2014, 15:31) *

Не заметил Ваш пост выше
Цитата(SM @ Nov 18 2014, 14:33) *
Проблема в расстоянии от команды перехода до точки назначения. Для далеких переходов следует использовать нечто типа:

LDR PC, JmpAddr

JmpAddr: .word 0xFFFD0000

или, если предполагается переключение ARM <=> THUMB, то

LDR R0, JmpAddr
BX R0
JmpAddr: .word 0xFFFD0000



UPD:
А вообще, я бы покопал на тему захода в SwRstDisable ARM-а (PSC0/LPSC14) - это было бы пожестче, если реализуемо.

Это тоже работает, спасибо, не мог понять, как в программный счётчик запихнуть адрес 0xFFFD0000, пробовал почти то что и надо LDR PC, 0xFFFD0000, но немного не то sad.gif

Цитата(SM @ Nov 18 2014, 15:31) *
весь вопрос в расстоянии от команды перехода до точки, куда переходить. На "короткие" расстояния - дотягивает команда B/BX label. На длинные - уже B/BX Rx нужна, или LDR PC,xxxx

Тут что-то не понимаю, как оно может скомпилить код B 0xFFFD0000? Или это только то что я вижу в CCS Disassembly, на самом деле было что-то типа:

Код
boot_label:
...
   B boot_label
...

, где boot_label = 0xFFFD0000?
SM
Цитата(doom13 @ Nov 18 2014, 16:08) *
, где boot_label = 0xFFFD0000?


любая метка есть символьное обозначение какого-то, вполне определенного, числа... Это эквивалентно, что метку поставить, что метку определить через .set, что число указать. Однако, если комипилятор видит, что инструкция "не дотянется" до адреса, он ее и обругает.

А LDR можно еще написать как

LDR PC, =0xFFFD0000

компилятор должен сам это переделать в

LDR PC,label

[.....]
label: .word 0xFFFD0000
doom13
Цитата(SM @ Nov 18 2014, 16:16) *

Счас понял, о чём Вы говорите. Я пытался сделать
Код
   B 0xFFFD0000
,
но это неправильный синтаксис и оно ругалось. Можно сделать правильно:
Код
BootRom:    .long 0xFFFD0000
B        BootRom

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

Цитата(SM @ Nov 18 2014, 16:16) *
А LDR можно еще написать как

LDR PC, =0xFFFD0000

А вот это я пробовал и ещё раз проверил, не компилится оно у меня!?
CODE

"../source/sys/progrst.asm", ERROR! at line 15: [E0200] Bad term in expression
3 Assembly Errors, No Assembly Warnings
LDR pc, =0xFFFD0000


>> Compilation failure
"../source/sys/progrst.asm", ERROR! at line 15: [E0001] Illegal symbol
LDR pc, =0xFFFD0000

"../source/sys/progrst.asm", ERROR! at line 15: [E0003] Unexpected trailing operand(s)
LDR pc, =0xFFFD0000
jcxz
Цитата(doom13 @ Nov 18 2014, 19:08) *
Тут что-то не понимаю, как оно может скомпилить код B 0xFFFD0000? Или это только то что я вижу в CCS Disassembly, на самом деле было что-то типа:

Да, скорей всего именно так. Он просто Вам показывает целевой адрес. Если-бы он показывал смещения (как в коде команды) было-бы очень неудобно высчитывать куда направлен переход.
SM
BootRom: .long.set 0xFFFD0000
B BootRom

а что с "=" не компилируется, это уже компиляторозависимо. Не каждый транслятор это поймет.


UPD
или, вот так (GNU-тый as):
.set BootRom, 0xFFFD0000
я путаю разные синтаксисы от разных ассемблеров...
doom13
Цитата(jcxz @ Nov 18 2014, 06:39) *
Используйте встроенный сторожевик для сброса.

Затестил, всё просто, работает без очистки и установки регистров в начальное состояние.
Но, всё равно ещё интересно, что надо обнулять для нормального перезапуска и это:
Цитата(SM @ Nov 18 2014, 14:33) *
А вообще, я бы покопал на тему захода в SwRstDisable ARM-а (PSC0/LPSC14) - это было бы пожестче, если реализуемо.

SM
проверил - компилируется (компилятор gcc 4.7.7, ассемблер из него)....

LDR PC, =0xFFFD0000

листинг:

Код
  20                  .globl _start
  21                  _start:
  22:/home/s-markov/Linux_psp/sau-load/preload/start.S ****     ldr    r3, _start_armboot
  23:/home/s-markov/Linux_psp/sau-load/preload/start.S ****     bx    r3
  24                  
  25:/home/s-markov/Linux_psp/sau-load/preload/start.S ****     ldr    pc, =0xFFFD0000
  26                  
  27 000c 00000000     _start_armboot:        .word start_armboot
  28                  
  29                              .globl    _end
  30 0010 00000000     _end:            .word    __end
  31                              .globl    _code_len
  32 0014 18000000     _code_len:        .word    __end - _start + 4
  32      0000FDFF


отлично видно, что число 0xFFFD0000 он сам разместил в конце как слово данных. Кодов операции нету, что тоже понятно, их линкер только сформирует.

Цитата(doom13 @ Nov 18 2014, 17:18) *
что надо обнулять для нормального перезапуска

Надо, как минимум, перевести все LPSC в состояния "power-on", по сути, обресетить периферию.
doom13
Цитата(SM @ Nov 18 2014, 17:33) *

У меня компилер TI v5.1.1 в настройках пректа стоит, наверное, поэтому и не компилится данная инструкция.

Цитата(SM @ Nov 18 2014, 17:33) *
Надо, как минимум, перевести все LPSC в состояния "power-on", по сути, обресетить периферию.

Попробовал перед переходом на BOOTROM загнать все PSC модули в состояние SwRstDisable state, работает, но иногда, при нескольких последовательных ресетах может повиснуть.
SM
Цитата(doom13 @ Nov 18 2014, 18:04) *
загнать все PSC модули в состояние SwRstDisable

Ну надо не все, а по списку из TRM, только те, которые по дефолту в этом состоянии.
doom13
Цитата(SM @ Nov 18 2014, 18:32) *
Ну надо не все, а по списку из TRM, только те, которые по дефолту в этом состоянии.

Ну не совсем все, SPI1 оставил - с него прошивка грузится и при его состоянии SwRstDisable загрузчик перестаёт работать, хотя должен был бы сам настроить его в нужное состояние (Enable). Проверю ещё кто должен быть по дефолту в состоянии сброса, спасибо.
jcxz
Цитата(doom13 @ Nov 19 2014, 00:23) *
Ну не совсем все, SPI1 оставил - с него прошивка грузится и при его состоянии SwRstDisable загрузчик перестаёт работать, хотя должен был бы сам настроить его в нужное состояние (Enable). Проверю ещё кто должен быть по дефолту в состоянии сброса, спасибо.

Логично, но почему-то до бутописателей это не доходит.... sad.gif
Сам сталкивался на OMAP L137 с подобной проблемой:
Загрузка идёт с внешней SPI-Flash микросхемы, после старта firmware и чтения конфига с той-же flash, перевожу её командой в Power Down (вроде ведь логично если такая функция есть в микросхеме и она больше не нужна ?). Но после этого, если подать HW RESET на OMAP, он больше не грузится с flash (грузится только после выкл./вкл. питания).
Если не подавать Power Down, то всё ок (а если она в Power Down, то она не отвечает ни на какие команды до команды Power Up).
Значит писатели встроенного бутлоадера не додумались, что флешка может быть в Power Down. sad.gif(((((
А вроде такая очевидная вещь....
doom13
Цитата(jcxz @ Nov 19 2014, 10:59) *

Согласно даташиту на мой процессор, его SPI1 по дефолту находится в состоянии SwRstDisable. Вот тут-то и вопрос - кто его загнал в это состояние? Если это ROM загрузчик до передачи управления моей программе (т.е. для ROM загрузчика дефолтное состояние - включено), тогда всё понятно, если я его выключаю и передаю управление ROM загрузчику, то он и дохнет. Но если дефолтное состояние SwRstDisable - это для загрузчика, то он должен включать данный модуль и моё выключение на него влиять не должно.
SM
Цитата(doom13 @ Nov 19 2014, 12:45) *
Но если дефолтное состояние SwRstDisable - это для загрузчика, то он должен включать данный модуль и моё выключение на него влиять не должно.

Скорее всего, загрузчик считывает, что за резет был, и если это не POR, то делает значительно меньше инициализаций. Однако, без дизассемблера это не понять.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.