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

LPC1778 не получается переместить программу

Здравствуйте уважаемые специалисты.

Использую KEIL 4.53 + LPC1778.

Столкнулся с непонятной ситуацией.

При попытке зашить программу в нужный адрес, отличный от 0 (например 0х10000)- получаю отвал PLL ну и остановку контроллера. В общем для LPC2367 я выставлял IROM1 start address 0x10000 - все было хорошо. Контроллер работал и отлаживался замечательно.

А на LPC1778 что-то не проходит такой фокус. Причем создается ощущение, что контроллер просто не запускается.

Может надо таблицу векторов перемещать, или еще что-нибудь а RAM ??? А то наблюдается полный ступор...

Если кто сталкивался, прошу помощи.

 

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


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

Может надо таблицу векторов перемещать, или еще что-нибудь а 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

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


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

Так.... Как обычно включаю экстрасенсорные способности, чтобы угадать недосказанное.... :1111493779:

Судя по этой фразе:

...

получаю отвал PLL ну и остановку контроллера.

...

у автора проблемы с запуском из под JTAG. Иначе - откуда такие выводы про PLL???

А значит - таблица векторов здесь не при чём.

При запуске из под JTAG (по-крайней мере под IAR) абсолютно параллельно что там находится по адресу 0, есть там таблица или нету.

 

Однако процессор об этом ничего не знает, после сброса будет пытаться использовать таблицу по 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;

а то кто-ж его знает - может захочется её в ОЗУ держать. Да и нафиг это делать до си-стартапа? Всё равно во время его прерывания запрещены.

 

LDR R0, =SystemInit

BLX R0

LDR R0, =__main

BX R0

А зачем BLX и BX? Вроде и обычные BL и B прекрасно достают....

 

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


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

...откуда такие выводы про PLL???

Моя интерпретация: имеется бутлоадер, использующий 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;

 

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


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

Оттуда-же откуда Ваши фантазии про бутлоадер :biggrin:

 

"...При попытке зашить программу в нужный адрес..." - означает видимо, что по "ненужному" адресу (0х00000000) присутствует бутлоадер.

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


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

Нет, не означает.

Возможно - только планируется. А пока чел пытается скомпилить и запустить рабочее ПО с того адреса JTAG-ом. Что вполне возможно.

Только возможно он забыл стереть остатки старого ПО с адреса 0, а в этом случае могут как раз и возникнуть вышеописанные проблемы. Если ROM-бутлоадер CPU увидит эти остатки во флеш, попытается стартануть это старое ПО и тут вдруг получит коннект и прошивку по JTAG... Вот после такого как раз и может снести крышу.

Так что если мои догадки верны, и попытки идут посредством JTAG, то советую предварительно стереть ВСЮ флешь CPU.

 

А вообще - гадания - вещь неблагодарная....

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


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

Может, всё хорошо, только отладчику скрипт нужен с правильными адресами?

Типа такого, только цифирьки свои вписать

/*----------------------------------------------------------------------------
* 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
[codebox] для длинного кода, [code] - для короткого!!!

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


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

Предлагаю переименовать тему в "Пасхальные гадания"

Походу - топикстартер уже давно решил свою проблему и вообще забыл об этой теме, пока мы тут распинаемся.... :rolleyes:

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


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

Большое спасибо, всем заинтересовавшимся!

ОФФТОП: Честно говоря, думал в праздники люди не читают форумы.

Постараюсь немного прояснить ситуацию.

Про PLL я решил потому, что в окне Building Output, сразу при записи программы

после фразы Application Running... появляется надпись SWD Communication Failure.

После этого пропадает генерация на кварце... Следовательно контроллер сбрасывается, а при старте PLL не конфигурируется и не запускается.

Что попробовал:

- Полностью стирал кристалл

- Комментировал область, где CRP включается.

- Менял стартовый адрес программы

 

По всей видимости надо как-то модифицировать startup...Похоже он не запускается.

 

По поводу создания секции BOOT, немного неясно. Дело в том, что для LPC2367, нечего не менял в стандартном startUPе.

Правда, компилятор использовал 4.00.

 

Пока бутлоадера нет(Планировал добавить его позже. По сути он просто делает переход программы к нужному адресу).

 

Просто пытаюсь записать код в нужную область флэша.

 

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

Это вроде логично, но сам компилятор наверное должен это сделать...

К тому же не просто так кейловцы в настройки проекта вынесли область "Read/Only Memory Areas"

А получается что она не работает... Или скорее всего, у меня что-то не работает.

 

Если не секрет, если таблица прерываний копируется в ОЗУ, то программа должна это как-то понять. Т.е. где-то должен поменяться начальный адрес таблицы?

 

 

 

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


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

Про PLL я решил потому, что в окне Building Output, сразу при записи программы

после фразы Application Running... появляется надпись SWD Communication Failure.

После этого пропадает генерация на кварце... Следовательно контроллер сбрасывается, а при старте PLL не конфигурируется и не запускается.

Может быть программа пытается запустить PLL, но делает это неправильно и МК остаётся без тактирования.

Попробуйте запустить программу убрав оттуда включение PLL, Пусть МК работает от RC.

 

По всей видимости надо как-то модифицировать startup...Похоже он не запускается.

Точку прерываний в стартап поставьте.

 

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

Это вроде логично, но сам компилятор наверное должен это сделать...

Может компилятор и всю программу сам напишет?

 

Если не секрет, если таблица прерываний копируется в ОЗУ, то программа должна это как-то понять. Т.е. где-то должен поменяться начальный адрес таблицы?

Программа сама и настроит МК на новую таблицу - скопирует её в ОЗУ и поменяет NVIC->VTOR.

 

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


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

Всё-таки попробуйте Dbg_ROM.ini подложить дебаггеру. Например, отладчик CMSIS-DAP на LPC1769 без такого скрипта начинает бродить по встроенному бутлоадеру и далее всё падает. Это если не задан переход на main, а если задан, тогда падает сразу после заливки

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


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

Про 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?

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


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

Сейчас попробовал следующий вариант:

-Полностью очистил флэш

- Записал программу с адреса 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
[codebox] для длинного кода, [code] - для короткого!!!

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


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

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

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

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

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

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

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

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

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

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