Перейти к содержанию
    

ISP бутлоaдер

МК LPC1549 – прошивка записывается (ISP бутлоaдер по CAN сети) и запускается. Нужно считать Flash для проверки. Читаю – в первой странице не то что должно быть. Защита от чтения не установлена.

Докопался до того места что для считывания первых 512 байт Flash памяти нужно в ISP загрузить кусочек кода который мапит Flash на нулевой адрес. То есть нужно в регистр SYSMEMREMAP (0x40074000 адрес) записать значение 0x02. Как это сделать?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ох, как-то замороченно у них получилось...

Оставили б альтернативные адреса (например, флеш живёт по адресу 0x0800 0000, по спец-команде дополнительно мапится на 0), и всем было б хорошо...

 

Писать/читать регистры периферии можно командами "write to ram" и "read memory".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ох, как-то замороченно у них получилось...

Оставили б альтернативные адреса (например, флеш живёт по адресу 0x0800 0000, по спец-команде дополнительно мапится на 0), и всем было б хорошо...

 

Писать/читать регистры периферии можно командами "write to ram" и "read memory".

RAM этого МК занимает адресное пространство от 0х02000000 до 0х02009000, а SYSMEMREMAP расположен в 0x40074000. "write to ram" не сработает.

 

Подглядел в дизассемблере компилятора:

//LPC_SYSCON->SYSMEMREMAP = 0x2; //change memory map 0x2 
00001d5e:   ldr r3, [pc, #148]    ; (0x1df4 <main+172>)
00001d60:   movs r2, #2
00001d62:   str r2, [r3, #0]

Наверное, можно применить следующую последовательность команд:

LDR     R0, =0x40074000; Прочитать в R0 значение регистра SYSMEMREMAP, 0x40074000 адрес
MOV     R1, #2; Загрузить в R1 значение 0x2 которое нужно записать в регистр SYSMEMREMAP        
STR     R1, [R0]; Записать значение из R1 в регистр по адресу из R0     
BX      LR; Возрат - переход по адресу, записанному в регистре LR (R14)

Как считаете?

Еще остается вопрос как из ассемблера перевести в последовательность цифр.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

RAM этого МК занимает адресное пространство от 0х02000000 до 0х02009000, а SYSMEMREMAP расположен в 0x40074000. "write to ram" не сработает.

Почему же не сработает?

Это просто инструкция ядру "запиши по адресу", дальше пусть все эти bus matrix думают, к какому именно устройству Вы хотели обратится.

 

Можно, конечно, написать микро-программку, загрузить её в ОЗУ, сказать Go(нужный адрес). Только мне неочевидно, что произойдёт после завершения этой программы. Подозреваю, обратно в загрузчик надо возвращаться принудительно.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Почему же не сработает?

Это просто инструкция ядру "запиши по адресу", дальше пусть все эти bus matrix думают, к какому именно устройству Вы хотели обратится.

 

Можно, конечно, написать микро-программку, загрузить её в ОЗУ, сказать Go(нужный адрес). Только мне неочевидно, что произойдёт после завершения этой программы. Подозреваю, обратно в загрузчик надо возвращаться принудительно.

Загружал последовательность из темы http://electronix.ru/forum/index.php?s=&am...t&p=1325093, изменял адрес на 0x40074000. В загрузчик возвращается но после этого читает не понятно что во всех секторах Flash.

С самой микро-программкой вроде понятно, даже на ассемблере можно на ваять, а перевести в числа как? Никогда такого не делал. С какой стороны подступиться?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я тоже никогда не делал.

Пришлось научиться :-)

 

Берём gcc.

Пишем:

void remap_flash ()
{
    asm volatile(
        "mov  r0, #(0x40074000 & 0xFFFF)    \r\n"
        "movt r0, #(0x40074000 >> 16)        \r\n"
        "movs r1, #2                        \r\n"
        "str r1, [r0]                        \r\n"
      );
}

Вызываем из main().

Смотрим листинг:

080103d8 <remap_flash()>:
_Z11remap_flashv():
... main.cpp:25
    asm volatile(
        "mov  r0, #(0x40074000 & 0xFFFF)    \r\n"
        "movt r0, #(0x40074000 >> 16)        \r\n"
        "movs r1, #2                        \r\n"
        "str r1, [r0]                        \r\n"
      );
80103d8:    f44f 4080     mov.w    r0, #16384; 0x4000
80103dc:    f2c4 0007     movt    r0, #16391; 0x4007
80103e0:    2102          movs    r1, #2
80103e2:    6001          str    r1, [r0, #0]
80103e4:    4770          bx    lr
80103e6:    bf00          nop

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

        "mov  r0, #(0x40074000 & 0xFFFF)    \r\n"
        "movt r0, #(0x40074000 >> 16)        \r\n"

Спасибо за науку.

А зачем разбивать запись адреса на две команды?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да это просто :-)

Длина команды thumb2 - 16 бит или 32. 32-битная константа напрямую в эту команду не влезает (нужно же место под код самой команды).

Можно положить константу рядом, и ссылаться на неё (что-то вроде LDR r0, [pc, #смещение-до константы]); компилятор так и делает.

Но руками проще загрузить в регистр за два раза, благо у кортексов команда MOVT сделана, похоже, специально для этого.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да это просто :-)

Длина команды thumb2 - 16 бит или 32. 32-битная константа напрямую в эту команду не влезает (нужно же место под код самой команды).

Можно положить константу рядом, и ссылаться на неё (что-то вроде LDR r0, [pc, #смещение-до константы]); компилятор так и делает.

Но руками проще загрузить в регистр за два раза, благо у кортексов команда MOVT сделана, похоже, специально для этого.

Да, нужно ассемблер под читать.

 

Скормил в RAM последовательность:

0x4F 0xF4 0x80 0x40 0xC4 0xF2 0x07 0x00 0x02 0x21 0x01 0x60 0x70 0x47

Все равно не читает.

Делаю по шагам:

1) Установка адреса для записи в RAM 0x02001000:

0x23 0x15 0x50 0x00 0x00 0x10 0x00 0x02

2) Команда записи данных в RAM:

0x21 0x50 0x1F 0x01

3) Запись данных в RAM 7 байт:

0x00 0x4F 0xF4 0x08 0x40 0xC4 0xF2 0x07

4) Запись данных в RAM 7 байт:

