logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

WinAvr zła kompilacja. Kompilator nie uwzględnia skoków.

operator5wp 09 Sty 2011 16:57 2515 26
  • #1 8982321
    operator5wp
    Poziom 16  
    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:

     
     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 :
    
     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 :
    Cytat:

    # 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

  • #2 8982600
    maly_elektronik
    Poziom 23  
    Deassemblery nie są zbyt dokładne :)

    Spróbuj zaprogramować i zobaczyć czy czasem układ nie będzie działał poprawnie :)
  • #3 8983240
    tmf
    VIP Zasłużony dla elektroda
    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.
  • #4 8984408
    operator5wp
    Poziom 16  
    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"
    Cytat:

    //----------------------------------------------------------------------------
    // 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...
  • #5 8984456
    sulfur
    Poziom 24  
    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.
  • #6 8984515
    tmf
    VIP Zasłużony dla elektroda
    operator5wp napisał:
    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.
  • #7 8984706
    operator5wp
    Poziom 16  
    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:


    Cytat:

    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.
  • #8 8985547
    Konto nie istnieje
    Konto nie istnieje  
  • #9 8985734
    szelus
    Poziom 34  
    operator5wp napisał:
    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 napisał:

    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?
  • #10 8985800
    Konto nie istnieje
    Konto nie istnieje  
  • #11 8986060
    szelus
    Poziom 34  
    Ż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 napisał:

    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.
  • #12 8986123
    operator5wp
    Poziom 16  
    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.
  • #13 8986249
    szelus
    Poziom 34  
    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:
    
    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.
  • #14 8986353
    tmf
    VIP Zasłużony dla elektroda
    _marek napisał:
    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?
  • #15 8986393
    operator5wp
    Poziom 16  
    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....
  • #16 8989220
    Konto nie istnieje
    Konto nie istnieje  
  • #17 8989357
    mirekk36
    Poziom 42  
    szelus napisał:
    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:
    
    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ć:

    
    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

    Cytat:
    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 ?
  • #18 8989757
    szelus
    Poziom 34  
    mirekk36 napisał:
    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ć?
  • #19 8989764
    Konto nie istnieje
    Konto nie istnieje  
  • #20 8989785
    szelus
    Poziom 34  
    _marek napisał:

    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.
  • #21 8990337
    mirekk36
    Poziom 42  
    szelus napisał:
    mirekk36 napisał:
    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.
  • #22 8990369
    szelus
    Poziom 34  
    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.
  • #23 8990570
    operator5wp
    Poziom 16  
    szelus napisał:
    ...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 :

    Cytat:

    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ć :

    Cytat:

    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.
  • #24 8990695
    mirekk36
    Poziom 42  
    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 napisał:

    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:

    Cytat:
    ALE - Port E, Bit 1


    A zajrzyj sobie też do opisów Timera i wyjścia OCx gdzie też piszą o PE2
  • #25 8990761
    operator5wp
    Poziom 16  
    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 :
    Cytat:

    /*
    PE2 = ALE
    PE1 = OC1B
    PE0 = ICP / INT2
    */

    /* PORTE */
    #define PE2 2
    #define PE1 1
    #define PE0 0
REKLAMA