|
LPC1778 не получается переместить программу, Не могу переместить программу в нужный адрес FLASH |
|
|
|
May 8 2013, 20:23
|
Знающий
   
Группа: Участник
Сообщений: 643
Регистрация: 29-05-09
Из: Германия
Пользователь №: 49 725

|
Цитата(Metallist64 @ May 8 2013, 13:40)  Может надо таблицу векторов перемещать, или еще что-нибудь а RAM ??? А то наблюдается полный ступор... Почти правильно: надо иметь две таблицы векторов. Основная сгенерируется в рамках компиляции программы и разместится по адресу, который Вы указываете в качестве начального (Ваш пример 0х10000). Однако процессор об этом ничего не знает, после сброса будет пытаться использовать таблицу по 0х0 и уйдёт в никуда... Поэтому необходимо еще разместить минимальную таблицу векторов из двух слов по стандартному адресу загрузки: первое слово должно содержать значение для загрузки указателя стека, а второе - адрес, куда прыгать. Фактически, оба слова должны быть копией таких слов из "основной" таблицы векторов. Однако надо еще настроить и контроллер прерываний на новое место таблицы векторов путем записи ее адреса в регистр VTOR. Поэтому в startup_LPC17xx.s файле Вашего процессора начальный "загрузчик" должен будет выглядеть как: Код ...
; Vector Table Mapped to Address 0 at Reset AREA BOOT, DATA, READONLY
__Boot DCD __initial_sp ; Top of Stack DCD Reset_Handler; Reset Handler ... AREA RESET, DATA, READONLY EXPORT __Vectors
__Vectors DCD __initial_sp ; Top of Stack DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler ...
Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT __main IMPORT SystemInit MOV32 R1, #VTOR ; Load VTOR register address LDR R0, =__Vectors; Load user program vector table address STR R0, [R1] ; Store to VTOR to relocate the vector table LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP ... Но еще надо будет указать компоновщику разместить секцию BOOT по адресу 0х0. Это можно сделать, указав ему модифицированый (и переименованный!) файл *.sct, взяв за основу тот, что генерирует KEIL для проекта автоматически. Там найти что-то типа: Код LR_IROM_CODE 0х10000 0x0003F800 { ER_IROM1 0х10000 0x0003F800 { *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } } и перед ним вставить: Код LR_IROM_BOOT 0x0 0x8 { ER_IROM_BOOT 0x0 0x8 { *.o (BOOT, +First) } }
Сообщение отредактировал KnightIgor - May 8 2013, 20:30
|
|
|
|
|
May 9 2013, 15:39
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Так.... Как обычно включаю экстрасенсорные способности, чтобы угадать недосказанное.... Судя по этой фразе: Цитата(Metallist64 @ May 8 2013, 18:40)  ... получаю отвал PLL ну и остановку контроллера. ... у автора проблемы с запуском из под JTAG. Иначе - откуда такие выводы про PLL??? А значит - таблица векторов здесь не при чём. При запуске из под JTAG (по-крайней мере под IAR) абсолютно параллельно что там находится по адресу 0, есть там таблица или нету. Цитата(KnightIgor @ May 9 2013, 02:23)  Однако процессор об этом ничего не знает, после сброса будет пытаться использовать таблицу по 0х0 и уйдёт в никуда... Поэтому необходимо еще разместить минимальную таблицу векторов из двух слов по стандартному адресу загрузки: первое слово должно содержать значение для загрузки указателя стека, а второе - адрес, куда прыгать. ... Ну вот здесь Вы совсем зря обманываете товарища.... Читаем "LPC178x/7x User manual" параграф "3.10.1 PLL and startup/boot code interaction": When there is no valid user code (determined by the checksum word) in the user flash or the ISP enable pin (P2[10]) is pulled low on startup, the ISP mode will be entered and the boot code will setup the Main PLL with the IRC.а также "37.3.1.1 Criterion for Valid User Code": The reserved Cortex-M3 exception vector location 7 (offset 0x001C in the vector table) should contain the 2’s complement of the check-sum of table entries 0 through 6. This causes the checksum of the first 8 table entries to be 0. The boot loader code checksums the first 8 locations in sector 0 of the flash. If the result is 0, then execution control is transferred to the user code.Так что маловато будет ваших 2-х слов.... Да и вообще - на вышеозначенном CPU более политкорректно прописывать начало таблицы в NVIC таким макаром: Код u32 j; if ((j = (u32)&__Vectors) >= 0x20000000) j |= B29; NVIC.VTABLE = j; а то кто-ж его знает - может захочется её в ОЗУ держать. Да и нафиг это делать до си-стартапа? Всё равно во время его прерывания запрещены. Цитата(KnightIgor @ May 9 2013, 02:23)  LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 А зачем BLX и BX? Вроде и обычные BL и B прекрасно достают....
|
|
|
|
|
May 9 2013, 17:20
|
Местный
  
