| Author |
Message
|
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#1
09 Jan 2011 17:57 WinAvr zła kompilacja... |
|
|
|
Witam, robię projekt "sterownik cd" z EP2002/7 i próbuje skompilować podany kod, niby wszystko się kompiluje dobrze. Analizując plik ""hex"" w AVRstudio wykryłem że kompilator pozbył się skoków do funkcji "SetAdress..." oto kawałek kodu w C oraz wynik już skompilowanego kodu:
| Code: |
u08 SetAddress(u08 cs, u08 adr)
{
u16 i;
if (cs==CTRL)
i = adr+0x08; // select A4 low -> CS1 -> CTRL
else
i = adr+0x10; // select A3 low -> CS0 -> CMD
return *(u08 *) (0xE000+i);//
}
//----------------------------------------------------------------------------
// Read data BYTE from Drive
//----------------------------------------------------------------------------
u08 ReadBYTE(u08 cs, u08 adr)
{
u08 tmp;
SetAddress(cs,adr);
cbi(MCUCR, SRE); // disable RAM
outp(0x00, DDRA); // port A as input
outp(0x00, DDRC); // port C as input
outp(0xff, PORTA); // activate Pullups
outp(0xff, PORTC); // activate Pullups
cbi(PORTB, 1); // set DIOR lo
asm volatile ("nop"); // allow pin change
tmp = inp(PINA); // read byte
sbi(PORTB, 1); // set DIOR hi
asm volatile ("nop"); // allow pin change
sbi(MCUCR, SRE); // enable RAM
return tmp;
}
//----------------------------------------------------------------------------
// Write data BYTE to Drive
//----------------------------------------------------------------------------
void WriteBYTE(u08 cs, u08 adr, u08 dat)
{
SetAddress(cs,adr);
outp(0xff, DDRA); // port A as output
outp(0xff, DDRC); // port C as output
cbi(MCUCR, SRE); // disable RAM
asm volatile ("nop"); // allow pin change
outp(dat, PORTA); // write byte
cbi(PORTB, 0); // set DIOW lo
asm volatile ("nop"); // allow pin change
asm volatile ("nop"); // allow pin change
sbi(PORTB, 0); // set DIOW hi
sbi(MCUCR, SRE); // enable RAM
}
|
assembler :
| Code: |
SetAddress...
+00000165: 2F98 MOV R25,R24
+00000166: 2F26 MOV R18,R22
+00000167: 2733 CLR R19
+00000168: 2399 TST R25
+00000169: F419 BRNE PC+0x04
+0000016A: 01F9 MOVW R30,R18
+0000016B: 9638 ADIW R30,0x08
+0000016C: C002 RJMP PC+0x0003
+0000016D: 01F9 MOVW R30,R18
+0000016E: 9670 ADIW R30,0x10
+0000016F: 50E0 SUBI R30,0x00
+00000170: 42F0 SBCI R31,0x20
+00000171: 8180 LDD R24,Z+0
+00000172: 2799 CLR R25
+00000173: 9508 RET
ReadBYTE.... <--- brak skoku do SetAdress
+00000174: B785 IN R24,0x35
+00000175: 778F ANDI R24,0x7F
+00000176: BF85 OUT 0x35,R24
+00000177: BA1A OUT 0x1A,R1
+00000178: BA14 OUT 0x14,R1
+00000179: EF8F SER R24
+0000017A: BB8B OUT 0x1B,R24
+0000017B: BB85 OUT 0x15,R24
+0000017C: 98C1 CBI 0x18,1
+0000017D: 0000 NOP
+0000017E: B399 IN R25,0x19
+0000017F: 9AC1 SBI 0x18,1
+00000180: 0000 NOP
+00000181: B785 IN R24,0x35
+00000182: 6880 ORI R24,0x80
+00000183: BF85 OUT 0x35,R24
+00000184: 2F89 MOV R24,R25
+00000185: 2799 CLR R25
+00000186: 9508 RET
WriteBYTE.... <--- brak skoku do SetAdress
+00000187: EF8F SER R24
+00000188: BB8A OUT 0x1A,R24
+00000189: BB84 OUT 0x14,R24
+0000018A: B785 IN R24,0x35
+0000018B: 778F ANDI R24,0x7F
+0000018C: BF85 OUT 0x35,R24
+0000018D: 0000 NOP
+0000018E: BB4B OUT 0x1B,R20
+0000018F: 98C0 CBI 0x18,0
+00000190: 0000 NOP
+00000191: 0000 NOP
+00000192: 9AC0 SBI 0x18,0
+00000193: B785 IN R24,0x35
+00000194: 6880 ORI R24,0x80
+00000195: BF85 OUT 0x35,R24
+00000196: 9508 RET
|
Kompilator nie uwzględnia skoków do "SetAdress", co zrobić by to poprawnie kompilowało. Używam WinAvr 20030310 ale próbowałem na najnowszych wersjach i nic to nie dało wynik ten sam. Optymalizację mam ustawioną na "-S", przy "-0" niby jest dobrze ale za to do procedur dodaje za dużo kodu. Pomocy...!!!
Podaje jeszcze plik make :
| Quote: |
# WinAVR Sample makefile (c) 2002-2003 Eric B. Weddington
# Released to the Public Domain
# Please read the make user manual!
#
#
# On command line:
# make all = Make software.
# make clean = Clean out built project files.
# make coff = Convert ELF to COFF using objtool.
#
# To rebuild project do make clean then make all.
#
# MCU name
MCU = atmega161
# Output format. (can be srec, ihex)
FORMAT = ihex
# Target file name (without extension).
TARGET = cdrom
# Optimization level (can be 0, 1, 2, 3, s)
# (Note: 3 is not always the best optimization level. See avr-libc FAQ)
OPT = s
# List C source files here. (C dependencies are automatically generated.)
SRC = $(TARGET).c \
ata_if.c delay.c uart.c
# List Assembler source files here.
ASRC =
# Optional compiler flags.
CFLAGS = -g -O$(OPT) -funsigned-char -funsigned-bitfields -fpack-struct \
-fshort-enums -Wall -Wstrict-prototypes -Wa,-ahlms=$(<:.c=.lst)
# Optional assembler flags.
ASFLAGS = -Wa,-ahlms=$(<:.s=.lst), -gstabs
# Optional linker flags.
LDFLAGS = -Wl,-Map=$(TARGET).map,--cref
# Additional library flags (-lm = math library).
LIBFLAGS = -lm
# ---------------------------------------------------------------------------
# Define directories, if needed.
DIRAVR = c:/winavr2
DIRAVRBIN = $(DIRAVR)/bin
DIRAVRUTILS = $(DIRAVR)/utils/bin
DIRINC = .
DIRLIB = $(DIRAVR)/avr/lib
# Define programs and commands.
SHELL = sh
CC = avr-gcc
OBJCOPY = avr-objcopy
OBJDUMP = avr-objdump
REMOVE = rm -f
COPY = cp
ELFCOFF = objtool
HEXSIZE = @avr-size --target=$(FORMAT) $(TARGET).hex
ELFSIZE = @avr-size $(TARGET).elf
FINISH = @echo Errors: none
BEGIN = @echo -------- begin --------
END = @echo -------- end --------
# Define all object files.
OBJ = $(SRC:.c=.o) $(ASRC:.s=.o)
# Define all listing files.
LST = $(ASRC:.s=.lst) $(SRC:.c=.lst)
# Combine all necessary flags and optional flags. Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
ALL_LDFLAGS = -mmcu=$(MCU) $(LDFLAGS)
# Default target.
all: begin gccversion sizebefore $(TARGET).elf $(TARGET).hex $(TARGET).eep $(TARGET).lss sizeafter finished end
# Eye candy.
begin:
$(BEGIN)
finished:
$(FINISH)
end:
$(END)
# Display size of file.
sizebefore:
@echo Size before:
-$(HEXSIZE)
sizeafter:
@echo Size after:
$(HEXSIZE)
# Display compiler version information.
gccversion :
$(CC) --version
# Target: Convert ELF to COFF for use in debugging / simulating in AVR Studio.
coff: $(TARGET).cof end
%.cof: %.elf
$(ELFCOFF) loadelf $< mapfile $*.map writecof $@
# Create final output files (.hex, .eep) from ELF output file.
%.hex: %.elf
$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
%.eep: %.elf
-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
# Create extended listing file from ELF output file.
%.lss: %.elf
$(OBJDUMP) -h -S $< > $@
# Link: create ELF output file from object files.
.SECONDARY : $(TARGET).elf
.PRECIOUS : $(OBJ)
%.elf: $(OBJ)
$(CC) $(ALL_LDFLAGS) $(OBJ) $(LIBFLAGS) --output $@
# Compile: create object files from C source files.
%.o : %.c
$(CC) -c $(ALL_CFLAGS) $< -o $@
# Assemble: create object files from assembler source files.
%.o : %.s
$(CC) -c $(ALL_ASFLAGS) $< -o $@
# Target: clean project.
clean: begin clean_list finished end
clean_list :
$(REMOVE) $(TARGET).hex
$(REMOVE) $(TARGET).eep
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).cof
$(REMOVE) $(TARGET).elf
$(REMOVE) $(TARGET).map
$(REMOVE) $(TARGET).obj
$(REMOVE) $(TARGET).a90
$(REMOVE) $(TARGET).sym
$(REMOVE) $(TARGET).lnk
$(REMOVE) $(TARGET).lss
$(REMOVE) $(OBJ)
$(REMOVE) $(LST)
# Automatically generate C source code dependencies. (Code taken from the GNU make user manual.)
# Note that this will work with sh (bash) and sed that is shipped with WinAVR (see the SHELL variable defined above).
# This may not work with other shells or other seds.
%.d: %.c
set -e; $(CC) -MM $(ALL_CFLAGS) $< \
| sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' > $@; \
[ -s $@ ] || rm -f $@
# Remove the '-' if you want to see the dependency files generated.
-include $(SRC:.c=.d)
# Listing of phony targets.
.PHONY : all begin finish end sizebefore sizeafter gccversion coff clean clean_list
|
|
|
| Back to top |
|
 |
maly_elektronik Poziom 19

Joined: 18 Nov 2006 Posts: 659 Location: Pisarzowice
|
#2
09 Jan 2011 18:50 Re: WinAvr zła kompilacja... |
|
|
|
Deassemblery nie są zbyt dokładne :)
Spróbuj zaprogramować i zobaczyć czy czasem układ nie będzie działał poprawnie :)
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4766 Location: Katowice
|
#3
09 Jan 2011 20:40 Re: WinAvr zła kompilacja... |
|
|
|
Jeśli się tej funkcji pozbył to zupełnie prawidłowo zrobił - zobacz co ta funkcja robi i zastanów się po co ma to robić jeśli jej wynik jest nieużywany.
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#4
09 Jan 2011 23:45 Re: WinAvr zła kompilacja... |
|
|
|
Co do deasembler'a to dobrze działa. Co do funkcji 'SetAdress' ustawia bity nastawne dla złącza IDE, na adresie A0-A7 za pomocą instrukcji odczytu "LDD r24, Z" co daje automatyczne ustawienie na zatrzasku 74hc543 tak jak jest na schemacie z EP, tego projektu. Po wyjściu z tej funkcji wyłączana jest pamięć ram i następnie są ustawiane inne dane dla odczytu lub zapisu dla złącza IDE.
Ustawienia linii z pliku "ata_if.c"
| Quote: |
//----------------------------------------------------------------------------
// Select address and CS signals
//
// addressing bits
// 35 DA0 A0 0x01 Address Line 0
// 33 DA1 A1 0x02 Address Line 1
// 36 DA2 A2 0x04 Address Line 2
//
// chip selects
// 37 CS0 A3 0x08 Command Block Select
// 38 CS1 A4 0x10 Control Block Select
//
//
//----------------------------------------------------------------------------
|
Wydaje mi się że kompilator uznał że funkcja nic nie zwraca i usunął ją z głównych procedur, ale bez niej ustawienia się nie zmienią więc program się nie wykona. Nie musze programować by sprawdzić czy działa czy nie skoro już na pierwsze oko widać że kompilacja jest nie pełna. Można by te dane ustawić inaczej ale poco wtedy używać języka 'c' skoro w asemblerze bym miał to co chcę. Czyli kompilator jest do kitu...
|
|
| Back to top |
|
 |
Google

|
#
09 Jan 2011 23:45 |
|
|
|
|
|
| Back to top |
|
 |
sulfur Poziom 18

Joined: 19 May 2010 Posts: 505 Location: Częstochowa
|
#5
09 Jan 2011 23:53 Re: WinAvr zła kompilacja... |
|
|
|
A mnie się wydaje, że kompilator uznał, że funkcja coś zwraca, ale autor kodu z tego nie korzysta, a zatem rezultat funkcji nie jest potrzebny. Proszę zastosować się do rad kolegi tmf.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4766 Location: Katowice
|
#6
10 Jan 2011 00:07 Re: WinAvr zła kompilacja... |
|
|
|
| operator5wp wrote: |
Co do deasembler'a to dobrze działa. Co do funkcji 'SetAdress' ustawia bity nastawne dla złącza IDE, na adresie A0-A7 za pomocą instrukcji odczytu "LDD r24, Z" co daje automatyczne ustawienie na zatrzasku 74hc543 tak jak jest na schemacie z EP, tego projektu. Po wyjściu z tej funkcji wyłączana jest pamięć ram i następnie są ustawiane inne dane dla odczytu lub zapisu dla złącza IDE.
Wydaje mi się że kompilator uznał że funkcja nic nie zwraca i usunął ją z głównych procedur, ale bez niej ustawienia się nie zmienią więc program się nie wykona. Nie musze programować by sprawdzić czy działa czy nie skoro już na pierwsze oko widać że kompilacja jest nie pełna. Można by te dane ustawić inaczej ale poco wtedy używać języka 'c' skoro w asemblerze bym miał to co chcę. Czyli kompilator jest do kitu... |
Kolego, więcej pokory, zanim napiszesz, że kompilator jest do kitu, szczególnie, że twoja wiedza o C jak widać jest nikła.
Ta funkcja nic nie robi, jeśli jej wynik jest ignorowany i kompilator słusznie przy optymalizacji ją wywalił. To co piszesz to pobożne intencje autora tego kodu a nie rzeczywistość. Żeby odczyt spod adresu, który tam jest wyliczany był dokonywany niezależnie czy wynik jest potrzebny, czy nie, brakuje magicznego modyfikatora volatile przy rzutowaniu typów.
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#7
10 Jan 2011 00:57 Re: WinAvr zła kompilacja... |
|
|
|
Dla kompilatora nic nie robi, to fakt. Co do "c" to za bardzo go nie lubię i nie znam go dobrze, bardziej preferuje asembler bo wiem co jest w kodzie... spróbowałem z tym "volatile" i zrobiłem tak:
| Quote: |
u08 SetAddress(u08 cs, u08 adr)
{
u16 i;
if (cs==CTRL)
i = adr+0x08; // select A4 low -> CS1 -> CTRL
else
i = adr+0x10; // select A3 low -> CS0 -> CMD
return *(volatile u08 *) (0xE000+i); //<-- tu dałem 'volatile'
}
|
teraz po kompilacji funkcja jest już w asemblerze dobrze skompilowana. Tyle się męczyłem i przez takie coś straciłem tyle czasu. Jeszcze sprawdzę czy inne funkcje są dobrze przetworzone. Tylko czemu oryginalny kod nie ma tej zmiennej przecież nawet starszy winavr też źle kompilował , chyba że kod był kompilowany bez optymalizacji. Dzięki i pozdrawiam, ale i tak wolę asembler.
|
|
| Back to top |
|
 |
_marek Poziom 15

Joined: 18 Jun 2010 Posts: 207 Location: Bydgoszcz
|
#8
10 Jan 2011 13:07 Re: WinAvr zła kompilacja... |
|
|
|
Witam.
Z całym szacunkiem dla dobrych chęci poprzedników i znajomości asemblera ale nie o volatile tu chodzi. Tak poprawiona funkcja nie wnosi nic do programu i jest równoznaczna z usunięciem jej przez kompilator.
Proszę zwrócić uwagę na jej ciało. W żaden sposób nie wpływa ono na jakąkolwiek zmienną globalną ,statyczną, wskaźnik czy rejestrI/O. Funkcja ta jedynie zwraca wynik a używanie jej w sposób:
typ funkcja(x,y);
jest sugerowaniem że w 4literach mamy wartość którą zwraca(pomijając obcinanie tego wyniku).
Więc co ta funkcja w ogóle tam robi ?
|
|
| Back to top |
|
 |
szelus Poziom 20

Joined: 12 Jul 2004 Posts: 1016
|
#9
10 Jan 2011 14:11 Re: WinAvr zła kompilacja... |
|
|
|
| operator5wp wrote: |
Tylko czemu oryginalny kod nie ma tej zmiennej przecież nawet starszy winavr też źle kompilował , chyba że kod był kompilowany bez optymalizacji.
|
Może był kompilowany bez optymalizacji, a może optymalizacje były mniej zaawansowane. Nie byłby to pierwszy w historii przypadek kodu działającego przez przypadek...
| _marek wrote: |
Z całym szacunkiem dla dobrych chęci poprzedników i znajomości asemblera ale nie o volatile tu chodzi. ... |
Nie masz racji. Normalnie kompilator nie może usunąć wywołania funkcji (z uwagi na możliwe tzw. uboczne efekty jej działania). Jednakże w sytuacji gdy kompilator zna w momencie wywołania ciało funkcji może rozpatrzyć w procesie optymalizacji wszystkie efekty jej działania (tak, jak w przypadku inline).
Funkcja SetAddress() rzeczywiście nie miała żadnych efektów ubocznych, poza zwracanym wynikiem, więc kompilator słusznie uznał, że skoro wynik jest niepotrzebny, to i funkcja jest niepotrzebna. Dodanie kwalifikatora volatile przy odczycie spod wskaźnika informuje kompilator, że ten odczyt ma efekty uboczne (bo tak jest) i nie może być optymalizowany. Bez tej informacji skąd kompilator miałby wiedzieć, że jest jakiś zewnętrzny hardware, który coś tam robi?
|
|
| Back to top |
|
 |
Google

|
#
10 Jan 2011 14:11 |
|
|
|
|
|
| Back to top |
|
 |
_marek Poziom 15

Joined: 18 Jun 2010 Posts: 207 Location: Bydgoszcz
|
#10
10 Jan 2011 14:36 Re: WinAvr zła kompilacja... |
|
|
|
Jeśli funkcja "coś tam robiąca" będzie typu void ,lub będziemy jawnie korzystać ze zwracanej wartości kompilator niczego nam nie usunie. Takie efekty uboczne i "łatanie ich" gmatwają tylko kod i sprawiają problemy wymagające czasu, czego przykładem jest autor tematu.
Więc jaki miało sens wymuszenie wstawienia tego fragmentu do kodu i nie korzystanie z niego ?
Tego właśnie nie rozumiem.
|
|
| Back to top |
|
 |
szelus Poziom 20

Joined: 12 Jul 2004 Posts: 1016
|
#11
10 Jan 2011 15:43 Re: WinAvr zła kompilacja... |
|
|
|
Że nie jest to ładnie i przejrzyście napisany kod, to się oczywiście zgadzam.
Jeżeli chodzi o sens wymuszania, to niedoczytałeś:
| operator5wp wrote: |
Co do funkcji 'SetAdress' ustawia bity nastawne dla złącza IDE, na adresie A0-A7 za pomocą instrukcji odczytu "LDD r24, Z" co daje automatyczne ustawienie na zatrzasku 74hc543 tak jak jest na schemacie z EP, tego projektu.
|
Odczyt spod adresu E0xx powoduje odpowiednie ustawienie zewnętrznego rejestru i o tym trzeba było poinformować kompilator. Czy czytana wartość jest gdzieś jeszcze używana w kodzie, to nie mam pojęcia. Jeżeli nie, to funkcja powinna być zadeklarowana jako void, jeżeli gdzieś indziej jest ta zwracana wartość używana, to to wywołanie powinno być zrzutowane na void dla przejrzystości.
|
|
| Back to top |
|
 |
Google

|
#
10 Jan 2011 15:43 |
|
|
|
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#12
10 Jan 2011 16:00 Re: WinAvr zła kompilacja... |
|
|
|
Analizując kod, to odczyt z tej funkcji nigdzie nie jest zapisywany jedynie jest to użyte do ustawiania tych danych adresowych... Ja nie jestem autorem kodu ale moim zdaniem ta funkcja powinna być jakoś inaczej rozwiązana by nie powodować takich kłopotów przy kompilacji... W załączniku dałem plik ze strony projektu... Pozdrawiam.
|
|
| Back to top |
|
 |
szelus Poziom 20

Joined: 12 Jul 2004 Posts: 1016
|
#13
10 Jan 2011 16:33 Re: WinAvr zła kompilacja... |
|
|
|
Ze schematu mi wychodzi, że sygnały RD/WR zewnetrznej pamięci nie są w tym projekcie wykorzystane - ergo, nie ma znaczenia czy piszemy, czy czytamy dla zatrzaśniecia adresu w rejestrze. Wobec tego przerobiłbym tę funkcję tak:
| Code: |
void SetAddress(u08 cs, u08 adr)
{
u16 fullAddr = 0xE000 + adr;
if (cs==CTRL)
fullAddr += 0x08; // select A4 low -> CS1 -> CTRL
else
fullAddr +=0x10; // select A3 low -> CS0 -> CMD
*(volatile u08 *)fullAddr = 0;
}
|
W razie jakbyś zmieniał, możesz przyjrzeć się ostrzeżeniom kompilatora, czy na pewno nic złego się nie dzieje.
|
|
| Back to top |
|
 |
tmf Poziom 24

Joined: 12 Aug 2009 Posts: 4766 Location: Katowice
|
#14
10 Jan 2011 16:57 Re: WinAvr zła kompilacja... |
|
|
|
| _marek wrote: |
Jeśli funkcja "coś tam robiąca" będzie typu void ,lub będziemy jawnie korzystać ze zwracanej wartości kompilator niczego nam nie usunie. Takie efekty uboczne i "łatanie ich" gmatwają tylko kod i sprawiają problemy wymagające czasu, czego przykładem jest autor tematu.
Więc jaki miało sens wymuszenie wstawienia tego fragmentu do kodu i nie korzystanie z niego ?
Tego właśnie nie rozumiem. |
Mylisz się. Tu nie chodzi o czysty język, tylko styk języka programowania ze sprzętem. Volatile informuje kompilator, że operacja, która pozornie nic nie robi musi jednak być wykonana. I nie jest to gmatwanie, tylko norma. Zmiana rezultatu funkcji na void absolutnie nie wymusi jej wykonania. Kompilator ciągle ją wywali, bo w dalszym ciągu ciało funkcji z punktu widzenia optymalizatora kompletnie nic nie robi. Z tego samego powodu homemade funkcje delay są przez optymalizator wywalane i dopiero dodanie w pętli volatile asm ("nop") temu zapobiega. Tak samo nie jest to gmatwanie, tylko dostarczanie kompilatorowi brakujących informacji o celu danej operacji.
Powyższa funkcja w tym kontekście została wykorzystana do ustawienia zatrzasku, ale jej ogólne wywołanie sugeruje, że gdzieś może być użyta do pobierania bajtu z pamięci/urządzenia leżącego w obszarze ExRAM. Z drugiej strony może z jakiegoś powodu musi być generowana operacja odczytu a autor funkcji chciał usunąć ostrzeżenie o nieużywanym rezultacie odczytu? Poza tym nikt nie uważa, że opublikowany kod musi być perfekcyjny?
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#15
10 Jan 2011 17:11 Re: WinAvr zła kompilacja... |
|
|
|
Dodam że ten kod 'cd_free', jest na bazie kodu yampp3 i tam jest wg schematu podłączona pamięć do procesora jako bufor dla odczytanych danych z twardego dysku....
|
|
| Back to top |
|
 |
