|
MMU D-Cache I-Cache для ARM926EJ-S, Как работает и как настроить? |
|
|
|
Dec 27 2010, 05:54
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Доброго всем здравия! Уважаемые специалисты, помогите разобраться с этими монстрами. Имеется AT91SAM9260 на базе процессора ARM926EJ-S. Для повышения скорости работы нужно настроить: 1) MMU (Memory Management Unit) - Блок управления памятью. Он отвечает за управление доступом к памяти, запрашиваемым центральным процессором путем трансляции адресов виртуальной памяти в адреса физической памяти. MMU разделяет виртуальное адресное пространство на участки одинакового размера (4 Кб, 64 Кб или 1 Mb ) называемые страницами. Процесс обращается к памяти с помощью адреса виртуальной памяти, который содержит в себе номер страницы и смещение внутри страницы. Процессор преобразует номер виртуальной страницы в адрес соответствующей ей физической страницы при помощи буфера ассоциативной трансляции. Младшие n бит адреса (смещение внутри страницы) остаются неизменными. Старшие биты адреса представляют собой номер (виртуальной) страницы. MMU обычно преобразует номера виртуальных страниц в номера физических страниц используя TLB(Translation Lookaside Buffer) - Буфер Ассоциативной Трансляции. Вопрос 1. Как настроить это MMU для указанного выше процессора? Как организовать и заполнить TLB? Как ее подключить к MMU и пользоваться ей? 2) Нужно настроить D-Cache (Data Cache - Кэш данных) и I-Cache (Instruction Cache - Кэш комманд процессора). Кэш — это некий промежуточный буфер, содержащий информацию, которая может быть запрошена с наибольшей вероятностью. Доступ к данным в кэше идёт быстрее, чем выборка исходных данных из внешней памяти. Таким образом комманды и данные выбираются из быстрее и производительность растет. Кэш состоит из набора записей. Каждая запись ассоциирована с данными, являющимися копией данных в основной памяти. Каждая запись имеет идентификатор, определяющий соответствие между элементами данных в кэше и их копиями в основной памяти. Области (сегменты) основной памяти жёстко привязываются к строкам кэш-памяти (в каждой строке могут быть данные из фиксированного набора адресов), что значительно сокращает время поиска. С каждой ячейкой ОЗУ может быть связано более одной строки кэш-памяти. Таким образом, одна запись в Кэше может содержать несколько комманд (наиболе часто употребляемых) из сооветствующей области памяти. Вопрос 2. Как инициализировать D-Cache и I-Cache? Как и когда (при каких условиях) их очищать? Как с ними работать? Что имеется у меня: ARM926EJ-S Technical Reference Manual - написано много, очень грузно, четких инструкций не обнаружено. Много всяких режимов, я так и не понял какой нужен именно мне. Имеется пример, а точнее функции от IAR, но ни в одном проекте они не применяются, т.е. функции нигдек не используются. Тем самым я не могу понять последовательность действий при инициализации вышеупомянутых модулей. Также есть пример из темы данного форума Производительность SAM9XE, непонятки с этим процом. Там есть как раз пример Translation Table, но не очень понятно как с ней работать и почему именно такие адреса. В ARM926EJ-S еще есть некий регистр TTBR - Translation Table Base Register - я так понял, это регистр указателя начального (базового) адреса расположения TLB. Вопрос где хранить TLB и по какому адресу? У меня никак не может сложиться общая картина совместной работы этих модулей. Буду признателен специалистам, которые смогут прояснить мне эти вопросы.
Сообщение отредактировал ZED - Dec 27 2010, 06:08
|
|
|
|
|
Dec 27 2010, 06:26
|

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

