Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Proszę, dodaj wyjątek dla www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Połączenie WinAVR i asemblera.

30 Kwi 2006 21:44 2179 10
  • Poziom 12  
    Witam.

    Moje pytanie dotyczy sposobów wygodnego dołączania kodu napisanego w asemblerze do programu napisanego w C. Żeby nie przynudzać podam konkretny przykład:

    Mam taką procedurkę napisaną w asemblerze:
    Code:

    USART_FlushRX:
       sbis UCSRA, RXC
       ret
       in temp0, UDR
    rjmp USART_FlushRX


    Chciałbym móc ją wywoływać z poziomu C. Oczywiście nic nie stoi na przeszkodzie żeby dopisać tych kilka rozkazów w postaci wstawki asemblerowej np.
    Code:

    asm ("sbis UCSRA, RXC")
    itd...


    Ale to BARDZO mało wygodna metoda. Zwłasza jeśli tego asemblerowego kodu jest dużo. Załóżmy, że mam plik procedury.asm (którego zawartość przedstawiłem wyżej) i chciałbym wywoływać procedury w nim zawarte z poziomu języka C. Czy istnieje jakaś sprawna metoda wykonania tego?

    Kompilator C to oczywiście WinAVR, a asembler avrasm2.

    Pozdrawiam wszystkich,
    Tomek
  • Pomocny post
    Poziom 39  
    felixgotom napisał:

    ...
    Chciałbym móc ją wywoływać z poziomu C. Oczywiście nic nie stoi na przeszkodzie żeby dopisać tych kilka rozkazów w postaci wstawki asemblerowej np.
    Code:

    asm ("sbis UCSRA, RXC")
    itd...


    Muszę Cię zmartwić , bo taka "wstawka" nie przejdzie ;(
    Ale można tak:
    plik.c
    Code:

    #include <avr/io.h>

    extern void USART_FlushRX(void);
    int main(void)
    {
     USART_FlushRX();
     return(0);
    }

    plik.s
    Code:

    #include <avr/io.h>
    #define temp0 r0
    .global USART_FlushRX

    .func USART_FlushRX
    ;******** wypada to zrobić tak ...
    USART_FlushRX:
       sbis _SFR_IO_ADDR(UCSRA),RXC
       ret
       in temp0,_SFR_IO_ADDR(UDR)
       rjmp USART_FlushRX
    .endfunc

    ;********** .. lub mniej elegancko
       sbis UCSRA-0x20,RXC
       ret
       in temp0,UDR-0x20
       rjmp USART_FlushRX

    Ty , zrobisz jak zechcesz ;)

    Piotrek
  • Poziom 12  
    Ok, dzięki wielkie. Sporo mi rozjaśniłeś, ale mam jeszcze kilka pytań:

    1. W którym miejscu pliku .c mam dołączyć plik .s? W pętli main czy poza nią? Po prostu gdzie i co dopisać (pewnie coś pokroju asm ("#include plik.s"), ale nie wiem).

    2. Co to za składnia w pliku .s? Nie jest to avrasm2, w takim razie jaki to asembler i gdzie mogę poszukać opisu preprocesora do niego?

    3. Czy istnieje jakaś możliwość "podmiany" tego innego asemblera na avrasm2?

    4. Czy zamiast pisać _SFR_IO_ADDR(UCSRA) nie mógłbym dołączyć pliku .inc (tego który dołączam standardowo do projektów asemblerowych np. tn2313def.inc) i używać po prostu UCSRA?

    5. Czy jest gdzieś jakiś konkretny opis łączenia WinAVR z asemblerem? - jeśli jest to szkoda żebym zaśmiecał forum - oczy mam, a czytać też umiem ;).

    Dzięki wielkie za pomoc.
    Tomek
  • Poziom 39  
    1)plik.s dołączasz w makefile , a nie jako include.
    2)ten asembler to avr-as.exe(as.exe) , a jego składnia jest inna niż atmelowskiego avrasm.
    3)wątpię.Ponieważ pośredni kod wynikowy kompilatora C jest w istocie plikiem *.S , a dopiero potem *.o , to raczej trudno zmusić gcc , by wygenerowało plik.s , którego składnię "zrozumie" avrasm2.
    4)nie , bo avr-as takiego pliku "nie zrozumie".Można sobie taki plik spreparować z np. iom32.h powyrzucać zbędne definicje,warunki oraz dodać na początku #define _SRF_IO8(x) x (nie będzie brany pod uwagę ofset 0x20) i zapisać ten plik jako np. m32.h
    5)w dokumentacji coś znajdziesz i w necie

    Piotrek
  • Poziom 24  
    Witam, odświerzam temat...

    Ja pracują na AVR Studio 4(z WinAVR) i pisząc w C potrzebuję użyć już gotowego kodu w asm i przygotowanego do pracy z C.

    Jak mam dołączyć PLIK.S w pliku MAKEFILE?
  • Poziom 31  
    Najlepiej robi sie to w ten sposob ze wszystkie pliki .c i .s kompiluje sie za pomoca odpowiednich dla nich narzedzi do formatu .o (object file) a nastepnie wszystkie pliki .o linkuje sie w program wykonywalny (najczesciej elf lub coff). Potem z tego pliku generuje sie plik dla loadera (najczesciej .hex lub .srec).
  • Poziom 24  
    A jaśniej? Jak zrobić plik *.o? Jak go potem dodać do MakeFile?
  • Poziom 31  
    Znalazlem taki to Makfile u siebie
    Code:

    #----------------------------------------------------------------------
    #
    #   This is a Makefile for Motorola HC08 microcontrollers using SDCC
    #
    #   written by Radoslaw Pietrzyk
    #
    #----------------------------------------------------------------------

    # Target name
    TARGET =

    # FAMILY name
    FAMILY = hc08

    # MCU type (not important)
    MCU = MC68HC908QT4

    # List C source files here. (C dependencies are automatically generated.)
    SRC =

    # List asm source files here
    ASRC =

    # Compiler
    CC = sdcc

    # Assembler
    ASMC = as-hc08

    # The code start address
    CODE_ADDRESS = 0xEE00

    # The xram start address
    XRAM_ADDRESS = 0x80

    #The ram start address(only especially for this application)
    RAM_ADDRESS = 0xCD


    # The stack start address
    STACK_ADDRESS = 0xFF

    #Compiler flags(see compiler help)
    CFLAGS = -m$(FAMILY) -p$(MCU) --opt-code-size --model-small --stack-auto --code-loc $(CODE_ADDRESS) --data-loc $(RAM_ADDRESS) --stack-loc $(STACK_ADDRESS)

    # Assembler flags (see assembler help)
    ASMFLAGS = -aglos

    # Define Messages
    # English
    MSG_BEGIN = -------- begin --------
    MSG_END = --------  end  --------
    MSG_LINKING = Linking:
    MSG_COMPILING = Compiling:
    MSG_CLEANING = Cleaning project:

    REMOVE = rm -f 



    # Define all object files.
    OBJ = $(SRC:.c=.rel) $(ASRC:.asm=.rel)


    begin:
       @echo
       @echo $(MSG_BEGIN)

    end:
       @echo
       @echo $(MSG_END)

    # Default target.
    all: begin ccversion compile build end

    build:$(OBJ)
       @echo
       @echo $(MSG_LINKING)
       $(CC) $(CFLAGS) -o $(TARGET).S19 $(OBJ)




    # Display compiler version information.
    ccversion :
       @echo
       @$(CC) --version



    # Program the device. 
    program:
       @echo
       @echo -- no command line programmer yet --
       @echo -- using PROG08SZ from www.pemicro.com --
       @echo
       @echo Programming...
       @prog08sz.exe
       @echo Finished


    .PRECIOUS : $(OBJ)


    # Compile: create object files from C source files.
    %.rel : %.c
       @echo
       @echo $(MSG_COMPILING) $<
       $(CC) $(CFLAGS) -c $<

    %.rel : %.asm
       @echo
       @echo $(MSG_COMPILING) $<
       $(ASMC) $(ASMFLAGS) $<

    # Target: clean project.
    clean:
       @echo
       @echo $(MSG_CLEANING)
       $(REMOVE) *.rel
       $(REMOVE) *.S19
       $(REMOVE) *.rst
       $(REMOVE) *.mem
       $(REMOVE) *.sym
       $(REMOVE) *.map
       $(REMOVE) *.lnk
       $(REMOVE) *.lst
       $(REMOVE) *.txt
       $(REMOVE) *.asm

    # Listing of phony targets.
    .PHONY : all ccversion build clean compile program


    Nie bardzo chce mi sie tlumaczyc ale powinienes dac rade zrozumiec. Sprobuj dopasowac do swoich potrzeb a jak bedziesz mial konkretne pytania to wal smialo.
  • Poziom 30  
    Pozwolę sobie odświeżyć.
    Mam problem z kompilacją w AVRstudio takiego czegoś:
    Code:

    #include <avr/io.h>
    #define RxD 0
    #define   TxD 1
    #define   bitcnt R20
    #define   temp R21
    #define   Txbyte R24
    #define   RXbyte R23
    #define         sb   1
    .global send
    send:
    putchar:
          ldi   bitcnt,9+sb   
          com   Txbyte      
          sec      
    putchar0:
          brcc   putchar1   
          cbi   PORTD,1   
          rjmp   putchar2      
    putchar1:
          ;sbi   _SFR_IO_ADDR(PORTD), 1
          sbi   PORTD-0x20,1
          nop
    putchar2:
          rcall UART_delay
          rcall UART_delay
          lsr   Txbyte   
          dec   bitcnt      
          brne   putchar0   
          ret         
    #define      b   31   
    UART_delay:   ldi   temp,b
    UART_delay1:   dec   temp
          brne   UART_delay1
          ret

    Przy próbie kompilacji pisze mi:
    ../uart.S:23: Error: constant value required (czyli "cbi PORTD,1" )
    ../uart.S:27: Error: constant value required (czyli "sbi PORTD-0x20,1")
    ../uart.S:27: Error: number must be less than 32

    mój mejkfajl (generowany przez AVRstudio):
    Code:

    ###############################################################################
    # Makefile for the project uart_test
    ###############################################################################

    ## General Flags
    PROJECT = uart_test
    MCU = attiny26
    TARGET = uart_test.elf
    CC = avr-gcc.exe

    ## Options common to compile, link and assembly rules
    COMMON = -mmcu=$(MCU)

    ## Compile options common for all C compilation units.
    CFLAGS = $(COMMON)
    CFLAGS += -Wall -gdwarf-2      -DF_CPU=1000000UL -Os -fsigned-char
    CFLAGS += -MD -MP -MT $(*F).o -MF dep/$(@F).d

    ## Assembly specific flags
    ASMFLAGS = $(COMMON)
    ASMFLAGS += -x assembler-with-cpp -Wa,-gdwarf2

    ## Linker flags
    LDFLAGS = $(COMMON)
    LDFLAGS +=  -Wl,-Map=uart_test.map


    ## Intel Hex file production flags
    HEX_FLASH_FLAGS = -R .eeprom

    HEX_EEPROM_FLAGS = -j .eeprom
    HEX_EEPROM_FLAGS += --set-section-flags=.eeprom="alloc,load"
    HEX_EEPROM_FLAGS += --change-section-lma .eeprom=0


    ## Objects that must be built in order to link
    OBJECTS = uart_test.o uart.o

    ## Objects explicitly added by the user
    LINKONLYOBJECTS =

    ## Build
    all: $(TARGET) uart_test.hex uart_test.eep uart_test.lss size

    ## Compile
    uart.o: ../uart.S
       $(CC) $(INCLUDES) $(ASMFLAGS) -c  $<

    uart_test.o: ../uart_test.c
       $(CC) $(INCLUDES) $(CFLAGS) -c  $<

    ##Link
    $(TARGET): $(OBJECTS)
        $(CC) $(LDFLAGS) $(OBJECTS) $(LINKONLYOBJECTS) $(LIBDIRS) $(LIBS) -o $(TARGET)

    %.hex: $(TARGET)
       avr-objcopy -O ihex $(HEX_FLASH_FLAGS)  $< $@

    %.eep: $(TARGET)
       avr-objcopy $(HEX_EEPROM_FLAGS) -O ihex $< $@

    %.lss: $(TARGET)
       avr-objdump -h -S $< > $@

    size: ${TARGET}
       @echo
       @avr-size -C --mcu=${MCU} ${TARGET}

    ## Clean target
    .PHONY: clean
    clean:
       -rm -rf $(OBJECTS) uart_test.elf dep/* uart_test.hex uart_test.eep uart_test.lss uart_test.map


    ## Other dependencies
    -include $(shell mkdir dep 2>/dev/null) $(wildcard dep/*)


    Czy jakaś dobra dusza pomogłaby mi zrozumieć, o co tu chodzi?
  • Poziom 39  
    Klima napisał:
    ...Czy jakaś dobra dusza pomogłaby mi zrozumieć, o co tu chodzi?

    A skąd Ty wytrzasnąłeś POTRD , w attiny26 :?:
    Ja w tym uC widzę tylko PORTA i PORTB ;)

    Piotrek
  • Poziom 30  
    O, kurde.... Dzięki, sprawdzę wieczorem, czy PORTA pomoże. :)