реклама на сайте
подробности

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> MMU D-Cache I-Cache для ARM926EJ-S, Как работает и как настроить?
vmp
сообщение Dec 28 2010, 08:44
Сообщение #16


Местный
***

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



Цитата(ZED @ Dec 28 2010, 13:46) *
Тогда получается, что TLB нужно хранить в SDRAM?

И какие в этом проблемы? В моем примере так и сделано.
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 28 2010, 09:47
Сообщение #17


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



Цитата(vmp @ Dec 28 2010, 15:44) *
И какие в этом проблемы? В моем примере так и сделано.


Единственное, надо чтобы TLB лежала в некешеруемой области sdram.
Go to the top of the page
 
+Quote Post
ZED
сообщение Dec 28 2010, 10:01
Сообщение #18


Местный
***

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
vmp
сообщение Dec 28 2010, 10:30
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 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))
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Dec 28 2010, 10:51
Сообщение #20


Гуру
******

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



Чисто совет. Кэш - отличная штука. Ускоряет так нормально.
И если не мудрить, то просто работаешь как обычно.
Кэшируемая или не кэшеруемая память - это важно лишь в очень специфических случаях. В обычной жизни такие случаи не встречаются.

И еще не имеет особого смысла, особенно для 9260 кэшировать СРАМ. Ибо врядли вы там будете прямой доступ к памяти организовывать, а быстродействие кэша и СРАМ одинаковое. (Кэш срам полезен, когда в ней не только программа работает, но и область прямого доступа есть. Тогда программа работаетв кэше, а память свободна для DMA).


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 28 2010, 11:24
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Цитата(sergeeff @ Dec 28 2010, 15:47) *
Единственное, надо чтобы TLB лежала в некешеруемой области sdram.

Ни малейшей необходимости в этом нет.

P.S. TLB = Translation Lookaside Buffer, а таблица называется Translation Table.
Go to the top of the page
 
+Quote Post
ZED
сообщение Dec 28 2010, 11:54
Сообщение #22


Местный
***

Группа: Свой
Сообщений: 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 и всего подобного.
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Dec 28 2010, 13:02
Сообщение #23


Гуру
******

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



Ну и что что в некэшируемой. Ставите нужный битик в описании нужной страницы и все. И она уже некэшируемая.
Всякие там буфера прямого доступа, оне приравниваются по своему сволочизму к аппаратным регистрам.


--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post
sergeeff
сообщение Dec 28 2010, 21:02
Сообщение #24


Профессионал
*****

Группа: Свой
Сообщений: 1 481
Регистрация: 10-04-05
Пользователь №: 4 007



To ZED:

У Atmel'a, чтобы не было проблем с когерентностью буферов и DMA надо просто все буфера для DMA объявить в некешируемой области. Для этого прислушайтесь к совету vmp. В чистом виде это относится и к EMAC (там еще особые требования по выравниванию адресов таблиц).
Go to the top of the page
 
+Quote Post
aaarrr
сообщение Dec 28 2010, 21:25
Сообщение #25


Гуру
******

Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448



Вообще, лучше все же применять творческий подход, а не рубить сразу - тут кэшируем, а тут не кэшируем. Во многих случаях может быть весьма уместен режим write-through (например, у framebuffer'а экрана), построчная или полная инвалидизация кэша (как раз при работе с буферами ПДП), залочка части программы/данных для критичных участков и т.п. Понятно, что сразу подобные упражнения могут и не понадобиться, но списывать их со счетов, один раз все настроив и забыв, совсем не стоит.
Go to the top of the page
 
+Quote Post
ZED
сообщение Dec 29 2010, 03:24
Сообщение #26


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102



Спасибо Вам большое за советы и помощь!
Go to the top of the page
 
+Quote Post
ZED
сообщение Dec 29 2010, 06:36
Сообщение #27


Местный
***

Группа: Свой
Сообщений: 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 и Кэшах?
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Dec 29 2010, 07:18
Сообщение #28


Гуру
******

Группа: Участник
Сообщений: 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)
Go to the top of the page
 
+Quote Post
ZED
сообщение Dec 29 2010, 07:52
Сообщение #29


Местный
***

Группа: Свой
Сообщений: 264
Регистрация: 17-04-07
Из: Москва
Пользователь №: 27 102



Цитата
Ремап никак не связан с варнингами. (Или это симулятор-отладчик такое выдает?)

Именно он, когда дохожу до вышеуказанной строчки.

Цитата
Скорее всего потому, что стараюсь не передавать слишком много параметров в функции.

Так функция и не содержит никаких параметров: void Init_CLK(void).
Go to the top of the page
 
+Quote Post
DpInRock
сообщение Dec 29 2010, 08:19
Сообщение #30


Гуру
******

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



Симуляторы и отладчики - зло.
Вообще тогда смотрите размер стека. Если по умолчанию, то там совсем маленькие стеки (0x10).
А если разрешены вложенные прерывания, то совсем будет плохо....




--------------------
On the road again (Canned Heat)
Go to the top of the page
 
+Quote Post

3 страниц V  < 1 2 3 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 21st July 2025 - 20:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.0153 секунд с 7
ELECTRONIX ©2004-2016