AltemirX 0 3 сентября, 2011 Опубликовано 3 сентября, 2011 · Жалоба Всем доброго времени суток. Адаптирую загрузчик с LPC2xxx на LPC176x. Копался в мануалах, столкнулся с тем, что у кортекса таблица векторов прерываний гораздо больше, чем у arm7. Как я понял, она может занимать максимум 1КБ против 64 байт у arm7. Для предыдущих проектов использовалась программа шифрования прошивки, которая знала расположение спецтаблицы, находящейся по определённому адресу сразу следом за таблицей векторов. Получается, теперь необходимо или ремапить таблицу векторов в кортексе для сохранения совместимости с софтом верхнего уровня, либо переписывать этот софт? Можно ли занимать адреса, скажем, 0x40...0x100 объявлением массива через __root const? И ещё, в каком документе от ARM описан участок памяти 0x0000 - 0x0400? В DDI0337H_cortex_m3_r2p0_trm.pdf нет. Просто code и всё. Кто может подсказать, что и где там обычно расположено? Компилятор - IAR. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gladov 0 5 сентября, 2011 Опубликовано 5 сентября, 2011 · Жалоба Всем доброго времени суток. Адаптирую загрузчик с LPC2xxx на LPC176x. Копался в мануалах, столкнулся с тем, что у кортекса таблица векторов прерываний гораздо больше, чем у arm7. Как я понял, она может занимать максимум 1КБ против 64 байт у arm7. Для предыдущих проектов использовалась программа шифрования прошивки, которая знала расположение спецтаблицы, находящейся по определённому адресу сразу следом за таблицей векторов. Получается, теперь необходимо или ремапить таблицу векторов в кортексе для сохранения совместимости с софтом верхнего уровня, либо переписывать этот софт? Можно ли занимать адреса, скажем, 0x40...0x100 объявлением массива через __root const? И ещё, в каком документе от ARM описан участок памяти 0x0000 - 0x0400? В DDI0337H_cortex_m3_r2p0_trm.pdf нет. Просто code и всё. Кто может подсказать, что и где там обычно расположено? Компилятор - IAR. Да, придется спецтаблицу передвинуть за таблицу векторов. Но проблемы не вижу, т.к. со сменой ядра Вам обязательно пересобирать как загрузчик, так и основной софт. Вот и сдвиньте все дальше. Адреса 0х40 и выше конечно можно использовать как угодно (и объявлять тоже), но только есть ли гарантия, что не произойдет прерывания, адрес вектора которого попадет на ваши личные данные? Описание на области памяти ищите в DS на контроллер. Cortex-M3 стандартизует лишь область векторов прерываний, да и то не строго, а остальное, как правило, отдано под пользовательский код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 5 сентября, 2011 Опубликовано 5 сентября, 2011 · Жалоба Да, придется спецтаблицу передвинуть за таблицу векторов... Да, к этому и пришёл. Спасибо. Думаю, в моём случае сдвинуть на 1КБ - не проблема. Описание на области памяти ищите в DS на контроллер. Cortex-M3 стандартизует лишь область векторов прерываний, да и то не строго, а остальное, как правило, отдано под пользовательский код. Если б NXP где-то явно это описала... В UM10360.pdf Rev. 2 — 19 August 2010 только на стр. 19 общая карта памяти :( Похоже, дизасмить придётся. А такой вопрос - где обычно после IARа находится стартовый вектор? Т.е., по какому адресу вызывать свою программу из загрузчика, если в *.icf файле я определяю: define symbol __ICFEDIT_region_ROM_start__ = 0x00008000; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gladov 0 5 сентября, 2011 Опубликовано 5 сентября, 2011 · Жалоба Да, к этому и пришёл. Спасибо. Думаю, в моём случае сдвинуть на 1КБ - не проблема. Если б NXP где-то явно это описала... В UM10360.pdf Rev. 2 — 19 August 2010 только на стр. 19 общая карта памяти :( Похоже, дизасмить придётся. А такой вопрос - где обычно после IARа находится стартовый вектор? Т.е., по какому адресу вызывать свою программу из загрузчика, если в *.icf файле я определяю: define symbol __ICFEDIT_region_ROM_start__ = 0x00008000; Если внимательно прочесть, то ничего дизасмить не придется. После стандартных 16 прерываний ядра Cortex-M3 лежат ВСЕ векторы, которые имеются в данном камне. Считате, умножаете на 4 и т.д. После векторов память используется ИАРом по своему усмотрению. Но имхо и это знать вовсе не обязательно. Какая Вам разница куда именно ИАР положит какой код? Если обязательно сделать "дырку" между векторами и кодом для служебной информации, так сделайте ее с помощью конфига линкера. Точка входа в приложение у ИАРа располагается произвольно и знать ее вовсе не обязательно. Достаточно вычитать адрес начала кода из образа (опять же, см. описание первых 0х40 байтов в кортексе). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 5 сентября, 2011 Опубликовано 5 сентября, 2011 · Жалоба Попробовал сделать ремап векторов прерываний. Не заводится проц (или не выходит из NXP-шного загрузчика?). :( Что ещё не так мог сделать? Вроде всё просто должно быть. В коде написал: VTOR = 0x400; В *.icf файле: /*###ICF### Section handled by ICF editor, don't touch! ****/ /*-Editor annotation file-*/ /* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = 0x00000400; /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x10000000; define symbol __ICFEDIT_region_RAM_end__ = 0x10007FFF; /*-Sizes-*/ define symbol __ICFEDIT_size_cstack__ = 0x400; define symbol __ICFEDIT_size_heap__ = 0x800; /**** End of ICF editor section. ###ICF###*/ define memory mem with size = 4G; define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; initialize by copy { readwrite }; //initialize by copy with packing = none { section __DLIB_PERTHREAD }; // Required in a multi-threaded application do not initialize { section .noinit }; place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; place in ROM_region { readonly }; place in RAM_region { readwrite, block CSTACK, block HEAP }; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 5 сентября, 2011 Опубликовано 5 сентября, 2011 · Жалоба И ещё. Почему при указании в *.icf файле строки, например: define symbol __ICFEDIT_region_ROM_start__ = 0x00001100; всё-равно заполняет область 0x100...0xFFF кодом? В map-файле он явно написал: "A1": place at 0x00001000 { ro section .intvec }; "P1": place in [from 0x00001100 to 0x0003ffff] { ro }; "P2": place in [from 0x10000000 to 0x10007fff] { rw, block CSTACK, block HEAP }; Section Kind Address Size Object ------- ---- ------- ---- ------ "A1": 0xc4 .intvec ro code 0x00001000 0xc4 startup_LPC17xx.o [1] - 0x000010c4 0xc4 "P1": 0x675c .text ro code 0x00001100 0x2050 blablabla.o [1] ... Позиции в области 0x100...0xFFF нигде в map файле не встречаются. Если же в свойствах проекта указать заполнение нулями этой области, тогда да, там чисто, map-ы не отличаются, а код разумно вырастает на 4КБ. Правда, ни векторы, ни код всё-равно линкуются не туда. Где что не так? P.S. С этим разобрался. Виноват IAR. hex-файл генерит правильно, а в бинарнике отрезает младшую часть неиспользуемых адресов *WALL* Только сильно легче не стало. С ремап-ом всё-равно не запускается код. Неужели никто не делал? P.P.S. Похоже, догадываюсь, почему ремап не работает. Кто подскажет, чем заменить в icf-файле ранее использованную в xcl-файле директиву типа -KINTVEC=05000,1 ? Подобное позволяло иметь копию векторов прерываний по адресу 0x5000. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gladov 0 6 сентября, 2011 Опубликовано 6 сентября, 2011 · Жалоба P.P.S. Похоже, догадываюсь, почему ремап не работает. Кто подскажет, чем заменить в icf-файле ранее использованную в xcl-файле директиву типа -KINTVEC=05000,1 ? Подобное позволяло иметь копию векторов прерываний по адресу 0x5000. А можно поинтересоваться для чего нужны 2 копии таблицы векторов? Вы очень упорно копаете, но создается стойкое ощущение, что немного не туда :) У Вас же будет бутлоадер? Наверное, он ляжет в один-два сектора в начале ПЗУ, так? А ведь он туда ляжет со своей таблицей, так? Тогда зачем Вам иметь еще и две таблицы у приложения? Его нужно просто сдвинуть на N-е кол-во секторов вперед и все. Только сдвинуть целиком, вместе с таблицей векторов. Например, так: ... /*-Memory Regions-*/ define symbol __ICFEDIT_region_ROM_start__ = 0x00002000; define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; define symbol __ICFEDIT_region_RAM_start__ = 0x10000000; define symbol __ICFEDIT_region_RAM_end__ = 0x10007FFF; /*-Specials-*/ define symbol __ICFEDIT_intvec_start__ = __ICFEDIT_region_ROM_start__; /*-Sizes-*/ ... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 6 сентября, 2011 Опубликовано 6 сентября, 2011 · Жалоба А можно поинтересоваться для чего нужны 2 копии таблицы векторов? Вы очень упорно копаете, но создается стойкое ощущение, что немного не туда :) Можно, конечно. Причин было две: 1. Пока не был дан проект от второго программиста, который занимается основной программой, хотел в самом загрузчике обкатать перемещение таблицы векторов прерываний во флэше. Протупил (споткнулся) из-за неправильно генерируемого бинарника сначала, потом понял, что простыми методами из самого загрузчика не сделать такой тест. Надо хотя бы примитивную главную программку залить, или играться с ремапом в ОЗУ, т.к. начальная же область пустая :) 2. Поскольку проекты перетаскиваются с arm7, то ранее на Builder-е была создана спецпрограммка, которая в постбилде отрезала начальный пустой ненужный кусок от главной программы (включая вектора), получала инфу из спецтаблицы, расположенной следом за векторами (и меняла её тоже, всякую инфу добавляя), при этом имелась копия такой таблицы для главной программы по предопределённому адресу (с учётом смещения главной, ессно), из которой оная также получала необходимые сведения. Также постбилдной утилитой проводилось шифрование прошивки. Хотелось перенести такую технологию без изменений, введя копию таблицы через icf-файл, но, поняв в соседней ветке, что это нельзя сделать, пришлось делать через код в главной проге, объявляя две копии по предопределённым адресам. В принципе, несложно, но некрасиво :) Уже всё проверил. Так что всем спасибо за советы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Alechek 0 6 сентября, 2011 Опубликовано 6 сентября, 2011 · Жалоба От сабя скажу следующее: Я тоже вначале был немного в раздумьях, куда же девать всю эту таблицу и почему я ее должен прописывать статически. В итоге от всей таблицы в ПЗУ осталось лишь DATA __vector_table DCD sfe(CSTACK) ; Top of Stack DCD __iar_program_start ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler DCD MemManage_Handler ; MPU Fault Handler DCD BusFault_Handler ; Bus Fault Handler DCD UsageFault_Handler ; Usage Fault Handler __vector_table_0x1c DCD 0 ; Valid user Code После первоначального запуска инициализирутся драйвер NVIC, который создает таблицу в ОЗУ. Далее работаем уже исключительно с ней. Очень удобно (и единственно возможно на данном камне) при динамической инициализации векторов прерываний. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 6 сентября, 2011 Опубликовано 6 сентября, 2011 · Жалоба В итоге от всей таблицы в ПЗУ осталось лишь... Хм, тоже неплохое решение, которое вполне имеет право на существование. Возьму на заметку. Благодарю. Да, ещё вопросик. Использую в сишном коде асмовскую вставку вида: asm("mov sp,#0x8400"); asm("ldr sp,[sp,#0]"); Для сишных файлов константа 0x8400 определена. Есть ли какая-то возможность подставить эту константу для асма? Погуглил. Пишут, что требуется явно указывать :( Оно и понятно, но всё же... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 6 сентября, 2011 Опубликовано 6 сентября, 2011 · Жалоба Я для IAR такой код перехода в программу поставил VTOR = (unsigned)__section_begin(".intvect"); asm ("ldm r1, {r0,r1}\n" "mov r13, r0\n" "mov r15, r1"); while(1); Здесь при оптимизации и записи в VTOR, нужная константа уже будет в r1 (можно по листингу проверить) осталось только стек и точку входа считать... в конце while(1) стоит для оптимизатора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 7 сентября, 2011 Опубликовано 7 сентября, 2011 · Жалоба Я для IAR такой код перехода в программу поставил... Очень элегантно! Спасибо! По коду всё понял. Не поделитесь заодно полным описанием набора инструкций для Cortex-M3? Что-то я у ARM на сайте не нашёл pdf-ника нормального. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 7 сентября, 2011 Опубликовано 7 сентября, 2011 · Жалоба Не поделитесь заодно полным описанием набора инструкций для Cortex-M3? Что-то я у ARM на сайте не нашёл pdf-ника нормального. Вам нужен arm architecture v7m reference manual, посмотрите новости местных закромов :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
AltemirX 0 7 сентября, 2011 Опубликовано 7 сентября, 2011 · Жалоба KRS Отлично! Ещё раз - благодарю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Vitaliy_ARM 0 16 сентября, 2011 Опубликовано 16 сентября, 2011 · Жалоба Пишу спец загрузчик и как раз столкнулся с тем, что мне надо иметь две таблицы векторов прерываний. Задача загрузчика записать приложение по адресам 0x0-0xFFFF, т.е после чего он уже будет не нужен. И на место него пользовательское приложение будет писать другие данные, но это не важно. Механизм такого загрузчика предполагается сделать так. 1. Копируются вектора прерываний куда-нибудь (во флешь или озу) 2. Делается ремап. 3. Стартует загрузчик Можно ли сделать копирование векторов прерываний в другую страницу на этапе линковки загрузчика, скажем по адресу 0x18000? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться