banner



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.

Table thirteen.ten. MPU Annals Names in CMSIS

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

Figure thirteen.3. Case Steps to Set the MPU.

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

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel