ST-ARM理論(1):系統(tǒng)架構(gòu),地址映射
前提摘要
-
個人說明:
限于時間緊迫以及作者水平有限,本文錯誤、疏漏之處恐不在少數(shù),懇請讀者批評指正。意見請留言或者發(fā)送郵件至:“noahpanzzz@gmail.com”
-
參考
正文
系統(tǒng)架構(gòu)
CPU的核心主要功能為運算器和控制器,但是CPU并不具備數(shù)據(jù)存儲的功能。CPU與外界存儲器建立數(shù)據(jù)通道分為“哈佛結(jié)構(gòu)”和“馮諾伊曼結(jié)構(gòu)”兩種不同思路。
馮諾伊曼結(jié)構(gòu)的優(yōu)點是總線資源占用少,缺點是執(zhí)行效率較低,馮諾伊曼結(jié)構(gòu)執(zhí)行程序的同時不能讀取數(shù)據(jù)。而相反的是哈佛結(jié)構(gòu)的優(yōu)點是執(zhí)行效率較高,缺點是總線資源占用多,哈佛結(jié)構(gòu)執(zhí)行程序的同時能夠讀取數(shù)據(jù)。
如今半導體技術(shù)發(fā)展迅速,對于資源限制已經(jīng)沒有那么嚴重了。
ST-ARM
ST公司設(shè)計的ARM架構(gòu)芯片,采用的是“哈佛結(jié)構(gòu)”,ICode總線直接連接到Flash,而不需要經(jīng)過經(jīng)過總線矩陣。
上圖為STM32F1系列系統(tǒng)架構(gòu)圖。
地址映射
Cortex-M3
- ARM Cortex-M3架構(gòu),32位CPU,所以就有32位地址線和數(shù)據(jù)線。
- 32位地址線決定了CPU的地址空間為4G(2^32 = 4G,按字節(jié)尋址)。
地址映射規(guī)則
- 芯片外接外部RAM和外部ROM的時候,RAM和ROM器件都是獨立器件,并沒有地址一說,或者說都只有自己的絕對地址,且從0x00開始。而對于CPU來說,0x00地址只能有1個,所以外接器件掛到CPU上時只能做地址映射,如RAM的地址為0x3000 0000, ROM地址為0x4000 0000, 這樣CPU就做了統(tǒng)一編址。
- 32位地址線決定了CPU的地址空間為4G,這些地址要統(tǒng)一分配使用,所以說內(nèi)存(RAM)、外設(shè)(寄存器)和存儲器(RAM)都需要被映射到這個4G空間里面,但是哪些占用低地址,哪些占用高地址?
- 這些問題已經(jīng)被ARM的設(shè)計者給設(shè)計好了的,地址從高到低如何使用,已經(jīng)被規(guī)定好,而我們只需要學習這些規(guī)則就好了。掌握規(guī)則,并使用規(guī)則。
- 因此可以想象到:ARM體系結(jié)構(gòu)中,系統(tǒng)上電或復位后,處理器將從地址0x00處取第一條指令,因此,上電的時候,地址0x00處必須是非易失性的ROM或FLASH。
- CPU地址總線的地址,由硬件電路控制其具體含義。物理地址中很大一部分是留給內(nèi)存條中的內(nèi)存的,但也常被映射到其他存儲器上 (如顯存、BIOS等)。就生成了物理地址,這個物理地址被放到CPU的地址線上。
- 物理地址空間,一部分給物理RAM(內(nèi)存)用,一部分給總線用,這是由硬件設(shè)計來決定的,但物理RAM一般不能上到4G,因為還有一部分要給總線用(總線上還掛著別的許多設(shè)備)。一般是把低端物理地址給RAM用,高端物理地址給總線用。
總結(jié):地址映射就是給地址進行命名的過程。
存儲器映射
- 存儲器本身不具有地址信息,它的地址是由芯片廠商或用戶分配的,給存儲器分配地址的過程就稱為存儲器映射。
- 在這 4G 的地址空間中,ARM 平均分成了 8 個塊,每塊 512MB,每個塊也都規(guī)定了用途。每個塊的大小都有 512MB,顯然這是非常大的,芯片廠商在每個塊的范圍內(nèi)設(shè)計各具特色的外設(shè)時并不一定都用得完,都是只用了其中的一部分而已。
序號 | 用途 | 地址范圍 |
---|---|---|
Block 0 | Code | 0x0000 0000 ~ 0x1FFF FFFF(512MB) |
Block 1 | SRAM | 0x2000 0000 ~ 0x3FFF FFFF(512MB) |
Block 2 | 片上外設(shè) | 0x4000 0000 ~ 0x5FFF FFFF(512MB) |
Block 3 | FSMC 的 bank1 ~ bank2 | 0x6000 0000 ~ 0x7FFF FFFF(512MB) |
Block 4 | FSMC 的 bank3 ~ bank4 | 0x8000 0000 ~ 0x9FFF FFFF(512MB) |
Block 5 | FSMC 寄存器 | 0xA000 0000 ~ 0xCFFF FFFF(512MB) |
Block 6 | 沒有使用 | 0xD000 0000 ~ 0xDFFF FFFF(512MB) |
Block 7 | Cortex-M3 內(nèi)部外設(shè) | 0xE000 0000 ~ 0xFFFF FFFF(512MB) |
上圖為STM32F1系列存儲器映射列表。
寄存器映射
- 寄存器是單片機內(nèi)部一種特殊的內(nèi)存,可以實現(xiàn)對單片機各個功能的控制,給寄存器分配地址的過程稱為寄存器映射。
大類 | 小類 | 說明 |
---|---|---|
內(nèi)存寄存器 | 內(nèi)核相關(guān)寄存器 | 包含R0~R15、xPSR、特殊功能寄存器等 |
內(nèi)存寄存器 | 中斷控制寄存器 | 包含NVIC和SCB相關(guān)寄存器,NVIC有:ISER、ICER、ISPR、IP等;SCB有:VTOR、AIRCR、SCR等 |
內(nèi)存寄存器 | SysTick寄存器 | 包含CTRL、LOAD、VAL和CALIB四個寄存器 |
內(nèi)存寄存器 | 內(nèi)存保護寄存器 | 可選功能,STM32F103沒有 |
內(nèi)存寄存器 | 調(diào)試系統(tǒng)寄存器 | ETM、ITM、DWT、IPIU等相關(guān)寄存器 |
外設(shè)寄存器 | 包含GPIO、UART、IIC、SPI、TIM、DMA等各種外設(shè) |
如果沒有給寄存器映射,那么操作寄存器就會變得特別復雜。
以GPIOA ODR寄存器為例,GPIOA ODR的地址為0x4001 080C(寄存器地址=總線基地址+外設(shè)偏移地址+寄存器偏移量,以GPIOA_ODR為例,GPIOA_ODR=0x4001 0000 + 0x800 + 0x0C = 0x4001 080C。需要注意的是AHB總線基地址是從0x4001 8000開始的,但是在程序中定義是從0x4002 0000開始,將SDIO的地址單獨獨立出來)。
那么直接操作寄存器地址:
*(unsigned int *)(0x4001 080C)=0xFFFF;
定義一個名字之后再操作:
#define GPIOA_ODR *(unsigned int *)(0x4001 080C)
GPIOA_ODR =0xFFFF;
但是這樣直接操作寄存器還是很復雜,因為寄存器的數(shù)量是非常多的。
結(jié)構(gòu)體映射
由于寄存器都是連續(xù)排列的,所以可以使用結(jié)構(gòu)體進行映射(以GPIOA寄存器為例)。
typedef struct
{
__IO uint32_t CRL;
__IO uint32_t CRH;
__IO uint32_t IDR;
__IO uint32_t ODR;
__IO uint32_t BSRR;
__IO uint32_t BRR;
__IO uint32_t LCKR;
}GPIO_TypeDef;
#define PERIPH_BASE ((uint32_t)0x40000000) /*!< Peripheral base address in the alias region */
#define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
#define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
#define GPIOA ((GPIO_TypeDef *) GPIOA_BASE)
那么GPIOA中CRL、CRH、IDR、ODR、BSRR、BRR、LCKR各個地址:
&GPIOA->CRL:0x40010800
&GPIOA->CRH:0x40010804
&GPIOA->IDR:0x40010808
&GPIOA->ODR:0x4001080c
&GPIOA->BSRR:0x40010810
&GPIOA->BRR:0x40010814
&GPIOA->LCKR:0x40010818
注:關(guān)于__IO
#ifdef __cplusplus
#define __I volatile /*!< defines 'read only' permissions */
#else
#define __I volatile const /*!< defines 'read only' permissions */
#endif
#define __O volatile /*!< defines 'write only' permissions */
#define __IO volatile /*!< defines 'read / write' permissions */
volatile的英文解釋是易變化的,不穩(wěn)定的。所以在變量的前面加這個修飾符目的是讓CPU去內(nèi)存中讀取數(shù)據(jù),而不是CPU去寄存器讀取數(shù)據(jù)。
由于外部因素使得內(nèi)存中存放該變量的值發(fā)生了改變,如果CPU不訪問內(nèi)存,而是直接讀取寄存器的舊值,則讀取的是錯誤的,導致程序失敗。文章來源:http://www.zghlxwxcb.cn/news/detail-801871.html
總結(jié)
本文均為原創(chuàng),歡迎轉(zhuǎn)載,請注明文章出處:。百度和各類采集站皆不可信,搜索請謹慎鑒別。技術(shù)類文章一般都有時效性,本人習慣不定期對自己的博文進行修正和更新,因此請訪問出處以查看本文的最新版本。本人能力有限,如果你有好的想法,還望不吝賜教!文章來源地址http://www.zghlxwxcb.cn/news/detail-801871.html
到了這里,關(guān)于ST-ARM理論(1):系統(tǒng)架構(gòu),地址映射的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!