|
|
  |
ISP бутлоaдер, Не читает стартовую страницу из Flash памяти |
|
|
|
Mar 18 2016, 08:21
|
Местный
  
Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482

|
Цитата(esaulenka @ Mar 18 2016, 10:27)  Ох, как-то замороченно у них получилось... Оставили б альтернативные адреса (например, флеш живёт по адресу 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) Как считаете? Еще остается вопрос как из ассемблера перевести в последовательность цифр.
|
|
|
|
|
Mar 18 2016, 08:54
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Цитата(kolisnichenko_r @ Mar 18 2016, 11:21)  RAM этого МК занимает адресное пространство от 0х02000000 до 0х02009000, а SYSMEMREMAP расположен в 0x40074000. "write to ram" не сработает. Почему же не сработает? Это просто инструкция ядру "запиши по адресу", дальше пусть все эти bus matrix думают, к какому именно устройству Вы хотели обратится. Можно, конечно, написать микро-программку, загрузить её в ОЗУ, сказать Go(нужный адрес). Только мне неочевидно, что произойдёт после завершения этой программы. Подозреваю, обратно в загрузчик надо возвращаться принудительно.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Mar 18 2016, 09:05
|
Местный
  
Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482

|
Цитата(esaulenka @ Mar 18 2016, 11:54)  Почему же не сработает? Это просто инструкция ядру "запиши по адресу", дальше пусть все эти bus matrix думают, к какому именно устройству Вы хотели обратится.
Можно, конечно, написать микро-программку, загрузить её в ОЗУ, сказать Go(нужный адрес). Только мне неочевидно, что произойдёт после завершения этой программы. Подозреваю, обратно в загрузчик надо возвращаться принудительно. Загружал последовательность из темы http://electronix.ru/forum/index.php?s=&am...t&p=1325093, изменял адрес на 0x40074000. В загрузчик возвращается но после этого читает не понятно что во всех секторах Flash. С самой микро-программкой вроде понятно, даже на ассемблере можно на ваять, а перевести в числа как? Никогда такого не делал. С какой стороны подступиться?
|
|
|
|
|
Mar 18 2016, 10:17
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Я тоже никогда не делал. Пришлось научиться :-) Берём 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
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Mar 18 2016, 10:53
|
Местный
  
Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482

|
Цитата(esaulenka @ Mar 18 2016, 13:17)  Код "mov r0, #(0x40074000 & 0xFFFF) \r\n" "movt r0, #(0x40074000 >> 16) \r\n" Спасибо за науку. А зачем разбивать запись адреса на две команды?
|
|
|
|
|
Mar 18 2016, 12:07
|
Местный
  
Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482

|
Цитата(esaulenka @ Mar 18 2016, 14:27)  Да это просто :-) Длина команды 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 Ошибок не возвращает, но и в первой странице не то. Правильно ли я интерпретировал последовательность микропрограммки?
|
|
|
|
|
Mar 18 2016, 12:57
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Не знаю. Сделайте то же самое, но под отладчиком: Код char remap_flash[] = { 0x00, 0x4F ... };
( (void (*)(void)) remap_flash) ();
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Mar 18 2016, 13:36
|
Местный
  
Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482

|
Цитата(esaulenka @ Mar 18 2016, 15:57)  Не знаю. Сделайте то же самое, но под отладчиком: Код 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.
|
|
|
|
|
Mar 18 2016, 14:13
|
Местный
  
Группа: Свой
Сообщений: 435
Регистрация: 12-09-07
Пользователь №: 30 482

|
Цитата(esaulenka @ Mar 18 2016, 16:56)  Да, кстати. Загрузчик понимает, что код - в thumb mode, и program counter должен быть нечётным? Попробуйте сделать GO на адрес 0x02001001 Проделал - МК отвечает: ошибка адреса. Для возврата в ISP нужна команда Chip_IAP_ReinvokeISP(), а она опять изменит в SYSMEMREMAP значение на 0х0. Круг какой-то. Как же люди делают?
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|