क्या।-Arduino स्केच GCC-AVR पर सीधे संकलित होगा?


10

ठीक है, हम सभी ने उन सवालों को पूरे वेब पर देखा है जैसे कि Arduino बनाम C ++, या इसी तरह के अन्य प्रश्न। और बहुसंख्यक उत्तर अमूर्त जानकारी के अलावा संकलन अंतर को भी नहीं छूते हैं।

मेरा प्रश्न वास्तविक मतभेदों (वरीयताओं को नहीं) को हल करने का लक्ष्य है कि कैसे। Cpp फ़ाइल या c ++ के समान अन्य फ़ाइल एक्सटेंशन का नाम बदलकर GCC-AVR का उपयोग किया जाएगा। मुझे पता है कि कम से कम आपको Arduino हैडर फ़ाइल को शामिल करना होगा, लेकिन उससे आगे, जीसी-एवीआर उदाहरण के लिए, .cpp फ़ाइल का उपयोग करते हुए, .cpp फ़ाइल को संकलित करने के लिए एक संकलन त्रुटि का कारण होगा। सादगी की खातिर, क्लासिक ब्लिंक उदाहरण का उपयोग करने के लिए यह बताने की सुविधा देता है कि अंतर क्या हैं। या यदि आपके पास उपयोग करने के लिए एक बेहतर कोड स्निपेट है, तो कृपया सभी तरीकों से स्निपेट को अपने उत्तर में शामिल करें और मतभेदों को अच्छी तरह से समझाएं।

कृपया कोई राय नहीं के रूप में जो एक बेहतर तरीका या उपयोग करने के लिए उपकरण है।

FYI करें। मैं विकास के लिए Platformio का उपयोग करता हूं और मैं संकलन के दौरान दृश्यों के पीछे हो रही रूपांतरण प्रक्रिया को देखता हूं। मैं यह समझने की कोशिश कर रहा हूं कि वास्तव में वहां क्या हो रहा है, इसलिए जब मैं Arduino में कोड करता हूं, तो मैं "शुद्ध" C ++ संस्करण भी समझता हूं।

मेरे प्रश्न के अग्रिम जवाब के लिए आपके विचार के लिए धन्यवाद।


क्या आप विशेष रूप gccसे अपने डेस्कटॉप, या AVR संकलक के लिए GCC के बारे में पूछ रहे हैं avr-gcc? फ़ाइल .inoऔर .cppफ़ाइल के बीच बहुत बड़ा अंतर है ।
ब्रेटम

@BrettAM Arduino UNO के रूप में GCC-AVR टूलकिट लक्ष्य बोर्ड है और Atmel AVR चिप का उपयोग करता है, जैसा कि मुझे यकीन है कि आप जानते हैं। मेरे प्रश्न में अस्पष्टता के लिए कॉल आउट के लिए धन्यवाद। और हाँ मुझे पता है कि बहुत बड़ा अंतर है। इसलिए मैं यह सवाल पूछ रहा हूं। यह जानने के लिए कि वे अंतर क्या हैं!
RedDogAlpha

जवाबों:


14

मेरा उत्तर यहां देखें: कक्षाएं और ऑब्जेक्ट: कितने और कौन से फ़ाइल प्रकार मुझे वास्तव में उनका उपयोग करने की आवश्यकता है? - विशेष रूप से: IDE चीजों को कैसे व्यवस्थित करता है

मुझे पता है कि कम से कम आपको Arduino हैडर फ़ाइल को शामिल करना होगा

हाँ आपको ऐसा करने की आवश्यकता होगी।

लेकिन इससे परे, यदि संकलन .ino से .cpp फ़ाइल का उपयोग करते हुए, उदाहरण के लिए, GCC-AVR कहा जाता है, तो एक संकलन त्रुटि का क्या कारण होगा।

IDE आपके लिए फ़ंक्शन प्रोटोटाइप बनाता है। एक .ino फ़ाइल में कोड को इसकी आवश्यकता हो सकती है या नहीं भी हो सकती है (यह शायद तब तक होगा जब तक कि लेखक को सामान्य C ++ तरीके से कोड करने के लिए पर्याप्त अनुशासित नहीं किया जाता है और वे स्वयं करते हैं)।


यदि "स्केच" में अन्य फाइलें (जैसे। अन्य .ino, .c या .cpp फाइलें) शामिल हैं, तो इन्हें संकलन प्रक्रिया में शामिल करने की आवश्यकता होगी जैसा कि मैं ऊपर वर्णित मेरे उत्तर में बताता हूं।

इसके अलावा, आपको स्केच द्वारा उपयोग की जाने वाली किसी भी लाइब्रेरी में (संकलन और) लिंक की आवश्यकता होगी।


आपने चीजों को लिंक करने के पक्ष के बारे में नहीं पूछा है, लेकिन स्वाभाविक रूप से विभिन्न फाइलों, जैसा कि संकलित किया गया है, को एक साथ लिंक करने की आवश्यकता है, और अपलोड करने के प्रयोजनों के लिए .elf और .hex फ़ाइल में बदल गया है। निचे देखो।


उदाहरण मेकफाइल

आईडीई आउटपुट के आधार पर मैंने कुछ समय पहले एक साधारण मेकफाइल बनाया :

#
# Simple Arduino Makefile
#
# Author: Nick Gammon
# Date: 18th March 2015

# where you installed the Arduino app
ARDUINO_DIR = C:/Documents and Settings/Nick/Desktop/arduino-1.0.6/

# various programs
CC = "$(ARDUINO_DIR)hardware/tools/avr/bin/avr-gcc"
CPP = "$(ARDUINO_DIR)hardware/tools/avr/bin/avr-g++"
AR = "$(ARDUINO_DIR)hardware/tools/avr/bin/avr-ar"
OBJ_COPY = "$(ARDUINO_DIR)hardware/tools/avr/bin/avr-objcopy"

MAIN_SKETCH = Blink.cpp

# compile flags for g++ and gcc

# may need to change these
F_CPU = 16000000
MCU = atmega328p

# compile flags
GENERAL_FLAGS = -c -g -Os -Wall -ffunction-sections -fdata-sections -mmcu=$(MCU) -DF_CPU=$(F_CPU)L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106
CPP_FLAGS = $(GENERAL_FLAGS) -fno-exceptions
CC_FLAGS  = $(GENERAL_FLAGS)

# location of include files
INCLUDE_FILES = "-I$(ARDUINO_DIR)hardware/arduino/cores/arduino" "-I$(ARDUINO_DIR)hardware/arduino/variants/standard"

# library sources
LIBRARY_DIR = "$(ARDUINO_DIR)hardware/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.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)avr-libc/realloc.c -o realloc.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)WInterrupts.c -o WInterrupts.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)wiring.c -o wiring.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)wiring_analog.c -o wiring_analog.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)wiring_digital.c -o wiring_digital.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)wiring_pulse.c -o wiring_pulse.c.o 
    $(CC) $(CC_FLAGS) $(INCLUDE_FILES) $(LIBRARY_DIR)wiring_shift.c -o wiring_shift.c.o 
    $(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.c.o 
    $(AR) rcs core.a realloc.c.o 
    $(AR) rcs core.a WInterrupts.c.o 
    $(AR) rcs core.a wiring.c.o 
    $(AR) rcs core.a wiring_analog.c.o 
    $(AR) rcs core.a wiring_digital.c.o 
    $(AR) rcs core.a wiring_pulse.c.o 
    $(AR) rcs core.a wiring_shift.c.o 
    $(AR) rcs core.a CDC.cpp.o 
    $(AR) rcs core.a HardwareSerial.cpp.o 
    $(AR) rcs core.a HID.cpp.o 
    $(AR) rcs core.a IPAddress.cpp.o 
    $(AR) rcs core.a main.cpp.o 
    $(AR) rcs core.a new.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-sections -mmcu=$(MCU) -o $(MAIN_SKETCH).elf $(MAIN_SKETCH).o core.a -lm 
    $(OBJ_COPY) -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 $(MAIN_SKETCH).elf $(MAIN_SKETCH).eep 
    $(OBJ_COPY) -O ihex -R .eeprom $(MAIN_SKETCH).elf $(MAIN_SKETCH).hex 

उस विशेष मामले में .ino फाइल को बिना किसी समस्या के संकलित करने के बाद उसे Blink.cpp में बदल दिया जाता है और इस लाइन को जोड़ा जाता है:

#include <Arduino.h>

अपने संक्षिप्त उत्तर के लिए धन्यवाद निक, मैं आपके स्तर के पास कहीं नहीं हूं, और एक मेक फाइल के बारे में भी नहीं सोचा था। तो मूल रूप से वाक्यविन्यास वही है, यह सिर्फ वस्तुओं को जोड़ने के बारे में है, है ना? मुझे विच्छेद करने के लिए अपनी मेक फ़ाइल साझा करने के लिए धन्यवाद। मुझे यकीन है कि इससे और भी सवाल उठेंगे! एक बार फिर धन्यवाद!
RedDogAlpha

जब मैंने इसे पोस्ट किया था, तब ऊपर की मेरी फ़ाइल ने काम किया, लेकिन मेरा मानना ​​है कि बाद में आईडीई के लिए ट्विकिंग की आवश्यकता हो सकती है (क्योंकि वे लाइब्रेरी में घूमते हैं या नाम बदलते हैं)। फिर भी, एक क्रिया संकलन करने से पता चलता है कि आईडीई वर्तमान में क्या पैदा कर रहा है, जिसे आपको शुरू करना चाहिए।
निक गैमन

10

मैं निक गैमन के जवाब में कुछ बिंदु जोड़ना चाहूंगा:

  • इसे संकलित करने के लिए आपको .ino फ़ाइल का नाम बदलने की आवश्यकता नहीं है: यदि आप स्पष्ट रूप से संकलक को यह C ++ (विकल्प -x c++) बताते हैं , तो यह असामान्य फ़ाइल एक्सटेंशन को अनदेखा करेगा और इसे C ++ के रूप में संकलित करेगा।
  • आपको #include <Arduino.h>.ino फ़ाइल में जोड़ने की आवश्यकता नहीं है : आप संकलक को आपके लिए ऐसा करने के लिए कह सकते हैं ( -include Arduino.h)।

उन तरकीबों का उपयोग करके, मैं Blink.ino को बिना किसी संशोधन के संकलित कर सकता हूं , बस उचित कमांड-लाइन विकल्पों के साथ avr-g ++ को आमंत्रित करके:

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-exceptions -ffunction-sections -fdata-sections \
    -Wl,--gc-sections -g -Wall -Wextra \
    -x c++ -include Arduino.h \
    /usr/share/arduino/examples/01.Basics/Blink/Blink.ino \
    -x none /usr/local/lib/arduino/uno/libcore.a -lm \
    -o Blink.elf

उपरोक्त कमांड-लाइन पर कुछ नोट्स:

  • /usr/local/lib/arduino/uno/libcore.aवह जगह है जहाँ मैंने संकलित Arduino कोर को बचाया। मुझे बार-बार उसी सामान से नफरत हो रही है।
  • -x noneफ़ाइल एक्सटेंशन को फिर से समझने के लिए कंपाइलर को बताने की आवश्यकता है। इसके बिना, यह मान लेगा libcore.a एक C ++ फ़ाइल है।

मैंने सुदर मुथु के अरुडिनो-मेकफाइल से उन चालों को सीखा । यह एक बहुत ही सामान्य मेकफाइल है जो कई बोर्डों और पुस्तकालयों के साथ काम करता है। Arduino IDE के सापेक्ष केवल एक चीज गायब है, आगे की घोषणाएं हैं।


बहुत अच्छा, एडगर! मेरा समाधान मूल रूप से आईडीई क्या करता है की नकल करता है, तुम्हारा वास्तविक समस्या का समाधान करने के लिए एक बहुत ही भद्दा तरीका है। बेशक आपको libcore.aपहले ही फाइल बनानी होगी। मुझे लगता है कि मेरे उत्तर में जो लाइनें core.aबनती हैं, वे पहले से बनाई जा सकती हैं, इसलिए उन्हें प्रत्येक बिल्ड का हिस्सा नहीं होना चाहिए। अनुभव से पता चला है कि अधिक जटिल स्केच (जैसे वायर या एसपीआई का उपयोग करके) को जोड़ने के लिए अधिक फ़ाइलों की आवश्यकता है core.a
निक गैमन

@ नीकगैमन: यह सही है, मुथु का मेकफाइल (और, मुझे लगता है, अरुडिनो आईडीई) का उपयोग करता है जो भी पुस्तकालयों का उपयोग आप libcore.a में करते हैं। मैं वास्तव में इस दृष्टिकोण को पसंद नहीं करता हूं, क्योंकि यह आपके द्वारा संकलित विशेष कार्यक्रम पर निर्भर "मुख्य पुस्तकालय" बनाता है। वायर या एसपीआई की तरह सिंगल-फाइल लाइब्रेरी के लिए, मैं मुख्य प्रोग्राम के समान लाइब्रेरी कमांड ++ लाइब्रेरी को उसी कंपाइल कमांड में रखना पसंद करता हूं। वह कमांड लाइन आसानी से काफी लंबी हो जाती है, इसलिए मैं मेकफाइल का उपयोग करता हूं।
एडगर बोनट

1
आईडीई के बारे में मुझे जो चीजें पसंद हैं उनमें से एक यह है कि आपको आसपास नहीं घूमना है। सरल परियोजनाओं के लिए वैसे भी, यह "बस काम करता है"।
निक गैमन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.