Skip to content

Commit 13d98b2

Browse files
authored
Rework MPU config for unaligned access to external memory (nanoframework#3044)
***NO_CI***
1 parent 9566cb2 commit 13d98b2

File tree

15 files changed

+214
-90
lines changed

15 files changed

+214
-90
lines changed

targets/ChibiOS/ORGPAL_PALTHREE/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@ nf_setup_target_build(
1818
CLR_EXTRA_SOURCE_FILES
1919
# the next one is required is the target implements and it's using external memory
2020
${CMAKE_CURRENT_SOURCE_DIR}/target_external_memory.c
21-
21+
${CMAKE_CURRENT_SOURCE_DIR}/target_mpu_config.c
22+
2223
BOOTER_EXTRA_COMPILE_DEFINITIONS
2324
USBH_DEBUG_MULTI_HOST=0
2425

targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
extern int32_t hal_lfs_config();
2121
extern void hal_lfs_mount();
22+
extern void Target_ConfigMPU();
2223

2324
// need to declare the Receiver thread here
2425
osThreadDef(ReceiverThread, osPriorityHigh, 2048, "ReceiverThread");
@@ -93,6 +94,9 @@ int main(void)
9394
crcStart(NULL);
9495
#endif
9596

97+
// MPU configuration
98+
Target_ConfigMPU();
99+
96100
// config and init external memory
97101
// this has to be called after osKernelInitialize, otherwise an hard fault will occur
98102
Target_ExternalMemoryInit();

targets/ChibiOS/ORGPAL_PALTHREE/nanoCLR/mcuconf.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,7 @@
2929
/*
3030
* Memory attributes settings.
3131
*/
32-
#define STM32_NOCACHE_ENABLE TRUE
33-
#define STM32_NOCACHE_MPU_REGION MPU_REGION_0
34-
#define STM32_NOCACHE_RBAR 0x20000000U
35-
#define STM32_NOCACHE_RASR MPU_RASR_SIZE_128K
32+
#define STM32_NOCACHE_ENABLE FALSE
3633

3734
/*
3835
* HAL driver system settings.

targets/ChibiOS/ORGPAL_PALTHREE/stm32f7xx_hal_conf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extern "C"
3434
// #define HAL_NAND_MODULE_ENABLED
3535
// #define HAL_NOR_MODULE_ENABLED
3636
// #define HAL_SRAM_MODULE_ENABLED
37-
// #define HAL_SDRAM_MODULE_ENABLED
37+
#define HAL_SDRAM_MODULE_ENABLED
3838
// #define HAL_HASH_MODULE_ENABLED
3939
// #define HAL_GPIO_MODULE_ENABLED
4040
// #define HAL_I2C_MODULE_ENABLED

targets/ChibiOS/ORGPAL_PALTHREE/target_external_memory.c

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55

66
#include <ch.h>
77
#include "hal.h"
8-
#include "fsmc_sdram_lld.h"
8+
#include <fsmc_sdram_lld.h>
9+
#include <stm32f7xx_hal.h>
910

1011
// SDRAM Mode definition register defines
1112
#define FMC_SDCMR_MRD_BURST_LENGTH_1 ((uint16_t)0x0000)
@@ -95,3 +96,46 @@ void Target_ExternalMemoryInit()
9596
fsmcSdramInit();
9697
fsmcSdramStart(&SDRAMD, &sdram_cfg);
9798
}
99+
100+
void Target_ExternalMemoryConfigMPU()
101+
{
102+
// ARM: STM32F7: hard fault caused by unaligned Memory Access
103+
// reference https://www.keil.com/support/docs/3777%20%20.htm
104+
// SYMPTOM
105+
// If you use an STM32F7xx microcontroller with an external SDRAM,
106+
// the Cortex-M7 core may unexpectedly run into the hard fault handler because of unaligned access.
107+
// This may happen for example, when the frame buffer of an LCD, a RAM filesystem or any other data is
108+
// located into the SDRAM address range 0xC0000000 - 0xC03FFFFF (max. 4MB).
109+
// The hard fault is executed although the bit UNALIGN_TRP (bit 3) in the CCR register is not enabled.
110+
111+
// CAUSE
112+
// In general, RAM accesses on Cortex-M7 based devices do not have to be aligned in any way.
113+
// The Cortex-M7 core can handle unaligned accesses by hardware.
114+
// Usually, variables should be naturally aligned because these accesses are slightly faster than unaligned
115+
// accesses.
116+
117+
// STM32F7xx devices have the external SDRAM mapped to the
118+
// address range 0xC0000000 - 0xC03FFFFF (max. 4MB).
119+
// According to the ARMv7-M Architecture Reference Manual chapter B3.1 (table B3-1),
120+
// the area 0xC0000000-0xDFFFFFFF (32MB) is specified as Device Memory Type.
121+
// According to chapter A3.2.1, all accesses to Device Memory Types must be naturally aligned.
122+
// If they are not, a hard fault will execute no matter if the bit UNALIGN_TRP (bit 3) in the CCR register is
123+
// enabled or not.
124+
125+
MPU_Region_InitTypeDef MPU_InitStruct;
126+
127+
// Configure the MPU attributes for SDRAM
128+
MPU_InitStruct.Enable = MPU_REGION_ENABLE;
129+
MPU_InitStruct.BaseAddress = 0xD0000000;
130+
MPU_InitStruct.Size = MPU_REGION_SIZE_8MB;
131+
MPU_InitStruct.AccessPermission = MPU_REGION_FULL_ACCESS;
132+
MPU_InitStruct.IsBufferable = MPU_ACCESS_NOT_BUFFERABLE;
133+
MPU_InitStruct.IsCacheable = MPU_ACCESS_NOT_CACHEABLE;
134+
MPU_InitStruct.IsShareable = MPU_ACCESS_NOT_SHAREABLE;
135+
MPU_InitStruct.Number = MPU_REGION_NUMBER0;
136+
MPU_InitStruct.TypeExtField = MPU_TEX_LEVEL1;
137+
MPU_InitStruct.SubRegionDisable = 0x00;
138+
MPU_InitStruct.DisableExec = MPU_INSTRUCTION_ACCESS_DISABLE;
139+
140+
HAL_MPU_ConfigRegion(&MPU_InitStruct);
141+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
//
2+
// Copyright (c) .NET Foundation and Contributors
3+
// See LICENSE file in the project root for full license information.
4+
//
5+
6+
#include <ch.h>
7+
#include <hal.h>
8+
#include <stm32_registry.h>
9+
#include <hal_nf_community.h>
10+
11+
extern void Target_ExternalMemoryConfigMPU();
12+
13+
// SRAM1 base address
14+
#define SRAM1_SIZE_128K (1UL << 16) // 2^17 bytes
15+
#define MPU_REGION_SRAM1 MPU_REGION_1
16+
17+
void Target_ConfigNonCacheableMemory()
18+
{
19+
// region
20+
MPU->RNR = MPU_REGION_SRAM1;
21+
22+
// base address
23+
MPU->RBAR = SRAM1_BASE;
24+
25+
// size and other configs
26+
MPU->RASR =
27+
((uint32_t)MPU_RASR_ATTR_AP_RW_RW | MPU_RASR_ATTR_NON_CACHEABLE | MPU_RASR_ATTR_S | MPU_RASR_SIZE_128K |
28+
MPU_RASR_ENABLE);
29+
}
30+
31+
void Target_ConfigMPU()
32+
{
33+
// disable MPU
34+
HAL_MPU_Disable();
35+
36+
// config MPU for external memory
37+
Target_ExternalMemoryConfigMPU();
38+
39+
// config MPU for non cacheable memory
40+
Target_ConfigNonCacheableMemory();
41+
42+
// enable MPU
43+
HAL_MPU_Enable(MPU_PRIVILEGED_DEFAULT);
44+
}

targets/ChibiOS/ORGPAL_PALX/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ nf_setup_target_build(
1818
CLR_EXTRA_SOURCE_FILES
1919
# the next one is required is the target implements and it's using external memory
2020
${CMAKE_CURRENT_SOURCE_DIR}/target_external_memory.c
21+
${CMAKE_CURRENT_SOURCE_DIR}/target_mpu_config.c
2122

2223
BOOTER_EXTRA_COMPILE_DEFINITIONS
2324
-DUSBH_DEBUG_MULTI_HOST=0

targets/ChibiOS/ORGPAL_PALX/nanoCLR/main.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
extern int32_t hal_lfs_config();
2121
extern void hal_lfs_mount();
22+
extern void Target_ConfigMPU();
2223

2324
// need to declare the Receiver thread here
2425
osThreadDef(ReceiverThread, osPriorityHigh, 2048, "ReceiverThread");
@@ -93,6 +94,9 @@ int main(void)
9394
crcStart(NULL);
9495
#endif
9596

97+
// MPU configuration
98+
Target_ConfigMPU();
99+
96100
// config and init external memory
97101
// this has to be called after osKernelInitialize, otherwise an hard fault will occur
98102
Target_ExternalMemoryInit();

targets/ChibiOS/ORGPAL_PALX/nanoCLR/mcuconf.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,7 @@
2727
/*
2828
* Memory attributes settings.
2929
*/
30-
#define STM32_NOCACHE_ENABLE TRUE
31-
#define STM32_NOCACHE_MPU_REGION MPU_REGION_0
32-
#define STM32_NOCACHE_RBAR 0x20000000U
33-
#define STM32_NOCACHE_RASR MPU_RASR_SIZE_128K
30+
#define STM32_NOCACHE_ENABLE FALSE
3431

3532
/*
3633
* HAL driver system settings.

targets/ChibiOS/ORGPAL_PALX/stm32f7xx_hal_conf.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extern "C"
3333
// #define HAL_FLASH_MODULE_ENABLED
3434
// #define HAL_NAND_MODULE_ENABLED
3535
// #define HAL_NOR_MODULE_ENABLED
36-
// #define HAL_SRAM_MODULE_ENABLED
36+
#define HAL_SDRAM_MODULE_ENABLED
3737
// #define HAL_SDRAM_MODULE_ENABLED
3838
// #define HAL_HASH_MODULE_ENABLED
3939
// #define HAL_GPIO_MODULE_ENABLED

0 commit comments

Comments
 (0)