_marek Poziom 15

Joined: 18 Jun 2010 Posts: 207 Location: Bydgoszcz
|
#16
11 Jan 2011 02:23 Re: WinAvr zła kompilacja... |
|
|
|
Racja.
Funkcja pozornie nic nie znacząca zostanie usunięta bez znaczenia że jest typu void.
Nawet jeśli zwraca jakąś wartość ale nic sensownego z nią nie zrobimy to i tak zniknie.
Ratuje nas volatile. Twierdziłem że to gmatwa kod ponieważ sam nie do końca wszystko
doczytałem/zrozumiałem. Albo to moje nawyki, albo nie znam innych.
Dzięki za naprowadzenie.
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8710 Location: Szczecin
|
#17
11 Jan 2011 09:45 Re: WinAvr zła kompilacja... |
|
|
|
| szelus wrote: |
Ze schematu mi wychodzi, że sygnały RD/WR zewnetrznej pamięci nie są w tym projekcie wykorzystane - ergo, nie ma znaczenia czy piszemy, czy czytamy dla zatrzaśniecia adresu w rejestrze. Wobec tego przerobiłbym tę funkcję tak:
| Code: |
void SetAddress(u08 cs, u08 adr)
{
u16 fullAddr = 0xE000 + adr;
if (cs==CTRL)
fullAddr += 0x08; // select A4 low -> CS1 -> CTRL
else
fullAddr +=0x10; // select A3 low -> CS0 -> CMD
*(volatile u08 *)fullAddr = 0;
}
|
W razie jakbyś zmieniał, możesz przyjrzeć się ostrzeżeniom kompilatora, czy na pewno nic złego się nie dzieje. |
Ale panowie po co robić jakieś cyrkowe sztuczki żeby funkcja, która zupełnie nie jest potrzebna w kodzie programu była używana - toż to jakby w ogóle nie ma najmniejszego sensu i tak też uznaje prawidłowo zresztą kompilator. Jaki cel osiągnie autor dzięki takiej przeróbce ??? ŻADEN, straci co najwyżej na pamięci FLASH która będzie zawierać niepotrzebny kod.
Pisał już o tym na początku tmf. Przypomnę, sama funkcja NIC nie robi jeśli chodzi o sprzęt, ma za zadanie tylko coś tam sprawdzić i zwrócić wynik. A wywoływana jest tak, że jej rezultat jest pomijany - więc po choinkę w ogóle ją wywoływać ???? albo bawić się volatile itp ???
Panie autor nie ma co na siłę kombinować, a jeśli coś ci nie działa w tym całym programie to na pewno nie przez ten fakt, że kompilator słusznie wywalił wszystkie skoki do tej funkcji i ją samą. Robisz gdzieś innego babola.
Wystarczy rzucić okiem na jedną z oryginalnych wersji tego programu na który się powołujesz i można stwierdzić, że albo coś sam pozmieniałeś nieumiejętnie albo przypadkowo albo nie wiem jeszcze jak. Proszę bardzo jak wygląda ta funkcja u źródeł i taka będzie się bez żadnych sztuczek kompilować:
| Code: |
u08 SetAddress(u08 addr)
{
#ifdef YAMPP3USB
cbi(MCUCR, SRE); // Disable ExtRAM
outp(0xff, DDRA);
outp(addr, PORTA);
sbi(PORTE,PE1);
cbi(PORTE,PE1);
return 0;
#else
return *(u08 *)(0xE000 + addr);
#endif
} |
o ile spełniona zostanie oczywiście istniejąca tam dyrektywa preprocesora a jeśli nie to funkcja nie zostanie tylko wtedy wywalona z kompilacji jeśli będzie brany pod uwagę jej rezultat.
Dodano po 1 [godziny] 14 [minuty]:
Powiem więcej, wychodzi na to, że autor przeróbek
| Quote: |
| Copyright (C) 2001 Pawel Dienwebel <pelos@promocja.net> |
który sam przerabiał oryginalny czyjś tam kod i dorzucał swoje rzeczy, robił to na szybko i w ogóle troszkę pomieszał ;) z tym SetAddress()
bo wychodzi na to, że to co oryginalnie było robione wewnątrz tej funkcji on poprzenosił bezpośrednio do:
ReadBYTE() oraz WriteBYTE()
natomiast jakby niechcący pozostawił wywołania SetAddress(), które tu są w ogóle nie potrzebne a niechcący kompilator posprzątał za niego śmieci ;)
Dodano po 3 [minuty]:
Reasumując panie autor zamiast narzekać na kompilator, którego jeszcze nie znasz, powinieneś się cieszyć, że odwalił w tym przypadku kawał dobrej roboty jako "terminator śmieci" ;) ..... może jednak warto dokładniej poznać ten język C dla AVR jak i sam kompilator hmmmm ?
|
|
| Back to top |
|
 |
szelus Poziom 20

Joined: 12 Jul 2004 Posts: 1016
|
#18
11 Jan 2011 11:50 Re: WinAvr zła kompilacja... |
|
|
|
| mirekk36 wrote: |
Przypomnę, sama funkcja NIC nie robi jeśli chodzi o sprzęt, ma za zadanie tylko coś tam sprawdzić i zwrócić wynik.
|
A czy kolega wogóle popatrzył na schemat, żeby się tak autorytatywnie wypowiadać?
|
|
| Back to top |
|
 |
_marek Poziom 15

Joined: 18 Jun 2010 Posts: 207 Location: Bydgoszcz
|
#19
11 Jan 2011 11:51 Re: WinAvr zła kompilacja... |
|
|
|
Wywołanie SetAddress() nie jest nie potrzebne.
Autor przeróbek usunął też zewnętrzną pamięć .Dlatego wyszły takie pozornie nic nie znaczące dziwactwa. Odczyt spod adresu E000+adr jest potrzebny do automatycznego zatrzaśnięcia zatrzasku. Jak by tego nie zmienić to program nie będzie używał zmiennej odczytywanej/zapisywanej (a co za tym idzie rezultatu funkcji) i całą funkcje wywali, o ile nie będzie ona volatile, lub w jej wnętrzu czegoś logicznego.
Liczy się tylko wystawiany adres, to co zapisujemy/odczytuje jest nieistotne i wprowadza w błąd.
Następne problemy stwarza praca na zmianę w trybie pamięci i jako zwykły port.
Nie ma co już "wieszać kotów" na autorze przeróbek, autor tematu też już rozumie dlaczego taki wynalazek jest dla kompilatora nie istotny. Może coś bardziej eleganckiego się nasunie.
Czy ten zatrzask tak bardzo przyspiesza komunikacje ?
|
|
| Back to top |
|
 |
szelus Poziom 20

Joined: 12 Jul 2004 Posts: 1016
|
#20
11 Jan 2011 11:58 Re: WinAvr zła kompilacja... |
|
|
|
| _marek wrote: |
Czy ten zatrzask tak bardzo przyspiesza komunikacje ? |
Moim zdaniem - wcale. Może nawet spowalnia, bo trzeba przełączać tryb portu w te i nazad. Ale i tak prędkość komunikacji jest bez znaczenia w tym projekcie.
Osobiście, to bym sterowanie zatrzaskiem podłaczył pod jakiś wolny port i wcale nie korzystał z trybu zewnętrznej pamięci w tym układzie - byłoby normalniej.
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8710 Location: Szczecin
|
#21
11 Jan 2011 14:48 Re: WinAvr zła kompilacja... |
|
|
|
| szelus wrote: |
| mirekk36 wrote: |
Przypomnę, sama funkcja NIC nie robi jeśli chodzi o sprzęt, ma za zadanie tylko coś tam sprawdzić i zwrócić wynik.
|
A czy kolega wogóle popatrzył na schemat, żeby się tak autorytatywnie wypowiadać? |
A co to znaczy wg ciebie autorytatywnie? To podyskutować już nie można? ;)
Tak patrzyłem na schemat ale nie będę go analizował dogłębnie bo po co?
Chodziło mi tylko o to, że funkcja w takiej postaci i tylko przy takim wykorzystaniu jak podał autor jest kompletnie niepotrzebna. I z tym chyba się nie spierasz? Uważałem tylko i uważam, że nie ma co na siłę przerabiać funkcji, która jest eliminowana przez kompilator, do takiej postaci aby na siłę pozostała. Jeśli uważasz inaczej to napisz - zamiast pytać czy stwierdzać że zbyt autorytatywnie się wypowiadam.
|
|
| Back to top |
|
 |
szelus Poziom 20

Joined: 12 Jul 2004 Posts: 1016
|
#22
11 Jan 2011 14:56 Re: WinAvr zła kompilacja... |
|
|
|
Tak, spieram się z tym. Było już pisane w tym wątku wielokrotnie, że ta funkcja nie jest całkiem niepotrzebna - ten odczyt z zewnetrznej pamięci ustawia "przy okazji" zewnętrzny zatrzask, którego zawartość jest następnie wykorzystywana do adresowania rejestów ATA/IDE.
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#23
11 Jan 2011 15:53 Re: WinAvr zła kompilacja... |
|
|
|
| szelus wrote: |
| ...ta funkcja nie jest całkiem niepotrzebna - ten odczyt z zewnetrznej pamięci ustawia "przy okazji" zewnętrzny zatrzask, którego zawartość jest następnie wykorzystywana do adresowania rejestów ATA/IDE. |
To jest %100 racji , pisałem o tym wcześniej. Autor projektu 'cd_free' bazował na schemacie i kodzie yampp3 też to pisałem, została tylko usunięta pamięć ram i dodane do kodu obsługa cd-romu. Można było przerobić kod i zatrzask inaczej używać stosując właśnie jak pisał mirekk36 :
| Quote: |
u08 SetAddress(u08 addr)
{
#ifdef YAMPP3USB
cbi(MCUCR, SRE); // Disable ExtRAM
outp(0xff, DDRA);
outp(addr, PORTA);
sbi(PORTE,PE1);
cbi(PORTE,PE1);
return 0;
#else
return *(u08 *)(0xE000 + addr);
#endif
}
|
ale jeszcze prościej było by usunąć wszystkie ( cbi(MCUCR, SRE); oraz sbi(MCUCR, SRE); ) z kodu i wyłączyć całkowicie ram bo i tak jej nie ma a dać :
| Quote: |
Void SetAddress(u08 addr)
{
outp(0xff, DDRA);
outp(addr, PORTA);
sbi(PORTE,PE1);
cbi(PORTE,PE1);
}
|
dało by to parę cykli procesora zaoszczędzone na coś innego... to taka mała uwaga co do tego projektu... Natomiast ja będę robił z pamięcią ram więc kod musze mieć taki jaki jest.
Mam takie zapytanie, przeglądałem notę dla atmega161 i tam jest jakiś błąd:
na stronie 106 jest podane że 'ALE' jest pod PE2 a na stronie 2 'ALE' jest jako PE1 to jak to jest z tym pinem. Jestem zdezorientowany.
|
|
| Back to top |
|
 |
Google

|
#
11 Jan 2011 15:53 |
|
|
|
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8710 Location: Szczecin
|
#24
11 Jan 2011 16:33 Re: WinAvr zła kompilacja... |
|
|
|
szelus - no masz rację, bo za szybko popatrzyłem na schemat i jakoś nie dotarło do mnie, że jest wykorzystywana linia ALE procka, myślałem, że ręcznie na jakimś pinie portu jest ten scalak zatrzaskiwany.
Dodano po 12 [minuty]:
| operator5wp wrote: |
Mam takie zapytanie, przeglądałem notę dla atmega161 i tam jest jakiś błąd:
na stronie 106 jest podane że 'ALE' jest pod PE2 a na stronie 2 'ALE' jest jako PE1 to jak to jest z tym pinem. Jestem zdezorientowany. |
No wygląda jak błąd i to tylko w tej tabelce bo już dalej masz:
| Quote: |
| ALE - Port E, Bit 1 |
A zajrzyj sobie też do opisów Timera i wyjścia OCx gdzie też piszą o PE2
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#25
11 Jan 2011 16:36 Re: WinAvr zła kompilacja... |
|
|
|
Czyli spokojnie mogę podłączyć zatrzask do PE1-ALE, podobnie jak jest w AT90s8515...
Mogli by to poprawić w tym pdf. Znalazłem jeszcze takie coś w kompilatorze winavr w ..\avr\include\avr\iom161.h :
| Quote: |
/*
PE2 = ALE
PE1 = OC1B
PE0 = ICP / INT2
*/
/* PORTE */
#define PE2 2
#define PE1 1
#define PE0 0
|
|
|
| Back to top |
|
 |
mirekk36 Poziom 25

Joined: 17 Jun 2006 Posts: 8710 Location: Szczecin
|
#26
11 Jan 2011 17:01 Re: WinAvr zła kompilacja... |
|
|
|
Może się autorowi właśnie na podstawie tej noty PDF też tak napisało w komentarzu bo to tylko komentarz PE2 = ALE
|
|
| Back to top |
|
 |
operator5wp Poziom 15

Joined: 08 Jun 2003 Posts: 235
|
#27
27 Jan 2011 15:00 Re: WinAvr zła kompilacja. Kompilator nie uwzględnia skoków. |
|
|
|
Ok... wasze porady pomogły więc zamykam temat.
|
|
| Back to top |
|
 |