the 1st edition: 20130416 (2)
the 2nd edition: 20160922
toolchain 的使用已經不在困擾我, 困難的是 cpu arm 架構與硬體平台, 這可要看不少資料。通過開發環境的試鍊後, 我打算點亮 led 燈來做為第一個 c 語言的練習程式。
不過沒想到這支作業系統之前的程式一開始就難倒我, 難點在於 io 的部份, 不像
前一個程式, 這個程式會用到平台相關的程式碼, 點亮 led, 得先要查詢接腳資料, 而查詢接腳資料是很磨人的, 我從
這裡的範例程式修改而來。這是 st 公司提供的 library, 可以省下不少看 datasheet 的功夫, 也可幫助程式 port 到其他 st 平台, 是很重要的參考資料。經過三年後 (20160922), 我終於知道要從 fig 1 的文件來得知這個資訊, 這是為什麼要針對 PD12 ~ 15 來設定的原因。
|
fig 2 |
而透過 fig 2 得知到初始化 AHB1 mygpio_led.c L253, 因為 GPIO 接腳就接在這個 bus 上。
一樣化繁為簡, 將程式庫的部份抽取出來, 簡化成一個小的作業系統之前的程式。
2 #include "stm32f4xx_gpio.h"
3 #include "stm32f4xx.h"
stm32f4xx_gpio.h, stm32f4xx.h, 從範例程式裡頭挖出來小改一下, 我已經把需要的相關程式碼
抽取出來放在 mygpio_led.c, 只有 stm32.h 和 mygpio_led.c, stm32.ld, 但不要以為這隻程式就很容易看, 得需要查閱 datasheet, 找出相關的暫存器設定方法。
大部份是 gpio, rcc 的 macro。stm32.h 是
coretex-m3 之 stm32 嵌入式系統設計的範例。由於沒有 SDRAM 控制器, 省下這部份的程式碼, lucky!!
程式結果就是先閃綠燈, 閃紅燈在一起熄滅, 如此循環下去。
|
fig 3 使用 saleae logic 16 抓取 30 秒 |
而在 20160814 買了
saleae logic 16 之後, 我就可以測量 GPIO 訊號, 請參考 fig 3 的接法, ch1 接在 PD12, ch2 接在 PD13。
fig 4 rx1 (ch1) 是 PD12 - green led
fig 4 sync (ch2) 是 PD 13 - orange led
再參考 fig 4, 當 rx1, sync 一起降下來的時候, 就是同時暗掉, 升上去時就是亮燈。
也可以得知 Delay(0x3FFFFF); 大概是 4 秒左右, 在這時候的我還沒有可以正確設定 timer 的能力, 不過現在我知道要怎麼設定了。
|
fig 4 使用 saleae logic 16 抓取 30 秒 |
我要解說的部份只和開機程式有關, IO 部份請自己搞定, 這不是文章的重點。和 x86 不同, cortex-m3 可以「完全」使用 c 語言來寫開機程式, 而不像 x86 需要 inline 組合語言。一開機, 位址 0~3 存放的值會被填到 sp, 完成 stack 設定, 在 c 語言中完成最重要的設定。
再來是 bss section:
這段 code 便是在初使化 .bss, .data, 就這樣完成 c startup code, 完全不需要組合語言介入, 厲害的設計。
也許你想知道 .bss, .data 為什麼要初始化, 這不是很容易寫在 blog 上, 用個例子簡單說明:
int a=6;
void func()
{
static int i;
}
a 位於 .data, i 位於 .bss, 在程式執行時, a 要是 6, 而 i 要是 0, 這不是憑空得來的, 初始化 .bss, .data 就是在完成這樣的工作, 我知道, 這只能解除你一半的疑惑, 你一定想知道更多吧!
那 x86 的 bss section 也可以這樣寫嗎?由於有名的 segment address, 你得先確定你指的位址 0x100 真的是絕對位址 0x100 嗎?這是很容易搞亂的。
而透過 link script, section(".isr_vector") 會被放到 0 開頭的位址, 達到 0~3 是 stack value, 4 ~ 7 是 reset handle 的目的, 進而透過 ResetISR call main 去執行 main()。
簡單的 gpio led 程式並沒有想像中簡單吧, 所以像是 arduino 之類的開發版將這些困難都隱藏起來是花了不少苦心, 不過我的學習方式正是要把隱藏在冰山下的真像挖出來, 這也是為什麼又過了三年, 還是只在 gpio led 打轉。
按照之前的慣例, 下一個應該是 c++ 的版本, 不過 ...
source code:
https://github.com/descent/stm32f4_prog/tree/master/led
補充 stm32 p103 模擬器中的初始化程式碼:
L36 會 call main
ref:
gpio gpio push-pull or open drain:
介紹一些 arm 指令:
http://jnotes.googlecode.com/svn-history/r105/trunk/Notes/NotesOnCM3/stm32WithGCC.html
books:
coretex-m3 之 stm32 嵌入式系統設計
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。