Homework 7 開發紀錄(A)
 

作業要求(A)

  • 安裝和設定 QEMU
  • 依據指示,將 00-Semihosting, 00-HelloWorld, …, 07-Threads 均實際測試並研讀程式碼
  • 在 github 上 fork mini-arm-os,並修改 07-Threads (不要增加新的目錄!),提供基本的 shell,然後能夠用新建立的 thread 計算 fibonacci 數列
  • shell 程式碼可參照 rtenv+ 的 main.c,裡頭提供 shell 實做
  • 建立新的 Hackpad,列於「+作業區」,需要標注「開發紀錄 (A)」
 

開發紀錄

首先閱讀+Build minimal ARM Kernel from Scratch 這份文件先對QEMU進行環境建置及相關設定接著閱讀 STM32 程式開發:以 GNU Toolchain 為例了解STM32的架構,紀錄了一些原本不是很清楚的資料。
 
Makefile
Makefile中指定編譯器的若干參數“-mcpu=cortex-m3 -mthumb -nostartfiles”,其中:
  • -mcpu: 要求gcc針對ARM Cortex-M3產生對應的指令
  • -mthumb: 指定產生Thumb指令,而非ARM指令,請留意,ARM Cortex-M3/M4只支援Thumb2指令
  • -nostartfile: 要求連結階段不要使用標準系統起始檔案(starup file),這在沒有作業系統支援的環境是必要的,因為我們自己處理C語言程式main()函式之前的種種準備動作
 
AMBA匯流排 
AMBA(Advanced Microcontroller Bus Architecture)匯流排規範是ARM公司設計的一種用於高性能嵌入式系統的匯流排標準。目的:滿足具有一個或多個CPU或DSP的嵌入式系統產品的快速開發要求; 增加設計技術上的獨立性,確保可重用的多種IP核可以成功地移植到不同的系統中,適合全定製、標準單元和門陣列等技術; 促進系統模塊化設計,以增加處理器的獨立性; 減少對底層矽的需求,以使片外的操作和測試通信更加有效。 
 
AMBA匯流排是一個多匯流排系統。規範定義了三種可以組合使用的不同類型的匯流排︰AHB(Advanced High-performance Bus)、ASB(Advanced System Bus)和APB(Advanced Peripheral Bus)。 
 
General Purpose Input/Output (GPIO)
  • GPIO 是種具有彈性且可以藉由軟體控制 (software-controlled) 的數位訊號
  • 常見於開發版邊緣, 以針腳 (Pin) 的形式呈現
  • 這些針腳即是開發版與外界溝通的重要橋樑
  • 簡單例子, 想像成是開關, 使用者可以打開或關閉 (input), 或由開發版來打開或關閉 (output)
  • 每個 GPIO 可以被當成 input, output, analog 或 alternate function
  • alternate function 是指其他的的功能, 如 I2C, SPI, USART, CCP, PWM, Clock 等。如何控制則取決於外部設備 (peripheral)
 
linker script
ELF(Executable and Linking Format)是 UNIX/Linux 系統中較先進的目的檔格式,可支援任意數目的分段 (當然有上限,必須可以用16 位元整數表達)。首先建立以下這幾個重要section的概念
  • .text (text section):此section保存的內容並非是英文”text”字面意思上的「文字」,而是ARM指令的機械碼序列,一般是唯讀
  • .rodata (唯讀data section):此段中的資料是只讀的變數。如 C 語言中用 const 關鍵字定義的全域變數即是此類
  • .data (有初始值的data section):在C語言程式中,定義一個全域變數並給予初始值,則該變數會被保存於在此section中
  • .bss (無初始值的data section):沒有初始值的全域變數,會存放在此section
 
特別要注意到,上述出現三種data section,都是只有全域變數才會出現在這三種section中,而區域變數在執行時期是堆疊變數,也就是執行時期依據需要而產生,沒被使用時(比方說{ … }標注的範圍以外)就被銷毀(或棄置),因此不需要有對應的section去特別保存這類變數。
 
  • LMA (Load Memory Address): 表示section被保存在記憶體上的位址
  • VMA (Virtual Memory Address): 表示程式碼執行時期的位址
 
00-HelloWorld
首先分析reg.h,在這個範例裡面定義了三種Memory Map,並且透過手冊來搜尋每個register的功能。
在手冊搜尋Memory Map可以找到RCC(Reset and clock control),GPIO,USART的起始位置
接著在搜尋要設定的暫存器定義對應的Address