Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Ремап, вектора прерываний...
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > ARM, 32bit
алексей500
Здравствуйте.

Работаю с контроллером AT91SAM7A3. Объясните, пожалуйста, некоторые вещи. По ходу выполнения стартапа вектора прерывания должны копироваться в RAM, потом происходит ремап. Вот в общем код этот:


CODE
; Copy Exception Vectors to Internal RAM

IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
ENDIF


; Remap on-chip RAM to address 0

MC_BASE EQU 0xFFFFFF00 ; MC Base Address
MC_RCR EQU 0x00 ; MC_RCR Offset

IF :DEF:REMAP
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR] ; Remap
ENDIF




Так вот. Почему-то этот код пропускается у меня. И в окне дизассемблера вообще нет соответствующих команд. Ну то есть когда тыкаю на команду, то в дизассемблере он никуда не переходит. Смотрю что лежит в RAM, там что-то изменилось, но в основном нули, а должны же быть значения такие же как и во FLASH(ну собственно вектора прерываний)? А вообще, зачем вектора копировать в RAM? До копирования же обработчик RESET лежит во FLASH насколько я понимаю. Вот и пусть лежит там и выполняется оттуда.
toweroff
А где-то есть что-то типа ?
Код
#define RAM_INTVEC


тогда условие
Код
IF :DEF:RAM_INTVEC
ENDIF


выполнится
алексей500
Спасибо, что отреагировали.
В коде этого нет

#define RAM_INTVEC


Но нашёл тут, что в Options for Target на вкладке ASM нужно описать RAM_INTVEC и REMAP. Там просто их в 1 устанавливают насколько я понял. Запустил, вроде всё нормально, вектора копируются в RAM и ремап делается, а потом, при выполнении main() затирается это всё(в основном нулямиsmile.gif). Что-то тут неладноеsmile.gif. Эти стартапы все в стандартных примерах к keil. И там они не определяют в вот RAM_INTVEC и REMAP во вкладке ASM.
алексей500
Не, чего-то голова уже кипит. Не пойму почему после того как начинает выполняться main(), по адресам в RAM, куда скопировались вектора прерываний, записываются либо нули либо что-то другое. Я не знаю может вообще так и должно быть. Вы главное скажите, если я так и оставлю, что программа будет лежать во FLASH и без ремапа, то это всё будет работать с прерываниями когда в контроллер зашью(кстати это я в симуляторе пока ковыряюсь)? То есть вектора прерываний будут располагаться по тем адресам где и должны(начиная с 0x00000000), только будут лежать не в RAM а во FLASH.
aaarrr
Цитата(алексей500 @ May 30 2010, 21:37) *
Что-то тут неладноеsmile.gif

Линкер просто ничего о ремапе не знает, нужно модифицировать скрипт. А можно просто забыть о ремапе как таковом - для SAM7 он большого смысла в общем-то и не имеет.
алексей500
Если в скаттере чуток сдвинуть начало IRAM, то всё нормально вроде, вектора остаются лежать вначале RAM, а затирается другой кусок laughing.gif

Просто это если самому проект создавать, то вроде бы всё нормально. А в примерах готовых там вообще по-разному. Стартапы разные, ремап в разных местах выполняется. Почему-то в примерах когда дебаг запускаешь, то по нулевому адресу FLASH не отображается, а если сам создаёшь проект, то прям до выполнения обработчика прерывания по RESET уже FLASH в нуле. Это я так понимаю тоже линкер смотреть надо?
И ещё, не могли бы вы объяснить, зачем в примерах делают ещё Target для записи в RAM? То есть записали в RAM и всё, больше питание контроллера отключать нельзя?
aaarrr
Цитата(алексей500 @ May 31 2010, 02:42) *
Это я так понимаю тоже линкер смотреть надо?

Нет. Смотреть надо скрипт отладчика и способ, которым производится ремап в программе.

Цитата(алексей500 @ May 31 2010, 02:42) *
И ещё, не могли бы вы объяснить, зачем в примерах делают ещё Target для записи в RAM? То есть записали в RAM и всё, больше питание контроллера отключать нельзя?

Делают просто чтобы не шить флеш при каждом изменении. Пригодно, разумеется, только для отладки.
Nikitoc
Чтобы не плодить похожих тем решил спросить здесь. Я, наконец-то, добрался до написания собственного загрузчика - так как SAM-BA замучила неимоверно. И решил разобраться в этом вопросе досконально. Прочитал с десяток тем в этом и других разделах. Многое понял, но не все, конечно. А именно - для чего нужен ремап (то что он переключает отображение FLASH и RAM на 0х00 - понятно, но для чего конкретно это необходимо)? Я (в общих чертах) так представляю себе реализацию загрузчика:
1. После старта программа расположенная в самом начале FLASH инициализирует основные узлы микропроцессора и определяет требуется ли обновление прошивки (по предопределенным признакам - например, наличию высокого уровня на какой-нибудь ножке. Естественно перед этим эта ножка настраивается должным образом.)
2. Если прошивка требуется - то программа копирует в ОЗУ функцию, которая по какому-нибудь интерфейсу (у меня UART) получает и записывает их во FLASH. (Это необходимо, потому, что нельзя пытаться записывать FLASH и при этом исполнять оттуда программу).
3. Проверяем контрольные суммы (полученную с прошивкой и подсчитанную при записи) и делаем программный RESET.

Поправьте меня если я что-то написал неправильно.
P.S. Растолкуйте еще, пожалуйста, про ремап.
Сергей Борщ
Цитата(Nikitoc @ Jul 7 2010, 14:48) *
(то что он переключает отображение FLASH и RAM на 0х00 - понятно, но для чего конкретно это необходимо)?
Чтобы поставить на место аппаратных векторов исключений обработчики приложения. Перед ремапом вектора копируются в начало ОЗУ.
Nikitoc
Цитата(Сергей Борщ @ Jul 7 2010, 14:52) *
Чтобы поставить на место аппаратных векторов исключений обработчики приложения. Перед ремапом вектора копируются в начало ОЗУ.

Я про это читал. Но что это даст, ведь после сброса память все равно отображается на FLASH (я имею в виду FLASH отображается на 0х00)? И как эту "фичу" использовать для реализации загрузчика?
aaarrr
Цитата(Nikitoc @ Jul 7 2010, 15:56) *
И как эту "фичу" использовать для реализации загрузчика?

Основное приложение сможет задействовать свои вектора, если понадобится. Без необходимости делать ремап не следует.
Nikitoc
Цитата(aaarrr @ Jul 7 2010, 15:33) *
Без необходимости делать ремап не следует.

А когда эта необходимость может возникнуть? Для чего нужно копировать исключительные вектора в ОЗУ?
Сергей Борщ
Цитата(Nikitoc @ Jul 7 2010, 15:51) *
А когда эта необходимость может возникнуть? Для чего нужно копировать исключительные вектора в ОЗУ?
Ну вот например у вас в загрузчике не используется исключение SWI. На его месте в загрузчике стоит заглушка. А в приложении это исключение используется. И вам нужно, чтобы по вектору этого исключения стоял переход на обработчик SWI приложения. Вот в таблице векторов приложения у вас и стоит переход на обработчик SWI. Вы копируете вектора приложения в ОЗУ, делаете remap и получаете на векторе SWI переход на обработчик в приложении. То же и с вектором сброса - после ремапа по адресу 0 (вектор исключения RESET) находится переход на стартап вашего приложения, и для запуска приложения из загрузчика вам нужно перейти на адрес 0. Без всяких промежуточных сбросов.
Nikitoc
Спасибо. Буду переваривать. Правда, не уверен, что все ясно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.