Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC1778 не получается переместить программу
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Metallist64
Здравствуйте уважаемые специалисты.
Использую KEIL 4.53 + LPC1778.
Столкнулся с непонятной ситуацией.
При попытке зашить программу в нужный адрес, отличный от 0 (например 0х10000)- получаю отвал PLL ну и остановку контроллера. В общем для LPC2367 я выставлял IROM1 start address 0x10000 - все было хорошо. Контроллер работал и отлаживался замечательно.
А на LPC1778 что-то не проходит такой фокус. Причем создается ощущение, что контроллер просто не запускается.
Может надо таблицу векторов перемещать, или еще что-нибудь а RAM ??? А то наблюдается полный ступор...
Если кто сталкивался, прошу помощи.
KnightIgor
Цитата(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)
  }
}
jcxz
Так.... Как обычно включаю экстрасенсорные способности, чтобы угадать недосказанное.... 1111493779.gif
Судя по этой фразе:
Цитата(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 прекрасно достают....
Axel
...откуда такие выводы про 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']
jcxz
Оттуда-же откуда Ваши фантазии про бутлоадер biggrin.gif
Axel
Цитата(jcxz @ May 9 2013, 20:56) *
Оттуда-же откуда Ваши фантазии про бутлоадер biggrin.gif


"...При попытке зашить программу в нужный адрес..." - означает видимо, что по "ненужному" адресу (0х00000000) присутствует бутлоадер.
jcxz
Нет, не означает.
Возможно - только планируется. А пока чел пытается скомпилить и запустить рабочее ПО с того адреса JTAG-ом. Что вполне возможно.
Только возможно он забыл стереть остатки старого ПО с адреса 0, а в этом случае могут как раз и возникнуть вышеописанные проблемы. Если ROM-бутлоадер CPU увидит эти остатки во флеш, попытается стартануть это старое ПО и тут вдруг получит коннект и прошивку по JTAG... Вот после такого как раз и может снести крышу.
Так что если мои догадки верны, и попытки идут посредством JTAG, то советую предварительно стереть ВСЮ флешь CPU.

А вообще - гадания - вещь неблагодарная....
sensor_ua
Может, всё хорошо, только отладчику скрипт нужен с правильными адресами?
Типа такого, только цифирьки свои вписать
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
jcxz
Предлагаю переименовать тему в "Пасхальные гадания"
Походу - топикстартер уже давно решил свою проблему и вообще забыл об этой теме, пока мы тут распинаемся.... rolleyes.gif
Metallist64
Честно говоря, топикстартер пытается понять, что ему ответили...


Metallist64
Большое спасибо, всем заинтересовавшимся!
ОФФТОП: Честно говоря, думал в праздники люди не читают форумы.
Постараюсь немного прояснить ситуацию.
Про PLL я решил потому, что в окне Building Output, сразу при записи программы
после фразы Application Running... появляется надпись SWD Communication Failure.
После этого пропадает генерация на кварце... Следовательно контроллер сбрасывается, а при старте PLL не конфигурируется и не запускается.
Что попробовал:
- Полностью стирал кристалл
- Комментировал область, где CRP включается.
- Менял стартовый адрес программы

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

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

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

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

Немного не понял, про то, что надо контроллер прерываний перенастраивать на новую таблицу...
Это вроде логично, но сам компилятор наверное должен это сделать...
К тому же не просто так кейловцы в настройки проекта вынесли область "Read/Only Memory Areas"
А получается что она не работает... Или скорее всего, у меня что-то не работает.

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


_Артём_
Цитата(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.
sensor_ua
Всё-таки попробуйте Dbg_ROM.ini подложить дебаггеру. Например, отладчик CMSIS-DAP на LPC1769 без такого скрипта начинает бродить по встроенному бутлоадеру и далее всё падает. Это если не задан переход на main, а если задан, тогда падает сразу после заливки
jcxz
Цитата(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?
Metallist64
Сейчас попробовал следующий вариант:
-Полностью очистил флэш
- Записал программу с адреса 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 на нужный адрес...
KnightIgor
Цитата(Metallist64 @ May 13 2013, 07:41) *
Попробовал запустить в симуляторе. Там видно что программа крутится в адресе 0х00000000 и не уходит из него.
В обще в окне дизассеблера, первая строка:
Такое ощущение, что какого-то перехода просто не хватает, типа RJMP на нужный адрес...

Вот по этому поводу я и распинался в сообщении №2. Ну не знают компилятор и компоновщик, что Вы хотите! Не будут они прописывать за Вас таблицы векторов, а процессор после сброса ВСЕГДА лезет по адресу 0х0 и загружает оттуда SP и PC. Сделайте, как я посоветовал. Это проверено.
jcxz
Цитата(KnightIgor @ May 13 2013, 16:14) *
а процессор после сброса ВСЕГДА лезет по адресу 0х0 и загружает оттуда SP и PC. Сделайте, как я посоветовал. Это проверено.
А вот передо мной сейчас лежит устройство как раз на LPC1778, только подключено к IAR через JTAG. Стираю FlashMagic-ом ВСЮ память, прошиваю через JTAG начиная с 0x00001000, стартую (из под JTAG) - и удивительно - ПО прекрасно работает. Наверное оно не знает, что у него первые 0x1000 байт забиты 0xFF, если бы знало - точно не работало-бы! smile3046.gif
Metallist64
Цитата(jcxz @ May 13 2013, 15:18) *
А вот передо мной сейчас лежит устройство как раз на LPC1778, только подключено к IAR через JTAG. Стираю FlashMagic-ом ВСЮ память, прошиваю через JTAG начиная с 0x00001000, стартую (из под JTAG) - и удивительно - ПО прекрасно работает. Наверное оно не знает, что у него первые 0x1000 байт забиты 0xFF, если бы знало - точно не работало-бы! smile3046.gif


А вы в настройках проекта просто указываете с какого адреса шить? В самой программе ничего не меняете?
jcxz
Меняется только адрес начала флеш-памяти, описанный в icf-файле (командный файл линкёра). Больше ничего.
Metallist64
Цитата(sensor_ua @ May 12 2013, 08:01) *
Может, всё хорошо, только отладчику скрипт нужен с правильными адресами?
Типа такого, только цифирьки свои вписать
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


Может быть, на сайте поддержки Keil сказали, что надо правильные адреса задать.
Только как понять, что куда записывать?
В PC я так понимаю надо начальный адрес программы записать.
А что надо записать в указатель стека?
Плюс еще команда неясная : _WDWORD(0xE000ED08, 0x00000000); // Setup Vector Table Offset Register

Может кто-нибудь сможет объяснить? А то смотрю на все это - как баран на новые ворота...

sensor_ua
Вот, например, цифирьки по образу и подобию
https://github.com/ransford/freertos-moo/bl...eil/Dbg_RAM.ini
(Vector Table Offset Register совпадает с SP, а PC смещен на 4, ну и тут рекомендуют начальное смещение кратное 2^6)
Вы же выставляете свои цифирьки в настройках проекта? Впишите их в скрипт
Metallist64
Уважаемые специалисты.
Вроде сделал как надо:

Код
FUNC void Setup (void) {
  SP = _RDWORD(0x10000000);                          // Setup Stack Pointer
  PC = _RDWORD(0x10000004);                          // Setup Program Counter
  _WDWORD(0xE000ED08, 0x10000000);            // Setup Vector Table Offset Register - VTOR
}

LOAD %L INCREMENTAL                                  // load the application

Setup();                                    // Setup for Running

g, main


Указатель стека указывает на ОЗУ, PC тоже задан со смещением +4. VTOR задан.
Данный .INI фаил я добавил в debug/simulator.
Но ничего не изменилось. В симуляторе стою на нулевом адресе. Насколько я понял, в регистре VTOR бит[29] установлен, значит таблица должна быть размещена в ОЗУ. Вроде все нормально.
Где же я еще торможу...? Симулятор даже не хочет работать... Вот беда..
sensor_ua
Цитата
Указатель стека указывает на ОЗУ...
А настройки во вкладке проекта Target совпадают?
Metallist64
Цитата(sensor_ua @ May 14 2013, 14:48) *


Да, настройки RAM в проекте совпадают с теми, которые я указываю в .INI файле.
Чувствуется, что нет начальной инициализации. Не стартует процессор...
В симуляторе даже не работает... Тупик какой-то...
sensor_ua
А для ROM со смещением так пробовал? Я из RAM не пускался - по идее туда чем-то нужно загрузить. Это либо должна сделать программа путём копирования откуда-то из ROM (наверно в стартапе), либо подгрузить отладчик.
Metallist64
Цитата(sensor_ua @ May 14 2013, 17:53) *
А для ROM со смещением так пробовал? Я из RAM не пускался - по идее туда чем-то нужно загрузить. Это либо должна сделать программа путём копирования откуда-то из ROM (наверно в стартапе), либо подгрузить отладчик.


Немного не понял, о чем речь.
Для ROM я указываю смещение в проекте...
Задаю стартовый адрес и длину.
Metallist64
Пока решил оставить затею отлаживать прошивку с любого адреса флэши.
Теперь решил попробовать создать простой бутлоадер,
который просто передает управление программе, которую записываю с нужным смещением.
Бутлоадер вроде как делает все правильно, выполняется даже часть кода из основной программы.
Но потом опять все ламается.
И при заливке основной прошивки видно, что прошивальщик очищает нулевой сектор...В которм лежит бут...
(поэтому приходится его прошивать повторно)
И потом что-то записывает с адреса 0х300. А потом переходит на нужный 0х10000...
Может кто-нибудь знает, почему такое поведение?
Зачем прошивальщик лезет в 0й сектор?
Да и опять после записи основной программы отваливается отладчик. Для прошивки бута приходится использовать внутренний загрузчик.

P.S. В настройках проектов везеде разделил и ROM и RAM. Они не должны пересекаться.
P.P.S. Проекты бута и основной программы пересоздавал заново. Ничего не изменилось.
Metallist64
В руководстве пользователя написано, что с адреса 0х0 по 0х400 располагается таблица активных векторов.
Но я так понимаю, что таблицы разных программ должны располагаться в разных местах(адреса обработчиков разные).
Может кто-нибудь знает, правильно происходит процесс? Или надо принудительно смещать таблицу векторов пользовательской программы? Потому что видимо они лезут в один и тот же адрес...
А то уже и не знаю куда копать...
Metallist64
Вот я баран!
Я в коде объявил несколько переменных, которые имеют абсолютный адрес во флэши.
Поэтому при записи основной программы, затирались сектора, в которых лежал бутлоадер.
Теперь бут не затирается, основная программа отлаживается, PLL вроде работает правильно(частоты показываются правильные), но с прерываниями пока не разобрался.
Как только прерывание - получаем ступор. Хотя бут вроде все корректно настраивает.
Может в стартапе снова инициализируется адрес 0х0 для таблице векторов?
KnightIgor
Цитата(Metallist64 @ May 15 2013, 14:05) *
Как только прерывание - получаем ступор. Хотя бут вроде все корректно настраивает.
Может в стартапе снова инициализируется адрес 0х0 для таблице векторов?

Модицифируйте startup_xxxx.s, как я предлагал:
Код
__Vectors       DCD     __initial_sp            ; Top of Stack
                DCD     Reset_Handler           ; Reset Handler
                DCD     NMI_Handler             ; NMI Handler
...
VTOR            EQU     (0xE000E000 + 0x0D08)
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


Между +++ в стандартный startup_xxxx добавлены команды, которые "следят" за тем, чтобы указатель на векторную таблицу всегда был настроен правильно.
Metallist64
Цитата(KnightIgor @ May 15 2013, 23:56) *
Модицифируйте startup_xxxx.s, как я предлагал:
Код
__Vectors       DCD     __initial_sp        ; Top of Stack
                DCD     Reset_Handler          ; Reset Handler
                DCD     NMI_Handler            ; NMI Handler
...
VTOR            EQU     (0xE000E000 + 0x0D08)
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


Между +++ в стандартный startup_xxxx добавлены команды, которые "следят" за тем, чтобы указатель на векторную таблицу всегда был настроен правильно.


Большое спасибо.
Но похоже в конце файла system_LPC177x_8x.c
оказалась вот такая штука:
Код
#ifdef  __RAM_MODE__
  SCB->VTOR  = 0x10000000 & 0x3FFFFF80;
#else
  SCB->VTOR  = 0x00000000 & 0x3FFFFF80; <-- насколько я понимаю, тут можно поставить начальный адрес программы
#endif

И похоже , что она перенастраивала на таблицу, которая находится в бутлоадере(вначале флэши).
В итоге, запускался не тот обработчик(или вообще незапускался) и программа останавливалась.
Остался еще один непонятный момент. При использовании команды RAM_MODE, адрес должен меняться меняться на стартовый адрес ОЗУ.
В моем случае 0x10000000. Но при указании этой команды, в отладчике видно, что все равно, используется адрес флэши, а не ОЗУ.
И немного не ясно, кто копирует таблицу из флэши в озу? Может это вручную надо делать.
Хотелось бы попробовать скопировать таблицу в ОЗУ и работать с ней.





Golikov A.
так и программу из флеши в озу тоже никто кроме вашего бутлодера не положит...
Metallist64
В ближайшее время попробую переложить в ОЗУ. Сейчас вроде работает с таблицей из флэши.
В общем всем огромное спасибо за помощь! Буду дальше изучать Cortex-M3!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.