Перейти к содержанию
    

AT91SAM7S деление

Всем, привет!

 

Осваиваю 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;
}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

целочисленное деление если я не ошибаюсь не дольше числа(если предположить что операции однотактовые ) тактов равное числу битов операндов + небольшие накладные расходы в зависимосто от архитектуры проца. Я както мерял, получалось на случайных данных порядка 20 тактов на arm7tdmi.

 

Мож в другом засада? Для 3-х секеунд это как то уж вообще сложно объяснение придумать, пустого цикла задержки отладчика в crt-коде нет?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В функции конфигурации DBGU модуля, установка (точнее расчет) скорости обмена занимает почти 3 секунды.

AT91C_BASE_DBGU->DBGU_BRGR = mck / (baudrate * 16); // mck = 48 000 000, baudrate = 9600

Эта строчка выполняется 3 секунды? Вы же понимаете, что это невозможно. Ищете, где на самом деле пропадает время.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, именно в этой строчке.

При замене baudrate на константу 9600 девайс тестовую посылку отсылаем "мгновенно" после включения.

Конечно я понимаю что так не должно быть, грешу на gcc...

Сижу пытаюсь отлаживать через SAM-ICE, пока асм армовский плохо знаю...

Качаю IAR, попробую в нем...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, именно в этой строчке.

При замене baudrate на константу 9600 девайс тестовую посылку отсылаем "мгновенно" после включения.

Бред.

Такие операции на любом полудохлом AVR'e пролетают со свистом.

И неважно, в ИАРе или ГСС

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да, именно в этой строчке.

При замене baudrate на константу 9600 девайс тестовую посылку отсылаем "мгновенно" после включения.

Конечно я понимаю что так не должно быть, грешу на gcc...

Сижу пытаюсь отлаживать через SAM-ICE, пока асм армовский плохо знаю...

Качаю IAR, попробую в нем...

Есть команда objdump дизасемблируйте эту строчку и посмотрите. Или в ассемблер прокомпилируйте. (gcc -S aaa.c)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Собственно этим и занимаюсь...

 

  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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А какой именно GCC используете?

mck и baudrate - константы, очень странно, что компилятор это не посчитал на этапе компиляции и не вставил константу в код. Обычно всё наоборот - когда нужно что бы значение обязательно считалось в программе на этапе выполнения, приходится везде тыкать volatile.

 

В плане диагностики - дергайте ножку порта до и после деления и смотрите осцилографом время.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хух, все встало на свои места после того как убрал -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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...