# SDRAM Examples on RT1060 and MCUXpresso SDK 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. When such files are located in project's root folder, the extension will ask if you want to use one of the scripts. Your choice will be saved in the debug configuration. To set the jlink script manually, you can set it in `launch.json`, using the `gdbServerConfigs/segger/scriptfile` property: ```json { "configurations": [ { ... "gdbServerConfigs": { ... "segger": { ... "scriptfile": ``` 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. 4. Debug the project using a Segger probe. 1. The extension will detect the jlink script files located in the project root and show a quick pick. 2. Select `evkcmimxrt1060_sdram_init.jlinkscript`. Note that your choice is stored in the `launch.json` and the quick pick will not appear again. 3. Debugging should start as usual, with the target stopped at `main()`. ## 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//dcd.c`. ![DCD location](pictures/nxp-sdram-dcd.png) 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](pictures/nxp-sdram-systeminit.png) - 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. ```cmake 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](#caching) by adding the following function in `hello_world.c`: ```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()`: ```c void SystemInitHook() { SCB_DisableICache(); } ``` 4. Debug the project using a LinkServer probe.