OK05 課程構建於課程 OK04 的基礎,使用它來閃爍摩爾斯電碼的 SOS 序列(...---...
)。這裡假設你已經有了 課程 4:OK04[1] 作業系統的程式碼作為基礎。
1、資料
到目前為止,我們與作業系統有關的所有內容提供的都是指令。然而有時候,指令只是完成了一半的工作。我們的作業系統可能還需要資料。
一些早期的作業系統確實只允許特定檔案中的特定型別的資料,但是這通常被認為限制太多了。現代方法確實可以使程式變得複雜的多。
通常,資料就是些很重要的值。你可能接受過培訓,認為資料就是某種型別的,比如,文字檔案包含文字,影象檔案包含圖片,等等。說實話,這隻是你的想法而已。計算機上的全部資料都是二進位制數字,重要的是我們選擇用什麼來解釋這些資料。在這個例子中,我們會用一個閃燈序列作為資料儲存下來。
在 main.s
結束處複製下麵的程式碼:
.section .data %定義 .data 段
.align 2 %對齊
pattern: %定義整形變數
.int 0b11111111101010100010001000101010
.align num
確保下一行程式碼的地址是 2num 的整數倍。
.int val
輸出數值val
。
要區分資料和程式碼,我們將資料都放在 .data
區域。我已經將該區域包含在作業系統的記憶體佈局圖。我選擇將資料放到程式碼後面。將我們的指令和資料分開儲存的原因是,如果最後我們在自己的作業系統上實現一些安全措施,我們就需要知道程式碼的那些部分是可以執行的,而那些部分是不行的。
我在這裡使用了兩個新命令 .align
和 .int
。.align
保證接下來的資料是按照 2 的乘方對齊的。在這個裡,我使用 .align 2
,意味著資料最終存放的地址是 22=4 的整數倍。這個操作是很重要的,因為我們用來讀取記憶體的指令 ldr
要求記憶體地址是 4 的倍數。
命令 .int
直接複製它後面的常量到輸出。這意味著 111111111010101000100010001010102 將會被存放到輸出,所以該標簽樣式實際是將這段資料標識為樣式。
關於資料的一個挑戰是尋找一個高效和有用的展示形式。這種儲存一個開、關的時間單元的序列的方式,執行起來很容易,但是將很難編輯,因為摩爾斯電碼的
-
或.
樣式丟失了。
如我提到的,資料可以代表你想要的所有東西。在這裡我編碼了摩爾斯電碼的 SOS 序列,對於不熟悉的人,就是 ...---...
。我使用 0 表示一個時間單元的 LED 滅燈,而 1 表示一個時間單元的 LED 亮。這樣,我們可以像這樣編寫一些程式碼在資料中顯示一個序列,然後要顯示不同序列,我們所有需要做的就是修改這段資料。下麵是一個非常簡單的例子,作業系統必須一直執行這段程式,解釋和展示資料。
複製下麵幾行到 main.s
中的標記 loop$
之前。
ptrn .req r4 %重新命名 r4 為 ptrn
ldr ptrn,=pattern %載入 pattern 的地址到 ptrn
ldr ptrn,[ptrn] %載入地址 ptrn 所在記憶體的值
seq .req r5 %重新命名 r5 為 seq
mov seq,#0 %seq 賦值為 0
這段程式碼載入 pattrern
到暫存器 r4
,並載入 0 到暫存器 r5
。r5
將是我們的序列位置,所以我們可以追蹤我們已經展示了多少個 pattern
。
如果 pattern
的當前位置是 1 且僅有一個 1,下麵的程式碼將非零值放入 r1
。
mov r1,#1 %載入1到 r1
lsl r1,seq %對r1 的值邏輯左移 seq 次
and r1,ptrn %按位與
這段程式碼對你呼叫 SetGpio
很有用,它必須有一個非零值來關掉 LED,而一個 0 值會開啟 LED。
現在修改 main.s
中你的全部程式碼,這樣程式碼中每次迴圈會根據當前的序列數設定 LED,等待 250000 毫秒(或者其他合適的延時),然後增加序列數。當這個序列數到達 32 就需要傳回 0。看看你是否能實現這個功能,作為額外的挑戰,也可以試著只使用一條指令。
2、當你玩得開心時,時間過得很快
你現在準備好在樹莓派上實驗。應該閃爍一串包含 3 個短脈衝,3 個長脈衝,然後 3 個短脈衝的序列。在一次延時之後,這種樣式應該重覆。如果這不工作,請檢視我們的問題頁。
一旦它工作,祝賀你已經抵達 OK 系列教程的結束點。
在這個系列我們學習了彙編程式碼,GPIO 控制器和系統定時器。我們已經學習了函式和 ABI,以及幾個基礎的作業系統原理,已經關於資料的知識。
你現在已經可以準備學習下麵幾個更高階的課程的某一個。
到現在,你已經有了足夠的資訊來製作作業系統,用其它方法和 GPIO 互動。如果你有任何機器人工具,你可能會想嘗試編寫一個透過 GPIO 管腳控制的機器人作業系統。