SDRAM Examples on RT1060 and MCUXpresso SDK - nxp-mcuxpresso/vscode-for-mcux GitHub Wiki

Some MCUXpresso SDK projects for i.MX RT devices contain build configurations that place the application code in SDRAM memory. To indicate this, the build configuration's name usually starts with "sdram".

The SDRAM is usually the largest RAM region available on the board, however it is also external and needs to be initialized before it can be used. This memory is typically initialized by the MCU BootROM during reset, based on configuration data (DCD) programmed into XIP header code in flash. But for RAM projects intending to use this SDRAM area to directly download and execute code from it, some additional steps are needed.

For Segger Probes

A .jlinkscript file to initialize the SDRAM is usually included in examples imported from MCUXpresso SDKs. However, in order to use the jlink script, it needs to be set in .vscode/mcuxpresso-tools.json, using the debug/segger/scriptfile property:

{
	...
	"debug": {
		...
		"segger": {
			...
			"scriptfile": <absolute path to the jlinkscript file>
		}
	}
}

After the property is set, the project can be debugged even with build configurations that place the application code in SDRAM.

Example for RT1060

  1. From the MCUXpresso SDK repository, import the hello_world project for the MIMXRT 1060-EVKC board.
  2. Switch the build configuration to sdram_txt_debug to place the application fully in SDRAM.
  3. The example folder contains a evkcmimxrt1060_sdram_init.jlinkscript file.
    1. Right click on the file and select Copy Path
    2. Open .vscode/mcuxpresso-tools.json, add the scriptfile property as described above, and paste the copied path as its value. (On Windows, backslashes need to be escaped)
      {
      	"version": "24.8",
      	"toolchainPath": "C:/NXP/MCUXpressoIDE_11.10.0_3058_ear1/ide/tools",
      	"linkedProjects": [],
      	"trustZoneType": "none",
      	"multicoreType": "none",
      	"debug": {
      		"linkserver": {},
      		"pemicro": {},
      		"segger": {
      			"device": "MIMXRT1062xxx6A",
      			"scriptfile": "C:\\Users\\my-user\\Desktop\\projects\\evkcmimxrt1060_hello_world_jlink\\evkcmimxrt1060_sdram_init.jlinkscript"
      		}
      	},
      	"projectType": "sdk-freestanding",
      	"sdk": {
      		"version": "2.15.0",
      		"path": "c:\\Users\\my-user\\Desktop\\sdks\\mcux-sdk4",
      		"boardId": "evkcmimxrt1060",
      		"deviceId": "MIMXRT1062xxxxB",
      		"coreId": "core0_MIMXRT1062xxxxB"
      	}
      }
  4. Debug the project using a Segger probe.

For LinkServer probes

LinkServer does not provide a script to initialize the SDRAM. To ensure that the SDRAM region is correctly initialized before it is used for debug operations targeting a SDRAM-based application, the recommended way is to first flash some application that includes the needed DCD section. This is a one-time operation - as long as the application remains in flash, every power cycle or debugger initiated reset leaves the SDRAM ready and available for a subsequent SDRAM download / debug operation.

Most SDK examples already make available the SDRAM initialization mechanism, by including the DCD data needed to initialize the SDRAM as part of project - even the most simple hello_world example typically includes it. The DCD data is usually included in the dcd.c file, which can be accessed from the project via __repo__/core/boards/<board>/dcd.c.

DCD location

Note that the code is enabled based on the XIP_BOOT_HEADER_DCD_ENABLE preprocessor macro and may therefore be excluded by default.

Caching

Even with the DCD data in flash, debugging a SDRAM project might stop at main() but debugging actions like Step and Breakpoints might not function correctly. These issues are usually caused by debugging while caching is enabled on the MCU. While not in debugging mode, the application should run without issues.

  1. The easiest solution is to disable caching for both applications (the one written into flash for the DCD data & the actual SDRAM application). MCUXpresso SDK projects usually enable caching in two locations:

    • In main() using a function like BOARD_ConfigMPU(). This function call should be removed.
    • In SystemInit(), which is a function executed before main(), located in a file included from the SDK.
      • The function can be easily located by first building the project and inspecting the ELF using the Image Info view. Clicking on its entry opens the respective file.

        SystemInit() in Image Info

      • It is not recommended to modify this file directly, since any changes will affect all the projects for the current device. The alternative is to provide an implementation for void SystemInitHook(); in the main file. This function gets called after SystemInit() finishes, which allows you to disable the cache again, after it was enabled by SystemInit().

      • The specific method to disable the cache depends on the device. Functions for enabling and disabling the cache are usually provided by the SDK.

  2. The other solution is to change the LinkServer device configuration JSON file to specify the cachelib option with the appropriate caching library. Since this requires more knowledge of LinkServer and the device, it will not be demonstrated here.

Example for RT1060

  1. Write a project containing the DCD data into flash.

    1. From the MCUXpresso SDK repository, import the hello_world project for the MIMXRT 1060-EVKC board.
    2. Remove all existing code inside the main() function.
    3. Change the build configuration to a flash based one, for example flexspi_nor_debug.
    4. Make sure XIP_BOOT_HEADER_DCD_ENABLE is defined for the selected build configuration.
      1. Open armgcc/flags.cmake
      2. Search for CMAKE_C_FLAGS_FLEXSPI_NOR_DEBUG (or the appropriately named variable for the chosen configuration)
      3. Add -DXIP_BOOT_HEADER_ENABLE=1 \ and -DXIP_BOOT_HEADER_DCD_ENABLE=1 \ if they don't already exist.
        SET(CMAKE_C_FLAGS_FLEXSPI_NOR_DEBUG " \
        	${CMAKE_C_FLAGS_FLEXSPI_NOR_DEBUG} \
        	-DXIP_EXTERNAL_FLASH=1 \
        	-DXIP_BOOT_HEADER_ENABLE=1 \
        	-DXIP_BOOT_HEADER_DCD_ENABLE=1 \
        	-DDEBUG \
        	...
    5. Disable caching by adding the following function in hello_world.c:
      void SystemInitHook() {
      	SCB_DisableICache();
      }
    6. Program the project into flash.
  2. Debug the actual project from SDRAM.

    1. As an example, we will import another hello_world project.
    2. Switch to the SDRAM build configuration. In this case, it is named sdram_txt_debug. Note that for this board, the sdram_debug configuration does not place the text section in SDRAM.
    3. Disable caching for this project as well.
      1. Remove BOARD_ConfigMPU() from main().
      2. Disable caching in the SystemInitHook():
        void SystemInitHook() {
        	SCB_DisableICache();
        }
    4. Debug the project using a LinkServer probe.
⚠️ **GitHub.com Fallback** ⚠️