|
Код unsigned int AT91F_ARM_ReadControl() { register unsigned int ctl; ctl = __MRC(15, 0, 1, 0, 0); return ctl; }
void AT91F_ARM_WriteControl(unsigned int ctl) { __MCR(15, 0, ctl, 1, 0, 0); }
void AT91F_ARM_WriteTTB(unsigned int ttb) { __MCR(15, 0, ttb, 2, 0, 0); } void AT91F_ARM_WriteDomain(unsigned int domain) { __MCR(15, 0, domain, 3, 0, 0); }
void AT91F_InitMMU(void) { unsigned int *TLB =(unsigned int *) (0x21FF8000);//last 32 K unsigned int i,ctl; // Program the TTB AT91F_ARM_WriteTTB(0x21FF8000); AT91F_ARM_WriteDomain(0xFFFFFFFF); // access are not checked for (i = 0; i < 4096; ++i) TLB[i] = 0; TLB[0x0] = (0x000<<20)|(1<<10)|(15<<5)|(1<<4)|(2<<2)|0x2; TLB[0x200] = (0x200<<20)|(1<<10)|(15<<5)|(1<<4)|(2<<2)|0x2;//screen for (i=0x201;i<(0x201+31);i++) TLB[i] = (i<<20)|(1<<10)|(15<<5)|(1<<4)|(3<<2)|0x2; TLB[0x006] = (0x006<<20)|(1<<10)|(15<<5)|(1<<4)|0x2; // LCD
TLB[0x21E] = (0x21E<<20)|(1<<10)|(15<<5)|(1<<4)|(0<<2)|0x2; //Peripheria TLB[0x21F] = (0x21F<<20)|(1<<10)|(15<<5)|(1<<4)|(1<<2)|0x2; //Peripheria
TLB[0xFFF] = (0xFFF<<20)|(1<<10)|(15<<5)|(1<<4)|0x2; //Peripheria
//enable MMU ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 0); AT91F_ARM_WriteControl(ctl); //enable I ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 12); AT91F_ARM_WriteControl(ctl); //enable D ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 2); AT91F_ARM_WriteControl(ctl); } Это для 9261. Все виртуальные адреса совпадают с физическими.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Dec 27 2010, 11:50
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Я так понял, что Ваша таблица TLB располагается в SDRAM. Базовый адрес TBL 0x21FF 8000. Сама программа у Вас располагалась в SRAM? начиная с адреса 0x30 0000. Строчка Код TLB[0x006] = (0x006<<20)|(1<<10)|(15<<5)|(1<<4)|0x2; // LCD видимо отключает кэширование и буфферизацию LCD. Код TLB[0x0] = (0x000<<20)|(1<<10)|(15<<5)|(1<<4)|(2<<2)|0x2; Это для Boot Memory. Я просто тут немного запутался, разве нам не нужно кэшировать весь Boot Memory, т.е. адреса 0x0000 0000 .. 0x0010 0000? Или достаточно указать только начальный адрес? Что делает эта строчка и для чего нужен режим Write-Back почему не Write-Trough: Код for (i=0x201;i<(0x201+31);i++) TLB[i] = (i<<20)|(1<<10)|(15<<5)|(1<<4)|(3<<2)|0x2; Видимо я не совсем понимаю, что скрывается за понятием адреса в битах [31:20] Form the corresponding bits of the physical address for a section.
|
|
|
|
|
Dec 28 2010, 03:37
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(DpInRock @ Dec 27 2010, 12:58)  Иными словами, если вы не извращенец - про все типы кэшей - включить и забыть. Очень опасный совет. Дело в том, что у ARM9 кеш-контроллер и DMA ничем не связаны, так что если работать по DMA с кешируемой памятью, то можно поиметь целую кучу непонятных глюков. Поэтому про кеши надо помнить, чтобы не создать буфер DMA в кешируемой области памяти. В том примере у меня один из 32 мегабайтов ОЗУ отводился именно под такие буфера. Заодно туда и TLB засунул. Адреса в примере определяются конфигурацией железа (SAM9XE).
|
|
|
|
|
Dec 28 2010, 04:04
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Может я чего-то не понимаю, но по карте памяти адресу 0x21FF 8000 соответствует область EBI Chip Select 1/SDRAMC. Если я ничего не путаю, то Remap всего лишь отображает SRAM на нулевой адрес 0x0000 0000. Тогда нижеуказанная строчка, которая задает начальный адрес расположения таблицы TLB 0x21FF 8000, определяет расположение этой таблицы в SDRAM? Код unsigned int *TLB =(unsigned int *) (0x21FF8000);//last 32 K . Правильно ли я понял, что программа у меня будет лежать в SDRAM, тогда мне таблицу нужно разместить, например в SRAM1, базовый адрес расположения таблицы тогда будет 0x30 0000 (Расположение SRAM1 на карте памяти), а в саму TLB записывать адреса расположение программы, т.е начальные адрес SDRAM, т.е. 0x2000 0000.
|
|
|
|
|
Dec 28 2010, 06:47
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
А можно еще такой вопрос? Поскольку у меня такие маленькие размеры SRAM (4 Кб) мне нужно делить память на блоки по 4 Кб? И если все делить не Мегабайтными страницами ( Section), а блоками по 4 Кб ( Coarse page). Тогда получается, что необходимо два дескриптора: грубый (1-ого уровня) и точный (2-ого уровня). Как тогда вести описание? Я предполагаю так: 1) Задать базовый адрес расположения Грубого дескриптора что-то типа (размещаю в SRAM1, она у меня 4 Кб): Код unsigned int *TLB =(unsigned int *) (0x30 0000);//last 32 K 2) Заполнить ее базовыми адресами точного дескриптора ( Coarse page table base address) т.е. проинициализировать TLB; 3) Задать базовый адрес расположения точного дескриптора. Тут вопрос куда его положит, во всю ту же SRAM1? Ну напримерпо адресу 0x30 0500 (последний адрес: 0x30 1000). И вопрос хватит ли мне ее? По идее не хватит, мне нужно описать 4096 4) Заполнить (проинициализировать) точные дескрипторы. Или такой вариант: Структура: Код typedef struct __TTL { unsigned int Descriptor_1; // Дескриптор 1-ого уровня unsigned int Descriptor_2[256]; // Дескриптор 2-ого уровня } TTL; И еще вопрос, откуда переферия по этим адресам ( 0x21E0 0000 и 0x21F0 0000): Код TLB[0x21E] = (0x21E<<20)|(1<<10)|(15<<5)|(1<<4)|(0<<2)|0x2; //Peripheria TLB[0x21F] = (0x21F<<20)|(1<<10)|(15<<5)|(1<<4)|(1<<2)|0x2; //Peripheria
|
|
|
|
|
Dec 28 2010, 07:14
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414

