1.stm32綜述
2.寄存器組
3.操作模式和特權級別
4.存儲器映射
5.中斷和異常
6.其他
Stm32綜述
這可以說是我第一款認真學習的單片機了,學完這個就要開啟我通往arm9的大門了,接下來把我學到的東西做一個系統的概述:
上圖是stm32的系統結構。
使用哈弗體系結構,取指和取數據分離,
ICODE指令總線連接到flash閃存指令存儲區,這個存儲區的地址在0x00000000-0x1FFFFFFF之間,負責取指操作。
DCODE數據總線負責在0x00000000-0x1FFFFFFF之間的數據訪問操作。這個數據存儲區可以是SPRAM也可以是閃存和外設。
系統總線:負責在0x20000000-0xDFFFFFFF和0xE0100000-0xFFFFFFFF之間所有的數據傳送。
注:看到這你可能會迷惑,M3內核不是只有指令總線和數據總線嗎?對的,但是指令總線和ICODE指令總線不是一個,選取一張M3內核樣例處理器的圖就明白了:
個人理解,D-code總線和系統總線都是來源於M3內核引出的數據總線。
DMA通過總線矩陣直接和內存相連。
總線矩陣協調內核和DMA對SPRAM,閃存,外設的訪問。
AHP總線橋接兩個APB總線,兩個APB總顯得最高速度不同,APB1最高速度限於36MHz,APB2限於72MHz。兩個APB總線上掛接着不同速率的設備。
Stm32f10系列的靜態SPRAM為64K,起始地址為0x20000000.
Stm32的啟動方式有以下幾種:
下面的是stm32的時鍾樹,stm32有四個不同的時鍾源:
1.HSE時鍾:高速外部時鍾信號,來自於外部晶振:可作為系統時鍾源,也可被PLL倍頻之后宮系統時鍾使用。
2.HSI時鍾:高速內部時鍾信號,來自於內部RC振盪器:可直接作為系統時鍾,或者二分頻之后作為PLL輸入,倍頻之后供系統使用。
3.LSE時鍾:低速外部時鍾,來自於外部晶振:為定時時鍾或者其他定時功能提供
4.LSI時鍾:低速內部時鍾,來自於內部RC振盪器:在停機或者待機的模式下,為獨立看門狗或者自動喚醒單元提供時鍾。
經過一些列倍頻,分頻得到了幾個和開發有關的時鍾:
1.SYSCLK:系統時鍾大部分時鍾的來源
2.HCLK:由AHB預分頻器輸出得到,高速總線AHB的時鍾信號
3.FCLK:由AHB預分頻器輸出得到,自由運行時鍾。
4.PCLK1:外設時鍾,由APB1預分頻器得到,最大36MHz
5.PCLK2:外設時鍾,由APB2預分頻器得到,最大72MHz
時鍾樹如下:
Stm32的GPIO的8種模式:
(1)GPIO_Mode_AIN 模擬輸入
(2)GPIO_Mode_IN_FLOATING 浮空輸入
(3)GPIO_Mode_IPD 下拉輸入
(4)GPIO_Mode_IPU 上拉輸入
(5)GPIO_Mode_Out_OD 開漏輸出
(6)GPIO_Mode_Out_PP 推挽輸出
(7)GPIO_Mode_AF_OD 復用開漏輸出
(8)GPIO_Mode_AF_PP 復用推挽輸出
4種輸入:模擬輸入和明顯接受模擬信號,比如用於ADC,上拉輸入和下拉輸入就是默認時高電平和低電平。浮空輸入在芯片內部既沒有接上拉電阻也沒有接下拉電阻,引腳電壓是個不確定值,輸入阻抗較大,常用語I2c,USART。
4種輸出:分復用和非復用,復用為分配給片上外設,非復用為用作正常的IO口。推免輸出為正常的輸出,而在開漏輸出模式,IO口可以由外部電路改變為低電平或不變。所以開漏模式可以讀IO輸入電平變化,實現C51的IO雙向功能。
當年看不懂的東西,現在越發清晰。
寄存器組
這一部分就屬於M3內核中的知識了。
M3內核中的寄存器主要如下:
下面挨個解釋
M3使用的是雙堆棧,復位之后默認使用MSP,默認是特權級,如果想要切換需要手動修改。而上面的MSP和PSP的用途只是一種推薦用途,並不是一定要那么用,比如說復位之后你可以不修改,那么你的常規代碼就一直是特權級,使用MSP(我就是這樣滴。。方便至上)。
這個寄存器又叫LR寄存器,那么當函數是一級調用的時候,就可以將返回地址直接存到LR中,省去了訪問內存,提高了效率,當函數調用高於一級,則需將前面的LR中的值壓棧,以便存儲新的值。
當進入異常的時候,LR寄存器的值更新為特殊的EXE_RETURN:
就是PC嘛。。。。
特殊功能寄存器一定要在特權級才能被訪問(使用MSR和MRS指令),至於是Thread 模式還是handler模式無所謂。
詳細功能如下:
xPSR屬於三合一寄存器,可以分出三個子狀態寄存器
通過MRS和MSR這三個寄存器可以單獨訪問,也可以兩兩組合訪問,也可以三合一訪問,這個寄存器大致如下(看下就好):
其實除了修改上面的寄存器可以開關中斷,M3還有專門的開關中斷指令:
CONTROL寄存器功能如下:
操作模式和特權等級
操作模式分為Thread模式和Handler模式,特權等級分為特權級和用戶級。用戶的程序代碼一定是Thread模式,而異常一定是handler模式,用戶程序代碼程序代碼可以是特權級和用戶級,但是異常只能是特權級。
Thread模式+用戶級,就不能訪問系統控制空間(SCS)和特殊寄存器(除了APSR)。
特權級切換到用戶級很容易,修改下control寄存器就好,用戶級切換到特權級的方式只有觸發一個異常,切換到handler模式,這個時候是特權級,然后修改control寄存器的零位,再返回就是特權級。
下圖是一個各種切換的示意圖:
這種設定的大致用意就是我們寫普通代碼的時候設置為用戶級,這樣的話可以防止對SCS和特殊寄存器這種敏感地帶的誤操作,想要訪問這些的話就只能通過進入handler模式一步步去訪問,而且這樣的話異常是特權級用MSP,普通的用戶代碼使用戶級用PSP,不會出現數據意外互相干擾和破壞,這樣的話整個系統的可靠性就會很好,當然我們寫小程序的時候不必這么拘謹,反正我一般都是一直特權級小程序。
存儲器映射
M3將內存分為8個主塊,每塊512MB,先上一張M3內核的存儲器映射:
所謂的SCS如下:
所謂的位帶就是將位帶區的1bit膨脹為位帶別名區的32bit也就是一個字,通過訪問位帶別名區就能達到訪問這個bit的目的,優勢如下:
當然位帶還有一個明顯的好處,就是在多任務的系統中,兩個任務同時去修改一個共享寄存器其中的兩個bit的話可能會出現“紊亂現象”,所以就需要將“讀-改-寫”三條指令加上臨界區等手段,但是有了位段,M3直接去寫那個bit的位帶別名區就可以了,這樣就成為了一個原子操作。
不過上面的圖確實是粗線條,下面上芯片手冊的詳細圖片一張:
M3有些數據傳送指令支持非對齊數據傳送,如LDR/LDRH/LDRSH。其他指令不支持。
對按字傳送來說,任何一個不能被4整除的地址都是非對齊的。而對於板子,任何一個不能被2整除的地址都是非對齊的。
M3支持大端模式和小端模式,但是推薦使用小端模式。M3的大端模式是“字節不變大端”。
中斷和異常
異常是指任何打斷程序順序執行的事件。在很多時候,中斷和異常這兩個概念是不做區分的,所以我以下也就不作區分了。
M3的異常系統簡直就是它的精華所在。
M3的異常分為系統異常和外部中斷。
系統異常如下(stm32沿用):
外部中斷M3內核支持240個,stm32只使用其中60個:
所有的異常,除了復位,NMI,硬FAULT優先級為-3,-2,-1固定,剩下的都是可編程優先級。
優先級:
M3內核中優先級寄存器為8位,這8位不用全用到,最少用到3位(MSB對齊),stm32只用到其中高四位,所以stm32總共有16種優先級。
M3內核中對於外部中斷有搶占優先級和響應優先級,高搶占優先級的中斷可以打斷低搶占優先級的中斷。搶占優先級相同的兩個中斷同時到達,響應響應優先級高的中斷。如果兩個中斷一切相同,那么響應序列號更小的那個。
因為外部中斷的優先級寄存器總共八位,所以需要對其進行划分,響應優先級至少有一位,所以M3中外部中斷搶占優先級最多其實是有128個而不是256個。下圖是從bit5開始划分,總共用到三位設置優先級:
具體的芯片決定優先級用到多少位,以及從哪一位開始划分搶占和響應,stm32用到4位設置中斷,有5種分組:組0從7bit划分(全部都是響應優先級),組1從6bit划分,組2從5bit划分,組3從4bit划分,組4從3bit划分(就是只用到搶占優先級)。
向量表:
當發生了異常需要響應的時候,M3需要定位其服務例程的入口地址,這些入口地址就存在所謂的“向量表”。缺省情況下,這張表存在0地址處(當然也可修改NVIC中的向量表偏移寄存器來重定位向量表),每一個表項占4字節。
如下:
首先向量表的開頭是主堆棧的地址。
可以看出,不論如何一個向量表至少包含下面4個表項:
1.MSP初始值
2.復位向量
3.NMI
4.硬fault服務例程
中斷的輸入與掛起:
當中斷輸入腳被置為有效后,該中斷就被懸起,到了系統中它的優先級最高的時候,就會得到響應。
但是當某個中斷得到響應之前,其懸起位被清除,則中斷被取消。(所以stm32都是在中斷服務程序的最后清除中斷標志位)
當某中斷的服務例程開始執行的時候,就稱此中斷進入了“活躍”狀態,並且其懸起位會被自動清除。
SVC和PENDSVC:
首先SVC(系統服務調用)和PENDSVC(可掛起系統服務調用)的區別在於SVC異常必須立即得到相應,而PENDSVC則不是,他可以像普通中斷一樣被掛起,知道其他重要任務完成才執行它,掛起PENDSVC的方式為:手工寫入NVIC的PENDSVC掛起寄存器。
SVC的用途:操作系統可以不讓用戶直接訪問硬件,而是通過觸發SVC異常來使用SVC系統調用來讓用戶程序簡介訪問硬件。好處:1.OS負責具體硬件,用戶程序不必花費心思控制硬件。2.OS的代碼應該是經過充分的測試的,所以整個系統可靠性高健壯性好。3.用戶程序無需在特權級下執行,無需擔憂因誤操作讓系統癱瘓。4.通過SVC機制,用戶程序與硬件無關。
PENDSVC的用處:上下文切換,如ucos上下文切換就是用到PENDSVC的。
NVIC:
中斷向量控制器,也就是控制中斷向量的地方,每個外部中斷(系統中斷由SCB控制)都在其中的寄存器占有一席之地,寄存器列表如下:
其中懸起寄存器可以系統自動設置,也可以手工修改以懸起一個中斷。
軟件中斷寄存器也蠻重要的,如下:
中斷的響應和返回:
中斷的響應:
8個寄存器以及入棧順序如下:
中斷的返回:
首先觸發中斷返回的指令有三種:
返回了之后,做如下兩件事:
1.出棧,回復現場
2.更新NVIC寄存器
咬尾中斷:
一圖以蔽之:
其他
總結了一天,終於到了這一步,還有些零碎的知識點寫上:
M3的堆棧是向下生長的。
M3取指,解碼,執行三級流水,因為其采用哈弗體結構,所以取指和訪存可以同時執行,M3內部有解碼模塊,所以構成了三級流水。