stm32和cortex M3學習內核簡單總結


1.stm32綜述

2.寄存器組

3.操作模式和特權級別

4.存儲器映射

5.中斷和異常

6.其他

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Stm32綜述

這可以說是我第一款認真學習的單片機了,學完這個就要開啟我通往arm9的大門了,接下來把我學到的東西做一個系統的概述:

 

上圖是stm32的系統結構。

 

使用哈弗體系結構,取指和取數據分離,

 

ICODE指令總線連接到flash閃存指令存儲區,這個存儲區的地址在0x00000000-0x1FFFFFFF之間,負責取指操作。

 

DCODE數據總線負責在0x00000000-0x1FFFFFFF之間的數據訪問操作。這個數據存儲區可以是SPRAM也可以是閃存和外設。

 

系統總線:負責在0x20000000-0xDFFFFFFF0xE0100000-0xFFFFFFFF之間所有的數據傳送。

 

注:看到這你可能會迷惑,M3內核不是只有指令總線和數據總線嗎?對的,但是指令總線和ICODE指令總線不是一個,選取一張M3內核樣例處理器的圖就明白了:

 

個人理解,D-code總線和系統總線都是來源於M3內核引出的數據總線。

 

DMA通過總線矩陣直接和內存相連。

 

總線矩陣協調內核和DMASPRAM,閃存,外設的訪問。

 

AHP總線橋接兩個APB總線,兩個APB總顯得最高速度不同,APB1最高速度限於36MHzAPB2限於72MHz。兩個APB總線上掛接着不同速率的設備。

 

Stm32f10系列的靜態SPRAM64K,起始地址為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

時鍾樹如下:

 

 

 

 

 

 

Stm32GPIO8種模式:

1GPIO_Mode_AIN 模擬輸入 
2GPIO_Mode_IN_FLOATING 浮空輸入
3GPIO_Mode_IPD 下拉輸入 
4GPIO_Mode_IPU 上拉輸入 
5GPIO_Mode_Out_OD 開漏輸出
6GPIO_Mode_Out_PP 推挽輸出
7GPIO_Mode_AF_OD 復用開漏輸出 
8GPIO_Mode_AF_PP 復用推挽輸出

 

4種輸入:模擬輸入和明顯接受模擬信號,比如用於ADC,上拉輸入和下拉輸入就是默認時高電平和低電平。浮空輸入在芯片內部既沒有接上拉電阻也沒有接下拉電阻,引腳電壓是個不確定值,輸入阻抗較大,常用語I2cUSART

 

4種輸出:分復用和非復用,復用為分配給片上外設,非復用為用作正常的IO口。推免輸出為正常的輸出,而在開漏輸出模式,IO口可以由外部電路改變為低電平或不變。所以開漏模式可以讀IO輸入電平變化,實現C51IO雙向功能。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

當年看不懂的東西,現在越發清晰。

 

寄存器組

這一部分就屬於M3內核中的知識了。

M3內核中的寄存器主要如下:

 

 

下面挨個解釋

 

 

 

 

M3使用的是雙堆棧,復位之后默認使用MSP,默認是特權級,如果想要切換需要手動修改。而上面的MSPPSP的用途只是一種推薦用途,並不是一定要那么用,比如說復位之后你可以不修改,那么你的常規代碼就一直是特權級,使用MSP(我就是這樣滴。。方便至上)。

 

      這個寄存器又叫LR寄存器,那么當函數是一級調用的時候,就可以將返回地址直接存到LR中,省去了訪問內存,提高了效率,當函數調用高於一級,則需將前面的LR中的值壓棧,以便存儲新的值。

 

      當進入異常的時候,LR寄存器的值更新為特殊的EXE_RETURN

      

       

       

 

 

就是PC嘛。。。。

 

     特殊功能寄存器一定要在特權級才能被訪問(使用MSRMRS指令),至於是Thread    模式還是handler模式無所謂。

     詳細功能如下:

 

    xPSR屬於三合一寄存器,可以分出三個子狀態寄存器

 

    通過MRSMSR這三個寄存器可以單獨訪問,也可以兩兩組合訪問,也可以三合一訪問,這個寄存器大致如下(看下就好):

 

 

 

    其實除了修改上面的寄存器可以開關中斷,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種分組:組07bit划分(全部都是響應優先級),組16bit划分,組25bit划分,組34bit划分,組43bit划分(就是只用到搶占優先級)。

 

 

向量表:

當發生了異常需要響應的時候,M3需要定位其服務例程的入口地址,這些入口地址就存在所謂的“向量表”。缺省情況下,這張表存在0地址處(當然也可修改NVIC中的向量表偏移寄存器來重定位向量表),每一個表項占4字節。

如下:

 

 

首先向量表的開頭是主堆棧的地址。

 

可以看出,不論如何一個向量表至少包含下面4個表項:

1.MSP初始值

2.復位向量

3.NMI

4.fault服務例程

 

中斷的輸入與掛起:

當中斷輸入腳被置為有效后,該中斷就被懸起,到了系統中它的優先級最高的時候,就會得到響應。

    但是當某個中斷得到響應之前,其懸起位被清除,則中斷被取消。(所以stm32都是在中斷服務程序的最后清除中斷標志位)

當某中斷的服務例程開始執行的時候,就稱此中斷進入了“活躍”狀態,並且其懸起位會被自動清除。  

    

 

SVCPENDSVC

首先SVC(系統服務調用)和PENDSVC(可掛起系統服務調用)的區別在於SVC異常必須立即得到相應,而PENDSVC則不是,他可以像普通中斷一樣被掛起,知道其他重要任務完成才執行它,掛起PENDSVC的方式為:手工寫入NVICPENDSVC掛起寄存器。

SVC的用途:操作系統可以不讓用戶直接訪問硬件,而是通過觸發SVC異常來使用SVC系統調用來讓用戶程序簡介訪問硬件。好處:1.OS負責具體硬件,用戶程序不必花費心思控制硬件。2.OS的代碼應該是經過充分的測試的,所以整個系統可靠性高健壯性好。3.用戶程序無需在特權級下執行,無需擔憂因誤操作讓系統癱瘓。4.通過SVC機制,用戶程序與硬件無關。

 

 

PENDSVC的用處:上下文切換,如ucos上下文切換就是用到PENDSVC的。

 

 

 

NVIC

中斷向量控制器,也就是控制中斷向量的地方,每個外部中斷(系統中斷由SCB控制)都在其中的寄存器占有一席之地,寄存器列表如下:

    

 

     其中懸起寄存器可以系統自動設置,也可以手工修改以懸起一個中斷。

 

     軟件中斷寄存器也蠻重要的,如下:

 

 

 

 

 

 

 

   

中斷的響應和返回:

     中斷的響應:

       

        8個寄存器以及入棧順序如下:

        

   

     中斷的返回:

         首先觸發中斷返回的指令有三種:

         

          返回了之后,做如下兩件事:

          1.出棧,回復現場

          2.更新NVIC寄存器

 

        

 

 

咬尾中斷:

   一圖以蔽之:

 

其他

總結了一天,終於到了這一步,還有些零碎的知識點寫上:

 

M3的堆棧是向下生長的。

 

M3取指,解碼,執行三級流水,因為其采用哈弗體結構,所以取指和訪存可以同時執行,M3內部有解碼模塊,所以構成了三級流水。

 

 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM