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

 
 
3 страниц V  < 1 2 3 >  
Reply to this topicStart new topic
> AT91SAM9G45, Настройка частоты работы GPIO
Sergey1212
сообщение Apr 24 2013, 18:19
Сообщение #16


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596



Цитата(Fedor @ Apr 24 2013, 21:07) *
И пропишите для вашей переменой i квалификатор register будет быстрее.


Смысл в том что я хочу его в ддр запустить но пока что там что там работает одинаково поэтому в сраме и эксперементирую больше чем в ддраме ожидаю увеличения производительности сначало в сраме
VDDPIO 3.3
register завтра попробую добавить

Сообщение отредактировал IgorKossak - Apr 24 2013, 18:40
Причина редактирования: избыточное цитирование
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 24 2013, 19:58
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



в дизасемблере надо смотреть что за такты в цикле, нет ли каких лишних на экономию регистров. На самом деле после компилятора на максимальной оптимизации я уверен смотреть нечего, и предложил это больше для вашего самоуспокоения. То есть вы бы увидели код, поняли что меньше 6 инструкций (или сколько там получается) не будет и успокоились бы)...


про кэш все абсолютно понятно. При работе кода из ДДР каждая инструкция требует чтение из памяти. Читать из ДДР - это далеко не 1 такт, там куча задержек на выбор ряда, колонки, потом просто ожидание данных и так далее. Чтение 1 инструкции из ДДР - это реально долго. Но если выбрать область памяти внутри проца, где время чтения 1 такт, и запихивать в нее куски кода из ДДР (а последовательно ДДР читает значительно быстрее, первая задержка считай делиться на все байты последовательности). Эти куски кода будут помещаться в кэш, тем более если есть циклы иногда они будут туда влезать целиком, и каждая инструкция будет выполнятся за 1 такт. Это и дает бешеный прирост производительности, без изменения вида кода.
Go to the top of the page
 
+Quote Post
Fedor
сообщение Apr 25 2013, 05:23
Сообщение #18


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125



Не мешает проверить также на какую область памяти у вас указывает sp
Если в DRAM то настроить MMU так, чтобы стек тоже кэшировался.
Go to the top of the page
 
+Quote Post
Sergey1212
сообщение Apr 25 2013, 09:08
Сообщение #19


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596



Цитата(Fedor @ Apr 25 2013, 09:23) *
Не мешает проверить также на какую область памяти у вас указывает sp
Если в DRAM то настроить MMU так, чтобы стек тоже кэшировался.

А как посмотреть куда указывает sp?
Просто не доганяю как в эклипсовском дизасемблере это проделать))
да и думаю если я бутстрапом подгружаю приложение в ддр то наверное и переменная i будет там же
И как настроить MMU чтобы стек кэшировался?
Есть где нибудь примеры или описание с кусками кода в пример как вообще это настраивать этот MMU и все остальное?
Где можно почитать о всяких таблицах и т.д.?

Драм вариант в эмуляторе не запускается поэтому там дизассемблером посмотреть немогу а в срамовсом варианте sp указывает на срам область 0x30ff80

Сообщение отредактировал Sergey1212 - Apr 25 2013, 08:36
Go to the top of the page
 
+Quote Post
Fedor
сообщение Apr 25 2013, 09:46
Сообщение #20


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125



Цитата(Sergey1212 @ Apr 25 2013, 15:08) *
А как посмотреть куда указывает sp?...
Драм вариант в эмуляторе не запускается поэтому там дизассемблером посмотреть немогу а в срамовсом варианте sp указывает на срам область 0x30ff80


В конфигурационном файле для линковшика (*.ld, *.lds) обычно прописывается точка-указатель которым инициализируется SP в стартап файле. В самом стартап-файле прописываются вектора прерываний, начальная загрузка и проч. в том числе и загрузка указателя стека. Этот стартап файл написан на ассемблере (*.S, *.asm). Все это должно быть у вас в исходниках проекта. Поскольку в арме стэк это обычная область памяти, настройка MMU не отличается, лишь бы область стека попала в кэшируемую часть памяти.
Go to the top of the page
 
+Quote Post
Sergey1212
сообщение Apr 25 2013, 10:57
Сообщение #21


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596



