顯示具有 Forth程式 標籤的文章。 顯示所有文章
顯示具有 Forth程式 標籤的文章。 顯示所有文章

2018年12月21日 星期五

如何在Flash ROM上實現直譯語言4: MCU需求修改

原先的LbForth是在DOS-Box上執行,在RAM上執行且記憶體空間完全獨立。
有數個功能要修改:
1 . 記憶體從矩陣改成指標,這樣才能做MCU內的配置。包括生成字典的地方才可以控制。
2 . 記憶體空間管理,因為寫回的記憶體若是Flash區,要轉去Flash燒寫函式去執行。其他讀寫一樣。
3 . 屬性標記修改,因為NOR Flash清空時是0xFF,一般RAM清空是0,且Flash只能單向設定(1轉0),所以內容要反過來,判定程式也要反過來。

實作時前二項修改很容易。
再來是屬性,它有二個flag在用,各佔一個bit,剩下的bit則是數值,標示名字字串長度,用於尋找字。
一個flag是immediate,它是編譯模式下特權標記,標記設定後的字在編譯模式下是執行,而非媥譯,用來形成控制結構用的。
一個flag是hide,它是將此字標記為廢字,不執行也不會進查找。這個設計很奇怪的和Flash寫入程序很合。因為編譯時沒有做全文章分析,有可能會出現程式中有錯,但寫了一大堆的字進入Flash內,但它不完全,所以不可以執行及查找,故需要這個flag去標記。用在Flash上面可以先留下1(設定),在新字確定完成時再回來清除(設成0)。
又剛好STM32L系列及STM32F系列其Flash動作相反。故要修改成可以設定反相又可以運作的程式。

改完後放入MCU,不會動。因為Flash Erase是有規則的,可以Erase大塊,不能Erase單元,但Write可以寫入一個單元。變成又要加入Flash邊界檢知,在字典長到下一個sector時,發動Erase。
然後,還是不行。發現Flash不能只改一個bit,這個和個人認知有出入。測試一下動作,發現對Flash寫入單元可以做的只有二個動作: 寫入資料,寫入0(全清)。
這下頭大了,屬性欄位要改,若是要可以用,immediate及hide要分出來不能和字串長度放一起。
這下動到字典管理了。要符合,變成用資料的值來做為flag應用。變成Erase後的值是hide,若是沒改,新字就是廢字。若要是有用字就要寫入值(非清除),若是為immediate設定,則再加寫0(只能加寫成全清)。

改完後,還有一些Flash上小問題,再以程式解決。然後總算看到去執行字典生成的高階字編譯。又出問題了。
高階字的空值預設是0,但Nor-Flash不是,所以要去改高階指令。這下又要去理解Forth編譯的細節,硬著頭皮上了。
改完後,真的弄清楚了整個Forth語言系統。
總算在STM32F系列上執行了。不過事情沒有完,移去STM32L系列又掛掉。因為它的Flash除了是0寫成0xFF外,又不能亂寫有ECC在,二次寫入是不行的。看來只能改用在QSPI Flash上看可不可以。

如何在Flash ROM上實現直譯語言3: Forth系統分析

LBForth和一般Forth不同,因為它不用從CPU指令來建造,所以沒有基本指令再堆積成高階功能的問題。
因為由C建造,所以它只要專心應付語言實現問題。這使得系統簡單不少。

所以只要看幾個大的函式,弄清其功能,就可以知道如何動作。
但在解析前,有一個必須解決的問題,它的字典資料結構要先弄清楚。
因為這個是Forth運行最重要的結構。

字典的主要內容:
1.字名(函式名): 輸入的文字代表
2.內容(執行欄): op code或是指標,op code是基本執行功能。高階字以指標表代,遇到指標會跳去對應的記憶體內容再解析,直到執行op code。
3 .結構串接: 以link-list串起來
4. 屬性及標記,後面用到時再分析
實際排列:有固定長度的放在前面,所以link-list為第一個word,第二個是屬性,和名字共用32個byte(佔4個word),接下來是執行欄,長度不定。

字典在程式碼內是看不到的,因為它是在執行才生成,這個動作有利於Flash的寫入,也是可以利用未用的程式Flash的原因。個人覺得這個設計解決MCU上可以動態增加函式的方法。

再來是Forth的執行結構,它和CPU設計有相關,所以很像硬體的方式。
主要有二個堆疊,一個是資料堆,所以資料及參數全部放在此運算。
另外是一個返回堆,主要是呼叫返回堆疊及一些控制結構變數也放在內。
二個堆疊各有一個管理指標暫存器。
另外在執行上,有一個指令指標暫存器(IP)用來標記目前執行位址。