0x11 0x00 0x02 0x21 0x01 0x60 0x70 0x47

5) Задание адреса входа в программу (МК) в RAM 0x02001000:

0x23 0x70 0x50 0x01 0x00 0x10 0x00 0x02

6) Старт МК («Go»):

0x2F 0x51 0x1F 0x01 0x01 0x00 0x00 0x00

 

Ошибок не возвращает, но и в первой странице не то.

Правильно ли я интерпретировал последовательность микропрограммки?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не знаю.

Сделайте то же самое, но под отладчиком:

 

char remap_flash[] = { 0x00, 0x4F  ... };

( (void (*)(void)) remap_flash) ();

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Не знаю.

Сделайте то же самое, но под отладчиком:

 

char remap_flash[] = { 0x00, 0x4F  ... };

( (void (*)(void)) remap_flash) ();

Отладчик отрабатывает последовательность: 0xF4, 0x4F, 0x40, 0x80, 0xF2, 0xC4, 0x00, 0x07, 0x21, 0x02, 0x60, 0x01, 0x47, 0x70

и регистр SYSMEMREMAP изменяет значение на 0х2.

Посылаю эту же последовательность в МК - он ее принимает, а потом перестает отвечать, наверное нужно вернуть его в режим ISP.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, кстати. Загрузчик понимает, что код - в thumb mode, и program counter должен быть нечётным?

Попробуйте сделать GO на адрес 0x02001001

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, кстати. Загрузчик понимает, что код - в thumb mode, и program counter должен быть нечётным?

Попробуйте сделать GO на адрес 0x02001001

Проделал - МК отвечает: ошибка адреса.

 

Для возврата в ISP нужна команда Chip_IAP_ReinvokeISP(), а она опять изменит в SYSMEMREMAP значение на 0х0.

Круг какой-то.

Как же люди делают?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...