How Do I Read An Arm Cortex R5 Vector Catch Register
Joseph Yiu , in The Definitive Guide to the ARM Cortex-M3 (2nd Edition), 2010
13.3 Setting Up the MPU
The MPU register might await complicated, but as long as y'all have a clear idea of the memory regions that are required for your awarding, it should not be difficult. Typically, yous need to take the post-obit memory regions:
- •
-
Program code for privileged programs (for case, OS kernel and exception handlers)
- •
-
Program code for user programs
- •
-
Data retentiveness for privileged and user programs in various memory regions (east.grand., information and stack of the application situated in the SRAM (Static Random Access Memory) memory region--0x20000000 to 0x3FFFFFFF)
- •
-
Other peripherals
It is not necessary to prepare upward a region for the retentiveness in the private peripheral bus range. The MPU automatically recognizes the private peripheral autobus retentiveness addresses and allows privileged software to perform data accesses in this region.
For Cortex-M3 products, virtually retentiveness regions can be set with TEX = b000, C = 1, B = 1. System devices such every bit the Nested Vectored Interrupt Controller (NVIC) should exist strongly ordered, and peripheral regions can be programmed as shared devices (TEX = b000, C = 0, B = one). However, if y'all want to make sure that any jitney faults occurring in the region are precise bus faults, y'all should utilize a strongly ordered memory attribute (TEX = b000, C = 0, B = 0) and then that write buffering is disabled. However, doing so can reduce system operation.
For users of a Cortex Microcontroller Software Interface Standard (CMSIS) compliant device driver, the MPU registers can be accessed using the post-obit register names as shown in Table thirteen.10. A simple flow for an MPU setup routine is shown in Effigy thirteen.three on page 220.
Register Names | MPU Register | Accost |
---|---|---|
MPU->TYPE | MPU Type register | 0xE000ED90 |
MPU->CTRL | MPU Control register | 0xE000ED94 |
MPU->RNR | MPU Region Number annals | 0xE000ED98 |
MPU->RBAR | MPU Region Base of operations Accost register | 0xE000ED9C |
MPU->RASR | MPU Region Attribute and Size register | 0xE000EDA0 |
MPU->RBAR_A1 | MPU Alias 1 Region Base of operations Address register | 0xE000EDA4 |
MPU->RBAR_A2 | MPU Allonym 2 Region Base Accost register | 0xE000EDAC |
MPU->RBAR_A3 | MPU Alias 3 Region Base of operations Address register | 0xE000EDB4 |
MPU->RASR_A1 | MPU Alias 1 Region Aspect and Size annals | 0xE000EDA8 |
MPU->RASR_A2 | MPU Alias 2 Region Aspect and Size register | 0xE000EDB0 |
MPU->RASR_A3 | MPU Allonym 3 Region Attribute and Size annals | 0xE000EDB8 |
Before the MPU is enabled and if the vector table is relocated to RAM, remember to set up the fault handler for the memory management fault in the vector table, and enable the memory management mistake in the System Handler Control and State register. They are needed to let the retention management fault handler to be executed if an MPU violation takes identify.
For a simple case of only four required regions, the MPU setup code (without the region checking and enabling) looks like this:
MPU->RNR = 0; // MPU Region Number Register
// select region 0
MPU->RBAR = 0x00000000; // MPU Region Base Address Annals
// Base Address = 0x00000000
MPU->RASR = 0x0307002F; // Region Attribute and Size Register
// R/West, TEX=0,S=one,C=1,B=1, 16MB, Enable=ane
MPU->RNR = 1; // select region one
MPU->RBAR = 0x20000000; // Base Address = 0x20000000
MPU->RASR = 0x03070033; // R/Westward, TEX=0,South=1,C=1,B=1, 64MB, Enable=one
MPU->RNR = 2; // select region two
MPU->RBAR = 0x40000000; // Base Address = 0x40000000
MPU->RASR = 0x03050033; // R/W, TEX=0,S=1,C=0,B=1, 64MB, Enable=1
MPU->RNR = three; // select region 3
MPU->RBAR = 0xA0000000; // Base Accost = 0xA0000000
MPU->RASR = 0x01040027; // Privileged R/W, TEX=0,Due south=i,C=0,B=0,
// 1MB, Enable=one
MPU->CTRL = 1; // MPU Control register – Enable MPU
This can also exist coded in assembly language:
LDR R0,=0xE000ED98 ; Region number register
MOV R1,#0 ; Select region 0
STR R1, [R0]
LDR R1,=0x00000000 ; Base Accost = 0x00000000
STR R1, [R0, #4] ; MPU Region Base of operations Address Register
LDR R1,=0x0307002F ; R/W, TEX=0,S=one,C=1,B=ane, 16MB, Enable=i
STR R1, [R0, #eight] ; MPU Region Aspect and Size Register
MOV R1,#1 ; Select region 1
STR R1, [R0]
LDR R1,=0x20000000 ; Base of operations Address = 0x20000000
STR R1, [R0, #four] ; MPU Region Base of operations Address Register
LDR R1,=0x03070033 ; R/Westward, TEX=0,S=ane,C=1,B=1, 64MB, Enable=1
STR R1, [R0, #8] ; MPU Region Attribute and Size Register
MOV R1,#2 ; Select region 2
STR R1, [R0]
LDR R1,=0x40000000 ; Base Address = 0x40000000
STR R1, [R0, #4] ; MPU Region Base Address Register
LDR R1,=0x03050033 ; R/Due west, TEX=0,S=1,C=0,B=ane, 64MB, Enable=1
STR R1, [R0, #8] ; MPU Region Aspect and Size Register
MOV R1,#3 ; Select region 3
STR R1, [R0]
LDR R1,=0xA0000000 ; Base of operations Address = 0xA0000000
STR R1, [R0, #4] ; MPU Region Base of operations Address Annals
LDR R1,=0x01040027 ; Privileged R/West, TEX=0,Due south=1,C=0,B=0, 1MB,
; Enable=ane
STR R1, [R0, #eight] ; MPU Region Attribute and Size Register
MOV R1,#1 ; Enable MPU
STR R1, [R0,#-4] ; MPU Control register
; (0xE000ED98-4=0xE000ED94)
This provides four regions:
- •
-
Code: 0x00000000–0x00FFFFFF (sixteen MB), full access, cacheable
- •
-
Data: 0x20000000–0x02003FFFF (64 MB), full admission, cacheable
- •
-
Peripheral: 0x40000000–0x5FFFFFFF (64 MB), total access, shared device
- •
-
External device: 0xA0000000–0xA00FFFFF (1 MB), privileged access, strongly ordered, XN
Past combining region choice and writing to the base address register, we can shorten the lawmaking to this:
MPU->RBAR = 0x00000010; // MPU Region Base of operations Address Annals
// Base Address = 0x00000000, valid, region 0
MPU->RASR = 0x0307002F; // Region Attribute and Size Register
// R/W, TEX=0,Southward=1,C=1,B=1, 16MB, Enable=i
MPU->RBAR = 0x20000011; // Base of operations Address = 0x20000000, valid, region i
MPU->RASR = 0x03070033; // R/W, TEX=0,S=ane,C=one,B=1, 64MB, Enable=ane
MPU->RBAR = 0x40000012; // Base Address = 0x40000000, valid, region 2
MPU->RASR = 0x03050033; // R/W, TEX=0,S=1,C=0,B=1, 64MB, Enable=1
MPU->RBAR = 0xA0000013; // Base Accost = 0xA0000000, valid, region 3
MPU->RASR = 0x01040027; // Privileged R/W, TEX=0,S=1,C=0,B=0,
// 1MB, Enable=i
MPU->CTRL = 1; // MPU Control annals – Enable MPU
Or, in assembly:
LDR R0,=0xE000ED9C ; Region Base Address register
LDR R1,=0x00000010 ; Base of operations Accost = 0x00000000, region 0,
; valid=1
STR R1, [R0, #0] ; MPU Region Base Address Register
LDR R1,=0x0307002F ; R/W, TEX=0,S=one,C=ane,B=one, 16MB, Enable=1
STR R1, [R0, #4] ; MPU Region Attribute and Size Register
LDR R1,=0x20000011 ; Base Address = 0x20000000, region 1,
; valid=1
STR R1, [R0, #0] ; MPU Region Base of operations Accost Register
LDR R1,=0x03070033 ; R/W, TEX=0,South=i,C=1,B=1, 64MB, Enable=1
STR R1, [R0, #iv] ; MPU Region Attribute and Size Annals
LDR R1,=0x40000012 ; Base Accost = 0x40000000, region 2,
; valid=1
STR R1, [R0, #0] ; MPU Region Base Accost Register
LDR R1,=0x03050033 ; R/West, TEX=0,S=1,C=0,B=1, 64MB, Enable=1
STR R1, [R0, #four] ; MPU Region Attribute and Size Register
LDR R1,=0xA0000013 ; Base Address = 0xA0000000, region three,
; valid=i
STR R1, [R0, #0] ; MPU Region Base Address Register
LDR R1,=0x01040027 ; R/W, TEX=0,Due south=one,C=0,B=0, 1MB, Enable=1
STR R1, [R0, #four] ; MPU Region Attribute and Size Register
MOV R1,#i ; Enable MPU
STR R1, [R0,#-8] ; MPU Control register
; (0xE000ED9C-viii=0xE000ED94)
We've shortened the lawmaking quite a bit. Nonetheless, y'all tin make further enhancements to create even faster setup code. This is done using MPU aliased register addresses (meet Table D.34 in Appendix D). The aliased register addresses follow the MPU Region Attribute and Size registers and are aliased to the MPU Base of operations Address register and the MPU Region Attribute and Size register. They produce a continuous accost of eight words, making information technology possible to employ Load/Store Multiple (LDM and STM) instructions:
LDR R0,=0xE000ED9C ; Region Base Accost annals
LDR R1,=MPUconfig ; Table of predefined MPU setup variables
LDMIA R1!, {R2, R3, R4, R5} ; Read iv words from table
STMIA R0!, {R2, R3, R4, R5} ; write 4 words to MPU
LDMIA R1!, {R2, R3, R4, R5} ; Read side by side 4 words from tabular array
STMIA R0!, {R2, R3, R4, R5} ; write next 4 words to MPU
B MPUconfigEnd
Marshal 4 ; This is needed to make sure the following tabular array
; is word aligned
MPUconfig ; so that we tin can employ load multiple instruction
DCD 0x00000010 ; Base Address = 0x00000000, region 0,
; valid=1
DCD 0x0307002F ; R/W, TEX=0,S=1,C=1,B=1, 16MB, Enable=1
DCD 0x20000011 ; Base of operations Address = 0x08000000, region one,
; valid=ane
DCD 0x03070033 ; R/W, TEX=0,S=1,C=1,B=1, 64MB, Enable=1
DCD 0x40000012 ; Base of operations Address = 0x40000000, region 2,
; valid=1
DCD 0x03050033 ; R/W, TEX=0,S=1,C=0,B=ane, 64MB, Enable=1
DCD 0xA0000013 ; Base of operations Accost = 0xA0000000, region 3,
; valid=ane
DCD 0x01040027 ; R/Due west, TEX=0,S=1,C=0,B=0, 1MB, Enable=1
MPUconfigEnd
LDR R0,=0xE000ED94; MPU Command register
MOV R1,#i ; Enable MPU
STR R1, [R0]
This solution, of course, tin can be used only if all the required information is known beforehand. Otherwise, a more generic approach has to be used. Ane manner to handle this is to use a subroutine (MpuRegionSetup) that can set up a region based on a number of input parameters and and so call information technology several times to gear up different regions:
void MpuRegionSetup(unsigned int addr, unsigned int region,
unsigned int size, unsigned int ap, unsigned int MemAttrib,
unsigned int srd, unsigned int XN, unsigned int enable)
{ // Setup process for each region
MPU->RBAR = (addr & 0xFFFFFFE0) | (region & 0xF) | 0x10;
MPU->RASR = ((XN & 0x1)<<28) | ((ap & 0x7)<<24) |
((MemAttrib & 0x3F)<<16) | ((srd&0xFF)<<viii) |
((size & 0x1F)<<one)| (enable & 0x1);
return;
}
void MpuRegionDisable(unsigned int region)
{ // Function to disable an unused region
MPU->RBAR = (region & 0xF) | 0x10;
MPU->RASR = 0; // disable
return;
}
void MpuSetup(void)
{ // Setup the whole MPU
MPU->CTRL = 0; // Disable MPU start
MpuRegionSetup(0x00000000, 0, 0x17, 3, 7, 0, 0, 1); // Region 0,16M
MpuRegionSetup(0x20000000, 1, 0x19, 3, vii, 0, 0, i); // Region 1,64M
MpuRegionSetup(0x40000000, 2, 0x19, 3, 5, 0, 0, 1); // Region two,64M
MpuRegionSetup(0xA0000000, 3, 0x13, i, 4, 0, 0, 1); // Region iii, 1M
MpuRegionDisable(4); // Disable unused region 4
MpuRegionDisable(five); // Disable unused region 5
MpuRegionDisable(half-dozen); // Disable unused region 6
MpuRegionDisable(7); // Disable unused region 7
MPU->CTRL = 1; // Enable MPU
render;
}
In this example, we included a subroutine that is used to disable a region that is not used. This is necessary if you do not know whether a region has been programmed previously. If an unused region is previously programmed to be enabled, information technology needs to be disabled so that information technology doesn't affect the new configuration.
The MPU setup routines can be rewritten in assembly equally
MpuSetup ; A subroutine to setup the MPU by calling subroutines that
; setup regions
Push button {R0-R6,LR}
LDR R0,=0xE000ED94 ; MPU Control Register
MOV R1,#0
STR R1,[R0] ; Disable MPU
; --- Region #0 ---
LDR R0,=0x00000000 ; Region 0: Base Address = 0x00000000
MOV R1,#0x0 ; Region 0: Region number = 0
MOV R2,#0x17 ; Region 0: Size = 0x17 (16MB)
MOV R3,#0x3 ; Region 0: AP = 0x3 (full admission)
MOV R4,#0x7 ; Region 0: MemAttrib = 0x7
MOV R5,#0x0 ; Region 0: Sub R disable = 0
MOV R6,#0x1 ; Region 0: {XN, Enable} = 0,one
BL MpuRegionSetup
; --- Region #1 ---
LDR R0,=0x20000000 ; Region i: Base Address = 0x20000000
MOV R1,#0x1 ; Region i: Region number = 1
MOV R2,#0x19 ; Region ane: Size = 0x19 (64MB)
MOV R3,#0x3 ; Region i: AP = 0x3 (full
admission)
MOV R4,#0x7 ; Region ane: MemAttrib = 0x7
MOV R5,#0x0 ; Region 1: Sub R disable = 0
MOV R6,#0x1 ; Region 1: {XN, Enable} = 0,ane
BL MpuRegionSetup
... ; setup for region #ii and #3
; --- Region #4-#7 Disable ---
MOV R0,#iv
BL MpuRegionDisable
MOV R0,#5
BL MpuRegionDisable
MOV R0,#6
BL MpuRegionDisable
MOV R0,#7
BL MpuRegionDisable
LDR R0,=0xE000ED94 ; MPU Control Register
MOV R1,#1
STR R1,[R0] ; Enable MPU
POP {R0-R6,PC} ; Render
MpuRegionSetup
; MPU region setup subroutine
; Input R0 : Base Address
; R1 : Region number
; R2 : Size
; R3 : AP (access permission)
; R4 : MemAttrib ({TEX[2:0], South, C, B})
; R5 : Sub region disable
; R6 : {XN,Enable}
Push button {R0-R1, LR}
BIC R0, R0, #0x1F ; Articulate unused bits in address
BFI R0, R1, #0, #four ; Insert region number to R0[3:0]
ORR R0, R0, #0x10 ; Set valid fleck
LDR R1,=0xE000ED9C ; MPU Region Base Address Register
STR R0,[R1] ; Set base address reg
AND R0, R6, #0x01 ; Get Enable bit
UBFX R1, R6, #1, #1 ; Get XN bit
BFI R0, R1, #28, #1 ; Insert XN to R0[28]
BFI R0, R2, #i , #5 ; Insert Region Size field (R2[4:0]) to
; R0[5:ane]
BFI R0, R3, #24, #3 ; Insert AP fields (R3[two:0]) to R0[26:24]
BFI R0, R4, #16, #6 ; Insert memattrib field (R4[5:0]) to
; R0[21:16]
BFI R0, R5, #8, #viii ; Insert subregion disable (SRD) fields
; to R0[15:eight]
LDR R1,=0xE000EDA0 ; MPU Region Base Size and Attribute
; Register
STR R0,[R1] ; Set base attribute and size reg
Pop {R0-R1, PC} ; Render
MpuRegionDisable
; Subroutine to disable unused region
; Input R0 : Region number
PUSH {R1, LR}
AND R0, R0, #0xF ; Clear unused bits in Region Number
ORR R0, R0, #0x10 ; Fix valid bit
LDR R1,=0xE000ED9C ; MPU Region Base Address Register
STR R0,[R1]
MOV R0, #0
LDR R1,=0xE000EDA0 ; MPU Region Base of operations Size and Attribute
; Register
STR R0,[R1] ; Set base attribute and size reg to 0
; (disabled)
POP {R1, PC} ; Return
The example shows the application of the Bit Field Insert (BFI) instruction in the Cortex-M3. This can greatly simplify bit-field merging operations.
Source: https://www.sciencedirect.com/topics/computer-science/memory-protection
Posted by: prescotttherejorty.blogspot.com
0 Response to "How Do I Read An Arm Cortex R5 Vector Catch Register"
Post a Comment