歡迎光臨
每天分享高質量文章

計算機實驗室之樹莓派:課程 5 OK05 | Linux 中國

OK05 課程構建於課程 OK04 的基礎,使用它來閃爍摩爾斯電碼的 SOS 序列

— Robert Mullins

 

OK05 課程構建於課程 OK04 的基礎,使用它來閃爍摩爾斯電碼的 SOS 序列(...---...)。這裡假設你已經有了 課程 4:OK04[1] 作業系統的程式碼作為基礎。

1、資料

到目前為止,我們與作業系統有關的所有內容提供的都是指令。然而有時候,指令只是完成了一半的工作。我們的作業系統可能還需要資料。

一些早期的作業系統確實只允許特定檔案中的特定型別的資料,但是這通常被認為限制太多了。現代方法確實可以使程式變得複雜的多。

通常,資料就是些很重要的值。你可能接受過培訓,認為資料就是某種型別的,比如,文字檔案包含文字,影象檔案包含圖片,等等。說實話,這隻是你的想法而已。計算機上的全部資料都是二進位制數字,重要的是我們選擇用什麼來解釋這些資料。在這個例子中,我們會用一個閃燈序列作為資料儲存下來。

在 main.s 結束處複製下麵的程式碼:

  1. .section .data %定義 .data
  2. .align 2 %對齊
  3. pattern: %定義整形變數
  4. .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$ 之前。

  1. ptrn .req r4 %重新命名 r4 ptrn
  2. ldr ptrn,=pattern %載入 pattern 的地址到 ptrn
  3. ldr ptrn,[ptrn] %載入地址 ptrn 所在記憶體的值
  4. seq .req r5 %重新命名 r5 seq
  5. mov seq,#0 %seq 賦值為 0

這段程式碼載入 pattrern 到暫存器 r4,並載入 0 到暫存器 r5r5 將是我們的序列位置,所以我們可以追蹤我們已經展示了多少個 pattern

如果 pattern 的當前位置是 1 且僅有一個 1,下麵的程式碼將非零值放入 r1

  1. mov r1,#1 %載入1 r1
  2. lsl r1,seq %對r1 的值邏輯左移 seq
  3. and r1,ptrn %按位與

這段程式碼對你呼叫 SetGpio 很有用,它必須有一個非零值來關掉 LED,而一個 0 值會開啟 LED。

現在修改 main.s 中你的全部程式碼,這樣程式碼中每次迴圈會根據當前的序列數設定 LED,等待 250000 毫秒(或者其他合適的延時),然後增加序列數。當這個序列數到達 32 就需要傳回 0。看看你是否能實現這個功能,作為額外的挑戰,也可以試著只使用一條指令。

2、當你玩得開心時,時間過得很快

你現在準備好在樹莓派上實驗。應該閃爍一串包含 3 個短脈衝,3 個長脈衝,然後 3 個短脈衝的序列。在一次延時之後,這種樣式應該重覆。如果這不工作,請檢視我們的問題頁。

一旦它工作,祝賀你已經抵達 OK 系列教程的結束點。

在這個系列我們學習了彙編程式碼,GPIO 控制器和系統定時器。我們已經學習了函式和 ABI,以及幾個基礎的作業系統原理,已經關於資料的知識。

你現在已經可以準備學習下麵幾個更高階的課程的某一個。

◈ Screen[2] 系列是接下來的,會教你如何透過彙編程式碼使用螢幕。
◈ Input[3] 系列教授你如何使用鍵盤和滑鼠。

到現在,你已經有了足夠的資訊來製作作業系統,用其它方法和 GPIO 互動。如果你有任何機器人工具,你可能會想嘗試編寫一個透過 GPIO 管腳控制的機器人作業系統。

 

贊(0)

分享創造快樂