第三章、 可由使用者程式化的 WINS
3.3 Firmware 設計
有別於傳統單晶片系統的 firmware 設計,本系統之 firmware 為一個直譯器
(interpreter);在主程式 (main loop) 中不斷地重複做解譯使用者命令、執行使用者命令的 工作,其流程圖如圖 14 所示。在程式執行之初,會將原本定義在程式裡面的使用者腳本 (script)全部複製到主記憶體 RAM(位址為 080H~0FFH,參考圖 15)之中,然後每次從 RAM 之中已載入的腳本取得使用者命令,接著呼叫相對應的副程式(例如時間延遲)以執行使用者 要求的動作。將 script 放在 RAM 的主要理由是:未來可設計成直接由 RS-232 甚至從無線 模組收到的資料取代 RAM 之中的 script,達到「空中換碼」或是「空中更新 script」的功 能。程式藉由一個 CMD Pointer 指標來記錄目前執行到那一個使用者命令,一個使用者命 令由兩個 byte 組成,放在 RAM 中的第一個命令其「列號碼」為 0,第二個命令為列號碼
為 1,依此類推,當執行到「跳躍」命令時,便是設定 CMD Pointer(Command Pointer 命 令指針)的內容,這會讓 MCU 跳到指定的列號碼繼續執行。
Start
Initiation
Reset User CMD pointer
Read User CMD
Execute User CMD
CMD ==
Reset ?
Increase CMD pointer Yes
No Firmware flow
圖 14:Firmware 流程圖與 MCU 內記憶體使用圖
System Working Registers System Variables
User Variables
System Buffers
User Command Area RAM allocation
00H 10H
30H
50H
80H
FFH
圖 15:MCU 內記憶體使用圖及使用者變數位址表
除了記憶體的安排之外,本篇論文還設定了 32 個使用者變數(暫存器),如圖 15 右側表 格所示,從記憶體位址 30H 至 4FH 共有 32 個位址可讓使用者隨心所欲地控制,以呼叫直 譯器命令操控這些變數內容;在 4EH 這個暫存器稱為 Accumulator(Acc.),許多邏輯部份 的運算與數學運算是必須靠這個暫存器完成的,而 4FH 這個暫存器稱為 Base,通常是配 合 Acc.進行加減乘除運算時使用,例如加法運算時 Base 便會保存進位狀態。在 4EH 與 4FH 這裡有特別的設計,就是使用者亦可以用 Reg30 來操作時 Acc.,可以用 Reg31 來操作時 Base,這增加了許多寫作程序時的彈性。
3.3.1 User command 設計
為了使本篇論文之 WINS 能讓使用者隨心所欲地控制,執行 3.1 章節所定義之目標,
本篇論文設計了一些類似高階語言直譯器之命令供使用者呼叫以控制 WINS 的動作;這些 命令種類涵蓋 I/O 控制、延遲、位元操作、數學運算、邏輯運算,流程分支、無線模組控 制等功能。
本系統提供的一個命令由兩個 byte 組成,第一個 byte 的高 5 bit 為命令的 Index,低 3 bit 為第一組 parameter 或稱為 sub-command。第二個 byte 為第二組 parameter。以延遲 控制為例,只要將 0Fh, 0D0h 放在 User Command Area 中,直譯器便會執行 delay 500mS 的動作,這是因為第一個 byte 的高 5 bit 為 00001 時 firmware 會呼叫延遲副程序,而低 3 bit 與第二個 byte 之 8 個 bit 合起來變成 07D0H,換成十進制成為 2000,而延遲副程序的時 間單位為 250us,以 2000 為參數呼叫便會延遲 0.5 秒。支援的命令如表格 5 所列出,目前 只用了預留的 32 個命令群組(命令的 index 有 5 個 bit,共 32 種組合)中的 10 個群組,未 來仍可繼續擴充,加入更多的命令(例如常用的一小段程序便可以直接將它寫成一個命令,
不需每次都需呼叫一連串使用者命令,佔用記憶體空間),一方面方便撰寫 script 的使用者,
一方便也可擴增 WINS 的功能:
表格 5:本篇論文提供之命令表
CMD Index (b7~b3)
CMD Para 1 (b2~b0)
Byte1 HEX
Para2 Remark
0 Jump to first CMD N/A 00 N/A
1 Delay High 3 bits
08~0F 00001xxx
Low 8 bits Delay n(11 bits) * 250uS
2 PortWrite
(b2: 1=Para2 is immediate data, 0=Para2 is user variable index) (b0: 1=Port2, 0=Port0)
14 15 10 11
Content is determined by Para1.2
3 PortRead (b0: 1=Port2, 0=Port0) 18 19 User Reg index 0~31 4 Data_Cpy 000: #Data -> A 20 Immediate data
CMD Index (b7~b3)
CMD Para 1 (b2~b0)
Byte1 HEX
Para2 Remark
001: #Data -> B 21 Immediate data 010: A->Rn 22 User Reg index 0~31 011: Rn <- A 23 User Reg index 0~31 100: A -> @Rn 24 User Reg index 0~31 101: @Rn -> A 25 User Reg index 0~31
110: A -> B 26
111: B -> A 27
000: (A+Data) -> BA 28 Immediate data B=1:Carry 001: (A-Data) -> A, B 29 Immediate data B=1:Borrow 010: (RL Reg#) n times ->
Reg#
2A (b7~b5, n times) (b4~b0, reg #)
011: (RR Reg#) n times ->
Reg#
2B (b7~b5, n times) (b4~b0, reg #)
100: (A AND Data) -> A 2C Immediate data 101: (A OR Data) -> A 2D Immediate data 5 Data_Proc
110: (A Logi Reg#) -> A 2E
b7~b5: Logi operation index, b4~b0: Reg#
000:AND, 001:NAND, 010:OR, 011:NOR, 100: XOR, 101:XNOR, 000: Jump to line # 30 Line # Uncondition Jump
001: JZ 31 Line # JMP if ACC==0
010: JNZ 32 Line # JMP if ACC!=0
011: DJNZ 33 b7~b5: Reg#, b4~b0: Line offset JMP if Rn(0~7) != 0 100: JB 34 b7~b5: bit n, b4~b0: Line offset JMP if bit n of ACC == 1
101: JNB 35
110: JTimer 36
6 Branch
111: JNTimer 37 b7~b5: bit n, b4~b0: Line offset JMP if bit n of ACC == 0 000: Set RF Channel 38 b7:1:Indirect:Data in
Rn:b4~b0:Reg#, b7:0:Immediate value
001: Set RF TxRx 39 b7=1(b4~b0:Reg#; Rn.0=1:Rx, Rn.0=0:Tx); b7=0(b0=1:Rx, b0=0:Tx)
010: Set RF Address 3A User Reg index Rn~Rn+4: RF address
011: Get RF Status 3B User Reg index Get RF module status, save in Rn 100: Send RF Data 3C User Reg index Send Rn~Rn+6 data out
101: Get RF Data 3D User Reg index Get input data, save in Rn~Rn+6, no wait
7 RF_Access
110: Enable Rx 3E b7=1(b4~b0:Reg#;
CMD Index (b7~b3)
CMD Para 1 (b2~b0)
Byte1 HEX
Para2 Remark
Rn.0=0:StandBy, Rn.0=1:Rx);
b7=0(b0=0:Standby, b0=1:Rx)
8 Timer_Proc 000: Set Timer 40 b7~b6:Timer index, b4~b0: Reg# Reg_n: TimerL, Reg_n+1: TimerH 000: #Data -> Reg0 48 Immediate data
001: #Data -> Reg1 49 Immediate data 010: #Data -> Reg2 4A Immediate data 011: #Data -> Reg3 4B Immediate data 100: #Data -> Reg4 4C Immediate data 9 Data_Cpy2
101: #Data -> Reg5 4D Immediate data