開發記錄(A)
 

作業要求 (A)

  • 安裝和設定 QEMU
  • 依據指示,將 00-Semihosting, 00-HelloWorld, …, 07-Threads 均實際測試並研讀程式碼
  • 在 github 上 fork mini-arm-os,並修改 07-Threads (不要增加新的目錄!),提供基本的 shell,然後能夠用新建立的 thread 計算 fibonacci 數列
  • shell 程式碼可參照 rtenv+ 的 main.c,裡頭提供 shell 實做 
 
硬體週邊控制
學習查詢STMicroelectronics的參考手冊來得知暫存器的設置
1.先到Memory map查詢要用到的周邊的記憶體位址在哪個範圍
 ex.
Boundary Address
Peripheral
Bus
Register map
0x4001 1400 - 0x4001 17FF
GPIO Port D
APB2
Section 8.5 on page 167
2.點Register map的link可以看到控制該周邊的所有暫存器、該暫存的memory offset、該暫存器的各個bit(共有32bits)該如何設置
ex.
  • Port configuration register high (GPIOx_CRH) (x=D)
位址: 0x40011400 + 0x4
Reset後的值: 0x44444444
依據我們的需求:
  • CNF9[1:0] = 00 (General purpose output push-pull)
  • MODE[1:0 ] = 01 (輸出模式,最大速度為10MHz)
 
到此可以得知我們需要控制的暫存器之位址及其內容需如何設置,之後就是撰寫程式:
#define GPIOD_CRH (*((volatile unsigned long *) (0x40011400 + 0x4)))
#define GPIOD_BSRR (*((volatile unsigned long *)(0x40011400 + 0x10)))
#define RCC_APB2ENR (*((volatile unsigned long *)(0x40021000 + 0x18)))
 
asm(".word 0x20001000");
asm(".word main");
int main()
{
    unsigned int c = 0;
 
    RCC_APB2ENR = (1 << 5); /* IOPDEN = 1 */
    GPIOD_CRH = 0x44444414;
 
    while (1) {
        GPIOD_BSRR = (1 << 25); /* ON */
        for (c = 0; c < 100000; c++);
        GPIOD_BSRR = (1 << 9); /* OFF */
        for (c = 0; c < 100000; c++);
    }
}
 
//blink.c需要注意的是,程式中有兩個for迴圈用來延時,STM32執行的速度相當快,若不加延時的話,LED燈閃爍的頻率會非常高,讀者不妨自行計算(時鐘頻率在稍後介紹)。閃爍頻率非常高的後果,就是人眼覺察不到閃爍,從而讓人誤認LED燈一直亮著。