Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: LPC 213x адрес main / c code
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Spb_Alex
keil, RV, lpc213x

сделал удаленную перепрошивку, и хочу перейти в новую программу, пока приходится тупо искать адрес main
/////////////////////////
int main(void)
{
main_addr = __current_pc();
main_addr = main_addr-4;
/////////////////////////
вроде все работает (файл sturtup.s одинаков для всех проектов, вектора прерываний (первые 64 байт новой прошивки)помещены в RAM),

хочется узнать, по какому адресу мне перейти, чтобы гарантированно попасть в main новой прошивки
aaarrr
Не совсем понял задачу - Вам нужен адрес main в текущей программе, или нужно положить его в виде константы в известном месте прошивки?

В первом случае делаем просто:
Код
void *main_addr = (void*)main;

Во втором я бы рекомендовал в startup.s по известному адресу добавить:
Код
    IMPORT main

main_addr
    DCD main


Кстати, оперировать с __current_pc() не совсем корректно, так как на самом деле main может начаться несколько раньше __current_pc().
Сергей Борщ
Цитата(Spb_Alex @ Nov 30 2007, 09:33) *
и хочу перейти в новую программу, пока приходится тупо искать адрес main
Немного непонятно, а кто же у вас инициализирует глобальные переменные для новой программы, т.е. то, что обычно делает ее cstartup?
Цитата(Spb_Alex @ Nov 30 2007, 09:33) *
вектора прерываний (первые 64 байт новой прошивки)помещены в RAM
...
хочется узнать, по какому адресу мне перейти, чтобы гарантированно попасть в main новой прошивки
Сделать ремап (а его все равно надо делать, чтобы эти скопированные вектора начали работать) и перейти на адрес 0. Выполнится cstartup новой прошивки, пройдет вся инициализация и попадете в main() естественным образом.
aaarrr
Цитата(Сергей Борщ @ Nov 30 2007, 13:41) *
Немного непонятно, а кто же у вас инициализирует глобальные переменные для новой программы, т.е. то, что обычно делает ее cstartup?

Тогда нужно на _main переходить.

На нулевой адрес следует переходить с известной осторожностью, и лучше при помощи WD или SoftReset'а какого-нибудь.
Сергей Борщ
Цитата(aaarrr @ Nov 30 2007, 12:52) *
Тогда нужно на _main переходить.
Возможно. Не знаю структуру кейловского стартапа.
Цитата(aaarrr @ Nov 30 2007, 12:52) *
На нулевой адрес следует переходить с известной осторожностью, и лучше при помощи WD или SoftReset'а какого-нибудь.
WD или SoftReset отменят ремап. попадем опять в загрузчик. У меня реализован переход на нулевой адрес, главное - чтобы загрузчик периферию не трогал.
Spb_Alex
Цитата(Сергей Борщ @ Nov 30 2007, 15:28) *
Возможно. Не знаю структуру кейловского стартапа.WD или SoftReset отменят ремап. попадем опять в загрузчик. У меня реализован переход на нулевой адрес, главное - чтобы загрузчик периферию не трогал.


загрузчик - это первая прошивка из 0 сектора, или sturtup.s?

Цитата(Сергей Борщ @ Nov 30 2007, 13:41) *
Немного непонятно, а кто же у вас инициализирует глобальные переменные для новой программы, т.е. то, что обычно делает ее cstartup? Сделать ремап (а его все равно надо делать, чтобы эти скопированные вектора начали работать) и перейти на адрес 0. Выполнится cstartup новой прошивки, пройдет вся инициализация и попадете в main() естественным образом.


Есть две прошивки, у них одинаковый sturtup.s, вектора ремапятся из второй, очищаем регистры.

далее по идее нужно перейти во вторую прошивку (у нее адрес 0х3000), если кидаю в pc - 0x3000, то не работает, видно в sturtup.s поганится МЕММАР, если кидаю адрес main то все работает, но адрес main не константа. "IMPORT main" в real view не работает.
Сергей Борщ
Цитата(Spb_Alex @ Nov 30 2007, 15:43) *
загрузчик - это первая прошивка из 0 сектора, или sturtup.s?
Первая прошивка.
Цитата(Spb_Alex @ Nov 30 2007, 15:43) *
Есть две прошивки, у них одинаковый sturtup.s, вектора ремапятся из второй, очищаем регистры.
А кто будет очищать глобальные переменные, прописывать в них начальные значения, вызывать конструкторы (если С++)? Это все делают функции, вызываемые из startup.s. И если startup.s одинаковый, это не значит, что вызываемые из него функции делают одно и то же - они используют разные массивы констант, в которых определены границы областей неинициалоизированных и инициализированных глобальных переменных, конструкторов, а также границы области начальных значений для инициализированных переменных.
Цитата(Spb_Alex @ Nov 30 2007, 15:43) *
видно в sturtup.s поганится МЕММАР
startup.s не такой огромный и сложный, чтобы в нем нельзя было разобраться и определить - поганится MEMMAP или нет (скорее всего нет).
Spb_Alex
Путем жесточайших экспериментов над lpc2138, установлено, что переходить по адресу 0х3000(ну где лежит вторая прошивка) - это самый правильный вариант, только надо почистить sturtup.s.

У меня даже отладчик, keil (через MT-Link) в новую прошивку вошел, (ес-но можно только память посмотреть, да в дизассемблере полазить), первые 0х60 байт второй прошивки почему-то отображаются FF - ами, по адресу 0х80000000 одни нули.

натолкнуло на мысль:
может мне надо было в память не 0х40 (64 dec), а 0х60 байт второй прошивки переносить для ремапа?
aaarrr
Цитата(Spb_Alex @ Nov 30 2007, 16:43) *
далее по идее нужно перейти во вторую прошивку (у нее адрес 0х3000), если кидаю в pc - 0x3000, то не работает, видно в sturtup.s поганится МЕММАР, если кидаю адрес main то все работает, но адрес main не константа.

А аппаратно почему нельзя сброситься, не пойму?

Цитата(Spb_Alex @ Nov 30 2007, 16:43) *
"IMPORT main" в real view не работает.

Должен работать. Что говорит, на что ругается?
Сергей Борщ
Цитата(Spb_Alex @ Nov 30 2007, 16:17) *
первые 0х60 байт второй прошивки почему-то отображаются FF - ами
Странно это.
Цитата(Spb_Alex @ Nov 30 2007, 16:17) *
по адресу 0х80000000 одни нули
Это же зарезервированная область (внешняя память у кристаллов с шиной). ОЗУ начинается с 0x40000000.
Spb_Alex
Цитата(aaarrr @ Nov 30 2007, 17:54) *
А аппаратно почему нельзя сброситься, не пойму?


потому что опять стартанет загрузчик

Цитата(Сергей Борщ @ Nov 30 2007, 18:25) *
Странно это. Это же зарезервированная область (внешняя память у кристаллов с шиной). ОЗУ начинается с 0x40000000.


это - преотображение векторов пререываний
Сергей Борщ
Цитата(Spb_Alex @ Dec 3 2007, 10:00) *
потому что опять стартанет загрузчик
это - преотображение векторов пререываний
Нет, вы путаете. На область векторов отображается область ОЗУ с адреса 0x40000000, а не 0x80000000. Как можно отразить память, которой нет физически?
Spb_Alex
Цитата(Сергей Борщ @ Dec 3 2007, 12:32) *
Нет, вы путаете. На область векторов отображается область ОЗУ с адреса 0x40000000, а не 0x80000000. Как можно отразить память, которой нет физически?


действительно спутал:

только в
" MEMMAP[1:0]=00 (Boot Loader Mode), a read/fetch from 0x0000 0008 will provide data
available also at 0x7FFF E008 (Boot Block remapped from on-chip Bootloader). "
Сергей Борщ
Цитата(Spb_Alex @ Dec 3 2007, 15:46) *
только в
" MEMMAP[1:0]=00
Тупик. Я перестал понимать, что теперь у вас не работает smile.gif
Alex03
Цитата(Сергей Борщ @ Nov 30 2007, 18:55) *
А кто будет очищать глобальные переменные, прописывать в них начальные значения, вызывать конструкторы (если С++)? Это все делают функции, вызываемые из startup.s. И если startup.s одинаковый, это не значит, что вызываемые из него функции делают одно и то же - они используют разные массивы констант, в которых определены границы областей неинициалоизированных и инициализированных глобальных переменных, конструкторов, а также границы области начальных значений для инициализированных переменных.startup.s


Немного поправлю.
По крайней мере в CW/GCC, начальная инициализация разделена на:
1. startup.s - Инициализация системы, векторов прерываний + ещё некоторые настройки...
2. crtX.s - С RunTime - т.е. инициализация именно C-ей. Настройка стеков, кучи, очистка/инициализация некоторых сегментов, вызовы конструкторов глобальных объектов.... вызов main().
Spb_Alex
Цитата(Сергей Борщ @ Dec 3 2007, 20:37) *
Тупик. Я перестал понимать, что теперь у вас не работает smile.gif


еще в Дата Nov 30 2007, 17:17 все заработало, перепрошивка устройства по GPRS / даже по SMS уже работает, единственное каждые 4Кб передачи по UART (буфер - 128байт) идет ошибка передачи, но это уже мелочи...
Сергей Борщ
Цитата(Alex03 @ Dec 4 2007, 08:22) *
Немного поправлю.
Спасибо. Теперь буду знать. Практически то же самое, но разбито на два модуля. В итоге все равно передавать управление на main() некорректно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.