照片中是一塊STM32開發板,搭配的 debugger 是 ST-Link-V2 。
STM32具有優異的性能,各種強大的設計使得開發產品非常容易,而且這晶片也不貴。
這次作為實驗對象的是 STM32F103vet6。
在前面的章節不斷的使用 Code Blocks 這個優秀的 IDE ,而本次的實驗要用 Code Blocks 來進行整合開發環境的建置,並且能夠單步執行。
首先要取得 Compiler 。可以先閱讀 How to install the ARM toolchain 這網站的指示。
然後到 GNU ARM Embedded Toolchain 網站去下載安裝檔
或者去 CodeSourcery 網站取得也行。
接著是STM32要運作時的一些必備函式庫,可以去STM32原廠網站找
下載並且解壓縮後,會有一個名為 STM32F10x_StdPeriph_Lib_V3.5.0 的資料匣
我下載的是3.5版所以會有這樣尾數命名。
在 STM32F10x_StdPeriph_Driver 這個目錄底下有原廠先寫好的函式庫方便操作硬體,我們將複製使用。
在CMSIS目錄下,有著原廠寫好的核心啟動程式碼,也就是STM32這種32位元啟動複雜的行為不必我們自己寫。
以上就是行前預備。
安裝 Compiler 完成之後,啟動 Code Blocks 做點設定。
從 Settings -> Compiler... 進入
Selected compiler 選擇 GNU GCC compiler for ARM 的項目,根據你自己安裝compiler位置設定好。
然後進入 Settings -> Debugger 設定新的 debugger 專門針對STM32的
記得 Do "not" run the debugee 這個項目要打勾,避免在非預期狀態下被啟動。
然後進入 Tools -> Configure tools ,設定一個快速工具好讓OpenOCD啟動。
這樣就可以在 GDB debugger 啟動前先快速的啟動 OpenOCD 以利連線。
開啟一個新專案來做STM32的範例。
一樣使用空白的專案,但下一步之後的Compiler選項記得點選 ARM 專用的。
專案開好後,專案設定的一些東西要變更。
首先是 Projetc -> Build options
由於選定的晶片,STM32屬於 Cortex-M3 系列的,所以要勾選 M3
然後在 Other options 底下要增加文字
-gdwarf-2 -mthumb -fomit-frame-pointer -Wall -Wstrict-prototypes -fverbose-asm -Os
在 #defines 下要增加
STM32F10X_HD
USE_STDPERIPH_DRIVER
在 Linker settings 的頁籤下,other linker options 要添加
-mthumb -nostartfiles -Tstm32f103vet6.ld -Wl,-Map=main.map,--cref,--no-warn-mismatch
最後是 Pre/post build steps 頁籤項目裡,Post-build steps 要增加
C:\Program Files (x86)\CodeBlocks\GunARM2016q2\bin\arm-none-eabi-objcopy -O ihex ${TARGET_OUTPUT_DIR}${PROJECT_NAME}.elf ${TARGET_OUTPUT_DIR}${PROJECT_NAME}.hex
cmd /c "C:\Program Files (x86)\CodeBlocks\GunARM2016q2\bin\arm-none-eabi-objdump" -S ${TARGET_OUTPUT_DIR}${PROJECT_NAME}.elf > ${TARGET_OUTPUT_DIR}${PROJECT_NAME}.asm
C:\Program Files (x86)\CodeBlocks\GunARM2016q2\bin\arm-none-eabi-size ${TARGET_OUTPUT_DIR}${PROJECT_NAME}.elf
接著進入 Project-> Properties ,在 Build targets 頁籤裡做這樣的設定
在 Debugger 頁籤加上遠端遙控的設定, IP位址是 localhost 而 port 是 3333。
同樣在 Debugger 頁籤下, Additional GDB commands 添加連線後的指令設定
monitor halt
load bin/STM32_Hello.elf
monitor sleep 1000
monitor reset
這段指令的意思就是,啟動後先停止,然後載入執行檔,睡眠 1000mS 再 Reset。
這些設定完成後,預備寫程式的檔案必須要有:
core_cm3.c
core_cm3.h
system_stm32f10x.c
system_stm32f10x.h
stm3210x.h
stm32x.conf.h
startup_stm32f10x_hd.s
stm32f103vet6.ld
以上構成基本的開機啟動功能。然後
main.c 放我們自己的程式
stm32f10x_gpio.c 和 stm32f10x_gpio.h 做 IO操作
stm32f10x_rcc.c 和 stm32f10x_rcc.h 做振盪器控制操作
但是在ARM compiler 裡,似乎有個辨識上的 bug 會使得 compiler 不會過關。
這兩個小小需要修改的點在 core_cm3.c 裡面。分別是
STREXB 和 STREXH
在程式內 "=r" (result) 會導致編譯失敗,因此改為 "=&r" (result)
添加一個 & 符號解決。
該問題的修改法參考來自此
http://www.cesareriva.com/fix-registers-may-not-be-the-same-error/
以上的程式建置進專案後,build 完成,就可以啟動單步除錯器了。
當然硬體要先接好
首先透過 Tools 啟動 OpenOCD
當出現這些訊息時,代表OpenOCD已經成功啟動。等待GDB去做連線。
這時只要按下
紅色的三角鍵,Code Blocks 就會啟動 GDB 去做連線。按下後log視窗會出現
可以看到 load 指令後載程式到晶片的資訊。
再按一次紅色的三角鍵就會開始運作,跑到斷點才會停止
然後可以看見點亮LED的情景
當斷點停止的時候,可以在OpenOCD的視窗內看到被停止的位址
以上範例程式碼放在 GitHub
Code Blocks 的操作設定參考自 http://www.hackvandedam.nl/blog/?p=707
OpenOCD 的操作可參考自 詹姆士酷斯拉
無意間發現您的blog,覺得您也是同好 ,和您分享新唐下個月的活動
回覆刪除http://www.nuvoton.com/hq/.content/event/event-edm/event00111/
期待您多文章的分享,謝謝