2016年8月2日 星期二

Published 下午4:42 by with 1 comment

[基礎] OpenOCD 與 STM32


在單晶片開發時,大部分都採用燒錄後執行程式,
並且透過UART吐出數據的方式來debug。

不過隨著系統的複雜度上升,這樣的開發方式逐漸會遇到瓶頸。
也因此,比較大的晶片例如32位元的,通常會內建 JTAG 裝置,
也就是一種後門,方便進行debug。

在此我們採用一種 On-Chip debugger 軟硬體搭配,
簡單來說就是能夠單步執行並且隨時能知道記憶體內容。

各家晶片都有自己的 On-Chip Debugger 裝置,對應的 JTAG 硬體也各有不同。

原本打算採用的是 100 ASK 公司出品的 OpenJtag
但是該公司的這支硬體呢,在Win10下的驅動程式似乎怪怪的不能安裝,
搜尋了一些教學顯示有些麻煩的設定要做,所以暫時先算了。

既然打算要用STM32,那就用先前操作 STM8 的 STLink2 繼續用吧。

在 STM32 的開發板都會把 JTAG 介面開出來,根據接腳圖可以確認是這樣:
這是對應標準的 JTAG 的腳位,適用於像是 ULink  或是 JLink 之類的硬體套件。
如果是要用ST公司的 STLink2 去連接,則會有點不一樣。

根據 這邊的說明 ,只要利用四支街腳就足夠了。如圖所示:
也就是把 STLink2 的 SWDIO 接往 TMS、 SWCLK接往TCK。
然後 GND 和 3V 接好即可通訊使用。

我們接好之後如下圖:

單純的只用杜邦線做銜接。

接好之後,只要確定STLink2的驅動沒問題,那麼只要將中介層的軟體弄好即可。

我們這邊採用的中介層是 OpenOCD
使用了這個中介軟體,就可以將 GDB送來的指令轉換到真正的硬體上。

在OpenOCD的原始網站上,提供的基本是原始碼而已,因為要做跨平台,
所以開放給使用者自已下載回去,在自己的作業系統上編譯。

要在Windows下自己編議OpenOCD可以說是相當麻煩,必須先安裝Cygwin,
也就是模擬Linux環境才能做。詳見這個網站有說明。

由於自己編譯太麻煩,所以根據OpenOCD網站的建議,
這裡可以拿到編好的安裝檔。

下載來之後的安裝畫面就像這樣
基本上都按下一步就能安裝完成了。

但是這個OpenOCD是沒有GUI,完全使用文字介面下指令操作的。
安裝的位置如果在  C:\Program Files 底下的話,之後操作讀取script檔時就會因為那個空格而讀不到。所以我們將OpenOCD安裝在 C:\OpenOCD 以利使用,打字也比較不累。

把所有的東西連線做好,當然開發板的電源記得要接上。


啟動命令列視窗,然後下命令

 cd  C:\OpenOCD\bin

進入OpenOCD執行檔的所在位置,接著執行

openocd -f C:\OpenOCD\scripts\interface\stlink-v2.cfg -f C:\OpenOCD\scripts\target\stm32f1x_stlink.cfg

這行的意思就是啟動OpenOCD並且以 stlink2 銜接 STM32F103 的意思,
所以才要隨之讀取附屬 script 檔。

成功啟動後會出現這樣的訊息:
游標停在那邊不是當機,是OpenOCD已經開始執行。
這時要另外啟動一個文字介面的視窗,並且打字輸入

telnet localhost 4444

就會出現

這樣子代表已經可以進入指令模式操作這顆晶片了。
如果使用GDB的話,則不必啟動這個telnet。

如果你的系統沒有telnet,可以參考這邊的教學來啟動Telnet。






Read More
      edit

2016年8月1日 星期一

Published 下午2:23 by with 1 comment

[基礎] STM32與開源軟體

這一次的主角是STM32。

照片中是一塊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 的操作可參考自 詹姆士酷斯拉





Read More
      edit