реклама на сайте
подробности

 
 
5 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> LPC11xx не стартует код из своего бутлоадера
zuy
сообщение Oct 21 2010, 10:42
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Использую LPC1114. По доке вроде все понятно.
Свой бутлоадер код во флеш прописал.
для старта делаю следующее:
1. копирую 48 векторов прерывания основной программы в ОЗУ с адреса 0x10000000
2. Делаю ремап LPC_SYSCON->SYSMEMREMAP = 0x01; т.е. отобрашаем вектора из ОЗУ в начало адресного простанства
3. инициализирую SP и PC данными из первых 8-ми байт моей проги.

Все это выглядит так:
Код
__asm void boot_jump( uint32_t address )
{
   LDR R1, [R0]    ;Load new stack pointer address
   MOV R13, R1
   LDR R1, [R0, #4];Load new program counter address
   BX  R1
}

void run(unsigned long address)
{
  unsigned long          *dst, size;
  const unsigned long    *src;
  
  // Copy vectors table
  src = (unsigned long *)address;
  dst = (unsigned long *)0x10000000;
  size = VECTORS_TABLE_SIZE >> 2;
  do  { *dst++ = *src++; } while (--size);

  LPC_SYSCON->SYSMEMREMAP = 0x01;        /* remap to SRAM */

  boot_jump(address);
}


В результате поведение непредсказуемое. то висит, то попадает куда-то в середину бутлоадера.
Если убрать ремап, то целевая прога запускается, но естественно с векторами из флеша.

Что я забываю в этой схеме?
Go to the top of the page
 
+Quote Post
Alekseeey
сообщение Oct 21 2010, 12:12
Сообщение #2


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 21-09-10
Пользователь №: 59 626



У меня та же проблема.

Пробую на отладке LPCXpresso, среда CodeRed. Процессор LPC1114.

Я взял проект blinky из примеров и попытался просто скопировать вектора в ОЗУ и сделать ремап.
(соотв. область озу зарезервирована в скрипте линкера).

Программа вылетает в HardFault exception.

Написал вопрос в LPCXpresso forum.

Жду ответа... У меня самого идеи кончились.

В дебаг режиме, при пошаговом выполнении, вылетает на команде bl.

Вот код функции Reset_Handler из примера с моими изменениями:

Код
void Reset_Handler(void)
{
    unsigned char *pulSrc, *pulDest;

    //
    // Copy the data segment initializers from flash to SRAM.
    //
    pulSrc = &_etext;
    for(pulDest = &_data; pulDest < &_edata; )
    {
        *pulDest++ = *pulSrc++;
    }

    //
    // Zero fill the bss segment.
    //
    for(pulDest = &_bss; pulDest < &_ebss; pulDest++)
      *pulDest = 0;

    // Copying the vector table to sram
    unsigned char i;
    unsigned char * vectDest;
    unsigned char * vectSrc;

    vectDest = (unsigned char *)(0x10000000);
    vectSrc  = (unsigned char *)(0x00000000);
    for (i = 0; i < 0xC0; i++)
    {
        *vectDest++ = *vectSrc++;
    };

    // Remap
    LPC_SYSCON->SYSMEMREMAP = 1;
    __DMB();

#ifdef __USE_CMSIS
    SystemInit();
#endif


    //
    // Call the application's entry point.
    // __main() is the entry point for redlib based applications (which calls main())
    // main() is the entry point for newlib based applications
    //
    if (__main)
        __main();
    else
        main();

    //
    // main() shouldn't return, but if it does, we'll just enter an infinite loop
    //
    while (1) {
    ;
    }
}



Go to the top of the page
 
+Quote Post
DpInRock
сообщение Oct 21 2010, 12:38
Сообщение #3


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Вообще-то так и должно быть.

Как правильно (это мое имхо, но которое работает).

0. Компилируем программу и линковщику показываем реальные адреса.
1. Грузим программу с нужного адреса.
2. Копируем вектора, только если ремаповая область не совпадает с расположением программы (к примеру код находится SDRAM или FLASH). Т.е в этом случае копируем из области своей программы в область которая может содержать вектора и ремапится.
3. Далее запрещаем прерывания и JMP на начало своей программы: либо на реальное начало, либо на начальный адрес зоны векторов, которые ремапили (там одно и тоже будет - goto Startup).

Что характерно, не надо трогать стеки. Ибо стартап их настроит как вы в линкере укажите.



--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
zuy
сообщение Oct 21 2010, 12:52
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Цитата(Alekseeey @ Oct 21 2010, 15:12) *
Вот код функции Reset_Handler из примера с моими изменениями:


Если честно не совсем понял зачем это все в Reset_Handler.
Он от бутлоадера или от прошиваемой проги?
Какая у вас логика работы бутлоадера?

Цитата(DpInRock @ Oct 21 2010, 15:38) *
Вообще-то так и должно быть.

Как правильно (это мое имхо, но которое работает).

0. Компилируем программу и линковщику показываем реальные адреса.
1. Грузим программу с нужного адреса.
2. Копируем вектора, только если ремаповая область не совпадает с расположением программы (к примеру код находится SDRAM или FLASH). Т.е в этом случае копируем из области своей программы в область которая может содержать вектора и ремапится.
3. Далее запрещаем прерывания и JMP на начало своей программы: либо на реальное начало, либо на начальный адрес зоны векторов, которые ремапили (там одно и тоже будет - goto Startup).

Что характерно, не надо трогать стеки. Ибо стартап их настроит как вы в линкере укажите.


А почему оно так должно быть и как починить?

0. Основная прога собрана с адреса 0x2000. RAM использует с 0x100000C0.
1. Верно, бутлоадер прощивает основную прогу во флеш по адресу 0x2000.
2. Копируем таблицу векторов. Т.е. 0xC0 байт c адреса 0x2000 в 0x10000000.
3. Ну перед джампом надо же сделать ремап, чтобы вектора из ОЗУ появились с адреса 0x0. И вот тут у меня сразу улетает куда-то в середину бутлоадера.

А как это стеки трогать не надо? У Cortex M0 вершина стека хранится в самом начале векторов и проц после ресета сам ее оттуда берет. А т.к. мы скачем в основную прогу без ресета, а из своего бутлоадера, то надо самому правильно стек настроить. Стартап у кортексов стеки не настраивает.

Go to the top of the page
 
+Quote Post
DpInRock
сообщение Oct 21 2010, 12:58
Сообщение #5


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Reset - это место откуда программа стартует. Как бы по сигналу сброса. Как бы независимо.
Но в реальности по сигналу сброса проц идет на собственный загрузчик и передает управление программе после ремапа. И тут якобы она стартует с 0. Делает вид,что после сброса как бы.

Разумеется, можно написать даже процедуру, которая будет располагаться с 0. Токо следущими идут вектора прерываний. И если прерывания не используются - да ради бога. Можно.

Против кортекса не попрешь. Извиняюсь.
Но логика все равно остается.
Не забывать прерывания убить.
Ну и правильно джамп сделать.
С переключением в режим супервизора. Я делаю
Код
void  JMP(unsigned int addr)
{

//asm ("mov r0, addr \n");
asm ("SWI 0 \n");
}

Вот так примерно.

В том плане, что я стартую с нуля всегда после ремапа. Ибо так универсальнее, разумеется.
(У меня все остальное - типа переключателя задач работает в супервизоре - выбрал за красивое название)
НУ, еще контроллр внешней памяти не забыть настроить... У меня-то вектора в локальной памяти...

Сообщение отредактировал DpInRock - Oct 21 2010, 13:05


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
Alekseeey
сообщение Oct 21 2010, 13:01
Сообщение #6


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 21-09-10
Пользователь №: 59 626



Цитата(zuy @ Oct 21 2010, 16:52) *
Если честно не совсем понял зачем это все в Reset_Handler.
Он от бутлоадера или от прошиваемой проги?
Какая у вас логика работы бутлоадера?


Логику работы бутлоадера я пока оставил в стороне - у меня не работает именно ремап.
Я попытался взять работающий пример и сделать ремап векторов не трогая ничего другого.
По идее все долно было работать без изменений. Но не работает. smile.gif Что-то делаю не правильно, но не знаю что.

А вообще логика бутлоадера будет такой: лоадер в 0-й странице флеш, грузит программу в страницы 1..7,
копирует ее вектора прерываний в ОЗУ и передает управление ей.

Go to the top of the page
 
+Quote Post
zuy
сообщение Oct 21 2010, 13:01
Сообщение #7


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Цитата(DpInRock @ Oct 21 2010, 15:54) *
Reset - это место откуда программа стартует. Как бы по сигналу сброса. Как бы независимо.
Но в реальности по сигналу сброса проц идет на собственный загрузчик и передает управление программе после ремапа. И тут якобы она стартует с 0. Делает вид,что после сброса как бы.


Да, это понятно. Мой бут делает в общем тоже самое, что и встроенный, только ремапит вектора не из флеша, а из ОЗУ.

Вроде нашел косяк. Забыл прерывания отключить до ремапа!

Тогда еще вопрос. А барьеры синхронизации или памяти нужно после ремапа ставить или нет?
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Oct 21 2010, 13:13
Сообщение #8


Гуру
******

Группа: Участник
Сообщений: 2 254
Регистрация: 4-05-07
Из: Moscow
Пользователь №: 27 515



Понятия не имею. Но для вас вряд ли имеет значение скорость старта. После ремпапа и перед джампом можно провести вечность. Ибо прерваний нет.
Но вот не скажу за кортекс - мода процессора будет иметь значение. Надо привилегированный режим.
А то ваша прога полезет модифицировать стеки всех режимов, а ей дадут отлуп.

Сообщение отредактировал DpInRock - Oct 21 2010, 13:14


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
Alekseeey
сообщение Oct 21 2010, 13:41
Сообщение #9


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 21-09-10
Пользователь №: 59 626



Цитата(zuy @ Oct 21 2010, 17:01) *
Да, это понятно. Мой бут делает в общем тоже самое, что и встроенный, только ремапит вектора не из флеша, а из ОЗУ.

Вроде нашел косяк. Забыл прерывания отключить до ремапа!

Тогда еще вопрос. А барьеры синхронизации или памяти нужно после ремапа ставить или нет?


Пожалуйста, опубликуйте работающий вариант процедуры ремапа.

В usermanual lpc1114 написано на стр. 317:
Vector table — If the program changes an entry in the vector table, and then enables the
corresponding exception, use a DMB instruction between the operations. This ensures that
if the exception is taken immediately after being enabled the processor uses the new
exception vector.

Судя по всему - надо.
Go to the top of the page
 
+Quote Post
zuy
сообщение Oct 21 2010, 17:28
Сообщение #10


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Цитата(Alekseeey @ Oct 21 2010, 16:41) *
Пожалуйста, опубликуйте работающий вариант процедуры ремапа.

Да вот что-то еще не прокатило, разбираюсь.
Как будет рабочий вариант, отпишу
Go to the top of the page
 
+Quote Post
zuy
сообщение Oct 21 2010, 19:14
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Нет, все равно решительно не понимаю, что делает ремап в LPC1114.
Вот простой код, который просто включает светодиод, и через некоторое время выключает:
Код
int main(void )
{
  unsigned long *dst, size, i;
  const unsigned long    *src;

  LPC_SYSCON->SYSAHBCLKCTRL |= (1<<16) | (1<<6);  // Enable IOCON GPIO
  LPC_GPIO1->DIR  |= ( 1 << 8 );                  // LED pin direction out
  LPC_GPIO1->DATA &= ~( 1 << 8 );                 // LED ON

  // Copy vectors table from 0x0 to RAM
  src = (unsigned long *)0;
  dst = (unsigned long *)0x10000000;
  size = 0xC0 >> 2;
  do  { *dst++ = *src++; } while (--size);

  // Pause, just to mention the LED state.
  i= 10000000;
  while( --i );

  __disable_irq();
  LPC_SYSCON->SYSMEMREMAP = 0x01;        // remap to SRAM
  __ISB();

  LPC_GPIO1->DATA |= ( 1 << 8 );    // LED OFF

  while( 1 );
}


Чтобы ремап не мешал работать, я копирую таблицу векторов из флеш в RAM.
Если строка с ремапом присутствует то код не работает,
если ее комментирую то все нормально.
Но я же скопировал таблицу в RAM. Т.е. после ремапа для процессора вообще ничего не поменялось в начале адресного пространства!

Кто-нибудь может объяснить что тут происходит?

Go to the top of the page
 
+Quote Post
Alekseeey
сообщение Oct 21 2010, 20:30
Сообщение #12


Участник
*

Группа: Участник
Сообщений: 32
Регистрация: 21-09-10
Пользователь №: 59 626



Цитата(zuy @ Oct 21 2010, 23:14) *
Нет, все равно решительно не понимаю, что делает ремап в LPC1114.

Кто-нибудь может объяснить что тут происходит?


Обьяснить, к сожалению не могу, но могу от себя добавить, что когда я
выполняю программу в отладчике по шагам, по ассемблерным коммандам,
то при включенном ремапе происходит HardFault на инструкциях ветвления.

Причем, в тестовой программе blinky это исключение возникает при попытке
перехода на main();, но не происходит при переходе на SystemInit();
В памяти SystemInit расположена вверх по адресам от точки вызова, а main - вниз,
не знаю, важно это или нет...



Вот только что увеличил размер зарез. области до 0x1000 и скопировал туда 0x1000 байт флеш. Программа blinky дошла до main и попыталась начать работать. Прогресс.

Да, проект blinky заработал. При включенном ремапе. После копирования в ОЗУ 0x1000 байт флеша. У меня нехорошие предчувствия по поводу ремапа...



Интересная опечатка (?) есть в старых версиях user manual на lpc1114: на картинке карты памяти размер области векторов указан 0x0200 байт. И если я копирую 0x0200 байт, то программа работает...

Go to the top of the page
 
+Quote Post
zuy
сообщение Oct 21 2010, 20:43
Сообщение #13


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Цитата(Alekseeey @ Oct 21 2010, 23:09) *
Обьяснить, к сожалению не могу, но могу от себя добавить, что когда я
выполняю программу в отладчике по шагам, по ассемблерным коммандам,
то при включенном ремапе происходит HardFault на инструкциях ветвления.

Отладчик Keil ?
Он для LPC1114 не совсем корректно работает. Тот пример что я привел в случае если ремап убрать, то вылетает в отладчике в HardFault, но работает отлично в железе.

Цитата(Alekseeey @ Oct 21 2010, 23:30) *
Интересная опечатка (?) есть в старых версиях user manual на lpc1114: на картинке карты памяти размер области векторов указан 0x0200 байт. И если я копирую 0x0200 байт, то программа работает...

Рано я обрадовался. в 0х200 байт у меня вся тестовая прога. Получается я ее скопировал всю в ОЗУ.
В реальном бутлоадере это не помогло :-(
Go to the top of the page
 
+Quote Post
rezident
сообщение Oct 21 2010, 20:55
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 10 920
Регистрация: 5-04-05
Пользователь №: 3 882



Возникло предположение, что ремапу подвергается Flash кратно одному полному сектору размером 512 байт. Посмотрел в других кристаллах Cortex-M0 и Cortex-M3 - аналогично: либо 512 байт, либо 256 слов. Видимо бангалорские писатели даташитов что-то перемудрили laughing.gif
К сожалению, под рукой у меня нету ни LPC1114, ни отладчика, чтобы чем-то помочь в исследовании проблемы sad.gif
Go to the top of the page
 
+Quote Post
zuy
сообщение Oct 21 2010, 21:09
Сообщение #15


Частый гость
**

Группа: Свой
Сообщений: 173
Регистрация: 30-11-05
Из: San Francisco
Пользователь №: 11 593



Цитата(rezident @ Oct 21 2010, 23:55) *
Возникло предположение, что ремапу подвергается Flash кратно одному полному сектору размером 512 байт. Посмотрел в других кристаллах Cortex-M0 и Cortex-M3 - аналогично: либо 512 байт, либо 256 слов. Видимо бангалорские писатели даташитов что-то перемудрили laughing.gif
К сожалению, под рукой у меня нету ни LPC1114, ни отладчика, чтобы чем-то помочь в исследовании проблемы sad.gif


Абсолютно верно. Я точно не проверял 512байт или какое другое значение,
но факт в том, что действительно ремап отображает не таблицу векторов в 0хС0 байт, а больше.

Я решил просто. Разместил код запуска основной проги в начале. Глянул какой максимальный адрес он занимает и
копирую в ОЗУ все до этого адреса. После ремапа, получается этот же код и отображается из ОЗУ и проц продолжает работать.
Далее я уже переписываю первые 0xc0 байт векторов из основной проги, и передаю ей управление через загрузку SP и PC.
Все работает.
Go to the top of the page
 
+Quote Post

5 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 08:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01539 секунд с 7
ELECTRONIX ©2004-2016