使用二個堆疊原因:
資料處理全部在資料堆疊上,故使用者要去做堆疊內容管理,這個在高階電腦語言是沒有的。因為此動作沒有執行效果,但可以限定RAM的使用只在資料堆疊上。這也是為何Forth使用RAM很少就可以運作。
MCU一向RAM就是不多,其他語言都有RAM需求問題,若是RAM大,MCU就不用寫得辛苦了。

實際上執行,有分成直譯模式及編譯模式。
平時在直譯模式下,輸入一個字串結束(空白字元出現),就去字典查找這個字,有找到,就依執行欄內容再進一步查找或是執行。
若是直譯失敗,再來是進行數字解析,因為這個字串有可能是數字字串,解析成功,就放入資料堆。
若再次直譯失敗,就沒法了,就執行錯誤處理(顯示輸入錯誤)。
有多字輸入下,會一個一個去執行,直到沒有新的輸入。
但有個直譯指令是不一樣的,它會進入編譯模式。
編譯模式下一樣有找字和轉換數字字串的動作,但再下去的動作不同,它不執行而是寫入Flash,生成新的字進入字典內。
在編譯模式下,一樣找字,找到字就將其執行欄位址寫入新字的內容,然後找下一個字。遇到數字時有點不一樣,會先寫入一個lit指令碼再寫入資料值。執行到lit指令碼會將下一欄的內容吐回資料堆疊。這樣就完成固定值的編譯。

了解Forth的運作後,才能做下一步的修改。

2018年12月13日 星期四

如何在Flash ROM上實現直譯語言2: 規劃及找材料

MCU上實現一個語言,在8位元時代就有,8051 Forth是我第一個看到的作品。
全部組合語言寫出來,以機器碼寫回。但有條件,RAM也是Code space,這個要在硬體上動手腳。
有興趣的人可以看一下CamelForth51,因為實用性不好,程式碼看了沒在用。

不過CamelForth的作者有另一個作品MSP430 Forth,它可以寫回Flash,無需佔用RAM做程式儲存。
可惜沒有用到大一點的MSP430,沒有機會用,也沒有機會看原始碼。但粗看和8051一樣用組合語言寫的。

二個Forth看完原始碼,皆打破我對Compile的觀念,原來字彙分析就可以集成語言。但它有一些基本模型在。
像是雙堆疊,有一個資料堆以及一個返迴堆。一般語言像C,只有一個堆疊,資料及返迴一起堆進Stack。
這個相當"硬體"的設計。
另外一個是直譯,沒有main函式。輸入字全部都可以執行。

再來是32位元時代,Forth仍用組合語言寫出來,這個完全沒有引起我的興趣。
因為這個時代,原廠都是給C函式庫,像USB如此複雜的裝置,要用別的語言再寫一次,那有時間?
要用,也用C寫的,但eLua有點大,它可以拆分將VM放入MCU內。用起來還是有點麻煩。

然後找到STM32Forth,看來可以了。且證明可以完全在Flash ROM上作業。不過它也有點問題。
加功能進去不是很容易,因為C的語法限制,不像組合語言一樣好寫,維護肯定不好用。先放著。

再來有一天找到LBForth,一看就是我要的。它有幾個特性:
  1. 它不使用機器碼,改用OP Code為基本單元。這個可以避免執行平台問題。
       2. 指令實現的C Source Code是集成的,不是分散的,這個易維護。但看來是動用到一些巨集技巧。

不過它在X86上執行,且為區域變數空間上。要在STM32上執行仍要改,順便修改時看看它是如何實作一個Forth。



2014年10月25日 星期六

Forth語言在Swarm發展之可行性

1.  Forth語言之困境
    身為Forther是不會願意接受這件事,但此為現狀,Bee很早就認為,只是隨ARM MCU之流行,情況更加嚴重。
    Forth因為小而完整發揮MCU能力,確實在8/16位元MCU上一直有特色。
    但隨著時代推展,進入32位元MCU時代,小而完整之特質已無法凸顯其特色。
    32位元MCU時代的特性為:
    1.  豐富週邊
    2.  大量免費C函式庫
    3.  大量免費軟體工具
        RTOS, FAT File System, USB Driver, Ethernet Example, GUI Library, SD Card Driver...等等。
    以上特色,使得MCU以C發展可以快速得到成果,Forth則無廠商願意寫函式庫,變得跟不上時代。
    32位元MCU各大廠又以軟體元件為其發展重點,快速拼裝已成為特性,大大的拉開C語言及其他語言的距離。
    32位元MCU除了C外,其他語言完全變成非主流。
   
2.  Swarm Robot / Multi-Robot System發展之問題
    Robot一直是MCU實現的好目標。使用Forth發展是很方便的。但因MCU隨著32位元時代來臨,Forth被淡忘。
    實際上單一Robot發展並不是很方便,若非C語言在MCU上有大量的工具,使用C語言是一項沒有得選擇的發展。
    Bee曾認為Forth在Robot上的發展可能有一席之地。但32位元MCU推展過於快速,完全沒有給Forth有時間及機會去成長。
    在一個偶然的機會,Bee想到找群體機器人(Swarm)上的相關資料,發現以目前的Robot發展是困難的。
    主因為在於Swarm Robot除了實現Robot外,需要解決Robot之間溝通之問題。
    實現通信不難,但Robot之間溝通,實為發展社會語言,若非有電腦語言發展能力,此問題不易解決。
    一般實作Robot,多以電子為主,語言只是實現工具,故一般工程師無法有效解決此問題。
    常用工具C語言在此問題上,完全是缺乏應用之空間。故在此領域推展很慢。
   
3.  Forth如何解決Robot通信及Swarm程式發展之可能
    Forth寫Robot程式和C寫Robot有很大的不同。
    C語言寫Robot比較像是外科手術:
    1. Robot關閉;  麻醉
    2. 寫程式下載; 開刀
    3. Robot打開;  叫醒
    但此程序對於多機器人的程式發展及測試是不利的。
    因為有很多狀況是機器人已經面對和另一個機器人要做溝通協調,外科手術反而打斷取得狀況的方法。
    Forth寫Robot程式則是像老師教學生:
    學生接受老師的指令,一步步動作。有新狀況也可以回報,並加以修正。
    在Swarm的環境,所有的通信都變成廣播型式的指令。
    Forth原先只有一個對象,在此環境中,只要增加指定對象的指令、交換資料的指令,就可以開始使用。
    此時程式設計師成為教練,每一個機器都是學生、學生間可以交換資料,並下命令改變其他學生的工作。
    故Forth可以直接成為Swarm Robot的自然語言,人機一體語言在此環境是極為自然的溝通。
    在通信格式上,幾乎只要將Forth指令用通信封包包一下就可以直接使用。
   
結論:
    Bee認為Forth的衰退是時代的必然。但Forth要能使用下去必須找一個符合的環境。
    只是經過長久的觀察才找出可以有效利用Forth特性的使用場所。
    另一個說法是:C語言在MCU上已是霸主。
    Forth在單打獨鬥上是輸C不少,所以就不要單打,改打群體戰。
    在群體戰這個新領域Forth再利用其小而完美的特性重新站起來。

2011年8月20日 星期六

Flash Forth的運行原理

因為使用到PIC,於是看看有無Forth可用,於是找到Flash Forth。
另一個目標是找Cortex M3上的Forth,結果找到一個分散式的Forth,PC端是用TCL寫的,TCL很不熟,就先放著。

比較令我感興趣的是PIC18上的Flash Forth。
雖然丁陳老師的eForth有做在PIC17上。但無法做新加程式,因為無法將程式寫回Flash。
但Flash Forth在PIC18上可以將程式寫回Flash。
因為MCU上我比較少做這個動作,所以沒有想到其實可以寫回Flash,就可以Run完整的Forth。
看了一下,就把回寫的地方改為燒回Flash的函式。
雖然寫回Flash是很慢,但人的反應也不快,所以不會感覺到。
只要Run的夠快就好了。

有去比對其他Forth,MSP430上的CamelForth也有這樣的能力。
不過作者有發現一個問題,就是CREATE> 指令受到影響。
而改以另一個指令去取代。

還是比較希望有Flash Forth在Cortex M3上面。目前還沒有看到。
Bee是知道FIG Taiwan的Holi有ARM7 Forth。不過他的堆疊成長方向和Cortex M3相反,要移反而麻煩。
只能說是Holi選錯了方向,因為ARM7確實二個方向都可以。
不過Cortex M3因為要精簡,就變成單向。而且組合語言指令有16 bit及32 bit混合,不像ARM7固定在32 bit上。
這些改變都要去動Forth核心動作。重寫可能還比改寫快。


2011年1月18日 星期二

使用Virtual Box安裝Win32Forth

64位元作業系統還是有不方便的地方。

所以使用VM再去裝WinXP是一個取代的方法。

Bee是安裝Virtual Box,裏面再安裝WinXP。

終於又看到熟悉的Windows,真是感動。

然後在裏面安裝Win32Forth總算可以動了。