|
Кэш инструкций включается установкой соответствующего бита в управляющем регистре. Кэш данных можно включить только в том случае, если включено MMU, а чтобы его включить, надо сначала подготовить таблицы переадресации. Если виртуальная память и защита памяти не нужны (т.е. если MMU включается исключительно ради кэша), то есть смысл использовать секции, а не страницы, и всё отображение памяти описать одной таблицей первого уровня (4096 элементов по слову каждое, всего 16 Кбайт). Что же касается TLB, то он, как и кэши, работает автоматически, и вручную манипулировать им необходимо лишь в весьма специфических случаях. Если с английским проблемы, можно посмотреть на ru.osdev.wikia.com.
|
|
|
|
|
Dec 28 2010, 07:46
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Цитата MMU включается исключительно ради кэша), то есть смысл использовать секции, а не страницы, и всё отображение памяти описать одной таблицей первого уровня (4096 элементов по слову каждое, всего 16 Кбайт). Это получается, что у меня таблица по-любому не влезет в SRAM1 объемом 4 Кб. Тогда получается, что TLB нужно хранить в SDRAM?
|
|
|
|
|
Dec 28 2010, 10:01
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Цитата И какие в этом проблемы? Да проблем с этим нет. Вы не могли бы мне объяснить назначения доменов и соответственно битов AP? Вот привожу, что у меня получилось: Небольшие уточнения, правильно ли я понимаю: TLB располагаем в конце SDRAM, основную программу вначале (я для кэшируемой области памяти выделил первые 32 Мб), инициализируем ее как Write-Back, переферию делаем некэшируемой. Все, TLB готов! Если я хочу задать переменную в некэшируемой области памяти, то беру адрес, для которого TLB = 0, ну например 0x2350 0000. Тогда объявляем указатель: Код unsigned int *variable = (unsigned int *) (0x2350 0000); variable = 1234; // присваевыем, как пример, число переменной P.S. SII, спасибо Вам за ссылку!
Сообщение отредактировал ZED - Dec 28 2010, 10:02
|
|
|
|
|
Dec 28 2010, 10:30
|