Вот lds:
CODE
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(entry)

MEMORY
{
sram (W!RX) : ORIGIN = 0x300000, LENGTH = 64K
ddr_ebi0 (W!RX) : ORIGIN = 0x73f00000, LENGTH = 64M
}

SECTIONS
{
.fixed :
{
. = ALIGN(4);
_sfixed = .;
*(.text*)
*(.rodata*)
*(.glue_7)
*(.glue_7t)
*(.data)
*(.CP15_*)
. = ALIGN(4);
_efixed = .;
} >ddr_ebi0

.prerelocate : AT (_efixed)
{
. = ALIGN(4);
_sprerelocate = .;
. = ALIGN(4);
_eprerelocate = .;
}

.postrelocate : AT (_efixed + SIZEOF(.prerelocate))
{
. = ALIGN(4);
_spostrelocate = .;
*(.vectors);
*(.ramfunc)
. = ALIGN(4);
_epostrelocate = .;
} >sram

.bss (NOLOAD) : {
_szero = .;
*(.bss)
. = ALIGN(4);
_ezero = .;
} >ddr_ebi0

_sstack = 0x73f00000 + 64 * 1024 * 1024;
}
end = .;

А вот стартап:
CODE
#include "board.h"

//------------------------------------------------------------------------------
// Definitions
//------------------------------------------------------------------------------

#define IRQ_STACK_SIZE 8*3*4

#define ARM_MODE_ABT 0x17
#define ARM_MODE_FIQ 0x11
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13

#define I_BIT 0x80
#define F_BIT 0x40

//------------------------------------------------------------------------------
// Startup routine
//------------------------------------------------------------------------------

.align 4
.arm

/* Exception vectors
*******************/
.section .vectors, "a", %progbits

resetVector:
ldr pc, =resetHandler /* Reset */
undefVector:
b undefVector /* Undefined instruction */
swiVector:
b swiVector /* Software interrupt */
prefetchAbortVector:
b prefetchAbortVector /* Prefetch abort */
dataAbortVector:
b dataAbortVector /* Data abort */
reservedVector:
b reservedVector /* Reserved for future use */
irqVector:
b irqHandler /* Interrupt */
fiqVector:
/* Fast interrupt */
//------------------------------------------------------------------------------
/// Handles a fast interrupt request by branching to the address defined in the
/// AIC.
//------------------------------------------------------------------------------
fiqHandler:
b fiqHandler

//------------------------------------------------------------------------------
/// Handles incoming interrupt requests by branching to the corresponding
/// handler, as defined in the AIC. Supports interrupt nesting.
//------------------------------------------------------------------------------
irqHandler:

/* Save interrupt context on the stack to allow nesting */
sub lr, lr, #4
stmfd sp!, {lr}
mrs lr, SPSR
stmfd sp!, {r0, lr}

