這次的實作分為兩個階段,第一階段我們直接用 C 語言在電腦上實作來驗證我們自己實作的 Ruby VM 是可以運作的,第二階段則是將程式碼放到 D1 Mini 上面運行。
因為微控制器大多是使用 C 或者 C++(Arduino)開發的,因此我們需要能在電腦上呼叫 GCC 或者其他可以編譯 C 語言的開發工具鍊。
我自己平常使用的是 macOS 正常情況下只需要將 XCode 安裝就沒問題了,如果是 Windows 或者 Linux 的環境就需要自行安裝 GCC 或者其他可以替代的工具。
大致上來說,我們的開發環境最好使用 macOS 或 Linux 並且有以下工具:
因為還需要利用 mruby 的編譯器來生成機器碼給我們的虛擬機讀取,因此同時也需要安裝 mruby 到電腦裡面。
在 macOS 或 Linux 的環境可以善用 rbenv 或者 rvm 去安裝,而 mruby 在寫這篇文章時是使用 2.1.2 版本去測試的,不過只要不是 mruby 1 和 mruby 2 的差別,大多不會有太大的差異。
在 macOS 的環境可以利用 Homebrew 安裝 rbenv 和 rvm 而 Linux 環境可以利用文件上的 Shell Script 快速安裝完畢。
除此之外,為了方便對開發版上傳原始碼,我們可以使用 PlatfromIO 作為 Arduino IDE 的替代,也能更容易的進行測試以及開發。
第一階段我們還不需要在開發版上運行我們所撰寫的程式碼,但我們會需要一個可以快速除錯的開發環境。
初期的規劃專案大概會有這樣的結構
├── Makefile
├── app.rb
├── bin
└── src
└── main.c
我們會使用 Make 來幫助我們編譯,雖然可以使用 Ruby 的 Rake 或者 CMakes 等工具來輔助,但是考慮到在使用 PlatformIO 的前提下使用 Make 是最容易切換的,因此我們會撰寫一個 Makefile 來提供測試所需的處理。
原始碼的部分會放在 elct9620/ironman2021 這個專案目錄下,目前對應的是 feature/1-prepare 階段的程式碼。
上面的程式碼是前幾個月嘗試實現能夠在 ESP8266 上運行的測試版本,還有很多不穩定以及有問題的地方需要改進。
首先我們先製作一個 src/main.c
的檔案來印出訊息,用來測試 Makefile 可以正常運作。
// src/main.c
#include <stdio.h>
int main(int argc, char** argv) {
printf("Hello World\n");
}
Make 在許多軟體專案中經常出現,因為他可以透過簡單的描述將複雜的指令集合起來執行,讓我們不需要每次都手動呼叫。
在這次的開發中我們目標如下
*.c
和 *.h
檔案編譯mrbc
指令生成能被 GCC 編譯進去的檔案第一階段我們只需要能將 src/main.c
找到並且轉換為執行檔即可,因此我們會像這樣撰寫 Makefile
# 非檔案處理的任務
.PHONY: clean run
# 變數
BIN_DIR = bin
SOURCES = $(wildcard src/*.c) # 搜尋所有 src 下的 .c 檔案
OBJECTS = $(SOURCES:.c=.o) # 將副檔名從 .c 置換為 .o
# 預設呼叫 run 任務
all: run
# 任何 .o 的任務會基於 .c 的檔案以及 src/app.c 這個檔案
%.o: %.c
$(CC) -I include -c $< -o $@
# bin/iron-rb 這個檔案是基於 OBJECTS 變數(所有的 .o 檔案)以及 src/app.o
bin/iron-rb: $(OBJECTS)
@mkdir -p $(BIN_DIR)
$(CC) -o $@ $^
# 刪除所有自動生成的檔案
clean:
rm -rf $(BIN_DIR)/*
rm -rf src/*.o
# 呼叫 clean 任務再產生 bin/iron-rb 並且執行 bin/iron-rb 這個檔案
run: clean bin/iron-rb
@bin/iron-rb
關於 Makefile 如何撰寫可以參考網路上的資料,上面的應用技巧除了參考開源專案之外,也透過 Google 查詢的原因以及撰寫方式。
當我們有 Makefile 以及 src/main.c
兩個檔案後,就可以使用 make
或者 make run
來自動運行。
$ make
Hello World
如果順利出現 Hello World
表示我們已經能透過 Makefile 自動編譯所有撰寫的 .c
檔案,此時我們就可以正式開始實作屬於自己的 Ruby VM 了!
下一篇我們會從讀取 IREP 開始實作。