我的Arduino板子是Uno(Rev 3),軟體開發環境為1.0版。
用了Arduino的軟體開發環境一陣子後,就會覺得好慢,每次執行Sketch-Verify/Compile(按鈕是個勾勾)或File-Upload(按鈕是個朝右的箭頭),都要花上一段時間。可以到File-Preferences,勾選Show verbose output during: compilation與upload,就可以清楚地看到它到底執行了哪些動作。
除了要編譯我們寫的程式碼外,它還需要編譯位於hardware\arduino\cores\arduino底下的Arduino核心程式,但是,讓我覺得納悶的是,為什麼每次都還要重新編譯那些核心呢,之前不是已經編譯過了嗎?我並沒有去更動那些東西啊?而且,如果我修改程式後先Sketch-Verify/Compile看看能不能通過編譯,通過後,再File-Upload,它居然又從頭開始執行那些已經執行過的編譯動作,真是夠了。
總之,Arduino的軟體開發環境,實在有點遜遜的,底下要介紹,怎麼在Cygwin命令列下,以make工具與Makefile檔進行編譯與上傳。
首先,還是要安裝Arduino的軟體開發環境,我們只是不用那套視覺化開發環境,改而使用命令列模式(終端機),但仍然需要裡頭各種工具與核心程式碼。
然後,要安裝Cygwin,到這裡下載Cygwin的setup.exe,安裝步驟如下:
執行setup.exe,我們將從網路下載、安裝,所以選第一個Install from Internet。
指定安裝目錄,預設為C:\cygwin,如果沒有特殊需求,就不要更動。
除了安裝,下載回來的東西也會另外存一份。請指定某路徑。
選取網路連線設定,請根據你上網的方式進行設定。
然後,選擇要從哪台伺服器下載,基本上都是國外的,速度慢,可以自行輸入"ftp://ftp.ntu.edu.tw/cygwin/",使用台灣的。
然後選擇要安裝哪些軟體,預設並不會安裝make,所以我們要自己手動勾選。
在Search欄位輸入"make",在Devel分類下,勾選make: The GNU version of the 'make' utility。應該要顯示3.82.90-1或類似的版本編號。
然後就是下載並安裝了,setup.exe可能會提示你,有些具有相依性的套件也要安裝,請選同意安裝。
我因為還灌了很多其他有的沒的,所以安裝後的C:\cygwin目錄共約700 MB。
不過,新版的make不知道為什麼,不能正確處理我底下要介紹的Makefile,所以,要把make改回3.80版。開啟cygwin終端機後,以底下步驟,改為3.80版。
cd /usr/bin
mv make.exe make_382.exe
wget http://geant4.cern.ch/support/extras/cygwin/make.exe
chmod +x make.exe
然後,因為make 3.80版需要某程式庫,所以請再執行一次setup.exe,加裝"libintl2"這個程式庫。
檢查一下,在cygwin終端機上執行make --version,應該要出現3.80字樣。
我已經提供一份範例,可到這裡下載,按下ZIP按鈕可打包下載。接下來我將使用這個範例作說明。
在BlinkMakefile目錄裡,總共有6支檔案BlinkMakefile.cpp、foo.c、foo.h、bar.cpp、bar.h、Makefile。(其他目錄是我的Arduino練習。)
BlinkMakefile.cpp,裡頭的程式就是讓腳位13的LED閃爍,不同的是,我們需要在檔案開頭加上#include <arduino.h>,這是因為,以前,arduino軟體開發環境會幫我們做這件事情,現在要自己來。
為了當示範,所以我還加了一支C程式檔foo.c與它的標頭檔foo.h,裡頭很簡單就是一個叫做delayDuration的函式,固定回傳1000,在BlinkMakefile.cpp裡,會把這個值當做點亮LED的時距。
還加了一支C++程式檔bar.cpp與它的標頭檔bar.h,裡頭就是個ClassBar類別定義,以成員函式getDelayDuration回傳一個值,但這個值每次呼叫會加100,第一次回傳100、第二次回傳200、等等,在BlinkMakefile.cpp裡,會把這個值當做熄滅LED的時距,所以熄滅時間會越來越長。
然後就是主角Makefile了,恕我無法詳細講解其語法了,底下說明你應該修改的地方:
原本Arduino軟體開發環境,程式檔使用.pde或.ino副檔名, 現在請全部改成.cpp。
PROJECT = BlinkMakefile
這是最後產出檔案(.elf、.hex、.eep)的檔名,可以改成任何你想要的名稱。
ifndef PROJ_SOURCE
PROJ_SOURCE := $(wildcard *.c) $(wildcard *.cpp)
endif
上面會找出你專案的原始程式碼(.c與.cpp),請把這些檔案放在跟Makefile同一個目錄裡即可。請不要使用子目錄。
MCU = atmega328p
板子上的微控制器是哪顆,填寫正確編譯器才知道要產出何種機械碼。我的板子是Arduino Uno Rev 3,所以填atmega328p。不僅編譯器需要這個參數,上傳時也需要。
F_CPU = 16000000L
微控制器的時脈。為了相容性,不管什麼板子,好像都是一樣的,所以應該不用改。
ARDUINO_VERSION = 100
Arduino軟體開發環境的版本編號,這會傳入編譯器,就可以在程式碼裡使用這個值。
FORMAT = ihex
輸出格式,應該不用改。
PORT = \\.\COM3
序列埠連接埠號,這就是軟體開發環境Tools-Serial Port的設定。你可能覺得奇怪\\.\是幹嘛的,這跟上傳工具的參數指定、Windows路徑、等等有的沒的有關係,總之這樣寫就不會遇到奇怪的問題。
UPLOAD_RATE = 115200
序列埠連接埠號的傳輸速率,一般都是設9600,但我的板子可以用115200。上傳時需要這個參數。
INSTALL_PATH = D:/Arduino/arduino-1.0
這個路徑要指向Arduino軟體開發環境的最上層目錄。也就是有arduino.exe執行檔、examples目錄、libraries目錄、等等的目錄。請依照你的安裝路徑修改。
CORE = $(INSTALL_PATH)/hardware/arduino/cores/arduino
這個路徑要指向Arduino的核心程式碼檔案的目錄,也就是有Arduino.h、wiring_analog.c、wiring_shift.c等等檔案的目錄。INSTALL_PATH設好後,這個應該就對了。
BUILTINLIB = $(INSTALL_PATH)/libraries
內建程式庫的路徑,裡頭應該含有EEPROM、Ethernet、LiquidCrystal、等目錄。INSTALL_PATH設好後,這個應該就對了。
SKETCHBOOK = D:/Arduino/sketchbook
自己寫的程式碼的路徑。
THIRDPARTYLIB = $(SKETCHBOOK)/libraries
第三方程式庫的路徑,也就是你自己額外安裝的程式庫。SKETCHBOOK設好後,這個應該就對了。
AVRDUDE_PROGRAMMER = arduino
設定要用什麼燒錄器上傳程式,arduino代表要使用微控制器裡的bootloader進行上傳。根據板子不同,可能要改成stk500、stk500v1、或stk500v2。可用參數請參考avrdude這隻工具程式的參數說明,avrdude是負責上傳(燒錄)程式的工具。
若要使用Arduino內建的程式庫,請修改Makefile裡的
BUILTINLIB_ENABLED =
在後面加入程式庫的名稱,例如
BUILTINLIB_ENABLED = EEPROM Ethernet Firmata LiquidCrystal
(需要設定BUILTINLIB指向內建程式庫的目錄)
若要使用額外安裝的程式庫,請修改Makefile裡的
THIRDPARTYLIB_ENABLED =
在後面加入程式庫的名稱,例如
THIRDPARTYLIB_ENABLED = BOUNCE
(當然,你要先下載程式庫、解壓縮、放進THIRDPARTYLIB指向的目錄。)
至於其他的,就屬於make的東西了,有興趣的話請自己看看囉。
接下來,開啟cygwin終端機,切換到BlinkMakefile目錄後,以底下指令進行編譯與上傳:
首先執行
make depend
根據上面設定的檔案與路徑,這會找出.c、.cpp、.h等檔案的相依關係,並附加在Makefile的後面。
make
這會開始編譯、連結,成功的話,最後會出現BlinkMakefile.elf、BlinkMakefile.eep.hex、BlinkMakefile.eep。(以及其他.o檔。)若再執行一次make,會出現make: Nothing to be done for `all'.,太好啦。
make upload
這會開始上傳,將程式燒錄到板子裡。
make clean
這會把make產生的檔案通通刪除。我這支Makefile,會把中間目的檔.o、以及其他檔案,直接產生在原始程式檔的目錄裡。這是我執行make的畫面。
這是我執行make upload的畫面。
完成啦。
不過,有個小問題,原本的Tools-Serial Monitor序列埠監看視窗呢?沒關係,我們可以用Windows裡的超級終端機或是Tera Term取代。
先介紹超級終端機(開始-程式集-附屬應用程式-通訊-超級終端機),開啟後:
嗯,大家上ptt應該都用別的程式吧,這裡請勾選"請不要再詢問我這個問題",然後按"否"。
填入一個名稱,隨便選個圖案。
若要求你輸入區碼,隨便輸入一個數字。
設定連接Arduino的序列埠號。
底下是序列埠的傳輸設定。
每秒傳輸位元,我使用115200,如果不行,請試試看一般的9600設定值。
資料位元,8。
同位檢查,無(N )。
停止位元,1。
流量控制,無。
連線成功後,就可以看到BlinkMakefile傳過來的LED明滅時距,每次點亮固定為1秒,第一次滅掉為0.1秒,每次延長0.1秒,所以熄滅時間會越來越長。
以上步驟成功後,在「開始-程式集-附屬應用程式-通訊」裡會多出一個超級終端機目錄,裡面有將以上設定儲存起來後的捷徑。
成功啦。
不過Windows附的超級終端機HyperTerminal,年久失修,Windows Vista、Windows 7裡頭已經沒有它的身影了。還好,可以用Tera Term。
到Tera Term網站下載,我下載的是teraterm-4.72.zip,只要解壓縮後就可使用,不用安裝。
執行ttermpro.exe,選Serial,選你Arduino板的序列埠號。我的是COM3。
畫面看起來怪怪的,因為還沒設定好序列埠的傳輸參數。選Setup-Serial port...進行設定。請根據你的情況設定,跟我不一樣的地方應該會是Port與Baud rate,其他應該都一樣。
成功啦。
然後,選Setup-Save setup...把設定儲存起來,下次執行ttermpro.exe就會直接連接。
還有其他可用的軟體,譬如PuTTY、Roger Meier's CoolTerm。
後記:
我因為裝了免費版的avast!防毒軟體,每次執行make、avr-g++、avr-gcc時,都會進行防毒掃描,變得很慢,所以我到avast!的設定裡,將這些執行檔排除在掃描外。(關閉前超過一分鐘,關閉後5秒。)
參考資料:
- Arduino官方網站的文件,Arduino Build Process。
- Arduino Playground(維基),Arduino from the Command Line,Windows command line build。
- Johannes Hoff: Arduino on the command line。
- Martin's Atelier: Arduino from the command line。
- Wikiid: Command line Arduino。
- AVRDUDE - AVR Downloader/UploaDEr,avrdude的參數。
- avr-gcc、avr-g++、avr-ar、avr-objdump、avr-objcopy、avr-size。
- Dependency Generation with Subdirectories using gcc。
- GNU make, how to determine a path is a file or a directory?。
- GNU Make Manual。
感謝,這篇太有用了 !
ReplyDelete不好意思!想請問一下:
ReplyDeleteMakefile:283: *** multiple target patterns. Stop.
這該如何解決?
光這樣看不出所以然。
DeleteMakefile:https://dl.dropboxusercontent.com/u/65894737/Makefile
Deletemake --version GNU Make 4.0
能麻煩您幫忙確認一下?
拜託了!
當初我在嘗試的時候,必須使用make 3.80版才行。
Delete我沒試過4.0版。
似乎是因為3.80以上的cygwin的make版本,若出現MS-DOS的路徑就會出問題,例如D:/xyz/abc,但若改為cygwin的路徑/cygdrive/d/xyz/abc,這支Makefile裡有些部分又會出問題,必須改寫。
Delete可到網路上找找,看看有沒有人更新。不過據我所知,似乎還沒有。
您好,我用 Cygwin 下的 make 4.0 可以成功編譯而且上傳。
ReplyDelete我用的是 1.5.7-beta IDE。
1. 在 Cygwin 的 shell 裡要執行 export PATH=$PATH:/cygdrive/c//hardware/tools/avr/bin
2. 如您所說 makefile 裡 MS-DOS 型式的路徑要改成 /cygdrive/c/xyz/abc
在您提供的 BlinkMakefile 裡的 Makefile 有 INSTALL_PATH 也就是 IDE 的路徑,
還有 SKETCHBOOK 要改成這種方式。
3. 如果是 1.5.7-beta IDE,還要修改 CORE,
CORE := $(INSTALL_PATH)/hardware/arduino/cores/arduino
->
CORE := $(INSTALL_PATH)/hardware/arduino/avr/cores/arduino
如果是用 1.0.5 IDE,這裡就不需要修。大概是 1.5.7-beta 支援其他的晶片吧 ?
以上改完就可以編譯成功。
4. 要上傳到板子,也就是您說的 make upload,
在 COM3 前要多加一個 '\' --> PORT := \\.\\COM3
在 AVRDUDE_FLAGS 的下一行 (因為加了 \ 所以對 makefile 來說是同一行)
-C $(INSTALL_PATH)/hardware/tools/avr/etc/avrdude.conf
讓 avrdude 能讀到 configuration file。
以上改完就可以上傳成功。
個人經驗,供您參考
Excellent,太棒了!
Delete多謝提供詳細的步驟。
請問我按照步驟做完後,下達make depend出現以下錯誤:
ReplyDelete/bin/sh: -c: line 0: syntax error near unexpected token `('
/bin/sh: -c: line 0: `rm -f /cygdrive/c/Program\ Files\ (x86)/Arduino /hardware/arduino/avr/cores/arduino/core.a'
Makefile:317: recipe for target 'clean' failed
make: *** [clean] Error 1
該怎麼解決?
建議
Delete1. 不要把Arduino安裝、放到含有中文名、空格、長名稱的路徑裡。
你的路徑... /Arduino /hardware/arduino/avr/ ...其中/Arduino的部份是不是有空格?
2. 你裝的是1.5.x版吧,我只試過1.0.x版。請參考上一個留言,有人使用1.5.7版並成功。
請問 為什麼選擇範例進行編譯會發生錯誤 我的電腦是 windows vista 32
ReplyDelete什麼錯誤?
Deletegoogle翻譯:
DeleteAVR-G++:錯誤:CreateProcess的:沒有這樣的文件或目錄
編譯時發生錯誤
這份報告的詳情將會在
“編譯時顯示詳細輸出資訊”
在檔案>偏好設定裡啟用。
> google翻譯
Delete為什麼要翻譯?
> 這份報告的詳情...
既然如此,請開啟「“編譯時顯示詳細輸出資訊”」選項,取得更詳細的錯誤訊息。
試試在程式裡加上#include "WProgram.h"或#include "Arduino.h"
一樣是編譯時發生錯誤
Delete詳細資訊:
D:\arduino-1.6.4\hardware\tools\avr/bin/avr-g++ -c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -MMD -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=10604 -DARDUINO_AVR_UNO -DARDUINO_ARCH_AVR -ID:\arduino-1.6.4\hardware\arduino\avr\cores\arduino -ID:\arduino-1.6.4\hardware\arduino\avr\variants\standard C:\Users\yy\AppData\Local\Temp\build7520302592673202118.tmp\Blink.cpp -o C:\Users\yy\AppData\Local\Temp\build7520302592673202118.tmp\Blink.cpp.o
avr-g++: error: CreateProcess: No such file or directory
麻煩你了
這篇的Arduino軟體開發環境為1.0版,我沒試過1.5以上的版本。
DeleteArduino自1.6.6開始提供arduino-builder,可試試。
呃,你是想在命令列模式下(譬如Cygwin)編譯Arduino程式,對吧?
Delete謝謝你的解答 不過我只是個新手 純粹想解決我的電腦不能執行Arduino的問題 ^^
Delete喔。因為你在這篇底下留言,所以...。
Deleteavr-g++: error: CreateProcess: No such file or directory這個錯誤訊息很模糊。
試試關閉防毒軟體,它可能妨礙Arduino IDE執行其他程式。
刪除原本的Arduino,下載最新版,再試試看。