/* Write in the IVR to support Protect Mode */
ldr lr, =AT91C_BASE_AIC
ldr r0, [lr, #AIC_IVR]
str lr, [lr, #AIC_IVR]

/* Branch to interrupt handler in Supervisor mode */
msr CPSR_c, #ARM_MODE_SVC
stmfd sp!, {r1-r3, r4, r12, lr}
blx r0

/* Restore scratch/used registers and LR from User Stack */
/* Disable Interrupt and switch back in IRQ mode */
ldmia sp!, {r1-r3, r4, r12, lr}
msr CPSR_c, #ARM_MODE_IRQ | I_BIT

/* Acknowledge interrupt */
ldr lr, =AT91C_BASE_AIC
str lr, [lr, #AIC_EOICR]

/* Restore interrupt context and branch back to calling code */
ldmia sp!, {r0, lr}
msr SPSR_cxsf, lr
ldmia sp!, {pc}^

//------------------------------------------------------------------------------
/// Initializes the chip and branches to the main() function.
//------------------------------------------------------------------------------
.section .text
.global entry

entry:
resetHandler:

/* Useless instruction for referencing the .vectors section */
ldr r0, =resetVector

/* Set pc to actual code location (i.e. not in remap zone) */
ldr pc, =1f

/* Initialize the prerelocate segment */
1:
ldr r0, =_efixed
ldr r1, =_sprerelocate
ldr r2, =_eprerelocate
1:
cmp r1, r2
ldrcc r3, [r0], #4
strcc r3, [r1], #4
bcc 1b

/* Perform low-level initialization of the chip using LowLevelInit() */
ldr sp, =_sstack
stmfd sp!, {r0}
ldr r0, =LowLevelInit
blx r0

/* Initialize the postrelocate segment */

ldmfd sp!, {r0}
ldr r1, =_spostrelocate
ldr r2, =_epostrelocate
1:
cmp r1, r2
ldrcc r3, [r0], #4
strcc r3, [r1], #4
bcc 1b

/* Clear the zero segment */
ldr r0, =_szero
ldr r1, =_ezero
mov r2, #0
1:
cmp r0, r1
strcc r2, [r0], #4
bcc 1b

/* Setup stacks
**************/
/* IRQ mode */
msr CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT
ldr sp, =_sstack
sub r4, sp, #IRQ_STACK_SIZE

/* Supervisor mode (interrupts enabled) */
msr CPSR_c, #ARM_MODE_SVC | F_BIT
mov sp, r4

/* Branch to main()
******************/
ldr r0, =main
blx r0

/* Loop indefinitely when program is finished */
1:
b 1b


Почему если я запускаю только айкеш производительность возрастает по сравнению с тем когда запускаю ММУ датакеш и айкеш в 1,5 раза

вот на всякий случай мой код включения мму дата и айкешей
CODE
static unsigned char *BufMMU = (unsigned char *) (SRAM_ADDRESS + 0x4000);

#include "cp15/cp15.h" //Atmel at91lib

void InitMMU(unsigned int *pTranslationTable)
{
int i;
int addSRAM;

// Program the TTB
printf("TTB = 0x%X\n\r", (unsigned int)pTranslationTable);

CP15_WriteTTB((unsigned int)pTranslationTable);

// Program the domain access register
CP15_WriteDomainAccessControl(0xFFFFFFFF); // domain 15: access are not checked

// Reset table entries
for (i = 0; i < 4096; i++) {
//printf("0x%X %d \r\n", (i << 20 | (3 << 10) | 0x12), (i << 20 | (3 << 10) | 0x12));
pTranslationTable[i] = i << 20 | (3 << 10) | 0x12;
}
// Program level 1 page table entry

// Vector adress
pTranslationTable[0x0] = (0x00000000)|TLB_NCNB;
// SRAM adress (with D cache)
addSRAM = (SRAM_ADDRESS >> 20);
printf("addSRAM = 0x%X\n\r", addSRAM);
printf("SRAM_ADDRESS = 0x%X\n\r", SRAM_ADDRESS);
pTranslationTable[addSRAM] = (SRAM_ADDRESS)|TLB_WB;
//DDRAM buf1 with write-through
pTranslationTable[0x701] = (AT91C_DDR2 + 0x00100000)|TLB_WT;
//DDRAM buf2 with write-through
pTranslationTable[0x702] = (AT91C_DDR2 + 0x00200000)|TLB_WT;
// Peripherals adress

pTranslationTable[0xFFF] = (0xFFF00000)|TLB_NCNB;
CP15_EnableMMU();
CP15_EnableDcache();
CP15_EnableIcache();
}

void main(void)
{
InitMMU((unsigned int*)BufMMU);

unsigned int mask = (1<<20);

AT91S_PIOM *pioa;
pioa = PIOA_BASE;
pio_enable(pioa, mask);
pio_disable_irq(pioa, mask);
pio_disable_multiple_driver(pioa, mask);
pio_disable_pull_ups(pioa, mask);
pio_output_enable(pioa, mask);

volatile unsigned int i;
while(1)
{
i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++
;i++;
PIO_ClearM(pioa, mask);
i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++;i++
;i++;
PIO_SetM(pioa, mask);
}
}


pTranslationTable[i] = i << 20 | (3 << 10) | 0x12;
Эту строку взял из убута до этого было
pTranslationTable[i] = 0
И при этом не работали мму и дкеш
но производительность при включении мму и дкеша сразу уменьшается чем это можно объяснить?

Сообщение отредактировал IgorKossak - Apr 25 2013, 13:58
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
Fedor
сообщение Apr 25 2013, 14:08
Сообщение #22


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125



Код
pTranslationTable[i] = i << 20 | (3 << 10) | 0x12;

Эта запись организует TLB и запрещает кеширование выбранных секций.
Т.е. в данном случае для всего адресуемого 4GB.
В убуте это видимо сделанно намеренно чтобы избежать коллизий при перезагрузке из линукса

Код
pTranslationTable[0x701] = (AT91C_DDR2 + 0x00100000)|TLB_WT;
//DDRAM buf2 with write-through
pTranslationTable[0x702] = (AT91C_DDR2 + 0x00200000)|TLB_WT;
// Peripherals adress

Здесь вы почемуто разрешаете кеширование, но для секций которые находятся вообще вне вашей области DRAM, судя по скрипту lds оно начинается с 0x73f00000, а у вас включено на 0x70100000 и на 0x70200000 ?
Код
ddr_ebi0 (W!RX) : ORIGIN = 0x73f00000, LENGTH = 64M

Видимо пример был для другого случая.
И вот такое |TLB_WT по моему больше подходит для перемещения массивов из одной области в другую, вам лучше write-back включить.
Вобщем судя по настройке MMU и DCaсhe хоть и включен, но бестолку.
Думаю, что нужно прочитать ARM926EJ-S Technical Reference Manual Complete.

Код
_sstack = 0x73f00000 + 64 * 1024 * 1024;

это ваш верх стека из lds.

Go to the top of the page
 
+Quote Post
Sergey1212
сообщение Apr 25 2013, 16:55
Сообщение #23


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596



поправил
pTranslationTable[i] = i << 20 | (3 << 10) | 0xDFE // Write-back 11 0 1111 1 11 10
т.е. как я понимаю разрешил кеширование всех секций?
а чем может быть опасно кеширование секций всмысле почему в том же убуте запрещено?
если кеширование разрешено то какие подводные камни могут выплыть?)
Какие области памяти не стоит кешированть?
зачем отдельно от мму есть возможность оключать датакеш?
зачем их вообще отключать почему нельзя было сделать их все время включеными?
если я буду кешировать все секции кроме 0x00000000 как сейчас получилось могут возникнуть какие-то проблемы?

Сообщение отредактировал Sergey1212 - Apr 25 2013, 17:23
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Apr 25 2013, 17:36
Сообщение #24


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



При работе периферии с прямым доступом к памяти (PDC работает с памятью, а данные могут быть в кэше при WB, читаем данные из кэша - а в памяьи данные изменены по PDC).
Периферию вообще как некэшируюмую область описать надо.

Сообщение отредактировал Genadi Zawidowski - Apr 25 2013, 17:37
Go to the top of the page
 
+Quote Post
Fedor
сообщение Apr 25 2013, 17:52
Сообщение #25


Участник
*

Группа: Участник
Сообщений: 73
Регистрация: 26-10-05
Пользователь №: 10 125




Не нужно кэшировать область памяти где расположена внутренняя периферия.
Куда читаете или пишете используя DMA, поскольку ЦП не знает про DMA , хотя вроде после каждой транзакции можно принудительно перезаливать кэш.
Смысл кэшировать сегиент кода? Это не данные для этого есть ICache.
Думаю что есть еще нюансы...
Ну и нужно помнить что кэш данных не даст существенного прироста производительности если вы работаете с данными из разрозненных областей памяти вне пределов размера кэша.
Go to the top of the page
 
+Quote Post
taoga
сообщение Apr 25 2013, 18:28
Сообщение #26


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



Вот код инициализации MMU из softpack для sam9g35.
Прикрепленный файл  mmu.rar ( 1.68 килобайт ) Кол-во скачиваний: 57
Go to the top of the page
 
+Quote Post
Sergey1212
сообщение Apr 25 2013, 18:30
Сообщение #27


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596



Цитата(Fedor @ Apr 25 2013, 21:52) *
Смысл кэшировать сегиент кода? Это не данные для этого есть ICache.

Извеняюсь конечно но чет я не понимаю не фига)
бутстрапом приложение копируется в 0x73f00000 это получается сегмент кода для которого достаточно только ICache?
а где тогда сегмент данных?
ICache кеширует только сам код программы?
а чем занимаются DCache и MMU?

Go to the top of the page
 
+Quote Post
taoga
сообщение Apr 25 2013, 18:55
Сообщение #28


Участник
*

Группа: Участник
Сообщений: 51
Регистрация: 8-10-09
Пользователь №: 52 809



Для измерения скорости работы проца можно использовать basic-dhrystone-project. Я использую его для sam9g35, до этого для sam9xe. Максимальную скорость дает включение полной оптимизации по скорости(iar). Примеры atmel это конечно полный отстой, в плане того, что все они работают только при отключенном MMU. Если немного поискать можно найти много информации по MMU на этом форуме. А если хотите все знать ищите информацию по ARM926EJ.
Go to the top of the page
 
+Quote Post
Sergey1212
сообщение Apr 25 2013, 19:06
Сообщение #29


Участник
*

Группа: Участник
Сообщений: 22
Регистрация: 23-04-13
Пользователь №: 76 596



Да пожалуй на пока инфы и примеров достаточно, надо теперь все переварить, в субботу выложу результаты полученные с хорошего осциллографа, по предварительным косвенным оценкам производительность вычисления i++ выросла в 25 раз! было 100 нс теперь предположительно должна стать 4 нс. Ногодрыгание имеющимся сейчас осциллографом не разглядеть.
Всем большое спасибо за ответы.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Apr 25 2013, 20:51
Сообщение #30


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



Цитата(Sergey1212 @ Apr 25 2013, 22:30) *
Извеняюсь конечно но чет я не понимаю не фига)
бутстрапом приложение копируется в 0x73f00000 это получается сегмент кода для которого достаточно только ICache?
а где тогда сегмент данных?
ICache кеширует только сам код программы?
а чем занимаются DCache и MMU?


