Fråga:
Kommer en .ino Arduino Sketch att kompileras direkt på GCC-AVR?
RedDogAlpha
2016-03-07 06:59:57 UTC
view on stackexchange narkive permalink

Okej, vi har alla sett de här frågorna över hela nätet som Arduino v.s. C ++, eller andra liknande frågor. Och en stor majoritet av svaren berör inte ens kompileringsskillnader annat än genom abstrakt information.

Min fråga syftar till att lösa de faktiska skillnaderna (inte preferenser) i hur en .ino-fil bytt namn till en .cpp-fil eller andra liknande filtillägg för c ++ skulle kompilera med GCC-AVR. Jag vet att du åtminstone måste inkludera Arduino-rubrikfilen, men utöver det, vad skulle orsaka ett kompileringsfel om du kompilerar nämnda .ino till .cpp-fil med exempelvis GCC-AVR. För enkelhetens skull, låt oss använda det klassiska blinkande exemplet för att förklara vad skillnaderna är. Eller om du har ett bättre kodavsnitt att använda, inkludera i alla fall kodavsnittet i ditt svar och förklara skillnaderna noggrant.

Snälla inga åsikter om vilket som är ett bättre sätt eller verktyg att använda.

FYI. Jag använder Platformio för utveckling och jag märker en konverteringsprocess som händer bakom kulisserna under sammanställningen. Jag försöker förstå vad som faktiskt händer där, så när jag kodar i Arduino förstår jag också den "rena" C ++ - versionen.

Tack för dina tankeväckande svar på min fråga i förväg.

Frågar du specifikt om `gcc` på skrivbordet eller GCC för AVR-kompilatorn` avr-gcc`? det finns en mycket större skillnad där än mellan en '.ino' och en '.cpp' fil.
@BrettAM GCC-AVR-verktygssatsen som Arduino UNO är målkortet och använder ett Atmel AVR-chip, som jag är säker på att du vet. Tack för uppmaningen till tvetydighet i min fråga. Och ja jag vet att det finns en mycket större skillnad. Det är därför jag ställer denna fråga. Att lära sig vad dessa skillnader är!
Två svar:
Nick Gammon
2016-03-07 08:24:37 UTC
view on stackexchange narkive permalink

Se mitt svar här: Klasser och objekt: hur många och vilka filtyper behöver jag faktiskt använda dem? - specifikt: Hur IDE organiserar saker.

Jag vet att du åtminstone måste inkludera Arduino-rubrikfilen

Ja du skulle behöva göra det.

men utöver det, vad skulle orsaka ett kompileringsfel om att kompilera nämnda .ino till .cpp-fil med exempelvis GCC-AVR.

IDE genererar funktionsprototyper åt dig. Kod i en .ino-fil kanske behöver eller inte (det kommer troligen att göra om inte författaren är tillräckligt disciplinerad för att koda på vanligt C ++ sätt och göra dem själva).


Om "skissen" innehåller andra filer (t.ex. andra .ino-, .c- eller .cpp-filer), då måste dessa införlivas i kompileringsprocessen som jag beskriver i mitt svar som nämns ovan.

Du måste också ( kompilera och) länka i några bibliotek som används av skissen.


Du har inte frågat om länkande sida av saker, men naturligtvis behöver de olika filerna, som sammanställts, länkas ihop och förvandlades sedan till en .elf- och .hex-fil för uppladdningsändamål. Se nedan.


Exempel på makefile

Baserat på IDE-utdata gjorde jag en enkel makefile för en tid tillbaka:

  ## Simple Arduino Makefile ## Författare: Nick Gammon # Datum: 18 mars 2015 # där du installerade Arduino appARDUINO_DIR = C: / Dokument och inställningar / Nick / Desktop / arduino-1.0.6 / # olika programCC = " $ (ARDUINO_DIR) hårdvara / verktyg / avr / bin / avr-gcc "CPP =" $ (ARDUINO_DIR) hårdvara / verktyg / avr / bin / avr-g ++ "AR =" $ (ARDUINO_DIR) hårdvara / verktyg / avr / bin / avr-ar "OBJ_COPY =" $ (ARDUINO_DIR) maskinvara / verktyg / avr / bin / avr-objcopy "MAIN_SKETCH = Blink.cpp # kompilera flaggor för g ++ och gcc # kan behöva ändra dessaF_CPU = 16000000MCU = atmega328p # kompilera flaggGENER_ c -g -Os -Vägg -funktion-sektioner -fdata-sektioner -mmcu = $ (MCU) -DF_CPU = $ (F_CPU) L -MMD -DUSB_VID = null -DUSB_PID = null -DARDUINO = 106
CPP_FLAGS = $ (GENERAL_FLAGS) -fno-undantagCC_FLAGS = $ (GENERAL_FLAGS) # plats för inkluderar filerINCLUDE_FILES = "-I $ (ARDUINO_DIR) hårdvara / arduino / kärnor / arduino" "-I $ (ARDUINO_DIR) / hårdvara "# library sourcesLIBRARY_DIR =" $ (ARDUINO_DIR) hårdvara / arduino / cores / arduino / "build: $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (MAIN_SKETCH) -o $ (MAIN_SKETCH). o $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) avr-libc / malloc.c -o malloc.co $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) avr-libc / realloc.c -o realloc. co $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) WInterrupts.c -o WInterrupts.co $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) ledningar.c -o ledningar.co $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) wiring_analog.c -o wiring_analog.co $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) wiring_digital.c -o wiring_digital.co $ ) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) wiring_pulse.c -o wiring_pulse.co $ (CC) $ (CC_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) wiring_shift.c -o wiring_shift.co $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) CDC.cpp -o CDC.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) HardwareSerial.cpp -o HardwareSerial.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) HID.cpp -o HID.cpp.o $ (CPP) $ ( CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) IPAddress.cpp -o IPAddress.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) main.cpp -o main.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) new.cpp -o new.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) Print.cpp -o Print.cpp.o $ ( CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) Stream.cpp -o Stream.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) Tone.cpp -o Tone.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) USBCore.cpp -o USBCore.cpp.o $ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) WMath.cpp -o WMath.cpp .o
$ (CPP) $ (CPP_FLAGS) $ (INCLUDE_FILES) $ (LIBRARY_DIR) WString.cpp -o WString.cpp.o rm core.a $ (AR) rcs core.a malloc.co $ (AR) rcs core.a realloc .co $ (AR) rcs core.a WInterrupts.co $ (AR) rcs core.a wiring.co $ (AR) rcs core.a wiring_analog.co $ (AR) rcs core.a wiring_digital.co $ (AR) rcs core.a wiring_pulse.co $ (AR) rcs core.a wiring_shift.co $ (AR) rcs core.a CDC.cpp.o $ (AR) rcs core.a HardwareSerial.cpp.o $ (AR) rcs core .a HID.cpp.o $ (AR) rcs-kärna. en IPAddress.cpp.o $ (AR) rcs-kärna. en main.cpp.o $ (AR) rcs-kärna. en ny.cpp.o $ (AR) rcs core.a Print.cpp.o $ (AR) rcs core.a Stream.cpp.o $ (AR) rcs core.a Tone.cpp.o $ (AR) rcs core.a USBCore.cpp.o $ ( AR) rcs core.a WMath.cpp.o $ (AR) rcs core.a WString.cpp.o $ (CC) -Os -Wl, - gc-sektioner -mmcu = $ (MCU) -o $ (MAIN_SKETCH ). själv $ (MAIN_SKETCH) .o core.a -lm $ (OBJ_COPY) -O ihex -j .eeprom --set-sektionsflaggor = .eeprom = allokering, belastning - ingen förändringsvarning --ändra- sektion-lma. eeprom = 0 $ (MAIN_SKETCH). själv $ (MAIN_SKETCH) .eep $ (OBJ_COPY) -O ihex -R .eeprom $ (MAIN_SKETCH). själv $ (MAIN_SKETCH) .hex 

In just det här fallet .ino-filen kompilerades utan problem efter att byta namn på den till Blink.cpp och lägga till den här raden:

  #include <Arduino.h>  
Tack Nick för ditt korta svar, jag är inte i närheten av den nivå du är och tänkte inte ens på en make-fil. Så i princip är syntaxen densamma, det handlar bara om att länka objekt, eller hur? Tack för att du delar din make-fil som jag kan dissekera. Jag är säker på att det kommer att bli fler frågor från det! Tack igen!
Min fil ovan fungerade när jag publicerade den, men jag tror att det kan behöva justeras för de senare IDE: erna (eftersom de flyttar runt eller byter namn på biblioteksfiler). Ändå visar en detaljerad sammanställning vad IDE genererar för närvarande, vilket bör komma igång.
Edgar Bonet
2016-03-07 15:37:37 UTC
view on stackexchange narkive permalink

Jag vill bara lägga till några punkter i Nick Gammons svar:

  • Du behöver inte byta namn på en .ino-fil för att kompilera den: om du uttryckligen säger till kompilatorn är det C ++ (alternativ -x c ++ ) kommer det att ange det ovanliga filtillägget och kompilera det som C ++.
  • Du behöver inte lägga till #include <Arduino.h> i .ino-filen: du kan be kompilatorn att göra det åt dig (-inkludera Arduino.h ).

Med dessa knep kan jag kompilera Blink .ino med ingen ändring , bara genom att åberopa avr-g ++ med rätt kommandoradsalternativ:

  avr-g ++ - mmcu = atmega328p -DARDUINO = 105 -DF_CPU = 16000000L \ -I / usr / share / arduino / hardware / arduino / cores / arduino \ -I / usr / share / arduino / hardware / arduino / variants / standard \ -Os -fno -undantag -funktionsavsnitt -fdata-sektioner \ -Wl, - gc-sektioner -g -Vägg -Wextra \ -x c ++ - inkluderar Arduino.h \ / usr / share / arduino / exampl es / 01.Basics / Blink / Blink.ino \ -x none /usr/local/lib/arduino/uno/libcore.a -lm \ -o Blink.elf  

Några anteckningar på kommandoraden ovan:

  • /usr/local/lib/arduino/uno/libcore.a är där jag sparade den kompilerade Arduino-kärnan. Jag hatar att kompilera om och om igen samma saker.
  • -x ingen behövs för att berätta för kompilatorn att tänka på filtilläggen igen. Utan det skulle det antas att libcore.a är en C ++ -fil.

Jag lärde mig dessa knep från Sudar Muthu's Arduino-Makefile. Det här är en generell Makefile som fungerar med många styrelser och med bibliotek. Det enda som saknas i förhållande till Arduino IDE är framdeklarationerna.

Mycket trevligt, Edgar! Min lösning efterliknar i princip vad IDE gör, din löser det faktiska problemet för att lämna på ett mycket snyggare sätt. Naturligtvis måste du göra filen 'libcore.a' i förväg. Jag antar att raderna i mitt svar som bygger 'core.a' kan göras i förväg, så att de inte behöver vara en del av varje build. Erfarenheten har visat att mer komplexa skisser (t.ex. att använda Wire eller SPI) behöver fler filer läggas till i "core.a".
@NickGammon: Det stämmer, Muthu's Makefile (och, antar jag, Arduino IDE) tenderar att placera vilka bibliotek du använder i libcore.a. Jag gillar inte riktigt det här tillvägagångssättet, eftersom det gör det förment "kärnbiblioteket" beroende av det specifika program du kompilerar. För enfilsbibliotek, som Wire eller SPI, föredrar jag bara att placera biblioteket C ++ - filen i samma kompileringskommando som huvudprogrammet. Den kommandoraden blir lätt ganska lång, så jag använder en Makefile.
En av de saker som jag gillar med IDE är att du inte behöver krossa. För enkla projekt ändå fungerar det "bara".


Denna fråga och svar översattes automatiskt från det engelska språket.Det ursprungliga innehållet finns tillgängligt på stackexchange, vilket vi tackar för cc by-sa 3.0-licensen som det distribueras under.
Loading...