ZiB 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба Всем, привет! Осваиваю AT91SAM7S256. Eclipse + GCC + SAM-ICE. Запустил демо проект с сайта at91.com (getting-started-project-1.4-at91sam7s-ek) В функции конфигурации DBGU модуля, установка (точнее расчет) скорости обмена занимает почти 3 секунды. AT91C_BASE_DBGU->DBGU_BRGR = mck / (baudrate * 16); // mck = 48 000 000, baudrate = 9600 так как апаратного деления у ARM-а нет, то деление происходит программным способом. Вопрос: Насколько оптимально производит деление компилаятор gcc? в сравнении с IAR-ом? Планирую в проекте использовать цело численное деление. void DBGU_Configure(unsigned int mode, unsigned int baudrate, unsigned int mck) { // Reset & disable receiver and transmitter, disable interrupts AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX; AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF; // Configure baud rate AT91C_BASE_DBGU->DBGU_BRGR = mck / (baudrate * 16); // Configure mode register AT91C_BASE_DBGU->DBGU_MR = mode; // Disable DMA channel AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS; // Enable receiver and transmitter AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN; } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
klen 1 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба целочисленное деление если я не ошибаюсь не дольше числа(если предположить что операции однотактовые ) тактов равное числу битов операндов + небольшие накладные расходы в зависимосто от архитектуры проца. Я както мерял, получалось на случайных данных порядка 20 тактов на arm7tdmi. Мож в другом засада? Для 3-х секеунд это как то уж вообще сложно объяснение придумать, пустого цикла задержки отладчика в crt-коде нет? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба В функции конфигурации DBGU модуля, установка (точнее расчет) скорости обмена занимает почти 3 секунды. AT91C_BASE_DBGU->DBGU_BRGR = mck / (baudrate * 16); // mck = 48 000 000, baudrate = 9600 Эта строчка выполняется 3 секунды? Вы же понимаете, что это невозможно. Ищете, где на самом деле пропадает время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZiB 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба Да, именно в этой строчке. При замене baudrate на константу 9600 девайс тестовую посылку отсылаем "мгновенно" после включения. Конечно я понимаю что так не должно быть, грешу на gcc... Сижу пытаюсь отлаживать через SAM-ICE, пока асм армовский плохо знаю... Качаю IAR, попробую в нем... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MrYuran 21 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба Да, именно в этой строчке. При замене baudrate на константу 9600 девайс тестовую посылку отсылаем "мгновенно" после включения. Бред. Такие операции на любом полудохлом AVR'e пролетают со свистом. И неважно, в ИАРе или ГСС Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Methane 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба Да, именно в этой строчке. При замене baudrate на константу 9600 девайс тестовую посылку отсылаем "мгновенно" после включения. Конечно я понимаю что так не должно быть, грешу на gcc... Сижу пытаюсь отлаживать через SAM-ICE, пока асм армовский плохо знаю... Качаю IAR, попробую в нем... Есть команда objdump дизасемблируйте эту строчку и посмотрите. Или в ассемблер прокомпилируйте. (gcc -S aaa.c) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZiB 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба Собственно этим и занимаюсь... DBGU_Init(9600); 1000f0: e59f3094 ldr r3, [pc, #148] ; 10018c <main+0xec> 1000f4: e3a00d96 mov r0, #9600 ; 0x2580 1000f8: e1a0e00f mov lr, pc 1000fc: e12fff13 bx r3 void DBGU_Init(unsigned int BaudRate) { 1002f0: e92d4010 push {r4, lr} // сброс приемника и передачика AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX; 1002f4: e3a0300c mov r3, #12 ; 0xc 1002f8: e3e04c0d mvn r4, #3328 ; 0xd00 1002fc: e50430ff str r3, [r4, #-255] // запрет прерываний AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF; 100300: e3e03000 mvn r3, #0 ; 0x0 // установка скорости передачи AT91C_BASE_DBGU->DBGU_BRGR = CHIP_MCK / (BaudRate * 16); 100304: e1a01200 lsl r1, r0, #4 { // сброс приемника и передачика AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RSTRX | AT91C_US_RSTTX; // запрет прерываний AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF; 100308: e50430f3 str r3, [r4, #-243] // установка скорости передачи AT91C_BASE_DBGU->DBGU_BRGR = CHIP_MCK / (BaudRate * 16); 10030c: e59f0040 ldr r0, [pc, #64] ; 100354 <DBGU_Init+0x64> 100310: e59f3040 ldr r3, [pc, #64] ; 100358 <DBGU_Init+0x68> 100314: e1a0e00f mov lr, pc 100318: e12fff13 bx r3 // устанвока режима работы // (asynchronous, 8bit, no parity) AT91C_BASE_DBGU->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL; 10031c: e3a03b02 mov r3, #2048 ; 0x800 // запрет прерываний AT91C_BASE_DBGU->DBGU_IDR = 0xFFFFFFFF; // установка скорости передачи AT91C_BASE_DBGU->DBGU_BRGR = CHIP_MCK / (BaudRate * 16); 100320: e50400df str r0, [r4, #-223] // устанвока режима работы // (asynchronous, 8bit, no parity) AT91C_BASE_DBGU->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL; 100324: e50430fb str r3, [r4, #-251] // отключаем DMA канал AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS; 100328: e59f302c ldr r3, [pc, #44] ; 10035c <DBGU_Init+0x6c> // подключаем линии ввода-вывода к DBGU // запрещаем прерывания AT91C_BASE_PIOA->PIO_IDR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; 10032c: e3e01c0b mvn r1, #2816 ; 0xb00 // устанвока режима работы // (asynchronous, 8bit, no parity) AT91C_BASE_DBGU->DBGU_MR = AT91C_US_PAR_NONE | AT91C_US_CHMODE_NORMAL; // отключаем DMA канал AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS; 100330: e5843021 str r3, [r4, #33] // подключаем линии ввода-вывода к DBGU // запрещаем прерывания AT91C_BASE_PIOA->PIO_IDR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; 100334: e3a02c06 mov r2, #1536 ; 0x600 AT91C_BASE_PIOA->PIO_ASR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; // передача управления перефирии AT91C_BASE_PIOA->PIO_PDR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; // разрешаем работу приемника и передатчика AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN; 100338: e3a03050 mov r3, #80 ; 0x50 // отключаем DMA канал AT91C_BASE_DBGU->DBGU_PTCR = AT91C_PDC_RXTDIS | AT91C_PDC_TXTDIS; // подключаем линии ввода-вывода к DBGU // запрещаем прерывания AT91C_BASE_PIOA->PIO_IDR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; 10033c: e50120bb str r2, [r1, #-187] // разрешаем внутренний подтягивающий резистор AT91C_BASE_PIOA->PIO_PPUER = AT91C_PA10_DTXD | AT91C_PA9_DRXD; 100340: e501209b str r2, [r1, #-155] // подключение к перифирии А AT91C_BASE_PIOA->PIO_ASR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; 100344: e501208f str r2, [r1, #-143] // передача управления перефирии AT91C_BASE_PIOA->PIO_PDR = AT91C_PA10_DTXD | AT91C_PA9_DRXD; 100348: e50120fb str r2, [r1, #-251] // разрешаем работу приемника и передатчика AT91C_BASE_DBGU->DBGU_CR = AT91C_US_RXEN | AT91C_US_TXEN; 10034c: e50430ff str r3, [r4, #-255] } 100350: e8bd8010 pop {r4, pc} 100354: 02dc6c00 .word 0x02dc6c00 100358: 001003d4 .word 0x001003d4 10035c: 00000202 .word 0x00000202 001003d4 <__aeabi_uidiv>: 1003d4: e2512001 subs r2, r1, #1 ; 0x1 1003d8: 012fff1e bxeq lr 1003dc: 3a000036 bcc 1004bc <__aeabi_uidiv+0xe8> 1003e0: e1500001 cmp r0, r1 1003e4: 9a000022 bls 100474 <__aeabi_uidiv+0xa0> 1003e8: e1110002 tst r1, r2 1003ec: 0a000023 beq 100480 <__aeabi_uidiv+0xac> 1003f0: e311020e tst r1, #-536870912 ; 0xe0000000 1003f4: 01a01181 lsleq r1, r1, #3 1003f8: 03a03008 moveq r3, #8 ; 0x8 1003fc: 13a03001 movne r3, #1 ; 0x1 100400: e3510201 cmp r1, #268435456 ; 0x10000000 100404: 31510000 cmpcc r1, r0 100408: 31a01201 lslcc r1, r1, #4 10040c: 31a03203 lslcc r3, r3, #4 100410: 3afffffa bcc 100400 <__aeabi_uidiv+0x2c> 100414: e3510102 cmp r1, #-2147483648 ; 0x80000000 100418: 31510000 cmpcc r1, r0 10041c: 31a01081 lslcc r1, r1, #1 100420: 31a03083 lslcc r3, r3, #1 100424: 3afffffa bcc 100414 <__aeabi_uidiv+0x40> 100428: e3a02000 mov r2, #0 ; 0x0 10042c: e1500001 cmp r0, r1 100430: 20400001 subcs r0, r0, r1 100434: 21822003 orrcs r2, r2, r3 100438: e15000a1 cmp r0, r1, lsr #1 10043c: 204000a1 subcs r0, r0, r1, lsr #1 100440: 218220a3 orrcs r2, r2, r3, lsr #1 100444: e1500121 cmp r0, r1, lsr #2 100448: 20400121 subcs r0, r0, r1, lsr #2 10044c: 21822123 orrcs r2, r2, r3, lsr #2 100450: e15001a1 cmp r0, r1, lsr #3 100454: 204001a1 subcs r0, r0, r1, lsr #3 100458: 218221a3 orrcs r2, r2, r3, lsr #3 10045c: e3500000 cmp r0, #0 ; 0x0 100460: 11b03223 lsrsne r3, r3, #4 100464: 11a01221 lsrne r1, r1, #4 100468: 1affffef bne 10042c <__aeabi_uidiv+0x58> 10046c: e1a00002 mov r0, r2 100470: e12fff1e bx lr 100474: 03a00001 moveq r0, #1 ; 0x1 100478: 13a00000 movne r0, #0 ; 0x0 10047c: e12fff1e bx lr 100480: e3510801 cmp r1, #65536 ; 0x10000 100484: 21a01821 lsrcs r1, r1, #16 100488: 23a02010 movcs r2, #16 ; 0x10 10048c: 33a02000 movcc r2, #0 ; 0x0 100490: e3510c01 cmp r1, #256 ; 0x100 100494: 21a01421 lsrcs r1, r1, #8 100498: 22822008 addcs r2, r2, #8 ; 0x8 10049c: e3510010 cmp r1, #16 ; 0x10 1004a0: 21a01221 lsrcs r1, r1, #4 1004a4: 22822004 addcs r2, r2, #4 ; 0x4 1004a8: e3510004 cmp r1, #4 ; 0x4 1004ac: 82822003 addhi r2, r2, #3 ; 0x3 1004b0: 908220a1 addls r2, r2, r1, lsr #1 1004b4: e1a00230 lsr r0, r0, r2 1004b8: e12fff1e bx lr 1004bc: e52de008 str lr, [sp, #-8]! 1004c0: eb000007 bl 1004e4 <__aeabi_idiv0> 1004c4: e3a00000 mov r0, #0 ; 0x0 1004c8: e49df008 ldr pc, [sp], #8 001004cc <__aeabi_uidivmod>: 1004cc: e92d4003 push {r0, r1, lr} 1004d0: ebffffbf bl 1003d4 <__aeabi_uidiv> 1004d4: e8bd4006 pop {r1, r2, lr} 1004d8: e0030092 mul r3, r2, r0 1004dc: e0411003 sub r1, r1, r3 1004e0: e12fff1e bx lr 001004e4 <__aeabi_idiv0>: 1004e4: e12fff1e bx lr Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Flexz 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба А какой именно GCC используете? mck и baudrate - константы, очень странно, что компилятор это не посчитал на этапе компиляции и не вставил константу в код. Обычно всё наоборот - когда нужно что бы значение обязательно считалось в программе на этапе выполнения, приходится везде тыкать volatile. В плане диагностики - дергайте ножку порта до и после деления и смотрите осцилографом время. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZiB 0 19 марта, 2009 Опубликовано 19 марта, 2009 · Жалоба хух, все встало на свои места после того как убрал -mlong-calls из Makefile... сейчас разбираюсь что за штука. Хотя во всех примерах Makefile содержит данную опцию. # ---------------------------------------------------------------------------- # ATMEL Microcontroller Software Support # ---------------------------------------------------------------------------- # Copyright © 2008, Atmel Corporation # # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: # # - Redistributions of source code must retain the above copyright notice, # this list of conditions and the disclaimer below. # # Atmel's name may not be used to endorse or promote products derived from # this software without specific prior written permission. # # DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR # IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE # DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, # OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF # LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, # EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ---------------------------------------------------------------------------- # Makefile for compiling the Getting Started project #------------------------------------------------------------------------------- # User-modifiable options #------------------------------------------------------------------------------- # Chip & board used for compilation # (can be overriden by adding CHIP=chip and BOARD=board to the command-line) CHIP = at91sam7s256 BOARD = at91sam7s-ek # Optimization level, put in comment for debugging #OPTIMIZATION = -Os # AT91 library directory AT91LIB = ../at91lib # Output file basename OUTPUT = getting-started-project-$(BOARD)-$(CHIP) # Compile for all memories available on the board (this sets $(MEMORIES)) include $(AT91LIB)/boards/$(BOARD)/board.mak # Output directories BIN = bin OBJ = obj #------------------------------------------------------------------------------- # Tools #------------------------------------------------------------------------------- # Tool suffix when cross-compiling CROSS = arm-elf- # Compilation tools CC = $(CROSS)gcc SIZE = $(CROSS)size STRIP = $(CROSS)strip OBJCOPY = $(CROSS)objcopy # Flags INCLUDES = -I$(AT91LIB)/boards/$(BOARD) -I$(AT91LIB)/peripherals INCLUDES += -I$(AT91LIB)/components -I$(AT91LIB) CFLAGS = -mlong-calls -ffunction-sections -Wall CFLAGS += -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) #-DNOTRACE ASFLAGS = -g $(OPTIMIZATION) $(INCLUDES) -D$(CHIP) -D__ASSEMBLY__ LDFLAGS = -g $(OPTIMIZATION) -nostartfiles -Wl,--gc-sections #------------------------------------------------------------------------------- # Files #------------------------------------------------------------------------------- # Directories where source files can be found UTILITY = $(AT91LIB)/utility PERIPH = $(AT91LIB)/peripherals BOARDS = $(AT91LIB)/boards VPATH += $(UTILITY) VPATH += $(PERIPH)/dbgu $(PERIPH)/aic $(PERIPH)/pio $(PERIPH)/pit $(PERIPH)/tc VPATH += $(BOARDS)/$(BOARD) $(BOARDS)/$(BOARD)/$(CHIP) # Objects built from C source files C_OBJECTS = main.o C_OBJECTS += led.o stdio.o C_OBJECTS += dbgu.o pio.o aic.o pio_it.o pit.o tc.o C_OBJECTS += board_memories.o board_lowlevel.o # Objects built from Assembly source files ASM_OBJECTS = board_cstartup.o # Append OBJ and BIN directories to output filename OUTPUT := $(BIN)/$(OUTPUT) #------------------------------------------------------------------------------- # Rules #------------------------------------------------------------------------------- all: $(BIN) $(OBJ) $(MEMORIES) $(BIN) $(OBJ): mkdir $@ define RULES C_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(C_OBJECTS)) ASM_OBJECTS_$(1) = $(addprefix $(OBJ)/$(1)_, $(ASM_OBJECTS)) $(1): $$(ASM_OBJECTS_$(1)) $$(C_OBJECTS_$(1)) $(CC) $(LDFLAGS) -T"$(AT91LIB)/boards/$(BOARD)/$(CHIP)/[email protected]" -o $(OUTPUT)[email protected] $$^ $(OBJCOPY) -O binary $(OUTPUT)[email protected] $(OUTPUT)[email protected] $(SIZE) $$^ $(OUTPUT)[email protected] $$(C_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.c Makefile $(CC) $(CFLAGS) -D$(1) -c -o $$@ $$< $$(ASM_OBJECTS_$(1)): $(OBJ)/$(1)_%.o: %.S Makefile $(CC) $(ASFLAGS) -D$(1) -c -o $$@ $$< endef $(foreach MEMORY, $(MEMORIES), $(eval $(call RULES,$(MEMORY)))) clean: -rm -f $(OBJ)/*.o $(BIN)/*.bin $(BIN)/*.elf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться