Q: 為何compile不能在Flash ROM上?
A: Compile有三個程序,Lex,Parser,Assembly。其中parser會使用大量RAM做堆疊搜尋,會使用大量RAM。這個程序產生出來的資料結構也不合適Flash寫入特性。
Q: 若是跳過Parser,能否成為一套語言?
A: 有可能,但有可能是採用機器類似的語法。可能有些怪。
Q: 若有些怪不是問題,它會有什麼好處?
A: 可以動態改變MCU程式,在不關機下進行程式變更。此特性對多變化的通信環境比較合適。
Q: 若MCU可用程式空間變大下,此功能是否會變得有用?
A: 會。因為程式更新開始變得痛苦,程式不管改大改小,都要進行脫機燒錄升級,若可以不重開下進行變更,在使用者觀感上會有很大的好處。因為IOT大部分不會給予太大的變動,使用動態編程式可以解決很多問題。且沒有程式空間用完的問題下,新加函式就算沒有用,也不會有浪費空間問題。
以上問題全部解決,於是找出可以用的語言來做。可以用的小型語言就是Forth。
先不看Forth是什麼。先看如何解決問題。
1. 不經由Compile程序做編程,又要在Flash上編程式,程式生成就是直述法。除去基本運算函式,程式會由基本運算組合起來的程式集所組成。只要經由查表,就生成,這個特性就符合Flash上的編程。但高階程式(也就是函式)要執行後可以返回,在執行時一定要有一個呼叫堆疊。這是很硬體的特性。
2. 資料操作,程式運行時需求區域變數去處理,函式呼叫也要有參數區。可以設置一個資料堆疊來完成。又多了一個硬體特性。
3. 函式如何運行:字典的結構
以編譯語言來說,有二個狀態要解決:執行及編譯
先做執行時期的功能:
若是有找到字詞,就執行。又要如何結構一個可以查的又可以動態成長的表?
串列鍵結可以解決此問題。將所有可以查的字用串列方式鍵結成一個"字典"。
這個字典有三個部分,第一欄是Link-List。第二欄是名字,因為長度不定,第一格變成要給一個長度,因為過此長度,就是第三欄,第三欄是執行內容,這也是不定長度,但不用記長度,因為接下去又回到第一欄,由Link-list就可以知道結尾。
4. 常數
對於只有純的字解析語言來說,會先查表,看看是否輸入字詞有函式符合,有則執行。但常數不是固定的字。
所 以等於可以在查字詞失敗時,有可能是常數,可以在此進行常數解析及轉換,都失敗,就等於都不是。
5. 語法結構
這裏要決定第一個語法結構,這個語言要用前敘式、中敘式還是用後敘式語法?
最省RAM的是後敘式,這個最符合MCU的ROM多RAM少結構。但此結構有另一個問題,後面再說明。
分字,使用空白字,這是唯一的關鍵字。或許有人會覺得不足,實際上還是要加一點特性就有機會像一套語言。
- 試寫並模擬
直譯動作原理。目前因為字典第三欄未定,為省空間,先放一個函式指標進去。找到字,就用指標執行。
需要的程式動作有:
取字,遇到空白,才取出一個待解的詞。
找字,比對輸入詞是否在字典內。
執行,比對成功就依內容指標跳去執行。
數值,有些是定數輸入,會再取用下一欄的資料,轉成數值。但這有跳過一欄問題,顯然要去調整"執行標記"指標。
- 編譯
也就是新加入一個字到字典內。
有二個狀態,第一個是新名字取出,寫入Flash。
再來第二個字就是執行字,取出後要找字。
新加入doLit功能,它是取值,同時調整 "執行標記"指標。
執行標記名為IP
8. 函式呼數堆疊
新加入doColon功能, IP暫存及返回堆疊,仿CPU,類似函式呼叫。IP會堆在堆疊上,再載入新一層函式指標。
也有類Return功能退回上一層函式。
- 組合編譯及執行
":"指令及";"指令。":" 是進入編譯模式,";"是編譯結束,回到直譯模式。
10. 進階編譯問題
immediate旗標及tick指令。
因為編譯下有一些計算問題,所以變成要有一些指令要編譯下仍可以執行。故設置immediate旗標,執行字被標記為immediate就進入直接執行。
"'" tick指令,用來解除immediate字的狀況,直接編譯入字典。
11. 控制結構
沒有if/else就不能算是一套語言,所以要有。但可以利用高階字寫出來。
因為是後敘式函式,變成順序有點相反。形成IF ELSE THEN結構。
12. 廻圈
利用返回堆做計數,使用者就不會看到廻圈計數器,又可以做到控制次數。
13. 其他函式
需要多少基本指令? 函式編碼,形成token threading,也就是類VM設計又保有指標數值的方法。
除錯指令,堆疊內容印出,才能知道執行狀況。
廢字問題,Flash要如何處理編譯失敗形成的廢字。新增Hide旗標,進入編譯時設定,編譯成功時解除。
在語法出錯時,己寫入Flash的指令就變成廢字不會使用到,也不會進入找字程序。
- 全部組合及模擬測試
C的語法限制。變成有些動作要去執行時才進行。
- 使用RAM/ROM資源大小
在STM32上實現結果:程式大約6KB,但自定義字原始碼約4KB。
執行時生成字典6KB,RAM使用在2KB就可以了。