Группа: Свой
Сообщений: 480
Регистрация: 21-11-04
Пользователь №: 1 188

|
...откуда такие выводы про PLL??? [/quote] Моя интерпретация: имеется бутлоадер, использующий PLL. В основной программе также присутствует инициализация PLL, в теле которой пррграмма глочнет. Известная (мне) проблема: перед переходом PLL надо заглушить. Типа: Код LPC_SC->CCLKSEL = 0x01; // set sysclk (12MHz) as clock source LPC_SC->PLL0CON = 0; // disable PLL LPC_SC->PLL0FEED = 0xAA; LPC_SC->PLL0FEED = 0x55; [quote name='jcxz' date='May 9 2013, 18:39' post='1160992']
|
|
|
|
|
May 12 2013, 05:01
|
Профессионал
    
Группа: Свой
Сообщений: 1 266
Регистрация: 22-04-05
Из: Киев
Пользователь №: 4 387

|
Может, всё хорошо, только отладчику скрипт нужен с правильными адресами? Типа такого, только цифирьки свои вписать CODE /*---------------------------------------------------------------------------- * Name: Dbg_ROM.ini * Purpose: ROM Debug Initialization File * Note(s): *---------------------------------------------------------------------------- * This file is part of the uVision/ARM development tools. * This software may only be used under the terms of a valid, current, * end user licence from KEIL for a compatible version of KEIL software * development tools. Nothing else gives you the right to use this software. * * This software is supplied "AS IS" without warranties of any kind. * * Copyright © 2008-2011 Keil - An ARM Company. All rights reserved. *----------------------------------------------------------------------------*/
/*---------------------------------------------------------------------------- Setup() configure PC & SP for RAM Debug *----------------------------------------------------------------------------*/ FUNC void Setup (void) { SP = _RDWORD(0x00000000); // Setup Stack Pointer PC = _RDWORD(0x00000004); // Setup Program Counter _WDWORD(0xE000ED08, 0x00000000); // Setup Vector Table Offset Register //_WDWORD(0x400FC0C4, _RDWORD(0x400FC0C4) | 1<<12); // Enable ADC Power //_WDWORD(0x40034034, 0x00000F00); // Setup ADC Trim }
LOAD %L INCREMENTAL // load the application
Setup(); // Setup for Running
g, main
Сообщение отредактировал IgorKossak - May 13 2013, 07:07
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
--------------------
aka Vit
|
|
|
|
|
May 12 2013, 14:51
|
Частый гость
 
Группа: Участник
Сообщений: 103
Регистрация: 29-01-08
Пользователь №: 34 558

|
Большое спасибо, всем заинтересовавшимся! ОФФТОП: Честно говоря, думал в праздники люди не читают форумы. Постараюсь немного прояснить ситуацию. Про PLL я решил потому, что в окне Building Output, сразу при записи программы после фразы Application Running... появляется надпись SWD Communication Failure. После этого пропадает генерация на кварце... Следовательно контроллер сбрасывается, а при старте PLL не конфигурируется и не запускается. Что попробовал: - Полностью стирал кристалл - Комментировал область, где CRP включается. - Менял стартовый адрес программы
По всей видимости надо как-то модифицировать startup...Похоже он не запускается.
По поводу создания секции BOOT, немного неясно. Дело в том, что для LPC2367, нечего не менял в стандартном startUPе. Правда, компилятор использовал 4.00.
Пока бутлоадера нет(Планировал добавить его позже. По сути он просто делает переход программы к нужному адресу).
Просто пытаюсь записать код в нужную область флэша.
Немного не понял, про то, что надо контроллер прерываний перенастраивать на новую таблицу... Это вроде логично, но сам компилятор наверное должен это сделать... К тому же не просто так кейловцы в настройки проекта вынесли область "Read/Only Memory Areas" А получается что она не работает... Или скорее всего, у меня что-то не работает.
Если не секрет, если таблица прерываний копируется в ОЗУ, то программа должна это как-то понять. Т.е. где-то должен поменяться начальный адрес таблицы?
|
|
|
|
|
May 12 2013, 15:03
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Metallist64 @ May 12 2013, 17:51)  Про PLL я решил потому, что в окне Building Output, сразу при записи программы после фразы Application Running... появляется надпись SWD Communication Failure. После этого пропадает генерация на кварце... Следовательно контроллер сбрасывается, а при старте PLL не конфигурируется и не запускается. Может быть программа пытается запустить PLL, но делает это неправильно и МК остаётся без тактирования. Попробуйте запустить программу убрав оттуда включение PLL, Пусть МК работает от RC. Цитата(Metallist64 @ May 12 2013, 17:51)  По всей видимости надо как-то модифицировать startup...Похоже он не запускается. Точку прерываний в стартап поставьте. Цитата(Metallist64 @ May 12 2013, 17:51)  Немного не понял, про то, что надо контроллер прерываний перенастраивать на новую таблицу... Это вроде логично, но сам компилятор наверное должен это сделать... Может компилятор и всю программу сам напишет? Цитата(Metallist64 @ May 12 2013, 17:51)  Если не секрет, если таблица прерываний копируется в ОЗУ, то программа должна это как-то понять. Т.е. где-то должен поменяться начальный адрес таблицы? Программа сама и настроит МК на новую таблицу - скопирует её в ОЗУ и поменяет NVIC->VTOR.
|
|
|
|
|
May 12 2013, 15:47
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Metallist64 @ May 12 2013, 20:51)  Про PLL я решил потому, что в окне Building Output, сразу при записи программы после фразы Application Running... появляется надпись SWD Communication Failure. После этого пропадает генерация на кварце... Следовательно контроллер сбрасывается, а при старте PLL не конфигурируется и не запускается. Ну вот - опять по крупицам.... Вы зашиваете чем? По SWD? и сразу после этого, ещё до запуска программы у вас эта ошибка? Значит у вас что не так с работой этого самого SWD. По крайней мере под IAR+JTAG и при убранной галке "идти к main", картина должна выглядеть так: загружаем ПО во флешь и сразу после загрузки видим в окне, что управление стоит на точке, адрес которой указан во втором элементе таблицы прерываний. Таблица прерываний должна начинаться с метки __vector_table ;The name "__vector_table" has special meaning for C-SPY: ;it is where the SP start value is found, and the NVIC vector ;table register (VTOR) is initialized to this address if != 0.Всё. Дальше можно начинать трассировать или просто запустить на исполнение. Причём стартовый адрес загрузки может быть любым, и даже в ОЗУ, и содержимое начальной части флешь почти безразлично - картина от этого не меняется. "Почти" - потому что иногда это не срабатывает, видимо потому, что если с начала флеш есть остатки какого-то ПО, до того как JTAG подключается к CPU, этот код может успеть запуститься, что-то сконфигурить (тот же самый PLL), после этого JTAG делает попытку подключения и не всегда это ему удаётся (как я понимаю - смотря как JTAG подключается и какой тип ресета при этом он использует). В таком случае помогает простое стирание всего флеш. Тогда управление при включении питания никуда не передаётся, а остётся в ROM-бутлоадере CPU. Если у вас не так, то у вас что-то не так с настройкой SWD или с таблицей прерываний (или откуда там SWD берёт стартовый адрес). Да, кстати - а вы учли, что адрес этой самой таблицы прерываний должен быть выровнен на 2^6?
|
|
|
|
|
May 13 2013, 06:41
|
Частый гость
 