к дополнительному перевариванию надо в общих чертах про кэши и АРМ.

У вас в проце отдельно шина данных и шина команд. Первые идеи были положить и данные и инструкции в одну память и сложение выглядело так

загрузить адрес инструкции
загрузить инструкцию
распознать ее, понять что надо складывать
загрузить адрес первого операнда
загрузить операнд
загрузить адрес 2 операнда
загрузить операнд
сложить
получить адрес результата
загрузить адрес результата
выложить данные.

Если к этому добавить что операнды обычно лежат черти как, а инструкции одна за одной, при это операнды лежат там где появились, а иснтрукции идут вперед и вперед, всем показалось разумным разделить области с операндами и инструкциями. При том пошли радикально, и разделили даже шины доступа к ним. А потом борясь с медленной памятью сделали кэши, вот мы и имеем их 2 штуки.
кеш данных - на шине данных кеширует операнды
кеш инструкций - на шине инструкций кеширует выполняемый код

Кеши имеют разные алгоритмы работы, но в целом они автоматизированы, попали в ячейку памяти забрали ее и некую область вокруг. Попали в область кеша работаем из него, промазали, сбросили кеш загрузили новую область. Размер кеша допустим 4 кбайта, если вы будите тыкаться в ячейки расположенные друг от друга в 5 кбайтах так и будет постоянный сброс кеша и загрузка, будет медленее чем без него.

И вот тут как я понимаю и помогает ММУ, как я понял при помощи него вы можете положить себе поближе нужные куски памяти, и постараться учесть как будет вести себя программа, как она будет и куда прыгать и так далее.. То есть это как бы интеллектуальный, управляемый кеш... Хотя я могу ошибаться, и тогда меня поправятsm.gif...

Если шину данных и адреса использовать для управления чем либо, то есть выставляя биты на ножках адреса и данных, то кешировать это пространство низя, данные будт в кеше, а ножки не будут шевелиться. Так же как и для переферии если надо менять ее регистры, то кеш не даст это делать, вы будите менять внутреннюю память проца (кеш), а не регистры. Ну и при обращении через ДМА - тоже беда, рассинхронизация памяти...
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 Текстовая версия Сейчас: 17th June 2025 - 20:37
Рейтинг@Mail.ru


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