Местный
  
Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070

|
Цитата(ZED @ Dec 28 2010, 16:01)  Да проблем с этим нет. Вы не могли бы мне объяснить назначения доменов и соответственно битов AP? Это для защиты памяти при многозадачной работе в общем адресном пространстве. Типа каждой задаче - свой домен, чужие объявляем недоступными. Цитата(ZED @ Dec 28 2010, 16:01)  Если я хочу задать переменную в некэшируемой области памяти, то беру адрес, для которого TLB = 0, ну например 0x2350 0000. Тогда объявляем указатель: Код unsigned int *variable = (unsigned int *) (0x2350 0000); // [b]Забыта *[/b] [b]*[/b]variable = 1234; // присваевыем, как пример, число переменной Я бы порекомендовал использовать возможности компилятора: Код #pragma location="NO_CACHE" unsigned int variable; variable = 1234; // А вот тут без звездочки В файле конфигурации линкера надо объявить секцию NO_CACHE и разместить ее в соответствующих адресах. В этом случае можно будет достаточно просто объявлять множество таких переменных, не занимаясь ручным заданием адресов Кстати, даже первый вариант можно описать в виде: #define variable (*(unsigned int *) (0x2350 0000))
|
|
|
|
|
Dec 28 2010, 11:54
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Блин код забыл прикрепить: CODE unsigned int AT91F_ARM_ReadControl() { register unsigned int ctl; ctl = __MRC(15, 0, 1, 0, 0); return ctl; }
void AT91F_ARM_WriteControl(unsigned int ctl) { __MCR(15, 0, ctl, 1, 0, 0); }
void AT91F_ARM_WriteTTB(unsigned int ttb) { __MCR(15, 0, ttb, 2, 0, 0); } void AT91F_ARM_WriteDomain(unsigned int domain) { __MCR(15, 0, domain, 3, 0, 0); }
//----------------------------------------------------------------------------- // Размер страницы = 4 Kб (0x1000) // Раскладка по памяти: // 0000 0000 - Boot Memory // 0010 0000 - ROM, не используется (32 Кб) // 0020 0000 - SRAM0 (4 Кб) // 0030 0000 - SRAM1 (4 Кб) // 0050 0000 - UHP (16 Кб) // 2000 0000 - SDRAM (32 Mб) // 4000 0000 - NAND DATA // 4020 0000 - NAND ADDR // 4040 0000 - NAND CMD // FFF0 0000 - Периферия //-----------------------------------------------------------------------------
//----------------------------------------------------------------------------- // Описания секций: // [1..0] = "01"; // 2 - B - Bufferable; // 3 - C - Cacheable; // 4 - '1'; // [8..5] - Domain = "1111"; // 9 = '0'; // [11..10] - AP; // [19..12] = "00000000" // [31..20] - Базовый адрес секции
// Биты AP // 01 - Нет доступа (No Access) // 10 - Только чтение (Read-only) // 11 - Чтение/Запись (Read/write)
// Биты C и B: // 0 0 - Не Кэшируемая, Не Буферизируемая // 0 1 - Не Кэшируемая, Буферизируемая // 1 0 - Write-Trough-кеш // 1 1 - Write-Back-кеш //-----------------------------------------------------------------------------
#define TLB_ADDR 0x2F000000 // Базовый адрес расположения TLB в памяти #define TLB_NCNB 0xDF2 // Noncachable, Nonbufferable 11 0 1111 1 00 10 #define TLB_WT 0xDFA // Write-through 11 0 1111 1 10 10 #define TLB_WB 0xDFE // Write-back 11 0 1111 1 11 10
// Инициализация MMU: void AT91F_InitMMU(void) { // TLB располагается в SDRAM unsigned int *TLB = (unsigned int *) (TLB_ADDR); unsigned int i, ctl; // Инициализация TTB: AT91F_ARM_WriteTTB(TLB_ADDR); // Записать начальный адрес расположения TTB (CP15 c2) AT91F_ARM_WriteDomain(0xFFFFFFFF); // Domain Access Control Register (CP15 c3) // Очистка TLB: for (i = 0; i < 4096; ++i) TLB[i] = 0; // После Reamp по адресу 0x00000000 расположена SRAM0: TLB[0x000] = 0x00000000 | TLB_WB; // После Reamp по адресу 0x00100000 расположена ROM: TLB[0x001] = 0x00100000 | TLB_NCNB; // SRAM1: TLB[0x003] = 0x00300000 | TLB_WB; // UHP: TLB[0x005] = 0x00500000 | TLB_WB; // Код основной программы, расположенный в SDRAM (32 Мб): for (i = 0x200; i < 0x200 + 31; i++){ TLB[i] = (i << 20) | TLB_WB; } // Переферия: TLB[0xFFF] = 0xFFF00000 | TLB_NCNB //Разрешить MMU ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 0); AT91F_ARM_WriteControl(ctl); //Разрешить I-Cache ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 12); AT91F_ARM_WriteControl(ctl); //Разрешить D-Cache ctl = AT91F_ARM_ReadControl(); ctl |= (1 << 2); AT91F_ARM_WriteControl(ctl); } Цитата И еще не имеет особого смысла, особенно для 9260 кэшировать СРАМ Т.е. эта строчка лишьняя: Код // После Reamp по адресу 0x00000000 расположена SRAM0: TLB[0x000] = 0x00000000 | TLB_WB; Цитата Чисто совет. Кэш - отличная штука. Ускоряет так нормально. И если не мудрить, то просто работаешь как обычно. Кэшируемая или не кэшеруемая память - это важно лишь в очень специфических случаях. В обычной жизни такие случаи не встречаются. Вот видимо у меня такой случай. Я все это делаю, чтобы запустить EMAC на вышеупомянутом контроллере. И вот в теме, которую я открыл, чтобы с ним разобраться EMAC AT91SAM9260. Так вот в этой теме мне сказали, цитирую: Цитата дескрипторы должны быть в не кешируемой области. Вот поэтому я так все дотошно и спрашиваю, хочу разобраться. Просто еще несколько месяцев назад я вообще не знал что такое ARM процессоры, IAR, J-Link и т.д. Не говоря уже о кэшах, MMU и всего подобного.
|
|
|
|
|
Dec 28 2010, 21:25
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Вообще, лучше все же применять творческий подход, а не рубить сразу - тут кэшируем, а тут не кэшируем. Во многих случаях может быть весьма уместен режим write-through (например, у framebuffer'а экрана), построчная или полная инвалидизация кэша (как раз при работе с буферами ПДП), залочка части программы/данных для критичных участков и т.п. Понятно, что сразу подобные упражнения могут и не понадобиться, но списывать их со счетов, один раз все настроив и забыв, совсем не стоит.
|
|
|
|
|
Dec 29 2010, 06:36
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Теперь возникли проблемы с PLL. Хотел протестировать работу MMU, для этого написал код дрыгания ножкой. В этом коде есть функция инициализации PLL: Код // Частота медленного RC-генератора SLCK 32.768 кГц. Период 1/32768 = 30.51 мкс // Максимальное время запуска основоного генератора: 75 мкс // Время запуска основного генератора:8 * OSCOUNT(=16) * 30.51 мкс = 3.9 мс // Запуск основного генератора: AT91C_BASE_PMC->PMC_MOR = (AT91C_CKGR_OSCOUNT & (0x40 << 8)) | AT91C_CKGR_MOSCEN; // Ждать пока пройдет время запуска: while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MOSCS)); // Переключение блока задающей частоты на основную тактовую частоту AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_CSS_MAIN_CLK; // Настройка PLL на частоту 192 МГц: AT91C_BASE_PMC->PMC_PLLAR = ( AT91C_CKGR_SRCA // 29 бит = 1 | (0x2 << 14) // OUTA = 2 | (0xBF << 8) // PLLACOUNT = 191 | (AT91C_CKGR_MULA & (0x7C << 16)) // MULA = 124 | (AT91C_CKGR_DIVA & 12)); // DIVA = 12 // Ждать пока пройдет время запуска: while(!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_LOCKA)); // Выбор задающей частоты и тактовой частоты процессора: // Предделитель тактовой частоты PRES = 1, Предделитель задающей частоты MDIV = 2. AT91C_BASE_PMC->PMC_MCKR = AT91C_PMC_PRES_CLK | AT91C_PMC_MDIV_1; // Ждать пока пройдет время запуска: while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); // В качестве основной частоты использовать частоту PLL: AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK; // Ждать пока пройдет время запуска: while (!(AT91C_BASE_PMC->PMC_SR & AT91C_PMC_MCKRDY)); Проблема в том, что на строчке: Код AT91C_BASE_PMC->PMC_MCKR |= AT91C_PMC_CSS_PLLA_CLK; IAR выдает следующее: Цитата Wed Dec 01 12:30:11 2010: The stack 'CSTACK' is filled to 99% (4087 bytes used out of 4096). The warning threshold is set to 90.% Wed Dec 01 12:30:11 2010: The stack 'IRQ_STACK' is filled to 95% (92 bytes used out of 96). The warning threshold is set to 90.% Полазил по форуму, там написано, что все дело в REMAP. Пробовал делать REMAP вручную: Код AT91C_BASE_MATRIX->MATRIX_MRCR = AT91C_MATRIX_RCA926I | AT91C_MATRIX_RCA926D; Все тоже самое. Помогите разобраться. Кстати еще вопрос, с какой примерно частотой у меня должна будет дрыгаться ножка при включенном MMU и Кэшах?
|
|
|
|
|
Dec 29 2010, 07:18
|

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

|
В жизни не получал таких варнингов от ИАР. Скорее всего потому, что стараюсь не передавать слишком много параметров в функции. И слежу за вложенностью... Ремап никак не связан с варнингами. (Или это симулятор-отладчик такое выдает?) Ремап надо делать или не делать в зависимости от надобности. Код B __iar_program_start ; это должна быть первой строчкой вашего стартапа.
__iar_program_start:
/********************************************************************** * ?CSTARTUP * * Execution starts here. * After a reset, the mode is ARM, Supervisor, interrupts disabled. */ ?cstartup: tst PC, #0x300000; test for current map beq _after_remap;
mvn r0, #0xFF ;remap here bic r0,r0, #0x1100 mov r1, #0x03 str r1, [r0, #+0]
_after_remap: В этом коде проверяется где нах. программа и делается ремап если надо. Ассемблера АРМ не знаю, делал наугад. Но работает железно. ---- По поводу ковыряния с кэшем - согласен с aaarrr - но только все делать последовательно. Сначала что по проще (написать и забыть), а уж потом, когда придет понимание процессов с одной стороны и нужда - с другой - то можно и потренироваться с управлением кэшем. Про ножку. Смотря откуда код исполняется... В даташите гляньте - там должна быть указана частота тактирования портов. Вот больше нее - никак. (Если порты тут тактируются - не помню). Лучше проверять по DBGU. Типа, работает - не работает.
--------------------
On the road again (Canned Heat)
|
|
|
|
|
Dec 29 2010, 07:52
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Цитата Ремап никак не связан с варнингами. (Или это симулятор-отладчик такое выдает?) Именно он, когда дохожу до вышеуказанной строчки. Цитата Скорее всего потому, что стараюсь не передавать слишком много параметров в функции. Так функция и не содержит никаких параметров: void Init_CLK(void).
|
|
|
|
|
Dec 29 2010, 08:22
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
В sdram.icf задано: Код define symbol __ICFEDIT_size_cstack__ = 0x1000; P.S. Забыл указать, что прошиваю и отлаживаюсь с помощью J-Link for ARM от IAR System.
|
|
|
|
|
Dec 29 2010, 08:36
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Цитата А IRQ стек? Код define symbol __ICFEDIT_size_irqstack__ = 0x60; Только ругается он на CSTACK.
Сообщение отредактировал ZED - Dec 29 2010, 08:37
|
|
|
|
|
Dec 29 2010, 08:58
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Ну я вообщето взял готовый проект getting-started-project-at91sam9260-ek и просто вставил туда свой код. Цитата 1. Написать свой загрузчик. Который бы грузил нечто в SRAM. 2. Это нечто из SRAM может по командам с PC либо записать что-то во флэшку, либо записать нечто в SDRAM и запустить это нечто (Предварительно, разумеется, инициализировав SDRAM). А можно пример?
Сообщение отредактировал ZED - Dec 29 2010, 09:00
|
|
|
|
|
Dec 29 2010, 10:00
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414

|
Цитата(ZED @ Dec 28 2010, 16:01)  правильно ли я понимаю: TLB располагаем в конце SDRAM Неправильно  TLB -- это внутренний узел устройства управления памятью (MMU), а посему в памяти ну никак находиться не может. Говоря упрощённо, TLB -- это кэш-память, в которой хранятся последние использованные строки таблиц переадресации. А вот эти самые таблицы действительно хранятся в памяти, откуда MMU их по мере надобности считывает и кэширует в TLB. Местоположение таблиц в памяти роли само по себе не играет, надо лишь обеспечить их правильное выравнивание (граница 16 Кбайт для таблицы первого уровня, если склероз не подводит). Так что выделяете под них то место, какое для Вас лично удобно, и всё. Цитата(ZED @ Dec 29 2010, 14:58)  Ну я вообщето взял готовый проект getting-started-project-at91sam9260-ek и просто вставил туда свой код. К готовым проектам относитесь настороженно и достаточно критически: их качество оставляет желать. Меня в своё время поразил стартовый код для 9261, я даже по этому поводу небольшим сообщением разродился. Цитата А можно пример? Вообще, эта задача, хотя и не слишком сложная, тривиальной тоже не является. Фактически всякие там SAM-BA и прочие средства программирования примерно так и работают: по JTAG загружают в оперативу некий код и запускают его на выполнение, а уже он обеспечивает запись во флэш-память, при необходимости подгружая информацию с ПК. В общем, пример не такой маленький получится, да и не уверен, что найти его просто...
|
|
|
|
|
Dec 30 2010, 03:27
|
Местный
  
Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102

|
Цитата По поводу примера. Это действительно не так чтоб очень,но большая работа. Но вполне по силам любому. А счего начать? Я даже не совсем представляю как все это должно выглядеть.
Сообщение отредактировал ZED - Dec 30 2010, 03:28
|
|
|
|
|
Jan 14 2011, 21:49
|
Местный
  
Группа: Свой
Сообщений: 276
Регистрация: 22-09-05
Из: Kiev
Пользователь №: 8 818

|
Цитата 1. Пишите PC программу, которая сможет загонять в SRAM файл и запускать его. Зачем советовать человеку изобретать велосипед?  Для этих целей есть SAB-BA. Если не будете доверять штатному инструментарию, то у вас не останется времени на сам проект...
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|