Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите разобраться с RVMDK
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
vesago
Писал проект в карме решил перебраться на RVMDK. В моем устройстве на LPC2214 две внешние микросхемы памяти. Одна статика для буфера, вторая - флешка. В карме я их прописывал в опциях проекта и объявлял как массивы по конкретным адресам, дабы линкер не пытался в них какие переменные запихнуть. Ну еще пред ними ставил но инит, чтоб при запуске не инициализировало.
В RMDK вообще не возможно массив поместить по поределенному адресу. По крайней мере __at не работатет. Как сделать, чтоб не инициализировало - тоже не знаю. Память в опциях диалога прописываю, а она в отладчике не пашет. Пишет, что запись не возможна. Стартап я поправил. Как мне прописать этувнешнюю память? Не хочется назад в карм возвращаться. Помогите.
VAI
Может это поможет? "\Keil\ARM\Hlp\rvi.chm" статья "Convert from CARM" п.п.4 "Configure the memory layout of your target hardware."
vesago
Спасибо, смотрел этот файл. Сделал один в один. В карме вроде того было. Здесь я тоже прописал память, но в отличии от карма она не пошла. При попытке записи по адресу который относится ко внешней памяти, пишет аксес виалейшн. Если кто имеет опыт подключения внешней памяти - поделитесь.
DeadMoroz
Я ответил на телесисе. Вот еще мой скатер-файл для примера:
LOAD_FLASH 0x00400000
{
Flash +0 ; (2Mx8bit)
{
Startup2.o (Reset, +First)
* (InRoot$$Sections) ; this one string for v2.5, 3.0
}
ExtRAM 0x01400000 ; code in Ext RAM
{
* (+RO, +RW, +ZI)
}
HEAP +0 UNINIT ; heap located after CODE+RW+ZI
{
heap.o (+ZI)
}
STACKS 0x0147FFF0 UNINIT ; end of External RAM (512Kx8bit)
{
stack.o (+ZI)
}
}

Программа стартует после рисета с FLASH. После ремапа она располагается с адреса 0х00400000. Далее код перегружается в SRAM (внешнюю) с адреса 0х01400000 и работа идет из нее. Там же расплагаются куча (после кода) и стек (от конца SRAM).
vesago
Благодарю! Я почитал. Переварю. Пробовал и примеры из кейла разбирать. В общем понятно, но вопрос открыт. Я прописал для LPC2214 основную память и внешнюю срам:
Код
LR_IROM1 0x00000000 0x00040000  {; load region
  ER_IROM1 0x00000000  {     ; load address = execution address
   *.o (RESET, +First)
   * (+RO)
  }
  RW_IRAM1 0x40000000 0x00004000  {; RW data
   * (+RW +ZI)
  }
  RW_RAM1 0x80000000 UNINIT 0x00004000  {
    2.o (+RW)
  }
}

В файле 2.с создавал различные переменные, которые пользовал в майне. В опшионс для 2.с прописал кроме дефаулт внешнюю память. Мне не понравилось, что линкер упорно не захотел разместить массив данных, расположенный в 2.с во внешней памяти. Массив он пихает в набортную память. Код как положено, а переменные в файле 2. как раз во внешней памяти. Я вообще представлял, что создаешь любые переменные, прописываешь в опциях модуля память и линкер автоматом их размещает. А тут он как-то избирательно подходит. Если массив - в инициализируемой памяти, если переменная, то во внешней. Таким образом не могу придумать главное - как мне помещать и считывать данные из внешней SRAM.
Вообще реалвью показался мне недружественным. С указателями требует крайней точности. unsigned char *blabla = 0x80000 не пройдет. Обязательно надо поставить unsigned char *blabla = (unsigned long*)0x80000. В функцию передаю аргумент, внутри функции он каким-то макаром передает левое значение. Я и volatile писал - не помогает. Короче не пойму - чего его народ хвалит?
aaarrr
Цитата(vesago @ Apr 5 2006, 12:59) *
Я вообще представлял, что создаешь любые переменные, прописываешь в опциях модуля память и линкер автоматом их размещает. А тут он как-то избирательно подходит. Если массив - в инициализируемой памяти, если переменная, то во внешней. Таким образом не могу придумать главное - как мне помещать и считывать данные из внешней SRAM.

Как Вы просили, так он и сделал - если нужно разместить массив во внешней памяти, то
линкеру нкжно было писать:
Код
LR_IROM1 0x00000000 0x00040000  {; load region
  ER_IROM1 0x00000000  {    ; load address = execution address
   *.o (RESET, +First)
   * (+RO)
  }
  RW_IRAM1 0x40000000 0x00004000  {; RW data
   * (+RW +ZI)
  }
  RW_RAM1 0x80000000 UNINIT 0x00004000  {
    2.o (+ZI)
  }
}


Цитата(vesago @ Apr 5 2006, 12:59) *
Вообще реалвью показался мне недружественным. С указателями требует крайней точности. unsigned char *blabla = 0x80000 не пройдет. Обязательно надо поставить unsigned char *blabla = (unsigned long*)0x80000. В функцию передаю аргумент, внутри функции он каким-то макаром передает левое значение. Я и volatile писал - не помогает. Короче не пойму - чего его народ хвалит?

И правильно, что ругается - прямое присвоение указателю числового значения недопустимо.
А ставить надо не unsigned char *blabla = (unsigned long*)0x80000, а unsigned char *blabla = (unsigned char*)0x80000.
Просто с типами надо работать аккуратнее.
vesago
Спасибо, помогло. Не пойму только для чего +ZI надо ставить. Ведь в в талмуде написано, что ZI - инициализировать память нулями. Получается, что ZI противоречит UNINIT, который говорит не трогать память. И еще - как сделать, чтоб линкер не пихал в эту область данные. Есть слово EMPTY, но оно не работает. Большой недостаток, что нельзя взять массив и указать, что он располагается по конкретному адресу. Вроде unsigned char tt[100]__at 0x80000000.
aaarrr
Цитата
в талмуде написано, что ZI - инициализировать память нулями. Получается, что ZI противоречит UNINIT, который говорит не трогать память.

К ZI у него относятся все "неинициализируемые" переменные, которые, на самом деле, забиваются
нулями. UNINIT, по идее, должен указать скаттеру на отсутствие необходимости в этом заполнении.
Цитата
И еще - как сделать, чтоб линкер не пихал в эту область данные. Есть слово EMPTY, но оно не работает.

Не понял вопрос. Сделайте пустую секцию - он ничего туда не положит.
Цитата
Большой недостаток, что нельзя взять массив и указать, что он располагается по конкретному адресу. Вроде unsigned char tt[100]__at 0x80000000.

Можно, только конкретный адрес дается не переменной, а секции, в которой эта переменная расположена. Переменная к секции привязывается при помощи #pragma arm section, кажется.
DeadMoroz
Я сделал тестовый поектик, посмотрите. Использую Atmel AT91M40800. У него нет флеша, только RAM. Поэтому при старте по нулевому адресу располагается внешняя флеш. После начальной инициализации и выполнения команды REMAP, по нулевому адресу располагается on chip RAM, флеш по адресу 0х00400000, внешняя SRAM по адресу 0х01400000. В скатер-файле она объявлена как ExtRAM. Все работает, глобальные переменные расположены во флеше после кода программы, внешние переменные - во внешней памяти.
vesago
Большое спасибо за разъяснения и пример. Появилась точка опоры. Буду все переваривать. Да и досконально талмуд почитать надобно. Проект правда пока буду писать в карме, потом портирую в реалвью. Мне он своей строгостью начал нравится. Да и перспективно. Но нет сейчас времени досконально разбираться. Сроки моего проекта стремительно подходят к концу.

Если можно - еще вопрос - в чем глубинный смысл файлов ретаргет. И достаточно ли документации в поставке кейла дабы в совершенстве овладеть тонкостями реалвью? Может имеется еще какая документация? В кейле как-то мутно дано.
DeadMoroz
Насколько я понимаю, основной смысл Retarget.c в вызове функции __initial_stackheap __user_initial_stackheap(), который делается системными библиотеками, ну еще там можно переопределить некоторые библиотечные функции типа fputs. А по докам - я еще пользуюсь доками от ADS1.2. Мое IMHO доки и примеры с каждой версией KARM/RVMDK ухудшаются.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.