Группа: Участник
Сообщений: 103
Регистрация: 29-01-08
Пользователь №: 34 558

|
Сейчас попробовал следующий вариант: -Полностью очистил флэш - Записал программу с адреса 0х0. Все работает отладчик отлаживает(использую SWD), на кварце генерация есть. Все работает. Затем просто меняю адрес в настройках проекта. Ставлю например 0х1000. Компилирую. Пытаюсь запустить debug сессию - и все. Программа прошивается, верифицируется и появляется надпись : SWD Communication Failure. На этом все заканчивается, сессия конечно не запускается. Следовательно, посмотреть как стартует программа не получается. Попробовал запустить в симуляторе. Там видно что программа крутится в адресе 0х00000000 и не уходит из него. В обще в окне дизассеблера, первая строка: Код 0x00000000 0000 MOVS r0,r0 А если адрес в настройках проекта оставить 0х0, то первая инструкция получается: Код 0x00000000 0670 DCW 0x0670 И видно, что программа идет дальше и пытается конфигурировать PLL. В общем наблюдается следующая картина. Если указать, что адрес программы должен начинаться с 0х10, то в окошке дизассемблера адреса с 0х0 по 0хЕ забиты одними и теме же инструкциями: Код 0x00000000 0000 MOVS r0,r0 Но с адреса 0х0 программа не уходит... Такое ощущение, что какого-то перехода просто не хватает, типа RJMP на нужный адрес...
Сообщение отредактировал IgorKossak - May 13 2013, 07:10
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|