STM32-Keil软件仿真和硬件仿真/在线仿真
軟件仿真和硬件仿真什么區別?軟件仿真就是沒有硬件參與的仿真,完全是模擬實現的。硬件仿真是將程序下載到控制芯片的FLASH或RAM中,直接在硬件上實現仿真。【有什么問題歡迎聯系討論,一起解決問題】
仿真這種東西,因為涉及到信任問題,用的好覺得好用,用不好可能會徒增麻煩——“還不如直接在硬件上調試靠譜”。但是總體上,仿真還是比較有用的,比如在排查軟件問題(寄存器配置等)的時候,使用軟件仿真是非常靠譜的。而如果涉及到硬件的問題(比如你的板子代碼需要讀取外部信號,或者輸出信號等),可能需要用到硬件仿真,或者說在線仿真。關于仿真,網上的資料說的還是挺全的,這里只做總結。
目錄
一、軟件仿真
1.1 仿真配置
1.2 操作方法
邏輯分析窗口
Watch窗口
堆棧局部變量窗口
Peripherals窗口
二、硬件/在線仿真
2.1 仿真器通信協議/接口
JTAG協議/接口
SWD協議/接口
RDI協議/接口
2.2 常見仿真器
Jlink
STlink
ULINK
2.3?Jlink的Keil5仿真配置
2.4?硬件仿真操作方法
一、軟件仿真
1.1 仿真配置
首先確定仿真的硬件環境。點擊魔術棒,,在Target項確認一下仿真的芯片型號無誤,然后選擇外部時鐘源頻率(因為STM32一般使用外部時鐘),一般是8MHz。
然后按照如下勾選,這里使用軟件仿真就勾選Use Simulator。勾選Run to main(),表示仿真時跳過匯編代碼,直接跳轉到 main 函數開始仿真。然后Dialog DLL和Parameter分別按照自己的型號進行修改,比如如果你是用的是STM32F103ZE××,就把-pSTM32F103VB改為-pSTM32F103ZE便可,這里是設置支持所選型號的芯片的軟硬件仿真,設置好后仿真的時候就可以通過 Peripherals 選擇對應外設的對話框觀察仿真結果(非常實用,后邊詳述)。
1.2 操作方法
點擊開始仿真。
這里的DEBUG工具條是比較常用,其中作為一般的使用者或者說入門的使用者來說,最常使用的還是下面加黑的幾個。
- 復位:其功能等同于硬件上按復位按鈕。相當于實現了一次硬復位。按下該按鈕之后,代碼會重新從頭開始執行。
- 執行到斷點處:該按鈕用來快速執行到斷點處,有時候你并不需要觀看每步是怎么執行的,而是想快速的執行到程序的某個地方看結果,這個按鈕就可以實現這樣的功能,前提是你在查看的地方設置了斷點。
- 掛起:此按鈕在程序一直執行的時候會變為有效,通過按該按鈕,就可以使程序停止下來,進入到單步調試狀態。
- 執行進去:該按鈕用來實現執行到某個函數里面去的功能,在沒有函數的情況下,是等同于執行過去按鈕的。
- 執行過去:在碰到有函數的地方,通過該按鈕就可以單步執行過這個函數,而不進入這個函數單步執行。
- 執行出去:該按鈕是在進入了函數單步調試的時候,有時候你可能不必再執行該函數的剩余部分了,通過該按鈕就直接一步執行完函數余下的部分,并跳出函數,回到函數被調用的位置。
- 執行到光標處:該按鈕可以迅速的使程序運行到光標處,其實是挺像執行到斷點處按鈕功能,但是兩者是有區別的,斷點可以有多個,但是光標所在處只有一個。
- 匯編窗口:通過該按鈕,就可以查看匯編代碼,這對分析程序很有用。
- 堆棧局部變量窗口:該按鈕按下,會彈出一個顯示變量的窗口,在里面可以查看各種你想要看的變量值,也是很常用的一個調試窗口。
- Watch窗口:可以用來查看全局變量。
- 串口打印窗口:該按鈕按下,會彈出一個類似串口調試助手界面的窗口,用來顯示從串口打印出來的內容。需要注意的是在硬件調試時無法使用,只能從硬件上獲取串口信息。
- 內存查看窗口:該按鈕按下,會彈出一個內存查看窗口,可以在里面輸入你要查看的內存地址,然后觀察這一片內存的變化情況。是很常用的一個調試窗口。
- 性能分析窗口(沒標的那個):按下該按鈕,會彈出一個觀看各個函數執行時間和所占百分比的窗口,用來分析函數的性能是比較有用的。
- 邏輯分析窗口:按下該按鈕會彈出一個邏輯分析窗口,通過 SETUP 按鈕新建一些 IO 口,就可以觀察這些 IO 口的電平變化情況,以多種形式顯示出來,比較直觀。
關于執行到某處以及設置/清除斷點等這些常規操作不在贅述。
邏輯分析窗口
點擊選擇邏輯分析儀(Logic Analyzer),
點擊左上角SETUP
然后輸入要查看的引腳,選擇顯示類型為Bit,最后Close(另外顯示顏色可以自由選擇)。這里的引腳名有一定的格式,比如這個是表示GPIOC13引腳,PORTC這里可以理解為GPIOC引腳狀態寄存器,(PORTC & 0x00002000)表示取其GPIOC13的狀態(bit),然后右移13位是把該值移到最低位(可以簡記為pin號是幾就右移幾位)。
如果不知道怎么確定“&”的數應該是多少,可以參考下面各pin號的值:
#define GPIO_Pin_0 ((uint16_t)0x0001) /*!< Pin 0 selected */ #define GPIO_Pin_1 ((uint16_t)0x0002) /*!< Pin 1 selected */ #define GPIO_Pin_2 ((uint16_t)0x0004) /*!< Pin 2 selected */ #define GPIO_Pin_3 ((uint16_t)0x0008) /*!< Pin 3 selected */ #define GPIO_Pin_4 ((uint16_t)0x0010) /*!< Pin 4 selected */ #define GPIO_Pin_5 ((uint16_t)0x0020) /*!< Pin 5 selected */ #define GPIO_Pin_6 ((uint16_t)0x0040) /*!< Pin 6 selected */ #define GPIO_Pin_7 ((uint16_t)0x0080) /*!< Pin 7 selected */ #define GPIO_Pin_8 ((uint16_t)0x0100) /*!< Pin 8 selected */ #define GPIO_Pin_9 ((uint16_t)0x0200) /*!< Pin 9 selected */ #define GPIO_Pin_10 ((uint16_t)0x0400) /*!< Pin 10 selected */ #define GPIO_Pin_11 ((uint16_t)0x0800) /*!< Pin 11 selected */ #define GPIO_Pin_12 ((uint16_t)0x1000) /*!< Pin 12 selected */ #define GPIO_Pin_13 ((uint16_t)0x2000) /*!< Pin 13 selected */ #define GPIO_Pin_14 ((uint16_t)0x4000) /*!< Pin 14 selected */ #define GPIO_Pin_15 ((uint16_t)0x8000) /*!< Pin 15 selected */比如,如果你需要查看PA11的引腳,就寫為(PORTA & 0x00000800)>> 11(0x00000800可以寫為0x0800)。因為為PA11,所以寫PORTA,從上宏定義可知,因為11腳對應的是0x0800,所以就&0x0800,因為是11腳就右移11位。
設置好引腳之后,在View下勾選上更新窗口,這樣的話仿真時各種數據會實時更新,邏輯分析儀也就可以看到實時波形。
設置好之后點擊運行,就可以在邏輯分析儀窗口看到該引腳的狀態實時波形。
Watch窗口
Watch創口可以用來觀察全局變量,只要將需要觀察的全局變量復制到下面的窗口中,運行之后就可以看到數據的變化。
比如這里是觀察一個結構體數組變量的情況,那個數據的值是多少、是什么類型一目了然。
當然,這里沒法看局部變量,要看局部變量的話還是要用堆棧局部變量窗口。
堆棧局部變量窗口
你可能會問,什么是堆、棧?點這!
什么是堆棧? 內存分配方式有三種: [1]從靜態存儲區域分配。內存在程序編譯的時候就已經分配好,這塊內存在程序的整個運行期間都存在。例如全局變量,static變量。 [2]在棧上創建。在執行函數時,函數內局部變量的存儲單元都可以在棧上創建,函數執行結束時這些存儲單元自動被釋放。棧內存分配運算內置于處理器的指令集中,效率很高,但是分配的內存容量有限。 [3]從堆上分配,亦稱動態內存分配。程序在運行的時候用malloc或new申請任意多少的內存,程序員自己負責在何時用free或delete釋放內存。動態內存的生存期由程序員決定,使用非常靈活,但如果在堆上分配了空間,就有責任回收它,否則運行的程序會出現內存泄漏,頻繁地分配和釋放不同大小的堆空間將會產生堆內碎塊。簡言之,我們可以通過這個串口觀察申請在堆棧區的變量,另外實測發現靜態變量也是可以看的。總之,通過Watch窗口和堆棧窗口我們可以查看幾乎所有的變量。
Peripherals窗口
它是用來仿真時觀察和修改芯片的在外設寄存器用的,第一個System Viewer可以通過箭頭所指的地方直接查看。
? ? ? ? ? ??
但是! 這是一個通用的選項,即涵蓋了所有的外設,這上邊可以查看的外設在我們的芯片型號上不一定有。比如我選用的是STM32VBT6只有3個串口,而這里可以看5個串口!而SyetemViwer下邊的是外設是根據前文配置仿真時配置的Dialog DLL和Parameter決定的,所以要使用這個功能,必須要把Dialog DLL和Parameter配置為你要仿真的芯片型號。
另外兩者的界面也有一些差別,看一哈
? ??
左圖是System Viwer的界面,直接顯示了改外設的所有寄存器極其每個位的值。右圖是另一個界面,可以相對前者比較直觀一些。
二、硬件/在線仿真
2.1 仿真器通信協議/接口
目前主流的協議是JTAG協議和SWD協議,一般常用的仿真器也是同時支持這兩種協議/接口的。
JTAG協議/接口
JTAG(Joint Test Action Group,聯合測試行動小組)是一種國際標準測試協議(IEEE 1149.1兼容),主要用于芯片內部測試。現在多數的高級器件都支持JTAG協議,如ARM、DSP、FPGA器件等。JTAG的工作原理可以歸結為:在器件內部定義一個TAP(Test Access Port,測試訪問口),通過專用的JTAG測試工具對內部節點進行測試和調試。一個含有JTAG Debug接口模塊的CPU,只要時鐘正常,就可以通過JTAG接口訪問CPU的內部寄存器、掛在CPU總線上的設備以及內置模塊的寄存器。
JTAG有5根線與目標CPU相連,TMS、TCK、TDI、TDO、NTRST:
- TMS:測試模式選擇,TMS用來設置JTAG接口處于某種特定的測試模式;
- TCK:測試時鐘輸入;
- TDI:測試數據輸入,數據通過TDI引腳輸入JTAG接口;
- TDO:測試數據輸出,數據通過TDO引 腳從JTAG接口輸出;
- NTRST:JTAG模塊復位
其中在引腳緊缺的時候NTRST復位引腳可以不用。
SWD協議/接口
SWD全稱Serial Wire Debug,是ARM為嵌入式設備推出的一種簡單的調試接口,這種接口通過一條雙向數據線和一條時鐘線實現對于ARM核心的調試。
SWD需要3根線與目標MCU相連,SWDIO,SWDCLK和GND。
- SWDIO 為雙向Data口,主機到目標的數據傳送。
- SWDCLK 為時鐘口,主機驅動。
- GND??GND腳。
關于SWD的協議的具體內容,可以參考這位篇文章。還不滿足的話可以參考這篇碩士論《WD協議的研究及ARM程序下載器的設計》。
RDI協議/接口
遠程調試接口(Remote Debug Interface),是ARM公司提出的標準調試接口,主要用于ARM芯片的仿真,由于各個IDE廠商使用的調試接口各自獨立,硬件無法進行跨平臺的調試。現在眾多的IDE廠家都逐步采用標準RDI作為ARM仿真器的調試接口,因此使跨平臺的硬件調試成為可能。EasyJTAG由于使用標準RDI調試接口,因此在任何使用標準RDI接口的IDE調試環境中都可以使用,例如ARM公司的ADS1.2/IAR公司的EWARM 3.30 。
2.2 常見仿真器
Jlink
J-Link是德國SEGGER公司推出基于JTAG的仿真器。簡單地說,是一個JTAG協議轉換盒,即一個小型USB到JTAG的轉換盒,其連接到計算機用的是USB接口,而到目標板內部用的還是jtag協議。它完成了USB接口和JTAG接口的轉換工作。JLINK是一個通用的開發工具,可以用于KEIL、IAR、ADS 等平臺。速度,效率,功能都很好,據說是眾多仿真器里最強悍的。
STlink
ST-LINK是專門針對意法半導體STM8和STM32系列芯片的仿真器。ST-LINK /V2指定的SWIM標準接口和JTAG / SWD標準接口。
ULINK
ULINK是ARM/KEIL公司推出的仿真器,專用于KEIL平臺下使用,ADS、IAR下不能使用。
?
2.3?Jlink的Keil5仿真配置
首先確認所選用的芯片支持哪種仿真通信協議,STM32F103支持 JTAG 和 SWD。并且PA13、PA14、PA15、PB3、PB4默認功能為調試引腳,如果要使用這些引腳,要Remap為普通IO。
魔術棒的DEBUG選項下選用使用仿真器以及所使用的仿真器的型號。
點擊setting,選擇接口類型(SW或JTAG),速度建議選4M,過高的話也行,只是有時候擦寫flash會失敗。
下載的時候使用的仿真器,所以要在這里勾選使用仿真器
最后,這里根據所選型號flash大小選擇合適的下載算法。如果不知道怎么選,看一下STM32芯片的命名規則,或點這里。
2.4?硬件仿真操作方法
仿真操作方法與軟件操作相同,不同的是,硬件/在線仿真是在硬件上跑的,可以向硬件輸入數據或者由硬件輸出數據,比如做按鍵仿真的時候,只能通過硬件/在線仿真才能測試出芯片有沒有正確地處理按鍵信息等。
總結
以上是生活随笔為你收集整理的STM32-Keil软件仿真和硬件仿真/在线仿真的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: nginx+mysql+端口映射_最浅显
- 下一篇: 2019最强一键刷机root教程,安卓用