不過記憶體用很凶。原本就用1.5G,開VM再用1G。

沒有辦法,現在4G快要用光了。


2011年1月16日 星期日

在Win7-64下,沒有Win32Forth可以玩了

最近有一位Forth同好連絡上Bee,要Bee教Forth程式。

不過Bee換了Win7-64之後就沒有玩過Forth了。

那有人要,就翻出以前的檔案來安裝吧!

結果Run之前的安裝程式,裝到一半就被McAfee防毒軟體給砍了。

心想被砍的是Win32Forth 6.12版。那就再去抓新的版本回來。

不過Win32Forth也沒有再出新的版本。

載了數版都被砍。無奈,回去安裝最原始的版本4.2版,結果沒有被防毒軟體砍,但仍不行。

原因是執行檔版本太舊64位元下無法支援。


唉!和Forth真的斷了。


2010年5月25日 星期二

測試DLL函式庫功能

這是Bee最常用的。拿來測試DLL內的功能並看單一結果。
在Win32Forth下直接寫以下程式,去連接OpenCV的DLL並呼叫函式

WinLibrary cv110.dll
WinLibrary cxcore110.dll
WinLibrary highgui110.dll

1 z" Win32Forth Call CV DLL " call cvNamedWindow

結果就有一個視窗出現,標題字串就是由Win32Forth傳的。

但有一些規則還是要注意(其實是Bee太久沒用,寫給自己做記錄):

1. 參數要查出真值,因為無法使用C的#include。
2. 參數要倒序先放,這是Win32Forth的習慣。
3. 字串使用 z",因為Forth的字串和C的格式不同。


2009年3月3日 星期二

打造GTK的Forth程式語言介面

Forth連上GTK了,也就是連上其他函式庫也可以參照這個方法。
http://tutor.ksana.tw/ksanagtk/

我發現和Lua的Alien函式庫做法差不多。可見得這個作法是正確的。

2009年2月18日 星期三

為何使用Forth

會使用Forth是一場機緣。但並不是完全沒有理由,在學的時候也有查過其特性才學的。
當時找到的資料是Forth是最小的作業系統混合語言。當時自認為對電腦很熟,想說已給了組合語言原始碼。大約千行的程式碼,應是不難破解其運作。
要了解作業系統及電腦語言的產生,Forth可以一次學會,這比一般分開學作業系統及電腦語言會快些。
結果是除了捷徑這件事是對的,其餘都是錯估。

初看Forth語言,很像是組合語言。因為有很多特性和C語言差很多,感覺要原始得多。
不過原始碼實在很難懂它是如何運作,最大的原因是,Forth系統的運作方式也是用Forth定義的。即使是用組合語言寫的,但高階部分是使用Forth語法。
故在自學Forth上是覺得入門門檻是高了些,因為還要去習慣Forth的習慣。
後來是和使用Forth的人在一起討論才對這個語言開始熟悉。在有人指點的狀況下,才能抓到Forth的重心。

在使用Forth上,最令我驚訝的是8051 Forth。因為在8051上是可以使用組合語言及C語言,但沒有一個語言可以做到動態編解譯程式,Forth就可以。
就以目前的功力來說,要在8051上做到動態編解譯程式,還真的找不到更精簡的架構。
動態解譯這項能力對Forth程式開發有很獨特的吸引力,它可以單獨執行函式,對機器做單一功能測試。這對於將電腦應用於機器測試上是很好的除錯能力。
大部分狀況用8051做控制是不大可能要做動態解譯來測試機器,但我在其他16位元及32位元上也不常見。

所以在Forth的功能表現上,有語言編譯的能力及作業系統管理特性。所以想說學了應可以學會編譯語言的方法及作業系統的知識。
剛好以Forth語言做為開發平台的公司有免費的討論會。所以有機會我便去參加討論會。
中間有許多人參與這個討論會,但我參加了二年才開始了解Forth的核心。可見得一開始真的是估錯了。
之所以會花二年的時間,一則是我並沒有急著用,另一個是一個月才一次討論,其中包括軟硬體設計。

Forth系統其程式碼很少,因為其函式很容易長得深,也造成其不易閱讀的特性。
但是確實有實現語言及作業系統機制,也因程式碼少,可以看見最簡單的作業系統及語言編譯方法,這對我了解電腦應用及原理有很大的幫助。
所以有段時間想用,但一直不易去使用。原因是可用的模組少。
以Win32Forth為例,是目前Windows平台上使用的Forth。但程式碼在Windows的函式太多(Windows內部函式也很多),一直不好上手。

最後目前我只能放在Dll的實驗上,看何時有比較好的機會再使用。