i.MX RT Crossover MCUs Knowledge Base

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX RT Crossover MCUs Knowledge Base

Discussions

Sort by:
Introduction  This document is an extension of section 3.1.3, “Software implementation” from the application note AN12077, using the i.MX RT FlexRAM. It's important that before continue reading this document, you read this application note carefully.  Link to the application note.  Section 3.1.3 of the application note explains how to reallocate the FlexRAM through software within the startup code of your application. This document will go into further detail on all the implications of making these modifications and what is the best way to do it.  Prerequisites RT10xx-EVK  The latest SDK which you can download from the following link: Welcome | MCUXpresso SDK Builder MCUXpresso IDE Internal SRAM  The amount of internal SRAM varies depending on the RT. In some cases, not all the internal SRAM can be reallocated with the FlexRAM.  RT  Internal SRAM FlexRAM RT1010 Up to 128 KB Up to 128 KB RT1015 Up to 128 KB Up to 128 KB RT1020 Up to 256 KB Up to 256 KB RT1050 Up to 512 KB Up to 512 KB RT1060 Up to 1MB  Up to 512 KB RT1064 Up to 1MB Up to 512 KB   In the case of the RT106x, only 512 KB out of the 1MB of internal SRAM can be reallocated through the FlexRAM as DTCM, ITCM, and OCRAM. The remaining 512 KB are from OCRAM and cannot be reallocated. For all the other RT10xx you can reallocate the whole internal SRAM either as DTCM, ITCM, and OCRAM. Section 3.1.3.1 of the application note explains the limitations of the size when reallocating the FlexRAM. One thing that's important to mention is that the ROM bootloader in all the RT10xx parts uses the OCRAM, hence you should keep some  OCRAM when reallocating the FlexRAM, this doesn't apply to the RT106x since you will always have the 512 KB of OCRAM that cannot be reallocated. To know more about how many OCRAM each RT family needs please refer to section 2.1.1.1 of the application note. Implementation in MCUXpresso IDE First, you need to import any of the SDK examples into your MCUXpresso IDE workspace. In my case, I imported the igpio_led_output example for the RT1050-EVKB. If you compile this project, you will see that the default configuration for the FlexRAM on the RT1050-EVKB is the following:  SRAM_DTC 128 KB SRAM_ITC 128 KB SRAM_OC 256 KB   Now we need to go to the Reset handler located in the file startup_mimxrt1052.c. Reallocating the FlexRAM has to be done before the FlexRAM is configured, this is why it's done inside the Reset Handler.  The registers that we need to modify to reallocate the FlexRAM are IOMUXC_GPR_GPR16, and IOMUXC_GPR_GPR17. So first we need to have in hand the addresses of these three registers. Register Address IOMUXC_GPR_GPR16 0x400AC040 IOMUXC_GPR_GPR17 0x400AC044   Now, we need to determine how we want to reallocate the FlexRAM to see the value that we need to load into register IOMUXC_GPR_GPR17. In my case, I want to have the following configuration:  SRAM_DTC 256 KB SRAM_ITC 128 KB SRAM_OC 128 KB   When choosing the new sizes of the FlexRAM be sure that you choose a configuration that you can also apply through the FlexRAM fuses, I will explain the reason for this later. The configurations that you can achieve through the fuses are shown in the Fusemap chapter of the reference manual in the table named "Fusemap Descriptions", the fuse name is "Default_FlexRAM_Part".  Based on the following explanation of the IOMUXC_GPR_GPR17 register: The value that I need to load to the register is 0xAAAAFF55. Where the first  4 banks correspond to the 128KB of SRAM_OC, the next 4 banks correspond to the 128KB of SRAM_ITC and the last 8 banks are the 256KB of SRAM_DTC.  Now, that we have all the addresses and the values that we need we can start writing the code in the Reset handler. The first thing to do is load the new value into the register IOMUXC_GPR_GPR17. After, we need to configure register IOMUXC_GPR_GPR16 to specify that the FlexRAM bank configuration should be taken from register IOMUXC_GPR_GPR17 instead of the fuses. Then if in your new configuration of the FlexRAM either the SRAM_DTC or SRAM_ITC are of size 0, you need to disable these memories in the register IOMUXC_GPR_GPR16. At the end your code should look like the following:    void ResetISR(void) { // Disable interrupts __asm volatile ("cpsid i"); /* Reallocating the FlexRAM */ __asm (".syntax unified\n" "LDR R0, =0x400ac044\n"//Address of register IOMUXC_GPR_GPR17 "LDR R1, =0xaaaaff55\n"//FlexRAM configuration DTC = 265KB, ITC = 128KB, OC = 128KB "STR R1,[R0]\n" "LDR R0,=0x400ac040\n"//Address of register IOMUXC_GPR_GPR16 "LDR R1,[R0]\n" "ORR R1,R1,#4\n"//The 4 corresponds to setting the FLEXRAM_BANK_CFG_SEL bit in register IOMUXC_GPR_GPR16 "STR R1,[R0]\n" #ifdef FLEXRAM_ITCM_ZERO_SIZE "LDR R0,=0x400ac040\n"//Address of register IOMUXC_GPR_GPR16 "LDR R1,[R0]\n" "AND R1,R1,#0xfffffffe\n"//Disabling SRAM_ITC in register IOMUXC_GPR_GPR16 "STR R1,[R0]\n" #endif #ifdef FLEXRAM_DTCM_ZERO_SIZE "LDR R0,=0x400ac040\n"//Address of register IOMUXC_GPR_GPR16 "LDR R1,[R0]\n" "AND R1,R1,#0xfffffffd\n"//Disabling SRAM_DTC in register IOMUXC_GPR_GPR16 "STR R1,[R0]\n" #endif ".syntax divided\n"); #if defined (__USE_CMSIS) // If __USE_CMSIS defined, then call CMSIS SystemInit code SystemInit(); ...‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   If you compile your project you will see the memory distribution that appears on the console is still the default configuration.  This is because we did modify the Reset handler to reallocate the FlexRAM but we haven't modified the linker file to match these new sizes. To do this you need to go to the properties of your project. Once in the properties, you need to go to C/C++ Build -> MCU settings. Once you are in the MCU settings you need to modify the sizes of the SRAM memories to match the new configuration.  When you make these changes click Apply and Close. After making these changes if you compile the project you will see the memory distribution that appears in the console is now matching the new sizes.  Now we need to modify the Memory Protection Unit (MPU) to match these new sizes of the memories. To do this you need to go to the function BOARD_ConfigMPU inside the file board.c. Inside this function, you need to locate regions 5, 6, and 7 which correspond to SRAM_ITC, SRAM_DTC, and SRAM_OC respectively. Same as for register IOMUXC_GPR_GPR14, if the new size of your memory is not 32, 64, 128, 256, or 512 you need to choose the next greater number. Your configuration should look like the following:    /* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(5, 0x00000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB); /* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(6, 0x20000000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB); /* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */ MPU->RBAR = ARM_MPU_RBAR(7, 0x20200000U); MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍   We need to change the image entry address to the Reset handler. To do this, you need to go to the file fsl_flexspi_nor_boot.c inside the xip folder. You need to declare the ResetISR and change the entry address in the image vector table.  Finally, we need to place the stack at the start of the DTCM memory. To do this, we need to go to the properties of your project. From there, we have to C/C++ Build and Manage Linker Script.  From there, we will need to add two more assembly instructions in our ResetISR function. We have to add these two instructions at the beginning of our assembly code:  In the attached c file, you'll find all the assembly instructions mentioned above.  That's it, these are all the changes that you need to make to reallocate the FlexRAM during the startup.  Debug Session  To verify that all the modifications that we just did were correct we will launch the debug session. As soon as we reach the main, before running the application, we will go to the peripheral view to see registers IOMUXC_GPR_GPR16, and IOMUXC_GPR_GPR17 and verify that the values are the correct ones. In register IOMUXC_GPR_GPR16 as shown in the image below we configure the FLEXRAM_BANK_CFG_SEL as 1 to use the use register IOMUXC_GPR_GPR17 to configure the FlexRAM.  Finally, in register IOMUXC_GPR_GPR17 we can see the value 0xAAAAFF55 that corresponds to the new configuration.  Reallocating the FlexRAM through the Fuses  We just saw how to reallocate the FlexRAM through software by writing some code in the Reset Handler. This procedure works fine, however, it's recommended that you use this approach to test the different sizes that you can configure but once you find the correct configuration for your application we highly recommend that you configure these new sizes through the fuses instead of using the register IOMUXC_GPR_GPR17. There are lots of dangerous areas in reconfiguring the FlexRAM in code. It pretty much all boils down to the fact that any code/data/stack information written to the RAM can end up changing location during the reallocation.  This is the reason why once you find the correct configuration, you should apply it through the fuses. If you use the fuses to configure the FlexRAM, then you don't have the same concerns about moving around code and data, as the fuse settings are applied as a hardware default.  Keep in mind that once you burn the fuses there's no way back! This is why it's important that you first try the configuration through the software method. Once you burn the fuses you won't need to modify the Reset handler, you only need to modify the MPU to change the size of regions as we saw before and the MCU settings of your project to match the new memory sizes that you configured through the fuses.  The fuse in charge of the FlexRAM configuration is Default_FlexRAM_Part, the address of this fuse is 0x6D0[15:13]. You can find more information about this fuse and the different configurations in the Fusemap chapter of the reference manual.  To burn the fuses I recommend using either the blhost or the MCUBootUtility.  Link to download the blhost.  Link to the MCUBootUtility webpage.    I hope you find this document helpful!  Víctor Jiménez 
View full article
Testing Boot times – Generating a bootable image Bootable Image Structure: The bootable image consists of: FlexSPI Configuration Block (FCB) Image Vector Table (IVT) Boot Data Device Configuration Data (DCD) Program image CSF, Certificates, and signatures (this stuff is optional and only comes with high-assurance boot I’ll briefly explain each below: FlexSPI Configuration Block (FCB) The FCB will configure the settings of the FlexSPI communication. It will establish how many ports will be used, what clock speed to run the FlexSPI controller at, etc. This is the first thing that happens, as everything else is stored in Flash memory. In order to read anything else, the flash must first be configured.  Image Vector Table (IVT)  The IVT is a table that tells the memory the addresses of where everything is stored. Boot Data The Boot Data contains pointers to the start address of the Memory. Device Configuration Data (DCD) The DCD contains configuration data to configure any peripherals. Program image The program image contains the code you write to go into the application. CSF, Certificates, and signatures These things are optional. They come with high-assurance boot sequence and will not be covered in this writeup. Below is a rough table outlining these different parts of the boot image: Bootable Image generation software / tools: MCUXpresso – download the MCUXpresso IDE Flash Loader – download from RT1050 page > software and tools > flashloader This entire folder will include the MFGTool, elftosb tool, and more documentation. DCD.bin file: I found mine included in this document: https://community.nxp.com/docs/DOC-340655 Bootable Image Generation Overview MCUXpresso can generate bootable images for Hyperflash and QSPI XiP, but if trying to boot and execute in place of SDRAM or intern SRAM, or from your own memory module, then you must generate a bootable image by through a combination of generating an s record or elf image on MCUXpresso, and then using the flashloader tool suite (elftosb and mfgtool) to create a bootable image and then a bootable program to upload to the board. The entire general process is described below. In subsequent sections, a more detailed step-by-step guide is provided for Hyperflash XiP, SDRAM, and SRAM, each. MCUXpresso Configurations and output: Begin with your application code in MCUXpresso. Change memory allocation in the memory configuration editor of the MCU Settings part of MCUXpresso according to where you would like to boot from. If applicable, be sure to specify in the preprocessor settings if you would like to enable the dcd in the boot image. Generate an s-record (.s19) file from MCUXpresso using binary utilities. Elftosb tool – .bin file generation You can find this tool in the flashloader. Call an imx command to it which will take as input the s-record file containing the program image, a dcd.bin file (may or may not be in the s-record), a FCB?, and a bd_file (given to you, specific to your memory configuration). The elftosb tool will generate as an output a .bin file. Elftosb tool – Bootable image generation Then call the elftosb tool again with a kinetis command. This will take the .bin file and convert it to a boot_image.sb file. MFG tool Then we can use the mfg tool to generate the program image for the board, and upload it. In order to do this, the board SW7 must be set to OFF-ON-OFF-ON, and switch the jumper from J1  (5-6) to J1 (3-4). Connect the USB cable to J9 to power the board. Then connect the board to your computer and run the Mfg tool. Click start and the image will be uploaded.      After this the bootable image will be uploaded to the board and you’ll be good to go! Remember to switch the pin headers back, so the board can boot normally. J1 (5-6) and SW7 to OFF-ON -ON -OFF to boot from Hyperflash. Now in the following sections I’ll break down specific examples of what to do depending on the specific memory location you’d like to boot from. Bootable Image Generation – XiP Hyperflash Please note that this can also be done in MCUXpresso, but In order to use my own dcd file, I did this project using the traditional flashloader tools.   MCUXpresso Configurations and output: Begin by changing memory allocation in the memory configuration editor (edit project settings >> C/C++ Build >> MCU settings >>edit. It should look like the one below. Then go to C/C++ Build >>settings > MCU C compiler > preprocessor and set the XIP_boot_header enable and and XIP_boot_header_DCD_enable both to 0 if you have a dcd.bin file to use. Otherwise set these fields to 1. Hit apply and close. Go to the debug portion and click on binary utilities, then generate an s-record (.s19) file from MCUXpresso.  Click build to re-build the project. Copy this .s19 file. Elftosb tool – .bin file generation In the flashloader tool, go to Tools > elftosb > Win, and drop the .s19 file in this folder, as well as the dcd.bin file. Fire up command prompt in administrator mode, and use command cd [elftosb directory] to get to this folder To generate the .bin file, call the command:   elftosb.exe -f imx -V -c ../../bd_file/imx10xx/imx-flexspinor-normal-unsigned-dcd.bd -o ivt_flexspi_nor_led_blinky.bin HYPERFLASH_led_blinky.s19   This command essentially uses the imx-flexspinor bd linker file to generate a .bin file that will include the dcd.bin header inside. Note that HYPERFLASH_led_blinky.s19 should be renamed to your actual file name acquired from MCUXpresso   Elftosb tool – Bootable image generation Then we must generate the boot_image.sb Then call the elftosb tool again with a kinetis command. This will take the .bin file and convert it to a boot_image.sb file. The command is:   elftosb.exe -f kinetis -V -c ../../bd_file/imx10xx/program_flexspinor_image_hyperflash.bd -o boot_image.sb ivt_flexspi_nor_led_blinky_nopadding.bin   Note: The output of the first imx command we made must match the input of this one (ivt_flexspi_nor_led_blinky_nopadding.bin). Also, the output must remain named boot_image.sb, otherwise it will not work. MFG tool Then we can use the mfg tool to generate the program image for the board, and upload it. In order to do this, the board SW7 must be set to OFF-ON-OFF-ON, and switch the jumper from J1  (5-6) to J1 (3-4). Connect the USB cable to J9 to power the board. Then connect the board to your computer and run the Mfg tool. Click start and the image will be uploaded.        Copy the boot_image.sb file that we created in the last step. Move it to the directory Tools > mfgtools-rel > Profiles > MXRT105X > OS Firmware, and drop it in here. Next, set SW7 on the board to OFF-ON-OFF-ON, and switch the jumper at the bottom to power the board. Then connect the USB cable to J9. This will allow you to program the board. Go back to the folder mfgtools-rel and Open the Mfg Tool. It should say HID- compliant vendor-defined device. Otherwise double check SW7 and the power pin at the bottom right.   Click start and if successful it should look like: Please note that this success only means that it was able to upload the bootable image to the board. This usually works well. However, if you find later that the board doesn’t do what it’s supposed to, then there might be a problem in the other steps of the processor. Check to make sure you used the right linker file, and that the settings in MCUXpresso are configured correctly. Press stop and exit Remember to switch the pin headers back, so the board can boot normally. J1 (5-6) and SW7 to OFF-ON -ON -OFF to boot from Hyperflash.   Bootable Image Generation – SDRAM The guide is based off this link: https://community.nxp.com/docs/DOC-340655 . Download the files provided there, and unzip. Everything is good except the first step of that pdf document is a little unclear. MCUXpresso Configurations and output: Begin by changing memory allocation in the memory configuration editor of the MCU Settings part of MCUXpresso. It should look like the one below. Then go to settings > MCU C compiler > preprocessor and set the XIP_boot_header enable and and XIP_boot_header_DCD_enable both to 0 Hit apply and close. Go to C/C++ Build >> Settings >> MCU Linker >> Manage linker script, and check the box Link application to RAM. Go to the debug portion and click on binary utilities, then generate an s-record (.s19) file from MCUXpresso.  Click build to re-build the project. You can check the console to verify the correct allocations of memory: Copy this .s19 file. Elftosb tool – .bin file generation In the flashloader tool, go to Tools > elftosb > Win, and drop the .s19 file in this folder, as well as the dcd.bin file. There’s another step for booting from SDRAM. Take the file imx-sdram-normal-unsigned-dcd.bd (included in the link posted) and drag it into Tools > bd_file > imx10xx Fire up command prompt in administrator mode, and use command cd [elftosb directory] to get to this folder To generate the .bin file, call the command:   elftosb.exe -f imx -V -c ../../bd_file/imx10xx/imx-sdram-normal-unsigned-dcd.bd -o evkbimxrt1050_led_blinky.bin SDRAM1_led_blinky.s19   This command essentially uses the imx-flexspinor bd linker file to generate a .bin file that will include the dcd.bin header inside. Note that HYPERFLASH_led_blinky.s19 should be renamed to your actual file name acquired from MCUXpresso   Elftosb tool – Bootable image generation Then we must generate the boot_image.sb Then call the elftosb tool again with a kinetis command. This will take the .bin file and convert it to a boot_image.sb file. The command is:   elftosb.exe -f kinetis -V -c ../../bd_file/imx10xx/program_flexspinor_image_hyperflash.bd -o boot_image.sb evkbimxrt1050_led_blinky_nopadding.bin   The output of the first imx command we made must match the input of this one. Also, the output must remain named boot_image.sb, otherwise it will not work. Also note that this says flexspinor image hyperflash, but that is correct since we are still technically needing to boot from Hyperflash initially before we copy everything over to SDRAM. Copy the boot_image.sb file. MFG tool Then we can use the mfg tool to generate the program image for the board, and upload it. In order to do this, the board SW7 must be set to OFF-ON-OFF-ON, and switch the jumper from J1  (5-6) to J1 (3-4). Connect the USB cable to J9 to power the board. Then connect the board to your computer and run the Mfg tool. Click start and the image will be uploaded.        Copy the boot_image.sb file that we created in the last step. Move it to the directory Tools > mfgtools-rel > Profiles > MXRT105X > OS Firmware, and drop it in here. Next, set SW7 on the board to OFF-ON-OFF-ON, and switch the jumper at the bottom to power the board. Then connect the USB cable to J9. This will allow you to program the board. Go back to the folder mfgtools-rel and Open the Mfg Tool. It should say HID- compliant vendor-defined device. Otherwise double check SW7 and the power pin at the bottom right.   Click start and if successful it should look like: Please note that this success only means that it was able to upload the bootable image to the board. This usually works well. However, if you find later that the board doesn’t do what it’s supposed to, then there might be a problem in the other steps of the processor. Check to make sure you used the right linker file, and that the settings in MCUXpresso are configured correctly. Press stop and exit Remember to switch the pin headers back, so the board can boot normally. J1 (5-6) and SW7 to OFF-ON -ON -OFF to boot from Hyperflash.   Bootable Image Generation – SRAM This one was a little trickier as there was no appnote, but not too bad. MCUXpresso Configurations and output: Begin by changing memory allocation in the memory configuration editor of the MCU Settings part of MCUXpresso. It should look like the one below. We are linking to copy everything to dtc RAM Then go to settings > MCU C compiler > preprocessor and set the XIP_boot_header enable and and XIP_boot_header_DCD_enable both to 0 Hit apply and close. Go to C/C++ Build >> Settings >> MCU Linker >> Manage linker script, and check the box Link application to RAM.   Go to the debug portion and click on binary utilities, then generate an s-record (.s19) file from MCUXpresso.  Click build to re-build the project. You can verify that application is linked to SRAM in the console: Copy this .s19 file. Elftosb tool – .bin file generation In the flashloader tool, go to Tools > elftosb > Win, and drop the .s19 file in this folder, as well as the dcd.bin file Fire up command prompt in administrator mode, and use command cd [elftosb directory] to get to this folder This step is specific to dtcm ram: Go to Tools >>bd_file >> imx10xx, and open up the imx-dtcm-unsigned-dcd.bd file and change the ivtOffset address to 0x1000. 0x400 is the default for SDCARD booting. To be clear, the bd file should look as below: To generate the .bin file, call the command:   elftosb.exe -f imx -V -c ../../bd_file/imx10xx/imx-dtcm-unsigned-dcd.bd -o evkbimxrt1050_led_blinky.bin SRAM1_led_blinky.s19   This command essentially uses the imx-flexspinor bd linker file to generate a .bin file that will include the dcd.bin header inside. Note that SRAM_led_blinky.s19 should be renamed to your actual file name acquired from MCUXpresso. Elftosb tool – Bootable image generation Then we must generate the boot_image.sb Then call the elftosb tool again with a kinetis command. This will take the .bin file and convert it to a boot_image.sb file. The command is:   elftosb.exe -f kinetis -V -c ../../bd_file/imx10xx/program_flexspinor_image_hyperflash.bd -o boot_image.sb evkbimxrt1050_led_blinky_nopadding.bin   The output of the first imx command we made must match the input of this one. Also, the output must remain named boot_image.sb, otherwise it will not work. Also note that this says flexspinor image hyperflash, but that is correct since we are still technically needing to boot from Hyperflash initially before we copy everything over to SDRAM. MFG tool Then we can use the mfg tool to generate the program image for the board, and upload it. In order to do this, the board SW7 must be set to OFF-ON-OFF-ON, and switch the jumper from J1  (5-6) to J1 (3-4). Connect the USB cable to J9 to power the board. Then connect the board to your computer and run the Mfg tool. Click start and the image will be uploaded.    Copy the boot_image.sb file that we created in the last step. Move it to the directory Tools > mfgtools-rel > Profiles > MXRT105X > OS Firmware, and drop it in here. Next, set SW7 on the board to OFF-ON-OFF-ON, and switch the jumper at the bottom to power the board. Then connect the USB cable to J9. This will allow you to program the board. Go back to the folder mfgtools-rel and Open the Mfg Tool. It should say HID- compliant vendor-defined device. Otherwise double check SW7 and the power pin at the bottom right.   Click start and if successful it should look like: Please note that this success only means that it was able to upload the bootable image to the board. This usually works well. However, if you find later that the board doesn’t do what it’s supposed to, then there might be a problem in the other steps of the processor. Check to make sure you used the right linker file, and that the settings in MCUXpresso are configured correctly. Press stop and exit Remember to switch the pin headers back, so the board can boot normally. J1 (5-6) and SW7 to OFF-ON -ON -OFF to boot from Hyperflash. Please note that this success only means that it was able to upload the bootable image to the board. This usually works well. However, if you find later that the board doesn’t do what it’s supposed to, then there might be a problem with the other steps of the processor. Check to make sure you used the right linker file, and that the settings in MCUXpresso are configured correctly. After this the bootable image will be uploaded to the board and you’ll be good to go!
View full article
The document will introduce how to configure LPSPI clock on I.MXRT1050. The purpose is to help IMXRT customers better understand the clock tree and configure LPSPI clock in SDK.    Customer can configure LPSPI clock according to the following steps: 1 Select Source according to the clock tree. 2   Set LPSPI_CKL_SEL according to the register CCM_CBCMR. 3 Enable LPSPIn clock according to the register CCM_CCGR1. 4 Set clock gate according to register CCM_ANALOG_PFD_480n[PFDn_CLKGATE]. 5 Set LPSPI_PODF according to register CCM_CBCMR. 6 Set TCR[PRESCALE] according to LPSPIx module. 7  Set CCR[SCKDIV] according to LPSPIx module. The customer can get the value LPSPI_CLK according to the above steps
View full article
The iMX RT1050 ROM will allow you to copy an application image from a serial NOR flash memory on the FlexSPI controller to SDRAM at boot time. If you want to run your application from SDRAM, then when debugging and developing your application you should use an initialization script for the debugger to setup the SDRAM so the application can be downloaded directly to the SDRAM for debugging. When you are ready to have your application boot without the debugger, then you'll need to use the RT flashloader tools to program the application to the flash and configure it to copy to the SDRAM. The attached document contains instructions on how to program a boot image to serial NOR flash (in this case the hyperflash that is on the EVK) that will be copied to the SDRAM at boot time.
View full article
Symptoms   Some of us may have experienced the issue that when we put the heap to DTCM, everything is OK. That’s the default settings for MCUXpresso SDK demos. But when we put the heap on cached memory like OCRAM or SDRAM, much of the middleware does not function correctly. This issue happens on USB stack, LwIP and SDcard. USB enumeration failed,  ethernet drop packets, the application no longer writes to SD card, system hanging indefinitely on uninitialized semaphores…   Diagnosis   To understanding this issue, we need to understand the i.MXRT L1 Cache. AN12042 describes the technology of the i.MXRT cache system.       The i.MXRT series implement a CPU core platform described in Figure1. The L1 I/D-Cache is embedded in the core platform. The data cache is 4-way set-associate and instruction cache is 2-way set-associate with cache line size of 32 bytes. It connects with the SIM_M7 bus fabric master port by AXI bus. The subsystem of internal/external memory like OCRAM(FlexRAM banks configured as OCRAM), FlexSPI (Serial NOR, NAND Flash and Hyper Flash/RAM etc) and SEMC(SDRAM, PNOR Flash, NAND Flash etc.) are connected to the bus fabric slave port. CPU core access the subsystem through this bus fabric by L1 cache. The ITCM/DTCM is accessed directly by CPU core, bypass the L1 cache.   OCRAM and SDRAM is cacheable by default.  The cache brings a great performance boost, but the user must pay attention to the cache maintenance for data coherency.  To avoid data coherency issue, the easiest way is to use non-cacheable buffers.  DTCM/ITCM is Tightly-Coupled Memories, core can access it directly (cache is not involved). That can explain why all SDK demos work correctly by default.   Solution   Put critical code and data into TCM, it is non-cacheable, which is the fastest way for CPU to access the code and data.  But forcing all global data into 128KB DTCM is constraining in many cases. Users can split a non-cache memory region from OCRAM or SDRAM, and put the buffers into this region by the linker of toolchain.   Next I will take evkmimxrt1060_host_msd_command_freertos demo for example to illustrate how to make USB HOST stack to run on OCRAM.  MCUxpresso IDE 11.2.1 is used for this demo.  1    Buffer definition  In USB stack, some important data structures are defined with macros USB_GLOBAL, USB_DMA_DATA_NONINIT_SUB, USB_DMA_DATA_INIT_SUB and USB_CONTROLLER_DATA; These structures are defined in the usb stack by default. We can see these structures in usb_device_ehci.c and usb_host_ehci.c (take usb host as an example).   In usb_device_ehci.c /* Apply for QH buffer, 2048-byte alignment */ USB_RAM_ADDRESS_ALIGNMENT(2048) USB_CONTROLLER_DATA static uint8_t qh_buffer[(USB_DEVICE_CONFIG_EHCI - 1) * 2048 +   2 * USB_DEVICE_CONFIG_ENDPOINTS * 2 * sizeof(usb_device_ehci_qh_struct_t)]; /* Apply for DTD buffer, 32-byte alignment */ USB_RAM_ADDRESS_ALIGNMENT(32) USB_CONTROLLER_DATA static usb_device_ehci_dtd_struct_t s_UsbDeviceEhciDtd[USB_DEVICE_CONFIG_EHCI]                                                                        [USB_DEVICE_CONFIG_EHCI_MAX_DTD];  In usb_host_ehci.c  /* EHCI controller driver instances. */ #if (USB_HOST_CONFIG_EHCI == 1U) USB_RAM_ADDRESS_ALIGNMENT(4096) USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4]; static uint8_t usbHostEhciFramListStatus[1] = {0};   USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1; #elif (USB_HOST_CONFIG_EHCI == 2U) USB_RAM_ADDRESS_ALIGNMENT(4096) USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList1[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4]; USB_RAM_ADDRESS_ALIGNMENT(4096) USB_CONTROLLER_DATA static uint8_t s_UsbHostEhciFrameList2[USB_HOST_CONFIG_EHCI_FRAME_LIST_SIZE * 4]; static uint8_t usbHostEhciFramListStatus[2] = {0, 0}; USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData1; USB_RAM_ADDRESS_ALIGNMENT(64) USB_CONTROLLER_DATA static usb_host_ehci_data_t s_UsbHostEhciData2; #else #error "Please increase the instance count." #endif     2    Linker file : partition a RAM block from OCRAM for non-cacheable buffers         Using managed linker script to configure memory RAM2 as a non-cacheable area.   3    MPU configuratins   ( board.c )  MPU divides the memory map into a few regions, and defines the memory attributes of each region. In this step, we need to configure the SRAM_OC_NCACHE_128(RAM2) as non-cacheable      /* Region 13 setting: Memory with  non-cacheable */     MPU->RBAR = ARM_MPU_RBAR(13, 0x202a0000);     MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 1, 0, 0, 0, 0, ARM_MPU_REGION_SIZE_128KB);   Now, SRAM_OC_NCACHE_128 (RAM2) is a non-cacheable section. Variables in  *(NonCacheable.init) and  *( NonCacheable) will be put to SRAM_OC_NCACHE_128.   4   Put USB variables into SRAM_OC_NCACHE_128(RAM2)  This is done by the following macros.  #define USB_LINK_NONCACHE_NONINIT_DATA  _Pragma("location = \"NonCacheable\"")  Relative source code is in file usb_misc.h   #if (defined(DATA_SECTION_IS_CACHEABLE) && (DATA_SECTION_IS_CACHEABLE)) #define USB_GLOBAL USB_LINK_NONCACHE_NONINIT_DATA #define USB_BDT USB_LINK_NONCACHE_NONINIT_DATA #define USB_DMA_DATA_NONINIT_SUB USB_LINK_NONCACHE_NONINIT_DATA #define USB_DMA_DATA_INIT_SUB USB_LINK_DMA_INIT_DATA(NonCacheable.init) #define USB_CONTROLLER_DATA USB_LINK_NONCACHE_NONINIT_DATA #else #define USB_GLOBAL USB_LINK_USB_GLOBAL_BSS #define USB_BDT USB_LINK_USB_BDT_BSS #define USB_DMA_DATA_NONINIT_SUB #define USB_DMA_DATA_INIT_SUB #define USB_CONTROLLER_DATA #endif   Please put macro “DATA_SECTION_IS_CACHEABLE=1” in the preprocessor define.     5    build and run project  evkmimxrt1060_host_msd_command_freertos, success!  Reference: Using the i.MXRT L1 Cache https://www.nxp.com.cn/docs/en/application-note/AN12042.pdf             
View full article
1 Introduction   NXP-MCUBootUtility is a GUI tool specially designed for NXP MCU secure boot. Its features correspond to the BootROM function in NXP MCU. Currently, it mainly supports i.MXRT series MCU chips, Compared to NXP official security enablement toolset (OpenSSL, CST, sdphost, blhost, elftosb, BD, MfgTool2), NXP-MCUBootUtility is a real one-stop tool, a tool that includes all the features of NXP's official security enablement toolset, and what's more, it supports full graphical user interface operation. With NXP-MCUBootUtility, you can easily get started with NXP MCU secure boot.   The main features of NXP-MCUBootUtility include: Support i.MXRT1021, i.MXRT1051/1052, i.MXRT1061/1062, i.MXRT1064 SIP Support both UART and USB-HID serial downloader modes Support various user application image file formats (elf/axf/srec/hex/bin) Can validate the range and applicability of user application image Support for converting bare image into bootable image Support for loading bootable image into FlexSPI NOR and SEMC NAND boot devices Support for loading bootable image into LPSPI NOR/EEPROM recovery boot device Support DCD which can help load image to SDRAM Support HAB encryption (Signed only, Signed and Encrypted) Can back up certificate with time stamp Support BEE encryption (SNVS Key, User Keys) Support common eFuse memory operation (eFuse Programmer) Support common boot device memory operation (Flash Programmer) Support for reading back and marking bootable image(NFCB/DBBT/FDCB/EKIB/EPRDB/IVT/Boot Data/DCD/Image/CSF/DEK KeyBlob) from boot device   2 Download   NXP-MCUBootUtility is developed in Python, and it is open source. The development environment is Python 2.7.15 (32bit), wxPython 4.0.3, pySerial 3.4, pywinusb 0.4.2, bincopy 15.0.0, PyInstaller 3.3.1 (or higher). Source code: https://github.com/nxp-mcuxpresso/mcu-boot-utility Feedback: https://www.cnblogs.com/henjay724/p/10159925.html   NXP-MCUBootUtility is packaged by PyInstaller, all Python dependencies have been packaged into an executable file (\NXP-MCUBootUtility\bin\NXP-MCUBootUtility.exe), so if you do not want to develop NXP-MCUBootUtility for new feature, there is no need to install any Python software or related libraries. Note1: Before using NXP-MCUBootUtility, you need to download HAB Code Signing Tool from NXP website,upzip it and put it in the \NXP-MCUBootUtility\tools\cst\ directory, then modify the code to enable AES function and rebuild \NXP-MCUBootUtility\tools\cst\mingw32\bin\cst.exe, or HAB related encryption function can not be used properly。See more details in 《The step-by-step guide to rebuild cst.exe for HAB encryption》 Note2: Before using NXP-MCUBootUtility, you need to rebuild the source in \NXP-MCUBootUtility\tools\image_enc\code directory to generate image_enc.exe and put it in \NXP-MCUBootUtility\tools\image_enc\win directory, or BEE related encryption function can not be used properly。See more details in 《The step-by-step guide to build image_enc.exe for BEE encryption》   3 Installation   NXP-MCUBootUtility is a pure green free installation tool. After downloading the source code package, double-click "\NXP-MCUBootUtility\bin\NXP-MCUBootUtility.exe" to use it. No additional software is required.   Before the NXP-MCUBootUtility.exe graphical interface is displayed, a console window will pop up first. The console will work along with the NXP-MCUBootUtility.exe graphical interface. The console is mainly for the purpose of showing error information of NXP-MCUBootUtility.exe. At present, NXP-MCUBootUtility is still in development stage, and the console will be removed when the NXP-MCUBootUtility is fully validated.   4 Interface   The following figure shows the main interface of the NXP-MCUBootUtility tool. The interface consists of six parts.
View full article
Introduction The RT1064 is the only Crossover MCU from the RT family that comes with an on-chip flash, it has a 4MB Winbond W25Q32JV memory. It's important to remark that it's not an internal memory but an on-chip flash connected to the RT1064 through the FlexSPI2 interface. Having this flash eliminates the need of an external memory. Although the intended use of the on-chip flash is to store your application and do XiP, there might be cases where you would like to use some space of this memory as NVM. This document will explain how to modify one of the SDK example projects to achieve this.  Prerequisites RT1064-EVK  The latest SDK which you can download from the following link: Welcome | MCUXpresso SDK Builder. In this document, I will use MCUXpresso IDE but you can use the IDE of your preference. The modifications that you need to make are the same despite the IDE that you are using.  Importing the SDK example  The RT1064-EVK comes with two external flash memories, 512 Mb Hyper Flash and 64 Mb QSPI Flash. The RT1064-SDK includes two example projects that demonstrate how to use any of these two external flash memories as NVM. In this document, we will take as a base one of these examples to modify it to use the on-chip flash as NVM. Once you downloaded and imported the SDK into MCUXpresso IDE, you will need to import the example flexspi_nor_polling_transfer into your workspace.    Modifying the SDK example The external NOR Flash memory of the EVK is connected to the RT1064 through the FlexSPI1 interface. Due to this, the example project that we just imported initializes the FlexSPI1 interface pins. In our case, we want to use the on-chip flash that is connected through the FlexSPI2 instance, since we will boot from this memory, the ROM bootloader will configure the pins of this FlexSPI interface. So, in the function BOARD_InitPins we can delete all the pins that were related to the FlexSPI1 interface. At the end your function should look like the following:  void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 is configured as LPUART1_TX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 is configured as LPUART1_RX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ /* Software Input On Field: Force input path of pad GPIO_SD_B1_11 */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_B0_12_LPUART1_TX, /* GPIO_AD_B0_12 PAD functional properties : */ 0x10B0u); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: R0/6 Speed Field: medium(100MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_B0_13_LPUART1_RX, /* GPIO_AD_B0_13 PAD functional properties : */ 0x10B0u); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: R0/6 Speed Field: medium(100MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ Function flexspi_nor_flash_init initializes the FlexSPI interface but in our case, the ROM bootloader already did this for us. So we need to make some modifications to this function as well. The only things that we will need from this function are to update the LUT and to do a software reset of the FlexSPI2 interface. At the end your function should look like the following:  void flexspi_nor_flash_init(FLEXSPI_Type *base) { /* Update LUT table. */ FLEXSPI_UpdateLUT(base, 0, customLUT, CUSTOM_LUT_LENGTH); /* Do software reset. */ FLEXSPI_SoftwareReset(base); } ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ Inside the file app.h, we need to change some macros since now we will use a different memory and a different FlexSPI interface. The following macros are the ones that you need to modify:  Macro Before After Observations EXAMPLE_FLEXPI FLEXSPI FLEXSPI2 On-chip flash is connected through FlexSPI2 interface  FLASH_SIZE 0x2000 0x200 The size of the on-chip flash is different from the external NOR flash  EXAMPLE_FLEXSPI_AMBA_BASE FlexSPI_AMBA_BASE FlexSPI2_AMBA_BASE On-chip flash is connected through FlexSPI2 interface  EXAMPLE_SECTOR 4 100 The size of the on-chip flash is less than the external NOR flash, hence we will decrease the sector size to avoid erasing our application  Everything else in this file remains the same.  Finally, there are two changes that we need to make in the customLUT. To understand these changes you need to analyze the datasheets of the memories. But in the end, the two modifications are the followings:  Erase sector command of the on-chip flash is 0x20 instead of 0xD7.  Exchange the FLEXSPI command index for NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD and NOR_CMD_LUT_SEQ_IDX_READ_NORMAL to align with XIP settings. At the end your customLUT should look like the following:  const uint32_t customLUT[CUSTOM_LUT_LENGTH] = { /* Fast read quad mode - SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x6B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04), /* Fast read mode - SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x0B, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST + 1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_1PAD, 0x08, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Normal read mode -SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x03, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_NORMAL + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Read extend parameters */ [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUS] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x81, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Write Enable */ [4 * NOR_CMD_LUT_SEQ_IDX_WRITEENABLE] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x06, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Erase Sector */ [4 * NOR_CMD_LUT_SEQ_IDX_ERASESECTOR] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x20, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), /* Page Program - single mode */ [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x02, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_SINGLE + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Page Program - quad mode */ [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x32, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_1PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_PAGEPROGRAM_QUAD + 1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_4PAD, 0x04, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Read ID */ [4 * NOR_CMD_LUT_SEQ_IDX_READID] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x9F, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Enable Quad mode */ [4 * NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x01, kFLEXSPI_Command_WRITE_SDR, kFLEXSPI_1PAD, 0x04), /* Enter QPI mode */ [4 * NOR_CMD_LUT_SEQ_IDX_ENTERQPI] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Exit QPI mode */ [4 * NOR_CMD_LUT_SEQ_IDX_EXITQPI] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_4PAD, 0xF5, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), /* Read status register */ [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x05, kFLEXSPI_Command_READ_SDR, kFLEXSPI_1PAD, 0x04), /* Erase whole chip */ [4 * NOR_CMD_LUT_SEQ_IDX_ERASECHIP] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xC7, kFLEXSPI_Command_STOP, kFLEXSPI_1PAD, 0), }; ‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ These are all the changes that you need to make to the flexspi_nor_polling_transfer to use the on-chip flash as NVM instead of the external NOR flash.  Important notes It's important to mention that you cannot write, erase or read the on-chip flash while making XiP from this memory. So, you need to reallocate all the instructions that read, write and erase the flash to the internal FlexRAM. Fortunately, the example that we use as a base (flexspi_nor_polling_transfer) already does this. This is accomplished thanks to the files located in the linkscritps folder. To learn more about how this works, please refer to section 17.15 of the MCUXpresso IDE User Guide.  Additional resources Datasheet of the on-chip memory (Winbond W25Q32JV).  MCUXpresso IDE User Guide.  I hope that you find this document useful!  Regards,  Victor 
View full article
Abstract It has been almost 6 years since the earliest RT1050 series was launched. There are already a lot of discussions and articles on how to configure FlexSPI to boot from SPI FLASH in the NXP community. But there are still so many questions about how to configure FlexSPI and how to start from Quad/Octal/Hyper SPI Flash. The difficulty of getting started with i.MX RT is the same for all embedded engineers around the world. Novice players often don't know where to start when they get chip and SDKs. Although the i.MX RT is claimed to be an MCU, unlike the vast majority of MCUs, it does not have its own built-in Flash, but requires Flash to be installed externally on FLEXSPI. The FLEXSPI interface is very flexible and can be used to plug in various serial Flash devices. Commonly used include four wire (QUAD), eight wire (Octal), and HyperFlash. Due to the different brands, capacity, connection, and bus of external flash devices, it is necessary to modify the configuration of the FLEXSPI interface to adapt to them. In addition, it is necessary to modify the download algorithm to adapt to various debug probes and IDEs. Faced with these difficulties, beginners need to explore for a long time and read a lot of materials to gradually understand. This clearly reduces the speed of project development, especially compared to the SoC with embedded FLASH. The purpose of this article is not to go through all the knowledge in detail, but to provide a complete process framework, so that newcomers can follow the map and complete it step by step, without having to search for information everywhere and spend a considerable amount of time in their minds piecing together puzzles.   The following diagram is the flowchart of the entire flash enablement process. In addition to the early hardware design, there are mainly two parts. One is the flash download algorithm for IDE; The second is the flash configuration header FCB in the application. Once these two are completed, one can officially enter the application development process of the project. As for flash encryption, multi-image startup, and so on, they are all very later matters and have nothing to do with this article. The serial numbers in the flowchart represent annotation and data index.     FLEXSPI can support various SPI bus from 1-bit to 8-bit. And through the FLEXSPI interface, bootROM can start application from NOR SPI Flash and NAND SPI Flash. But so far, most of the RT projects use NOR Flash. Because NOR Flash supports running directly on Flash (XIP), while NAND flash doesn’t. The program must be copied to RAM before it can run. The read and write speed of FLEXSPI is influenced by various factors, including but not limited to the type of Flash interface, maximum speed, interface width, cabling, cache, and so on. The application below is about the performance checking. https://www.nxp.com/docs/en/application-note/AN12437.pdf The FLEXSPI startup configuration is very flexible, but there are also limitations, and each RT devices are different. If it is not the default connection like EVK, it is still necessary to check RM. Besides RM, the article written by Jay Heng is very worth reading. Although they are in Chinese, the tables and figures in these articles are useful to reader. 恩智浦i.MX RTxxx系列MCU启动那些事(6.B)- FlexSPI NOR连接方式大全(RT600) 恩智浦i.MX RTxxx系列MCU启动那些事(6.B)- FlexSPI NOR连接方式大全(RT500) 恩智浦i.MX RT1xxx系列MCU启动那些事(11.B)- FlexSPI NOR连接方式大全(RT1015/1020/1050) 恩智浦i.MX RT1xxx系列MCU启动那些事(11.B)- FlexSPI NOR连接方式大全(RT1060/1064(SIP)) 恩智浦i.MX RT1xxx系列MCU启动那些事(11.B)- FlexSPI NOR连接方式大全(RT1010) 恩智浦i.MX RT1xxx系列MCU启动那些事(11.B)- FlexSPI NOR连接方式大全(RT1160/1170) It is important to note that if the speed of QUAD SPI exceeds 60M, FLEXSPI's DQS pin must be suspended. This has been mentioned in both RM and hardware design guide, but it is not very noticeable.   The way to tell the bootROM/flashloader how flash is connected is setting BOOT_CFG pin or burning eFUSE. Thus bootROM/flashloader can know where to read the FCB before the user program starts. FCB refers to Flash Configuration Block. The FCB position of each RT chip may vary. The FCB position in RT10xx is generally at the 0 address of Flash, while the FCB position in RT11xx and RTxxx is at 0x400. In short, the startup process is to first read eFUSE or BOOT_CFG pins by bootROM/flashloader to get where the flash is, then reads the configuration information of the Flash from the FCB using 30MHz single line SPI mode, and then configures the Flash. After that high-speed execution of user program in Flash is supported. BTW, bootROM and flashloader are different things. In RT10xx, bootROM connect with sdphost.exe to download flashloader to SRAM, and then flashloader connect wtih blhost.exe to do other works. This is called serial download mode. In RT1xxx and RTxxx, bootROM connect with blhost.exe directly. But flashloader is still needed.   To download the program to Flash for debugging and execution, you need to download flash algorithm first. The download algorithm for different flash devices are likely to be different.   RT1024 and RT1064 have already embedded a third-party flash die, so their algorithms are ready-made and already available in the demo in SDK. Additionally, they cannot be started from other external flash connected.   Multilink supports all RT series devices. You can read these two articles https://www.nxpic.org.cn/module/forum/thread-617191-1-1.html https://www.nxpic.org.cn/module/forum/thread-617508-1-1.html Sometimes there will be new algorithm or new device supported, please download from here: https://www.pemicro.com/arm/device_support/NXP_iMX/iMX/index.cfm   SFDP is a standard proposed by the JEDEC organization for serial interface flash, also known as JESD216. It provides a set of registers to represent the characteristics of flash. Flash algorithms can learn how to burn flash through this data. https://www.jedec.org/document_search?search_api_views_fulltext=JESD216   When using the MCUXpresso IDE, Segger Jlink's debugger only uses the flash download algorithm from its own installation package and does not accept the algorithm specified by the IDE. Keil and IAR can enable JLINK to use both the IDE's built-in download algorithm and the algorithm in the JLINK driver package. RT-UFL is a universal download algorithm designed by Jay Heng for JLINK. The supported devices include QSPI, Octal SPI, and HyperFlash. Even if a Flash does not support SFDP, it can still support it. It is really useful. And since this project is open source, users can also port its code to download algorithms for other debug probe. https://github.com/JayHeng/RT-UFL   In MCUXpresso, right-click on the project ->properties ->MCU Settings ->Memory with type flash to select driver. There are candidates like MIMXRT1170_QSPI_SFDP.cfx, or MIMXRT1060_SFDP_HYPERFLASH.cfx. As long as the flash used supports SFDP, you can give it a try.   If the above steps cannot find a suitable download algorithm, then you can only create one by yourself (of course, you can also search the community first, or ask to NXP support people via a ticket in NXP support. But most probability there isn’t). There are templates in the installation directory of MCUXpresso, which can be modified to fit your case. The modified parameters come from the test result of flexspi_nor_polling demo in SDK. MCUXpressoIDE_11.7.1_9221\ide\Examples\Flashdrivers\NXP\iMXRT   Keil also has templete, it is at Keil_v5\ARM\Flash\MiMXRT105x_ATXP032   This is for IAR. https://updates.iar.com/filestore/standard/001/001/123/arm/doc/FlashLoaderGuide.ENU.pdf   NXP officially recommends the Secure Provisioning Tool (SPT). In addition, the NXP-MCUBootUtility, which was born earlier, has almost the same functionality and is also constantly being updated. Secure Provisioning Tool: https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-secure-provisioning-tool:MCUXPRESSO-SECURE-PROVISIONING NXP-MCUBootUtility: https://github.com/JayHeng/NXP-MCUBootUtility   If SFDP is not supported, you can only use the FLEXSPI test program in the SDK package to explore the configuration parameters. Please refer to the NOR or the hyper project. SDK_2_13_0_EVK-MIMXRTxxxx\boards\evkmimxrtxxxx\driver_examples\flexspi\nor   If SFDP is supported, it would be easier to handle. I.MX RT's bootROM supports simplified configuration of flash. By input one or two word configuration words, the bootROM can automatically configure with flash. The meaning of configuration words can be found in the system boot chapter of RM.   Both SPT and MCUBootUtility configure FLEXSPI in this way. Users can select similar models in the menu and modify some parameters. These parameters will eventually become option0/option1 and be passed to the bootROM.     Click on the Test button in the figure above and pray it can pass. If it doesn't pass, modify the parameters and try again. Sometimes it's really can’t configure the flash by simplified way, so you can only use the "User FCB file" option and specify one for it.   Click the "Convert to FCB" button to export the binary file of FCB. This bin file can be used in the future to create complete images for download. There is also a great use here to reverse to flexspi_nor_config_t structure.   In RT1xxx SDK demo, it is flexspi_nor_config_t structure in \xip\evkmimxrt1xxx_flexspi_nor_configure.c. In RTxxx SDK demo, it is in \flash_config\flash_config.c. It will be compiled at allocate to FCB position. The content of this structure is similar to the configuration in flexspi_nor_polling project. Passing that project can also provide a complete reference for this structure. Completing this structure is the goal of this branch (see (3)). The binary file exported can be referred as this picture.   If you feel it is boring, the attachment fcbconverter.py is a python tool which can convert the .bin to flexspi_nor_config_t. After you finished this work, here is a good article which may guide you to the next step. It is because the LUT table generated here is very concise. Users can fill in a complete table as needed. https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/RT10xx-image-reserve-the-APP-FCB-methods/ta-p/1502894 QE bit is very important to Quad Flash. The point here is that if you use option0/option1 to configure flash, the bootROM or flashloader will automatically configure the QE bit. Since QE bits are nonvolatile, there is no need to worry about the QE bit of this board in the future. But if you don't plan to use option0/option1 to configure flash, you have to write this bit by yourself. You can use flexspi_nor_polling demo, which writes QE after initialization. If Octal FLASH is used, here is another article which can guide the entire process. https://community.nxp.com/t5/i-MX-RT-Knowledge-Base/RT1170-Octal-flash-enablement/ta-p/1498369 If a project initiated from FLEXSPI FLASH, it must include header information such as FCB and IVT. DCD is optional. Please refer to the system boot section of RM for specific content. The following AN explains it more clearly. https://www.nxp.com/docs/en/application-note/AN12108.pdf https://www.nxp.com/docs/en/application-note/AN12107.pdf   Conclusion: I.MX RT can support the vast majority of Quad Flash, Octal Flash, or HyperFlash on the market. Following this guide, FLASH problem will not hold you much time.  Finally, no matter what kind of difficulties you encounter, you can ask questions on NXP's community or create support ticket on the official website. NXP will have dedicated person to answer these questions.
View full article
The i.MXRT1060 provides tightly coupled GPIOs to be accessed with high frequency. RT1060 provides two sets of GPIOs registers to control pad output. GPIO1 to GPIO3 are general GPIOs, and GPIO6 to GPIO8 are tightly GPIOs, but they share the same pad, which means the gpio pin can select from GPIO1/2/3 or GPIO6/7/8. The registers IOMUXC_GPR_GPR26, IOMUXC_GPR_GPR27, and IOMUXC_GPR_GPR28 are for GPIO selection. To select the gpio pin between GPIO1/2/3 or GPIO6/7/8 you can use MCUXpresso Config Tools. For example, if you select pin G10 you can select either GPIOI_IO11 for normal GPIO or GPIO6_IO11 for fast GPIO.  I made an example based on the SDK v2.7.0 to compare the speed of Normal GPIO and Fast GPIO. For this, I used pin G10 (GPIOI_IO11 and GPIO6_IO11). Firstly, I used the normal GPIO pin (GPIOI_IO11). I will toggle the pin by writing directly to the GPIO_DR register. Notice that you can access this pin through J22 pin 3 in the evaluation board, so you can measure the performance of the pin. Here are the results: With the normal GPIO pin, we reach a period of 160ns when writing directly to the GPIO_DR register. Now, if we change to the fast GPIO and use the same instructions we have the following results. As you can see when using the fast GPIO pin, the period of the signal it's almost one-third of the period when using a normal GPIO. Now, The A1 silicon of the RT1060 has a new GPIO toggle feature. If we toggle the pin with the new register DR_TOGGLE instead of the GPIO_DR we will get better performance with both pins, normal GPIO and fast. Here are the results of the normal GPIO with the DR_TOGGLE register. As you can see when using the register DR_TOGGLE along with the normal GPIO pin we get a period of around 53 ns while when writing to the GPIO_DR register we got 160 ns. When using the register DR_TOGGLE and the fast GPIO we will get the best performance of the pin. Results are shown below. Many thanks to @jorge_a_vazquez for his valuable help with this document. Hope this helps! Best regards, Victor.
View full article
A small project I worked on was to understand how RT1050 boot-up performs from different memory types. I used the LED_blinky code from the SDK as a baseline, and ran some tests on the EVKB board. The data I gathered is described below, as well as more detailed testing procedures. Testing Procedure The boot-up time will be defined as the time from which the processor first receives power, to when it executes the first line of code from the main() function. Time was measured using an oscilloscope (Tektronix TDS 2014) between the rising edge of the POR_B* signal to the following two points: FlexSPI_CS asserted (first read of the FlexSPI by the ROM)** GPIO Toggle in application code (signals beginning of code execution).*** *The POR_B signal was available to scope through header J26-1 **The FlexSPI_CS signal is available through a small pull-up resistor on the board, R356. A small wire was soldered alongside this resistor, and was probed on the oscilloscope. ***The GPIO pin that was used was the same one that connected to USER_LED (Active low). This pin could be scoped through header J22-5. TP 2, 3, 4, and 5 are used to ground the probe of the oscilloscope. This was all done in the EVKB evaluation board. Here are a couple of noteworthy points about the test ran: This report mostly emphasizes the time between the rise of the POR_B signal, and the first line of execution of code. However, there is a time between when power is first provided to the board and the POR_B system goes up. This is a matter of power electronics and can vary depending on the user application and design. Because of this, this report will not place a huge emphasis on this. The first actual lines of code of the application is actually configuring several pins of the processor. Only after these pins are executed, does the GPIO toggle low and the time is taken on the oscilloscope. However, these lines of configuration code are executed so rapidly, that the time is ignored for the test.   Clock Configurations The bootable image was flashed to the RT1050 in all three cases. Afterwards, in MCUXpresso, the debugger was configured with “Attach Only” set to true. A debug session was then launched, and after the processor finished executing code, it was paused and the register values were read according to the RT1050 Reference Manual, chapter 18, CCM Block Diagram.  Boot Configuration: Core Clock (MHz) * FlexSPI Clock (MHz) SEMC Clock (MHz) FlexSPI 130 99 SDRAM 396 130 99 SRAM 396 130 99 *The Core Clock speed was also verified by configuring clko1 as an output with the clock speed divided by 8. This frequency was measured using an oscilloscope and verified to be 396 MHz. Results The time to chip select pin represents the moment when the first flash read happens from the RT1050 processor. The time to GPIO output represents the boot-up time.   As expected, XiP Hyperflash boots faster than other memories. SRAM and SDRAM memories must copy to executable memory before executing which will take more time and therefore boot slower. In the sections below, a more thorough explanation is provided of how these tests were ran and why Hyperflash XiP is expected to be the fastest. Hyperflash XiP Boot Up Below is an outline of the steps of what we expect the Hyperflash XiP boot-up process to look like: Power On Reset (J26-1) Begin access to Flash memory (FlexSPI_SS0) Execute in place in flash (XiP) First line of code is exectuted (USER_LED) In MCUXpresso, the map file showed the following: The oscilloscope image is below:   SDRAM Boot Up The processor will bootup from ROM, which will be told to copy an application image from the serial NOR flash memory to SDRAM (serial NOR flash uses Hyperflash communication). The RT flashloader tool will let me load up the application to the flash to be configured to copy over memory to the SDRAM and execute to it.   It is expected that copying to SDRAM will be slower than executing in place from Hyperflash since an entire copying action must take place.   The SDRAM boot-up process looks like the following: Power On Reset (J26-1) Begin access to Flash memory (FlexSPI_SS0) Copy code to SDRAM Execute in place in SDRAM (FlexSPI_SS0) First line of code is executed (USER_LED)   In MCUXpresso, the map file showed the following:   In order to run this test, I followed these instructions: https://community.nxp.com/docs/DOC-340655. SRAM Boot Up For SRAM, a similar process to that of SDRAM is expected. The processor will first boot from internal ROM, and then go to Hyperflash. It will then copy over everything from Hyperflash to internal SRAM DTC memory and then execute from there.  The SRAM Boot Up Process follows as such: Power On Reset (J26-1) Begin access to Flash memory (FlexSPI_SS0) Copy code to SRAM Execute in place in SRAM (FlexSPI_SS0) First line of code is executed (USER_LED)   In MCUXpresso, the map file showed the following:   This document was generated from the following discussion: javascript:;
View full article
1. Abstract     When the customer uses the NXP RT board to debug the code, sometimes, the board   suddenly meets debug connect issues when using the IDE and the debugger to download the code. Especially to the customer who is using the NXP RT EVK board with the onboard default CMSIS-DAP debugger. They even suspect the board is broken after trying a lot of times.     The debugger connects issues that normally happen when using the wrong FDCB, the download process is ended abnormally, the wrong flash loader, or the abnormal app code in the flash, .etc.     The reported issue result will be similar to the following pictures: Fig.1 Fig.2     The connect log maybe:       No connection to chip’s debug port       Error: Wire Ack Wait Fault     This document will give some methods to recover the board when meeting the debugger issues with the typical MIMXRT1060-EVK board +MCUXpresso IDE as the test platform. Other platform is also similar, the recovery method also can be used. 2. RT board recovery method     The main method is to change the RT board to the serial download mode, bring the core to a known state, then do the mass erase in IDE or with the MCUXpresso Secure Provisioning Tool(SPT).     First, let the board enter the serial download mode: Fig.3     Enter serial download mode:     1) SW7: 1-OFF,2-OFF,3-OFF,4-ON     2) Power off and power on again, or Press Reset button 2.1 IDE Mass Erase     MCUXpresso IDE, choose the related debugger interface, then choose “erase flash action”.     Here take the MIMXRT1060-EVK on board default debugger CMSIS DAP as an example: Fig.4 Fig.5    After this operation, when the Board is back to the internal boot again, the debugger can download to the flash again. 2.2 SPT Mass Erase     Customers also can use the NXP MCUXpresso Secure Provisioning Tool to do the code download or the mass erase in the serial download mode, this method also can recover the board, in fact, just let the core in the known status.     SPT tool download link: https://www.nxp.com/design/software/development-software/mcuxpresso-secure-provisioning-tool:MCUXPRESSO-SECURE-PROVISIONING     After installing the SPT tool, open it.     1) Create one RT1060 workspace Fig.6     2) Connect the board with USB or the UART     Here, take USB interface as an example. Fig.7 Fig. 8 Fig.9 Fig.10 Fig.11       Until now, the external flash is erased!     In the SPT, the customer also can double check the memory, especially whether the FDCB area is erased or not, just like in the following picture: Fig.12     The customer can go back to the internal boot mode and use the debugger to download the code again.       Internal boot mode:           SW7:1-OFF,2-OFF,3-ON,4-OFF      Press reset or power off and power on again to enter the internal boot mode, then use the debugger to test it again, this is the result: Fig.13     We can see, the MIMXRT1060-EVK debugger interface is recovered! 3. Conclusion     When the flash contains an app that is abnormal(access memory does not exist, memory is corrupted, misconfiguration of the clocks, etc.), it will cause the board to end up in an unknown state, then the debugger can’t take control over the core. But, when put the core in serial downloader mode, then it will put the core in a known state, this way, the debugger will be able to take control of the core.     So, when meeting the debugger issues in the RT board, try to mass erase the external flash in serial download mode, then it will recover the board debugger to a normal situation.
View full article
  RT1176 has two core. Normally, the CM7 core is the main core. When boot up, CM7 will boot up first. Then it will copy CM4’s image to RAM and kick off CM4 core. The details can be found in AN13264. In RT1176, CM4 has 128K ITCM and 128K DTCM. This space is not big. It is enough for CM4 to do some auxiliary work. But sometimes, customer need CM4 to do more. For example, the CM7 may run an ML algorithm and CM4 to deal with USB/ENET and camera. That need more code space than 128K. In this case, CM4 image should be moved to OCRAM1/2 or SDRAM. OCRAM and SDRAM are both connect to a NIC-301 AXI bus arbiter IP. They have similar performance and character. This article will try to use SDRAM because it is more difficult to move to. Before moving, customer should know an important thing. the R/W speed of CM4 accessing OCRAM/SDRAM is slow. Because the CM4 requests data from SDRAM through XB (LPSR domain - AHB protocol) and then through NIC (WAKEUPMIX domain AXI protocol) and the clock limitation is BUS / BUS_LPSR. If both code and data placed in SDRAM the performance will significantly be reduced. SDRAM is accessible only via SYSTEM bus (so, in such case no harward possible). If any other bus masters are accessing the same memory the performance is even more degraded due to arbitration (on XB or NIC). So, user should arrange the whole memory space very well to eliminate access conflict.   Prepare for the work 1.1 Test environment: • SDK: 2.9.1 for i.MX RT1170 • MCUXpresso: 11.4.0 Example: SDK_root\boards\evkmimxrt1170\multicore_examples\hello_world. Set hardware and software Set the board to XIP boot mode by setting SW1 to OFF OFF ON OFF. Import the hello_world example from SDK. Build the project.   Moving to SDRAM for debug option In CM7 project, add SDRAM space in properties->MCU settings->Memory detail   Then in properties->settings->Multicore, change the CM4 master memory region to SDRAM.   Unlike other IDE, MCUXpresso can wake up M4 project thread and download M4 image by IDE itself. it calls implicit. This field tell IDE where to place CM4 image. In properties->settings->Preprocessor, add XIP_BOOT_HEADER_DCD_ENABLE. This is to add DCD to image's head. DCD can be used to program the SDRAM controller for optimal settings, improving the boot performance. Next, switch to CM4 project. Add SDRAM space to memory table, just like what we do in CM7 project.     In properties-> Managed Linker Script, it’s better to announce Heap and stack space in DTCM. It also can be placed in SDRAM, but this should be careful. After that, we can start debugging. You can see that the SDRAM has been filled with CM4 image. Click Resume button, the CM4 project will stop at the beginning of the Main.   Moving to SDRAM for release option To compile the project in release mode, CORE1_IMAGE_COPY_TO_RAM should be added to Defined symbols table. But that is not enough. The CM7 project of SDK doesn’t copy the CM4 image. We must add this to CM7 project. 3.1 Create a new file named incbin.S. This is the code .section .core_m4slave , "ax" @progbits @preinit_array .global dsp_text_image_start .type dsp_text_image_start, %object .align 2 dsp_text_image_start: .incbin "evkmimxrt1170_hello_world_cm4.bin" .global dsp_text_image_end .type dsp_text_image_end, %object dsp_text_image_end: .global dsp_data_image_start .type dsp_data_image_start, %object .align 2 dsp_ncache_image_end: .global dsp_text_image_size .type dsp_text_image_size, %object .align 2 dsp_text_image_size: .int dsp_text_image_end - dsp_text_image_start 3.2 In hello_world_core0.c, add these code #ifdef CORE1_IMAGE_COPY_TO_RAM extern const char dsp_text_image_start[]; extern int dsp_text_image_size; #define CORE1_IMAGE_START ((uint32_t *)dsp_text_image_start) #define CORE1_IMAGE_SIZE ((int32_t)dsp_text_image_size) #endif 3.3 Right click the evkmimxrt1170_hello_world_cm4.axf in Project Explorer window, select Binary Utilities->Create Binary. A binary file called evkmimxrt1170_hello_world_cm4.bin will be created. Copy it to the release folder of CM7 project. If you want this work to be done automatically, you can add the command to properties->settings->Build stepes->Post-build steps   Compile the project and download. Press reset button. After a while, you will see a small led blinking. This led is driven by CM4. Debug the CM4 project on SDRAM only As we know that CM4 can debug alone without CM7 starting. But that is in ITCM and DTCM. Can it also work in SDRAM. Yes, but the original debug script file is not support this function. I attached a new script file. It can initialize SDRAM before downloading CM4 code. Replace the old .scp file with this one, nothing else need to be changed.
View full article
INTRODUCTION REQUIREMENTS INTEGRATION     1. INTRODUCTION   This document provides an step-by-step guide to migrate the webcam application explained on AN12103 "Developing a simple UVC device based on i.MX RT1050" to EVKB-MIMXRT1050. The goal is getting the application working on rev. B silicon, using the current SDK components (v2.4.2) and with MCUXpresso IDE (v10.2.1), because the original implementation from the application note is using rev. A silicon and is developed on IAR IDE.   2. REQUIREMENTS   A) Download and install MCUXpresso IDE v10.2.1. B) Build an MCUXpresso SDK v2.4.2 for EVKB-MIMXRT1050 from the "SDK Builder web page", ensuring that CSI and USB components are included, and MCUXpresso IDE is selected, and install it. For A) and B) steps, you could refer to the following Community document: https://community.nxp.com/docs/DOC-341985  C) Download the source code related to AN12103. D) Having the EVKB-MIMXRT1050 board, with MT9M1114 camera module. 3. INTEGRATION   a) Open MCUXpresso IDE, and click on "Import SDK example" shortcut, select the "evkbimxrt1050" board and click on "Next" button. b) Select the "driver_examples->csi->csi_rgb565" and "usb_examples->dev_video_virtual_camera_bm" examples, and click on "Finish" button. c) Copy the "fsl_csi.h", "fsl_csi.c", "fsl_lpi2c.h" and "fsl_lpi2c.c" files from the "drivers" folder of CSI project, to the "drivers" folder of the Virtual_Camera project. d) Copy the "pin_mux.h" and "pin_mux.c" files from the "board" folder of CSI project, to the "board->src" folder of the Virtual_Camera project, replacing the already included files. e) Copy the "camera" folder from AN12103 software package from the path below, to the Virtual_Camera project: <AN12103SW\boards\evkmimxrt1050\user_apps\uvc_demo\src\camera> Also copy the "main.c" file from AN12103 software package to the "sources" folder of the Virtual_Camera project. Ensure selecting the option "Copy files and folders" when copying folders/files. f) Right click on the recently added "camera" folder, and select "Properties". Then, on the "C/C++ Build" menu, remove the checkbox "Exclude resource from build" option, and then click on "Apply and Close" button. g) Right click on the Virtual_Camera project, and select "Properties". Then, select the "C/C++ Build -> Settings -> MCU C Compiler -> Preprocessor" menu, and click on the "+" button to add the following value: "SDK_I2C_BASED_COMPONENT_USED=1", and click on "OK" button. h) Now, move to the "Includes" menu of the same window, and click on the "+" button to add the following value: "../camera". Repeat the same procedure on "MCU Assembler -> General" menu, and then, click on "Apply and Close" button. i) Refer to "usb" folder from AN12103 software package from the path below, and copy "video_camera.h", "video_camera.c", "usb_device_descriptor.h" and "usb_device_descriptor.c" files to the "sources" folder of Virtual_Camera project, ensuring selecting the option "Copy files and folders" and overwriting the already included files: <AN12103SW\boards\evkmimxrt1050\user_apps\uvc_demo\src\usb> j) Select "video_data.h", "video_data.c", "virtual_camera.h" and "virtual_camera.c" files and "doc" folder, then right click and select "Delete". Click on "OK" button of the confirmation window to remove these resources from the Virtual_Camera project. k) Refer to "fsl_mt9m114.c" file from "camera" folder of Virtual_Camera project, and delete the "static" definition from functions "MT9M114_Init", "MT9M114_Deinit", "MT9M114_Start", "MT9M114_Stop", "MT9M114_Control" and "MT9M114_InitExt". l) Refer to "main.c" file from "sources" folder of Virtual_Camera project, and comment out the call to the function "BOARD_InitLPI2C1Pins". Also, refer to "board.c" file from "board->src" folder of Virtual_Camera project, and comment out the call to the function "SCB_EnableDCache". m) Refer to "camera_device.c" file from "camera" folder of Virtual_Camera project, and comment out the line "AT_NONCACHEABLE_SECTION_ALIGN(static uint16_t s_cameraFrameBuffer[CAMERA_FRAME_BUFFER_COUNT][CAMERA_VERTICAL_POINTS * CAMERA_HORIZONTAL_POINTS + 32u], FRAME_BUFFER_ALIGN);" and add the following line: static uint16_t __attribute__((section (".noinit.$BOARD_SDRAM"))) s_cameraFrameBuffer[CAMERA_FRAME_BUFFER_COUNT][CAMERA_VERTICAL_POINTS * CAMERA_HORIZONTAL_POINTS + 32u] __attribute__ ((aligned (FRAME_BUFFER_ALIGN))); n) Compile and download the application into the EVKB-MIMXRT1050 board. The memory usage is shown below: o) When running the application, if you also have the serial terminal connected, you should see the print message. Additionally, if connected to Windows OS, you could find it as "CSI Camera Device" under the "Imaging devices" category. p) Optionally, you could rename the Virtual_Camera project to any other desired name, with rigth click on Project, and selecting "Rename" option, and finally, click on "OK" button. It is also attached the migrated MCUXpresso IDE project including all the steps mentioned on the present document. Hope this will be useful for you. Best regards! Some additional references: https://community.nxp.com/thread/321587  Defining Variables at Absolute Addresses with gcc | MCU on Eclipse   
View full article
Introduction i.MX RT ROM bootloader provides a wealth of options to enable user programs to start in various ways. In some cases, people want to copy application image from Flash or other storage device to SDRAM and run there. In this article, I record three ways to realize this. Section 2 and 3 shows load image from NOR flash. Section 4 shows load image from SD card. Software and Tools: MCUXpresso IDE v11.1 NXP-MCUBootUtility 2.2.0   MIMXRT1060-EVK   RT1060 SDK v2.7.0   Win10   Add DCD by MCUxpresso IDE If customers use MCUXpresso to develop the project, they can add DCD head by MCUXpresso. To show the work flow, we take evkmimxrt1020_iled_blinky as the example. Step 1: Add the following to Compiler options: XIP_BOOT_HEADER_DCD_ENABLE=1 SKIP_SYSCLK_INIT Step 2: Modify the Memory Configuration Step 3: Select link application to RAM Step 4. Compile the project. MCUXpresso will generate linker script automatically. Step 5. Since the code should be linked to RAM, MCUXpresso will not prefix IVT and DCD. We can add these link information to linker script manually. Add below code to .ld file’s head.     .boot_hdr : ALIGN(4)     {         FILL(0xff)         __boot_hdr_start__ = ABSOLUTE(.) ;         KEEP(*(.boot_hdr.conf))         . = 0x1000 ;         KEEP(*(.boot_hdr.ivt))         . = 0x1020 ;         KEEP(*(.boot_hdr.boot_data))         . = 0x1030 ;         KEEP(*(.boot_hdr.dcd_data))         __boot_hdr_end__ = ABSOLUTE(.) ;         . = 0x2000 ;     } >BOARD_SDRAM   Then deselect “Manage linker script” in last screenshot. Step 6. Recompile the project, IVT/DCD/BOOT_DATA will be add to your project. Then right click the project axf file->Binary Utilities->Create S-record.   After all these step, you can open MCUBootUtility and download the .s19 file to NOR flash.   Add DCD by MCUBootUtility We can also keep the linker script managed by IDE. MCUBootUtility can add head too. Sometimes it is more flexible than other manners. Step 1. This time BOARD_SDRAM location should be changed to 0x80002000 while the size should be 0x1cff000. This is because the start 8k space in bootable image is saved for IVT and DCD. Step 2. compile the project and generate the .s19 file. Step 3. Open MCUBootUtility. In MCUBootUtility, we should first set the Device Configuration Data. Here I use MIMXRT1060_EVK. So I select the DCD bin file in NXP-MCUBootUtility-2.2.0\src\targets\MIMXRT1062. After that, select the application image file and click All-in-one Action button. MCUBootUtility can do all the work without any manual operation.   Boot from SD card to SDRAM In some application, customer don’t want XIP. They want to use SD card to keep application image and run the code in RAM. But if the code size is bigger than OCRAM size, they have to copy image into SDRAM when startup. With MCUBootUtility’s help, this work is very easy too.  User just need to change the memory map which is located to 0x80001000.   In MCUBootUtility, select the Boot Device to “uSDHC SD” and insert SD card. Then connect the target board. If RT1060 can read the SD card, it will display the SD card information. Then same as last section, set the DCD file and application image file. Click the All-in-One Action button, MCUBootUtility will generate the bootable image and write it to SD card.   SD card has huge capacity. It's too wasteful to only store boot image. People may ask that can they also create a FAT32 system and store more data file in it? Yes, but you need tool's help. When booting from SD card, ROM code read IVT and DCD from SD card address 0x400. To FAT32, the first 512 bytes in SD is for MBR(MAIN BOOT RECORD). Data in address 0x1c6 in MBR reords the partition start address. If the space from MBR to partition start address is big enough to store boot image, then FAT32 system and boot image can live in peace. .   Conclusions:      To help Boot ROM initialize SDRAM, DCD must be placed at right place and indexed by IVT correctly. When our code seems not work, we should first check IVT and DCD.          The IVT offset from the base address for each boot device type is defined in the table below. The location of the IVT is the only fixed requirement by the ROM. The remainder or the image memory map is flexible and is determined by the contents of the IVT.
View full article
INTRODUCTION REQUIREMENTS UTILITY USAGE INTEGRATION FUNCTIONAL DEMONSTRATION     1. INTRODUCTION   This document explains how to create an emWin application using as reference the emwin_temperature_control demo included on MCUXpresso SDK, and the emWin Utilities. The custom application for this example, is a Tic-Tac-Toe game, using the emWin GUI as user input, adding the proper logic for game implementation on the emWin generated code, and running on a MIMXRT1060-EVK board. 2. REQUIREMENTS   For the demonstration of this demo, the following material is required: MIMXRT1060-EVK board with the RK043FN02H-CT 4.3" LCD Panel. MCUXpresso IDE v11.0. MCUXpresso SDK v2.6.2 for EVK-MIMXRT1060, including the emWin middleware. Segger emWin 5.38b Libraries and Utilities. emWin 5.30 documentation. 3. UTILITY USAGE   For this demo, just GUIBuilder utility is used, and from this utility, just four widget elements are implemented on the application: Window, Text, Button and Image. At the beginning, one Window is added, configuring its xSize and ySize to 480 x 272, matching with screen's resolution. Over this Window, all the other elements are placed. Each Widget have proprieties that could be added/modified with the right click menu. The overall number of used widgets elements are the following: Three Text widgets, one for the title, other to indicate the next turn, and a third that is empty, because it will be dynamically updated to indicate the winner of the game (or indicating a Draw). Two Image widgets, on where BPM files are loaded and converted to constant arrays, to have the Cross/Circle icons indicating the current turn of the game. Ten Button widgets, one to reinitialize the game, and the other nine to build the 3x3 array used for the game. The complete application layout is shown on the following figure: Then, click on "File->Save" menu, and a file named "WindowDLG.c" file should be created on the same folder on where GUIBuilder utility is located. The "WindowDLG.c" file of this demo, as well as the BMP files for the cross/circle icons could be found on the attachments of this document. Additionally, you could also click on "File->Open" to open the downloaded "WindowDLG.c" file and modify it by your own. 4. INTEGRATION   1) First of all, it is required to import the "emwin_temperature_control" demo included on MCUXpresso SDK for MIMXRT1060-EVK board: Import SDK example(s) -> evkmimxrt1060 -> emwin_examples -> emwin_temperature_control 2) Just after importing the demo, by convenience we have renamed the project and the "source->emwin_temperature_control.c" to "evkmimxrt1060_emwin_tictactoe" and "emwin_tictactoe.c" (right click -> rename). After applying these changes, the demo should be able to be compiled and downloaded without errors and running without issues: 3) Then, open the "WindowDLG.c" file generated by the GUIBuilder and locate the "Defines" section. Copy all of them and replace the Definitions for Widgets IDs already included on the "emwin_tictactoe.c" file. 4) Also remove the "Some dimension defines" and "Colors" sections of the "emwin_tictactoe.c" file, and also the content of "Structures", "Static data". From the same file, also remove the sections for "_aGradient", "_GetSelectedRoom", "_SetFanButtonState", "_cbButton", "_cbButtonFan", "_cbKnob", "_DrawKnob", "_OnRelease". 5) Add the "_acImage_0" and "_acImage_1" arrays from the "WindowDLG.c" file to the "Static data" section of "emwin_tictactoe.c" file. 6) Replace all the elements from the "_aDialogCreate" array from the "emwin_tictactoe.c" with the ones from the "WindowDLG.c" file. 7) Add the function "_GetImageById" and replace the function "_cbDialog" from the "WindowDLG.c" file to the "emwin_tictactoe.c" file. 😎 Until here, the application should be compiled and downloaded without issues, although there is not included any functionality to perform the match. The downloaded layout is shown on the following image: 9) Now, for the implementation of the game itself, the following variables are added to the "Static data" section of "emwin_tictactoe.c" file. "player_turn" indicates who is the current player on move ("X" or "O"). "slots_free" is a counter to know how many remaining slots are free. "winner_player" stores who is the winner, or if the game is a Draw. "slot_status" array is in charge to store the current statusof each slot U8 i, player_turn=0, slots_free=9, winner_player=0; const U32 player_colors[] = {GUI_RED, GUI_BLUE}; enum {SLOT_FREE, SLOT_X, SLOT_O, SLOT_LOCK}; U8 slot_status[] = {SLOT_FREE, SLOT_FREE, SLOT_FREE,                               SLOT_FREE, SLOT_FREE, SLOT_FREE,                               SLOT_FREE, SLOT_FREE, SLOT_FREE}; 10) It was also implemented a function that checks all the possible Slot combinations to define the winner or if the match is a draw. It is the function "CheckWinner" and could be ckeched in the "emwin_tictactoe.c" file of the attachments, that already have all the required changes to have the Tic-Tac-Toe demo running. It is also required adding its function prototype to the "Prototypes" section of "emwin_tictactoe.c" file. 11) Basically, almost all of the game mechanics are defined by the "WM_NOTIFICATION_CLICKED" event of the 9x9 Buttons widgets, so, it is implemented inside the "_cbDialog" function. Below you could find the code for "ID_BUTTON_0"; the red highlights are what change for each Button event:     case ID_BUTTON_0: // Notifications sent by 'Button'       switch(NCode) {       case WM_NOTIFICATION_CLICKED:         // USER START (Optionally insert code for reacting on notification message)         if (slot_status[0] == SLOT_FREE){             hItem = WM_GetDialogItem(pMsg->hWin, ID_BUTTON_0);             BUTTON_SetTextColor(hItem, 0, player_colors[player_turn]);             if (!player_turn){                 BUTTON_SetText(hItem, "X");                 slot_status[0] = SLOT_X;             }             else{                 BUTTON_SetText(hItem, "O");                 slot_status[0] = SLOT_O;             }             player_turn ^= 1;             slots_free--;         }         // USER END         break; 12) For the Restart Button, the implemented logic is in charge of revert back all the Slots status to "Free", erase the content of all the Slots, and also restart the counter of free Slots to nine. 13) After polling all the GUI widgets events, the "CheckWinner" function is called, and then, the winner is defined, indicating it on the "Text_Winner" widget (on the upper-left corner of the screen) that was originally empty. 14) It is also implemented a functionality to directly draw a green rectangle (using emWin Draw functions) around the Cross/Circle icons, depending who is the player on move (also implemented inside the "_cbDialog" function, at the end).   //Draw green rectangle to indicate the player on move   if (!player_turn)   {     GUI_SetColor(GUI_GREEN);     GUI_DrawRoundedFrame(6, 106, 83, 183, 0, 4);     GUI_SetColor(GUI_BLACK);     GUI_DrawRoundedFrame(6, 186, 83, 263, 0, 4);   }   else   {       GUI_SetColor(GUI_GREEN);       GUI_DrawRoundedFrame(6, 186, 83, 263, 0, 4);       GUI_SetColor(GUI_BLACK);       GUI_DrawRoundedFrame(6, 106, 83, 183, 0, 4);   } 15) Finally, a printf with a welcome message was added to "main" function, just before initializing the GUI.     PRINTF("Tic-Tac-Toe demo on i.MXRT1060.\r\n"); 5. FUNCTIONAL DEMONSTRATION   Below are shown captures of the application running, when Cross wins, when Circle wins, and when the match is a draw.  
View full article
Introduction NXP i.MX RT1xxx series provide the High Assurance Boot (HAB) feature which makes the hardware to have a mechanism to ensure that the software can be trusted, as the HAB feature enables the ROM to authenticate the program image by using digital signatures, which can assure the application image's integrity, authenticated and undeniable. So the OEM can utilize it to make their product reject any system image which is not authorized to run. However, what's the trust chain of HAB for implementing the purpose? How the key and certificate generate In the installation directory of MCUXpresso Secure Provisioning:  ~\nxp\MCUX_Provi_v3.1\bin\tools_scripts\keys , there are scripts for generating keys: hab4_pki_tree.sh and hab4_pki_tree.bat (both are applicable to Linux and Windows systems respectively), running any of the above scripts will generate 13 pairs of public and private keys in sequence through OpenSSL, which constitute the below tree structure. Fig1 Key Tree structure The public key and private key generated by OpenSSL are paired one by one, saving the private key and publishing the corresponding public key to the outside world can easily implement asymmetric encryption applications. But how to ensure that the obtained public key is correct and has not been tampered with? At this time, the intervention of authoritative departments is required. Just like everyone can print their resume and say who they are, but if they have the seal of the Public Security Bureau, only the household registration book can prove you are you. This issued by the authority is called a certificate. What's in the certificate? Of course, it should contain a public key, which is the most important; there is also the owner of the certificate, just like the household registration book with your name and ID number, indicating that the book is yours; in addition, there is the issuer of the certificate and the validity period of the ID card is a bit like the issuer institution on the ID card, and how many years of the validity period. If someone fakes a certificate issued by an authority, it's like having fake ID cards and fake household registration books. To generate a certificate, you need to initiate a certificate request, and then send the request to an authority for certification, which is called a CA(Certificate Authority). After sending this request to the authority, the authority will give the certificate a signature. Another question arises, how can the signature be guaranteed to be signed by a genuine authority? Of course, it can only be signed with something that is only in the hands of the authority, which is the CA's private key. The signature algorithm probably works like this: a Hash calculation is performed on the target information to obtain a Hash value. And this process is irreversible, that is to say, the original information content cannot be obtained through the Hash value. When the information is sent out, the hash value is encrypted and sent together with the information as a signature. The process is as follows. Fig2 Signature and verification process Looking at the content of the certificate (as shown below), we will find that there is an Issuer, that is, who issued the certificate; The subject is to who the certificate is issued; Validity is the certificate period; Public-key is the content of the public key, and related signature algorithm. You will find that in order to verify the certificate, the public key of the CA is required. Then a new question arises. How can we be sure that the public key of the CA is correct? This requires a superior CA to sign the CA's public key, and then form the CA's certificate. If you want to know whether a CA's certificate is reliable, you need to see if the public key of the CA's superior certificate can unlock the CA's signature. Just likes if you don’t trust the District Public Security Bureau, you can call the Municipal Public Security Bureau and ask the Municipal Public Security Bureau to confirm its legitimacy of the District Public Security Bureau. This goes up layer by layer until the root CA makes the final endorsement. Through this layer-by-layer credit endorsement method, the normal operation of the asymmetric encryption mode is guaranteed. How does the Root CA prove itself? At this time, Root CA will issue another certificate (as shown below), called the Self-Signed Certificate, which is to sign itself with its own private key, giving people a feeling of "I am me, whether you believe it or not", Therefore, its format content is slightly different from the above CA certificate. Its Issuer and Subject are the same, and its own public key can be used for authentication. So the certificate authentication process will also end here. In this way, in addition to generating the public key and private key through running the script, the OpenSSL will also generate the certificate chain shown below.  Fig3 certificates Boot flow of the HAB mode Figure 4 shows the boot flow of the HAB mode. And steps 1, 2, and 3 are essentially the signature verification process. Fig4 Boot flow of the HAB mode The verification process (as shown in Figure 2) can be used to detect data integrity, identity authentication, and non-repudiation when the public key is trusted, so hab4_pki_tree.sh and hab4_pki_tree.bat scripts can ensure the generated public key and private key pair and the certificate are trusted, it's the "perfectly closed loop". However, the Application image in Figure 4 is plaintext, and the confidentiality of the data is not implemented, so the encrypted boot is always a combination of the HAB boot and the encrypted boot is an advanced usage of an authenticated boot. Reference AN4581: i.MX Secure Boot on HABv4 Supported Devices AN12681: How to use HAB secure boot in i.MX RT10xx  
View full article
RT1170 Octal flash enablement 1. Abstract The MIMXRT1170-EVK hardware can directly support two types of flash: QSPI flash IS25WP128 and Octal flash MX25UM51345GXDI00. QSPI flash is used by default, so the FCB of the related SDK and some IDE debugger download flash drivers are also default to the QSPI flash. In practical usage, some customers need to use Octal flash with RT1170, but after modifying the EVK hardware to Octal flash MX25UM51345GXDI00, they may encounter various issues, such as download issues, boot issues, debug issues, and when the flash is empty or there is a valid boot code in the flash, the download result is different and so on. This article will be based on NXP's official MIMXRT1170-EVK REV C1, modify the hardware onboard flash from QSPI flash to Octal flash MX25UM51345GXDI00, and modify the SDK project FCB, do ROM API test, do related tool download, do the debugger related flashloader modification and test with different IDE, so that customers who need it can refer to it. This article is not limited to EVK, but also applies to RT1170+Octal flash MX25UM51345GXDI00 with customer-defined board Pic 1 2. Hardware modification MIMXRT1170-EVK board modify flash to the octal flash, it needs to disconnect the QSPI flash pins, and connect the octal flash pins, the related modification points are: OPTION2: USE Octal Flash( Mount R381/R378/R382/R389/R402/R377/R388/R391, DNP R380/R399/R386/R390/R392/R385) Pic 2 The octal flash BOOT_CFG pin configuration are as follows: Pic 3 Pic 4 After modifying the hardware related resistors to choose the octal flash, SW1, SW2 should be configured to internal boot, and boot from octal flash, then it is controlled by the software part. 3. Octal flash APP FCB 3.1 Test SDK ROM API run from RAM To verify the board hardware can run from the octal flash, we can test the SDK attached fsl_romapi project: \SDK_2_12_0_MIMXRT1170-EVK\boards\evkmimxrt1170\driver_examples\fsl_romapi\cm7 Please note, can’t test the default project directly, as this project configuration is used by the QSPI flash, not the octal flash, if need to use the octal flash, customer need to modify the code at first, and add the GPIO to control the Flash_RST pin, which is used to reset the octal flash. The option0,1 value need to be modified to the octal flash values. 3.1.1 Octal flash option value     Pic 5 We can use the following option0 for testing, don’t need to configure the option1, as the octal flash is connected to the primary pin. option0= 0Xc0400007, option1 = 0 //query_pad =1, cmd_pad=1,133MHz option0= 0Xc0433007, option1 = 0 //query_pad =8, cmd_pad=8,133MHz option0= 0Xc0403007, option1 = 0 //query_pad =1, cmd_pad=8,133MHz 3.1.2 fsl_romapi project testing    The modified code for the ROM API project are as follows, before call ROM_FLEXSPI_NorFlash_GetConfig API, it needs to use the GPIO to reset the external octal flash at first, so, here add the Flash_RST=GPIO_AD_03=GPIO09_IO02 pin GPIO configuration. Pinmux.c related code:     gpio_pin_config_t gpio9_pinP15_config = { .direction = kGPIO_DigitalOutput, .outputLogic = 1U, .interruptMode = kGPIO_NoIntmode }; GPIO_PinInit(GPIO9, 02U, &gpio9_pinP15_config); IOMUXC_SetPinMux( IOMUXC_GPIO_AD_03_GPIO9_IO02, 0U); IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_03_GPIO9_IO02,//OD,it is a workaround for EVK HW bug 0X12);     Flexspi_romapi.c added code:     static serial_nor_config_option_t option_1bit = { .option0.U = 0xc0400007U, .option1.U = 0U, }; static serial_nor_config_option_t option_8bit = { .option0.U = 0xc0433007, .option1.U = 0U, }; static serial_nor_config_option_t option_1_8bit = { .option0.U = 0xC0403007, .option1.U = 0U, }; GPIO_PinWrite(GPIO9, 02U, 0U); // Delay some time to reset external flash with Flash_RST pin for (uint32_t i = 0; i < 60000; i++) __asm volatile ("nop"); GPIO_PinWrite(GPIO9, 02U, 1U); status = ROM_FLEXSPI_NorFlash_GetConfig(FlexSpiInstance, &norConfig, &option_8bit); if (status == kStatus_Success) { PRINTF("\r\n Successfully get FLEXSPI NOR configuration block with option_8bit\r\n "); } else { status = ROM_FLEXSPI_NorFlash_GetConfig(FlexSpiInstance, &norConfig, &option_1_8bit); if (status == kStatus_Success) { PRINTF("\r\n Successfully get FLEXSPI NOR configuration block with option_1_8bit\r\n "); } else { status = ROM_FLEXSPI_NorFlash_GetConfig(FlexSpiInstance, &norConfig, &option_1bit); if (status == kStatus_Success) { PRINTF("\r\n Successfully get FLEXSPI NOR configuration block with option_1bit\r\n "); } else { PRINTF("\r\n Get FLEXSPI NOR configuration block failure!\r\n"); error_trap(); } } }     The test result is: Pic 6 Pic 7 From the test result, we can see, after using the GPIO to reset the external flash, the practical used option value is: option0= 0xc0403007, option1 = 0 //query_pad =1, cmd_pad=8,133MHz It can read the SFDP successfully, get the flash config data to the norConfig, then use these values to configure the flexSPI module, at last, it realizes the octal flash related address area erase-write-read-erase operation. From the above test result, it means, the modified hardware is totally working. Please note, as we can’t confirm the external flash hardware is working, so this project FCB is still the default for the QSPI flash, not the octal flash, then when testing this fsl_romapi project, it’s better to run it from RAM not the external flash. The following picture is how to run the project from the internal RAM, not download the flash directly: Pic 8    Here, for the configuration, we also have one point that needs to note, why configure the GPIO pin Flash_RST: GPIO_AD_03 as OD(open drain)?    It is caused by the current MIMXRT1170-EVK hardware having a bug, so this OD configuration is used as the workaround. Octal flash MX25UM51345GXDI00 power supply voltage is 1.8V, but the GPIO_AD_03 bank voltage is 3.3V, between these two modules, no voltage convert hardware, so it will have the following situation: a) Default GPIO_AD_03 is input mode, this pin has the internal PD(pull down) 35K resistor,  and the external PU(pull up) 10K resistor to the 1.8V, Flash_RST=1.8V*35K/(10K+35K)=1.4V, this voltage also can be used as the enable signal. To the normal boot, as the ROM didn’t control the octal flash Flash_RST pin, then this pin can be freely chose by any pin in the practical usage, so, the reset pin default is input, the voltage is 1.4V, it can enable the octal flash, no influence. b) When need to control the octal flash reset, then it needs to use the GPIO control GPIO_AD_03 pin, if want to output 0, it is OK. But if want to output high level, use the internal PULL resistor, it will output 3.3V to the Flash_RST pin, this voltage already higher than the octal flash 1.8V, and the octal flash datasheet defines the max voltage is 2V, although the flash chip has the voltage buffer, input 3.3V in short time, won’t damage the chip, but after long time working, the chip normal working can’t be guaranteed, this will cause the risk. So, to solve this issues, we can do some workaround in the flashloader, rom API, when output the Flash_RST pin to higher, we can use OD mode, then the detail pin voltage is totally determined by the external pull circuit, and the EVK also have the external 10K PU to 1.8V, so it can output 1.8V not the 3.3V. Pic 9   In the NXP new MIMXRT1170-EVKB board, the hardware adds the voltage convert chip to solve these issues, it can realize the 3.3V and 1.8V conversion: Pic 10 3.2 MCUBootUtility program octal flash We can use the MCUBootUtility to test MIMXRT1170-EVK+octal flash in serial download mode, normally for the chip connect, memory erase, read and program. This method also can use the tool to generated the correct FCB header for the octal flash, then can test the boot situation in the internal boot mode. Serial download-> SW1:1-OFF,2-OFF,3-OFF,4-ON Internal boot-> SW1:1-OFF,2-OFF,3-ON,4-OFF The MCUBootUtility configuration is: Pic 11 This configuration is: option0=0Xc0403007,query 1wire, cmd 8 wire. Then app image can use the MCUBootUtility attached code: NXP-MCUBootUtility-3.5.0\apps\NXP_MIMXRT1170-EVK_Rev.A\cm7\led_blinky_0x3000a000.srec Pic 12   We can see, the code downloading is finished, after this, reset device, configure the board as internal boot mode, then do the POR or the HW reset, we can see the on board LED D34 is blinking, it means the hardware also can boot from the octal flash. 3.3 SDK APP FDCB modification If you need to debug the SDK APP demo from octal flash, you must ensure that the app correct FDCB is provided, then how to modify the app FDCB to octal flash? You can refer to the FDCB which is burned by the MCUBootUtility tool and the datasheet of the octal flash. Here is the FDCB that has been tested for many times. The key point is to provide the correct LUT table. Taking the RT1170 SDK led_blinky project as an example, the evkmimxrt1170_flexspi_nor_config.c file in the project xip file is modified as follows:     const flexspi_nor_config_t octalflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClksrc=kFlexSPIReadSampleClk_ExternalInputFromDqsPad, .csHoldTime = 3, .csSetupTime = 3, .deviceModeCfgEnable = 1, .deviceModeType = kDeviceConfigCmdType_Spi2Xpi, .waitTimeCfgCommands = 1, .deviceModeSeq = { .seqNum = 1, .seqId = 6, /* See Lookup table for more details */ .reserved = 0, }, .deviceModeArg = 2, /* Enable OPI DDR mode */ .controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable) | (1u << kFlexSpiMiscOffset_DdrModeEnable), .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_8Pads, .serialClkFreq = kFlexSpiSerialClk_133MHz, .sflashA1Size = 64ul * 1024u * 1024u, .dataValidTime = { [0] = {.time_100ps = 16}, }, .busyOffset = 0u, .busyBitPolarity = 0u, .lookupTable = { /* Read */// EEH+11H+32bit addr+20dummy cycles+ 4Bytes read data //133Mhz 20 dummy=10+10 [0 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0xEE, CMD_DDR, FLEXSPI_8PAD, 0x11),//0x871187ee, [0 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, DUMMY_DDR, FLEXSPI_8PAD, 0x0A),//0xb30a8b20, [0 + 2] = FLEXSPI_LUT_SEQ(DUMMY_DDR, FLEXSPI_8PAD, 0x0A, READ_DDR, FLEXSPI_8PAD, 0x04),//0xa704b30a, /* Read Status SPI */// SPI 05h+ status data 0X24 maybe 0X04 [4*1 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR , FLEXSPI_1PAD, 0x05, READ_SDR, FLEXSPI_1PAD, 0x24),//0x24040405, /* Read Status OPI *///05H+FAH+ 4byte 00H(addr)+4Byte read [4*2 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x05, CMD_DDR, FLEXSPI_8PAD, 0xFA),//0x87fa8705, [4*2 + 1] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x00),//0x87008700, [4*2 + 2] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x00, CMD_DDR, FLEXSPI_8PAD, 0x00),//0x87008700, [4*2 + 3] = FLEXSPI_LUT_SEQ(READ_DDR , FLEXSPI_8PAD, 0x04, STOP_EXE, FLEXSPI_1PAD, 0x00),//0x0000a704, /* Write enable SPI *///06h [4*3 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR , FLEXSPI_1PAD, 0x06, STOP_EXE, FLEXSPI_1PAD, 0x00),//0x00000406, /* Write enable OPI *///06h+F9H [4*4 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x06, CMD_DDR, FLEXSPI_8PAD, 0xF9),//0x87f98706, /* Erase sector */ //21H+DEH + 32bit address [4*5 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x21, CMD_DDR, FLEXSPI_8PAD, 0xDE),//0x87de8721, [4*5 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR , FLEXSPI_8PAD, 0x20, STOP_EXE, FLEXSPI_1PAD, 0x00),//0x00008b20, /*Write Configuration Register 2 =01, Enable OPI DDR mode*/ //72H +32bit address + CR20x00000000 = 0x01 [4*6 + 0] = FLEXSPI_LUT_SEQ(CMD_SDR , FLEXSPI_1PAD, 0x72, CMD_SDR, FLEXSPI_1PAD, 0x00),//0x04000472, [4*6 + 1] = FLEXSPI_LUT_SEQ(CMD_SDR , FLEXSPI_1PAD, 0x00, CMD_SDR, FLEXSPI_1PAD, 0x00),//0x04000400, [4*6 + 2] = FLEXSPI_LUT_SEQ(CMD_SDR , FLEXSPI_1PAD, 0x00, WRITE_SDR, FLEXSPI_1PAD, 0x01),//0x20010400, /*block erase*/ //DCH+23H+32bit address [4*8 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0xDC, CMD_DDR, FLEXSPI_8PAD, 0x23),//0x872387dc, [4*8 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, STOP_EXE, FLEXSPI_1PAD, 0x00),//0x00008b20, /*page program*/ //12H+EDH+32bit address+ write data 4bytes [4*9 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x12, CMD_DDR, FLEXSPI_8PAD, 0xED),//0x87ed8712, [4*9 + 1] = FLEXSPI_LUT_SEQ(RADDR_DDR, FLEXSPI_8PAD, 0x20, WRITE_DDR, FLEXSPI_8PAD, 0x04),//0xa3048b20, /* Chip Erase (CE) Sequence *///60H+9FH [4*11 + 0] = FLEXSPI_LUT_SEQ(CMD_DDR , FLEXSPI_8PAD, 0x60, CMD_DDR, FLEXSPI_8PAD, 0x9F),//0x879f8760, }, }, .pageSize = 256u, .sectorSize = 4u * 1024u, .blockSize = 64u * 1024u, .isUniformBlockSize = false, };     The LUT here is the full function LUT table, it includes: 8 wire read, 1/8 wire status read, 1/8 wire write enable, 8 wire sector erase, 1 wire write configuration enable for OPI DDR mode, 8 wire block erase, 8 wire page program, 8 wire chip erase. The detail command is the same as the MX25UM51345GXDI00 datasheet, and also the same as the MCUBootUtility tool generated FCB. 4. CMSIS DAP Flashloader MIMXRT1170-EVK default use the CMSIS DAP debugger, take the MCUXPresso IDE as an example, it will call the flashloader named as .cfx file, flashloader source code can be found from this path: C:\nxp\MCUXpressoIDE_11.6.0_8187\ide\Examples\Flashdrivers\NXP\iMXRT\ iMXRT117x_FlexSPI_SFDP.zip The exist .cfx file which can be used directly, the path is: C:\nxp\MCUXpressoIDE_11.6.0_8187\ide\binaries\Flash\ MIMXRT1170_SFDP_QSPI.cfx:  QSPI flash MIMXRT1170_SFDP_MXIC_OPI.cfx: octal flash Pic 13 When use flashloader + CMSIS DAP + MCUXpresso debug result is: Pic 14 One point need to note, mcuxpresso IDE flashloader source code iMXRT117x_FlexSPI_SFDP.zip, the project configured to the octal flash, the related Flash_RST control code need to be modified, otherwise, when it output high, the voltage will be 3.3V. Pic 15 In the above picture, add code: MEM_WriteU32(0x400E835CU, 0x12); Which is SW_PAD_CTL_PAD_GPIO_AD_03 register = 0x12, OD mode, then generate the mxic MX25UM51345GXDI00 octal flash .cfx file again, which is used for the mcuxpresso+CMSIS DAP debugger. 5. JLINK Flashloader with RT-UFL In actual use, many customers not only use the on-board CMSIS-DAP debugger, but also like to use external JLINK/JLINK plus, or use the on-board JLINK firmware (use LPCScrypt modify firmware, pay attention to update the JINK firmware according to the instructions on the webpage), or use the external JLINK firmware (need to disconnect the onboard debugger jumper). But if the JLINK flash driver is called directly, it will be QSPI flash. Here is how to use the flash driver of the octal flash in JLINK. Now the JLINK driver uses JLinkARM.dll to define the flash used by different chips, unlike the old JLINK driver. The firmware of the flash is called by JLinkDevices.xml. The .dll file cannot allow users to directly modify the corresponding flash of the device, so it is necessary to provide a flash driver file that supports RT1170 octal flash, and add a calling command in JLinkDevices.xml to override the default QSPI definition in JLinkARM.dll. NXP AE has developed a very useful full-function flash driver called RT-UFL, which can support general QSPI, hyperflash, octaflash, etc. Users can use JLINK to call RT-UFL flash driver, and then use JFLASH, JLINK commander, or IDE (MCUXpresso, IAR, MDK) to realize the debugging and downloading of RT chips combined with different flashes RT-UFL download link: https://github.com/JayHeng/RT-UFL More detail usage of RT-UFL, please check this blog link:   https://www.cnblogs.com/henjay724/ After downloading, install the RT-UFL to the JLINK driver, copy the following folder file: RT-UFL-1.0\algo\SEGGER\JLink_Vxxx to the JLINK driver install path: C:\Program Files\SEGGER\JLINKV768B The JLINK driver link is: https://www.segger.com/downloads/jlink/JLink_Windows_x86_64.exe Now, use the original RT-UFL firmware combined with JFLASH to test the octal flash in RT1170 directly, and the debugger is JLINK plus, just to check whether it can be run, device selection: MIMXRT1170_UFL_L0. _L0 suffix algorithm is suitable for QSPI Flash and Octal Flash (Page size is 256 Bytes, Sector size is 4KB), _L1/2 suffix algorithm is suitable for Hyper Flash (Page size is 512 Bytes, Sector size is 4KB/64KB). 5.1 RT-UFL JFlash Test Generate a .srec file for the led_blinky project which FCB has been modified to octal flash before, it will be used by JFLASH or JLINK commander later. Use JFLASH combined with JLINK plus to create a new JFLASH project. The chip is selected as MIMXRT1170_UFL_L0 which can support octal flash. The test situation is as follows, you can see that the connect can be successful, and the ARM CortexM7 core can be found, but the programming, reading, and erasing functions will fail. It can be said that the connection to the external octal flash is not successful at all: Pic 16 If the used JLINK is not the JLINK plus, due to the license can’t support the JFLASH, then customer can use the JLINK commander to test it, but here, the test result with the original RT-UFL is totally the same as the JFLASH: Pic 17 It can still meet the issues of “Failed to initialize RAMCode”, even use the mem32 readout the address data, sometimes, the data is not correct, not the real flash data, customer can compare the memory which the data which is readout from the MCUBootUtility. So, the RT-UFL flashdriver code need to be modified to the octal flash, to let the octal flash works. 5.2 RT-UFL Flashloader source code modification     From the analysis of the original RT-UFL combined with the octal flash test, after many modifications and tests, the modification points are listed one by one, the new flashloader file generated by the modified RT-UFL is tested using JFlash, JLINK commander, IDE, etc. JLINK tools are divided into external JLINK plus and onboard JLINK firmware (JFLASH is not supported). 5.2.1 Flashloader modification points 1) RAMCode errors In the JLinkDevices.xml file, define the RAM location to the OCRAM address:     <Device> <ChipInfo Vendor="NXP" Name="MIMXRT1170_UFL_octalFlash" WorkRAMAddr="0x20240000" WorkRAMSize="0x00040000" Core="JLINK_CORE_CORTEX_M7" JLinkScriptFile="Devices/NXP/iMXRT_UFL/iMXRT117x_CortexM7.JLinkScript" Aliases="MIMXRT1176xxx8_M7; MIMXRT1176xxxA_M7" /> <FlashBankInfo Name="Octal Flash" BaseAddr="0x30000000" MaxSize="0x01000000" Loader="Devices/NXP/iMXRT_UFL/MIMXRT_FLEXSPI_UV5_UFL.FLM" LoaderType="FLASH_ALGO_TYPE_OPEN" /> </Device>     2) Add erase sector ROM API The JLINK calls the erase sector, so add the related sector erase API: ufl_main.c     static void ufl_fill_flash_api(void) { ... case kChipId_RT117x: uflTargetDesc->flashDriver.init = g_bootloaderTree_imxrt117x->flexspiNorDriver->init; uflTargetDesc->flashDriver.page_program= g_bootloaderTree_imxrt117x->flexspiNorDriver->page_program; uflTargetDesc->isFlashPageProgram = true; uflTargetDesc->flashDriver.erase_all = g_bootloaderTree_imxrt117x->flexspiNorDriver->erase_all; uflTargetDesc->flashDriver.erase = g_bootloaderTree_imxrt117x->flexspiNorDriver->erase; uflTargetDesc->flashDriver.erase_sector= g_bootloaderTree_imxrt117x->flexspiNorDriver->erase_sector;//kerry add uflTargetDesc->flashDriver.read = g_bootloaderTree_imxrt117x->flexspiNorDriver->read; uflTargetDesc->flashDriver.set_clock_source = NULL; uflTargetDesc->flashDriver.get_config= g_bootloaderTree_imxrt117x->flexspiNorDriver->get_config; uflTargetDesc->iarCfg.enablePageSizeOverride = true; break; … }     ufl_flexspi_nor_flash_imxrt117x.h     typedef struct _flexspi_nor_flash_driver_imxrt117x { uint32_t version; status_t (*init)(uint32_t instance, flexspi_nor_config_t *config); status_t (*page_program)(uint32_t instance, flexspi_nor_config_t *config, uint32_t dst_addr, const uint32_t *src); status_t (*erase_all)(uint32_t instance, flexspi_nor_config_t *config); status_t (*erase)(uint32_t instance, flexspi_nor_config_t *config, uint32_t start, uint32_t lengthInBytes); status_t (*read)(uint32_t instance, flexspi_nor_config_t *config, uint32_t *dst, uint32_t addr, uint32_t lengthInBytes); void (*clear_cache)(uint32_t instance); status_t (*xfer)(uint32_t instance, flexspi_xfer_t *xfer); status_t (*update_lut)(uint32_t instance, uint32_t seqIndex, const uint32_t *lutBase, uint32_t seqNumber); status_t (*get_config)(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option); status_t (*erase_sector)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address);//kerry add status_t (*erase_block)(uint32_t instance, flexspi_nor_config_t *config, uint32_t address); const uint32_t reserved0; status_t (*wait_busy)(uint32_t instance, flexspi_nor_config_t *config, bool isParallelMode, uint32_t address); const uint32_t reserved1[2]; } flexspi_nor_flash_driver_imxrt117x_t;     3) Speed up the erase and program speed FlashDev.c     struct FlashDevice const FlashDevice = { FLASH_DRV_VERS, // Driver Version, do not modify! "MIMXRT_FLEXSPI_RT1170", // Device Name EXTSPI, // Device Type 0x30000000, // Device Start Address 0x01000000, // Device Size in Bytes (16mB) 256*4, // Programming Page Size 0, // Reserved, must be 0 0xFF, // Initial Content of Erased Memory 100, // Program Page Timeout 100 mSec 15000, // Erase Sector Timeout 15000 mSec // Specify Size and Address of Sectors 4096*8, 0x00000000, // Sector Size 4kB (256 Sectors) SECTOR_END };       FlashPrg.c:     int EraseSector (unsigned long adr) { uint32_t instance = g_uflTargetDesc.flexspiInstance; uint32_t baseAddr = g_uflTargetDesc.flashBaseAddr; /*Erase Sector*/ status_t status = flexspi_nor_flash_erase(instance, (void *)&flashConfig, adr - baseAddr, FLASH_DRV_SECTOR_SIZE*8);//kerry *8, 4096 if (status != kStatus_Success) { return (1); } else { return (0); } } int ProgramPage (unsigned long adr, unsigned long sz, unsigned char *buf) { status_t status = kStatus_Success; uint32_t instance = g_uflTargetDesc.flexspiInstance; uint32_t baseAddr = g_uflTargetDesc.flashBaseAddr; uint32_t loadaddr = adr - baseAddr; unsigned char *buffer; buffer = buf; int i; for(i = 0; i < 4; i ++) // kerry add 256*4 { status = flexspi_nor_flash_page_program(instance, (void *)&flashConfig, loadaddr, (uint32_t *)buffer); if (status != kStatus_Success) { return (1); } buffer+=256; loadaddr+=256; } return (0); }     The principle is to reduce the times it takes for the PC to send commands to JLINK and then send to the board, now, one command can directly erase and program multiple blocks. 4) Octal Flash option value polling It should be noted that after Flash Reset, or the first programming, it is necessary to read SFDP in a single-line manner. If it is not reset and there is a valid FCB in the flash, the flash is initialized to OPT mode and needs to be read in 8-line mode. At this time, the valid SFDP table of the flash chip cannot be read in the single-line mode. RT-UFL is a flashloader that supports multiple chips, and it does not use specific GPIO as the chip flash_RST. For RT-UFL, GPIO is not added to control flash_RST pin, and a large degree of freedom is reserved. Otherwise, once the customer uses the RST pins that are different from EVK still have problems, and even require customers to spend time modifying the flashloader source code, increasing development time. Therefore, in view of the above considerations, modify the code here, do not add RESET signal control, do not fix option value for single-line or 8-line, but polling the option with single-line and 8-line to read SPDF. ufl_main.c     static void ufl_set_target_property(void) case kChipId_RT117x: uflTargetDesc->flexspiInstance = MIMXRT117X_1st_FLEXSPI_INSTANCE; uflTargetDesc->flexspiBaseAddr = MIMXRT117X_1st_FLEXSPI_BASE; uflTargetDesc->flashBaseAddr = MIMXRT117X_1st_FLEXSPI_AMBA_BASE; // uflTargetDesc->configOption.option0.U = 0xc0433007; // uflTargetDesc->configOption.option1.U = 0x0; break;     Make sure that the above option are not configured, otherwise the option configuration will be fixed and the polling option function will no longer be enabled. ufl_auto_probe_flash.c     static const serial_nor_config_option_t s_flashConfigOpt[] = { // 1st Pinmux, PortA for octal 1 bit SFDP for no FCB in flash eg. MX25UM51345G {.option0.U = 0xc0403007, .option1.U = 0x00000000}, // 1st Pinmux, PortA for octal 8 bit SFDP for FCB in flash eg. MX25UM51345G {.option0.U = 0xc0433007, .option1.U = 0x00000000}, // 1st Pinmux, PortA for octal 1 bit SFDP &1 bit CMD for no FCB in flash eg. MX25UM51345G {.option0.U = 0xc0400007, .option1.U = 0x00000000}, ..}     After the above modifications, compile the source code project of RT-UFL: RT-UFL-1.0\build\mdk\MIMXRT_FLEXSPI_UV5.uvprojx, Generate a new MIMXRT_FLEXSPI_UV5_UFL.FLM programming algorithm and copy it to the following path: C:\Program Files\SEGGER\JLINKV768B\Devices\NXP\iMXRT_UFL The device name defined in JLinkDevices.xml is: MIMXRT1170_UFL_octalFlash. JLinkDevices.xml path: C:\Program Files\SEGGER\JLINKV768B modify the .xml, and add the above-mentioned "RAMCode error" section. After the modification is completed, refresh the JLinkDLLUpdater.exe file, so that several IDEs can synchronize the firmware defined by the updated xml file. 5.2.2 JFlash Test As can be seen from the test results of Jflash below, it can be successfully erased, and the app image can be downloaded to octal flash. After the download is successful, reset it, and you can see the onboard led is flashing. It shows that the modified RT-UFL flashloader has worked. It should be noted here that the use of JFLASH requires the use of an external Segger JLINK Plus. Some customers use normal JLINK or RT EVK onboard JLINK firmware, then they can try the JLINK commander method. Pic 18 5.2.3 JLINK command Test Use the JLINK plus associated with JLINK commander test result is: Pic 19 You can see that the firmware can be downloaded successfully. Now uses the EVK onboard JLINK firmware to test as follows, it can be seen that the programming is normal, so if users don’t have external JLINK can also directly use the RT EVK onboard JLINK firmware. One thing need to pay attention to is when using the onboard JLINK firmware, the firmware will cause the debugger port USB to not directly supply power to the RT chip, so it needs to be configured that J38 is connected to 3-4, and then find another USB cable to connect J20 to supply power to the board. Pic 20 5.3 MCUXpresso + JLINK +Modified RT-UFL Testing At first, select the MCUXPresso IDE JLINK debug path, add the JLINK driver path which is already added RT-UFL firmware, windows->preferences, then the path should like this: Pic 21 When downloading, still need to configure RUN->Debugger configurations, the JLINK configuration should be: Pic 22 Please note, don’t check the item “Reset before running” in the debug configuration, as this item is checked in default. Pic 23 If checked “Reset before running”, when debug it, the code will be blocked after downloading the code, and can’t jump to the main function. If customer click halt button, it will meet the issues that the code is stop at 0x223104, but after exit the debug mode, and do the POR again, you will find the flash already downloaded with the app successfully. Pic 24 This problem is related to the impact of RT1170 security policy on JLINK. For details, please refer to the following link: https://www.cnblogs.com/henjay724/p/15725966.html When JLink is connected to the chip, as long as the reset command is executed, it will directly enter the safe debugging mode (the PC stops at 0x223104). Therefore, make sure that "Reset before running" is not checked, so that you can enter the debug and main functions normally, and the test results are as follows: Pic 25 5.4  MDK+JLINK+Modified RT-UFLTesting Next, use the MCUXPresso CFG tool combined with the SDK package to export an MDK project, also based on the led_blinky project, and modify the FCB code for Octal flash, and then call the modified RT-UFL flashloader, the device name is: MIMXRT1170_UFL_octalFlash. Note, be sure to refresh: C:\Program Files\SEGGER\JLINKV768B\JLinkDLLUpdater.exe Make sure the IDE is using the latest firmware link. The following is a specific MDK project related configuration pictures: Pic 26 The project is selected as flexspi_nor_debug, and after compiling, the debug tool is configured as JLINK, the JLINK simulation sequence can be found, and the updated target before debugging in utilities should not be checked: Pic 27 Pic 28 Pic 29 Modify JlinkSettings.ini,configure override =1, device as the RT-UFL modified firmware device name: MIMXRT1170_UFL_octalFlash. Pic 30 Pic 31 As can be seen from the above picture, the modified RT-UFL Octal flash has been successfully used to run the MDK project. It should be noted that do not use the download button, because this button cannot use the overwritten and modified RT-UFL programming algorithm, it will still call the programming algorithm of the deleted area of ​​the interface, and an error will be reported if it cannot be found. 5.5 IAR + JLINK + Modified RT-UFL Testing Here is the use of IAR combined with JLINK to debug RT1170 octal flash, using the modified RT-UFL programming algorithm. The specific configuration is as follows: Pic 32 Don’t check “use flash loaders”, it means don’t use the IAR attached .out download algorithm, and use the JLINK driver’s modified RT-UFL octal flash flashdriver. Pic 33 Reset can choose core, if it is normal, debug will meet the same issues with the MCUXPresso which checked reset item, PC will stop to 0x223104. Pic 34 Here, modify project settings folder ->.jlink file, use the RT-UFL device name: MIMXRT1170_UFL_octalFlash, And override =1, then it will call the modified RT-UFL flashloader. If you can’t find the .jlink in the new created project, just select the JLINK debugger, click download at first, then it will generate the .jlink file, then modify it and debug it again. Pic 35 After modify the RT-UFL program algorithm to the octal flash, click “download and debug” button, it will enter the debug mode, in the following picture, the code is running successfully: Pic 36 6. Conclusion After the above details, the code download of the MIMXRT1170-EVK on-board octalflash can be realized, and the fsl_romspi project is used to run in RAM, which can verify the normal reading and writing of the hardware octalflash, and MCUBootutility to verify the programming and boot conditions. The modification of APP FCB is matched octal flash. The debugger uses JLINK or CMSIS DAP, and the correct flashdriver programming algorithm needs to be used. In particular, JLINK needs to use the RT-UFL as flashloader, but the source code needs to be modified. Finally, you can see that the combination of RT-UFL download algorithm and JLINK, successfully realize the download and operation of octal flash code on MCUXpresso, IAR, MDK three IDEs. This article is not limited to MIMXRT1170-EVK, but also applies to customer design boards using RT1170+ MX25UM51345GXDI00 octal flash. The attachment adds the modified RT-UFL programming algorithm and the octal flash project of the three major IDEs.  
View full article
1 Introduction RT1060 MCUXpresso SDK provide the ota_bootloader project, download link: https://mcuxpresso.nxp.com/en/welcome ota_bootloader path: SDK_2_10_0_EVK-MIMXRT1060\boards\evkmimxrt1060\bootloader_examples\ota_bootloader  this ota_bootloader can let the customer realize the on board app update, the RT1060 OTA bootloader mainly have the two functions: ISP method update APP Provide the API to the customer, can realize the different APP swap and rollback function ISP method is from the flashloader, the flashloader put the code in the internal RAM, when use it, normally RT chip need to enter the serial download mode, and use the sdphost download the flashloader to the internal RAM, then run it to realize the ISP function. But OTA_bootloader will put the code in the flash directly, RT chip can run it in the internal boot mode directly, each time after chip reset, the code will run the ota_bootloader at first, this time, customer can use the blhost to communicate the RT chip with UART/USB HID directly to download the APP code. So, to the ISP function in the OTA_bootloader, customer also can use it as the ISP secondary bootloader to update the APP directly. Then reset after the 5 seconds timeout, if the APP area is valid, code will jump to the APP and run APP. To the ota_bootloader swap and rollback function, customer can use the provided API in the APP directly to realize the APP update, run the different APP, swap and rollback to the old APP.    This document will give the details about how to use the ota_bootloader ISP function to update the APP, how to modify the customer application to match the ota_bootloader, how to resolve the customer APP issues which need to use the SDRAM with the ota_bootloader, how to use the ota_bootloader API to realize the swap and rollback function, and the related APP prepare. 2 OTA bootloader ISP usage Some customers need the ISP secondary bootloader function, as the flashloader need to put in the internal RAM, so customer can use the ota_bootloader ISP function realize the secondary bootloader requirement, to this method, customer mainly need to note two points: 1) APP need to add the ota_header to meet the ota_bootloader demand. 2) APP use the SDRAM, ota_bootloader need to add DCD memory  2.1 application modification OTA_bootloader located in the flash from 0x60000000, APP locate from 0x60040000. We can find this from the ota_bootloader bootloader_config.h file: #define BL_APP_VECTOR_TABLE_ADDRESS (0x60040000u) From 0x60040000, the first 0X400 should put the ota_header, then the real APP code is put from 0x60040400. Now, take the SDK evkmimxrt1060_iled_blinky project as an example, to modify it to match the ota_bootloader. Application code need to add these files: ota_bootloader_hdr.c, ota_bootloader_board.h, ota_bootloader_supp.c, ota_bootloader_supp.h These files can be found from the evkmimxrt1060_lwip_httpssrv_ota project, put the above files in the led_blinky source folder. 2.1.1 memory modification    APP memory start address modify from 0x60000000 to 0x60040000, which is the ota_bootloader defined address。 Fig 1 2.1.2 ota_hdr related files add   In the led_blinky project source folder, add the mentioned ota_bootloader related files. Fig 2 2.1.3 linker file modification In the evkmimxrt1060_iled_blinky_debug.ld, add boot_hdr, length is 0X400. We can use the MCUXpresso IDE linkscripts folder, add the .ldt files to modify the linker file. Here, in the project, add one linkscripts folder, add the boot_hdr_MIMXRT1060.ldt file, build . Fig 3 After the build, we can find the ld file already add the ota_header in the first 0x400 range. Fig 4 The above is the generated evkmimxrt1060_iled_blinky_ota_0x60040000.bin file, we can find already contains the boot_hdr. From offset 0x400, will put the real APP code. 2.2 ISP test related command Test board is MIMXRT1060-EVK, download the evkmimxrt1060_ota_bootloader project at first, can use the mcuxpresso IDE download it directly, then press the reset button, put the blhost and evkmimxrt1060_iled_blinky_ota_0x60040000.bin in the same folder, use the following command:   blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0 blhost.exe -t 2048000 -u 0x15a2,0x0073 -j -- flash-erase-region 0x60040000 0x6000 9 blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- write-memory 0x60040000 evkmimxrt1060_iled_blinky_ota_0x60040000.bin blhost.exe -t 5242000 -u 0x15a2,0x0073 -j -- read-memory 0x60040000 0x6000 flexspiNorCfg.dat 9 Fig 5 After the download is finished, press the reset, wait 5 seconds, it will jump to the app, we can find the MIMXRT1060-EVK on board led is blinking. This method realize the flash ISP bootloader downloading and the app working. The above command is using the USB HID to download, if need to use the UART, also can use command like this: blhost.exe -t 50000 -p COM45,19200 -j -- get-property 1 0 blhost.exe -t 50000 -p COM45,19200 -j -- flash-erase-region 0x60040000 0x6000 9 blhost.exe -t 50000 -p COM45,19200 -j -- write-memory 0x60040000 evkmimxrt1060_iled_blinky_ota_0x60040000.bin blhost.exe -t 50000 -p COM45,19200 -j -- read-memory 0x60040000 0x6000 flexspiNorCfg.dat 9 To the UART communication, as the ota_bootloader auto baud detect issues, it’s better to use the baudrate not larger than 19200bps, or in the ota_bootloader code, define the fixed baudrate, eg, 115200. 2.3 Bootloader DCD consideration Some customer use the ota_bootloader to associate with their own application, which is used the external SDRAM, and find although the downloading works, but after boot, the app didn’t run successfully. In the APP code, it add the DCD configuration, but as the ota_bootloader already put in the front of the QSPI, app will use the ota_hdr, which will delete the dcd part, so, to this situation, customer can add the dcd in the ota_bootloader. The SDK ota_bootloader didn’t add the dcd part in default. Now, modify the ota_bootloader at first, then prepare the sdram app and test it. 2.3.1 Ota_bootloader add dcd 2.3.1.1 add dcd files   ota_bootloader add dcd.c dcd.h, these two files can be found from the SDK hello_world project. Copy these two files to the ota_bootloader board folder. From the dcd.c code, we can see, dcd_data[] array is put in the “.boot_hdr.dcd_data” area, and it need to define the preprocessor: XIP_BOOT_HEADER_DCD_ENABLE=1 2.3.1.2 add dcd linker code   Modify the mcuxpresso IDE ld files, and add the dcd range.    .ivt : AT(ivt_begin) { . = 0x0000 ; KEEP(* (.boot_hdr.ivt)) /* ivt section */ . = 0x0020 ; KEEP(* (.boot_hdr.boot_data)) /* boot section */ . = 0x0030 ; KEEP(*(.boot_hdr.dcd_data)) __boot_hdr_end__ = ABSOLUTE(.) ; . = 0x1000 ; } > m_ivt Fig 6 0x60001000 : IVT 0x6000100c : DCD entry point 0x60001020 : boot data 0x60001030 : DCD detail data 2.3.1.3 add IVT dcd entry point   ota_bootloader->MIMXRT1062 folder->hardware_init_MIMXRT1062.c,modify the image_vector_table, fill the DCD address to the dcdc_data array address as the dcd entry point. Fig 7 Until now, we finish the ota_bootloader dcd add, build the project, generate the image, we can find, DCD already be added to the ota_bootloader image. Fig 8 DCD entry point in the IVT and the DCD data is correct, we can burn this modified ota_bootloader to the MIMXRT1060-EVK board. 2.3.2 SDRAM app prepare Still based on the evkmimxrt1060_iled_blinky project, just put some function in the SDRAM. From memory, we can find, the SRAM is in the RAM4: Fig 9 In the led_blinky.c, add this header: #include <cr_section_macros.h> Then, put the systick delay code to the RAM4 which is the SDRAM area. __RAMFUNC(RAM4) void SysTick_DelayTicks(uint32_t n) { g_systickCounter = n; while (g_systickCounter != 0U) { } } Now, we already finish the simple SDRAM app, we also can test it, and put the breakpoint in the SysTick_DelayTicks, we can find the address is also the SDRAM related address, generate the evkmimxrt1060_iled_blinky1_SDRAM_0x60040000.bin. If use the old ota_bootloader to download this .bin, we can find the led is not blinking. 2.3.3 Test result Command refer to chapter 2.2 ISP test related command, download the evkmimxrt1060_iled_blinky1_SDRAM_0x60040000.bin with the new modified ota_bootloader project, we can find, after reset, the led will blink. So the SDRAM app works with the modified ota_bootloader. 3 OTA bootloader swap and rollback OTA bootloader can realize the swap and rollback function, this part will test the ota_bootloader swap and rollback, prepare two apps and download to the different partition area, then use the UART input char to select the swap or rollback function, to check the which app is running. 3.1  memory map ota bootloader memory information. Fig 10 The above map is based on the external 8Mbyte QSPI flash. OTA bootloader: RT SDK ota bootloader code Boot meta 0: contains 3 partition start address, size etc. information, ISP peripheral information. Boot meta 1: contains 3 partition start address, size etc. information, ISP peripheral information. Swap meta 0: bootloader will use meta data to do the swap operation Swap meta 1: bootloader will use meta data to do the swap operation Partition 1: APP1 location Partition 2: APP2 location Scratch part: APP1 backup location, start point is before 0x60441000, which is enough to put APP1 and multiple sector size, eg, APP1 is 0X5410, sector size is 0x1000, APP1 need 6 sectors, so the scratch start address is 0x60441000-0x6000=0x43b000. User data: user used data area 3.2 swap and rollback basic Fig11  The APP1 and APP2 put in the partition1 and partition2 need to contains the ota_header which meet the bootloader demand, bootloader will check the APP CRC, if it passed, then will boot the app, otherwise, it will enter the ISP mode. Partition2 image need to has the valid header, otherwise, swap will be failed.   Swap function will erase partition2 scratch area, then put the partition1 code to the scratch, erase the partition 1 position, and write the partition 2 image to the partition1 position.   Rollback function will run the previous APP1, erase the partition 2 position, copy the parititon 1 image back to the partition 2, erase partition 1 position, copy partition 2 scratch image back to partition 1. 3.2.1 boot meta boot_meta 0: 0x0x6003c000 size: 0x20c boot_meta 1: 0x0x6003d000 size: 0x20c   OTA bootloader can read boot meta from the two different address, when the two address meta are valid(tag is 'B', 'L', 'M', 'T'), bootloader will choose the bigger version meta. If both meta is not valid, bootloader will copy default boot meta data to the boot meta 0 address.   Boot meta contains 3 partition start address, size information. SDK demo can call bootloader API to find the partition information, then do the image program.   Boot meta also contains the ISP peripheral information, the timeout(5s) information, the structure is: //!@brief Partition information table definitions typedef struct { uint32_t start; //!< Start address of the partition uint32_t size; //!< Size of the partition uint32_t image_state; //!< Active/ReadyForTest/UnderTest uint32_t attribute; //!< Partition Attribute - Defined for futher use uint32_t reserved[12]; //!< Reserved for future use } partition_t; //!@brief Bootloader meta data structure typedef struct { struct { uint32_t wdTimeout; uint32_t periphDetectTimeout; uint32_t enabledPeripherals; uint32_t reserved[12]; } features; partition_t partition[kPartition_Max];//16*4*7 bytes uint32_t meta_version; uint32_t patition_entries; uint32_t reserved0; uint32_t tag; } bootloader_meta_t;   3.2.2 swap meta Swap meta 0 : 0x6003e000, size 0x50 Swap meta 1 : 0x6003f000, size 0x50    OTA bootloader will read the swap meta from 2 different place, if it is not valid, bootloader will set the default data to swap meta 0(0x6003e000). If both image are valid, bootloader will choose the bigger version meta.    Bootloader will refer to the meta data to do the swap operation, sometimes, after reset, meta data will be modified automatically. It mainly relay on the swap_type: kSwapType_ReadyForTest :After reset, do swap operation. Modify meta swap_type to kSwapType_Test. Reset, as the meta data is kSwapType_Test, bootloader can do the rollback. kSwapType_Test : After reset, do rollback after operation, swap_type change to kSwapType_None.  kSwapType_Rollback bootloader will write kSwapType_Test to the meta, after reset, bootloader will refer to kSwapType_Test to do the operation.  kSwapType_Permanent After reset, modify meta data to kSwapType_Permanent, then the APP will boot with partition 1. Swap structure: //!@brief Swap progress definitions typedef struct { uint32_t swap_offset; //!< Current swap offset uint32_t scratch_size; //!< The scratch area size during current swapping uint32_t swap_status; // 1 : A -> B scratch, 2 : B -> A uint32_t remaining_size; //!< Remaining size to be swapped } swap_progress_t; typedef struct { uint32_t size; uint32_t active_flag; } image_info_t; //!@brief Swap meta information, used for the swapping operation typedef struct { image_info_t image_info[2]; //!< Image info table #if !defined(BL_FEATURE_HARDWARE_SWAP_SUPPORTED) || (BL_FEATURE_HARDWARE_SWAP_SUPPORTED == 0) swap_progress_t swap_progress; //!< Swap progress #endif uint32_t swap_type; //!< Swap type uint32_t copy_status; //!< Copy status uint32_t confirm_info; //!< Confirm Information uint32_t meta_version; //!< Meta version uint32_t reserved[7]; //!< Reserved for future use uint32_t tag; } swap_meta_t; 3.3 Common used API Bootloader provide the API for the customer to use it, the common used API are: 3.3.1 update_image_state   update swap meta data, before update, it will check the partition1 image valid or not, if image is not valid, swap meta data will not be updated, and return failure. 3.3.2 get_update_partition_info   get partition information, then define the image program address. 3.3.3 get_image_state   get the current boot image status. None/permanent/UnderTest 3.4  Swap rollback APP prepare Prepare two APPs: APP1 and APP2 bin file, and use the USB HID download to the partition1 and paritition 2. After reset, run APP1 in default, then use the COM input to select the swap and rollback function. Code is: int main(void) { char ch; status_t status; /* Board pin init */ BOARD_InitPins(); BOARD_InitBootClocks(); /* Update the core clock */ SystemCoreClockUpdate(); BOARD_InitDebugConsole(); PRINTF("\r\n------------------hello world + led blinky demo 2.------------------\r\n"); PRINTF("\r\nOTA bootloader test...\r\n" "1 - ReadyForTest\r\n" "3 - kSwapType_Permanent\r\n" "4 - kSwapType_Rollback\r\n" "5 - show image state\r\n" "6 - led blinking for 5times\r\n" "r - NVIC reset\r\n"); // show swap state in swap meta get_image_swap_state(); /* Set systick reload value to generate 1ms interrupt */ if (SysTick_Config(SystemCoreClock / 1000U)) { while (1) { } } while(1) { ch = GETCHAR(); switch(ch) { case '1': status = bl_update_image_state(kSwapType_ReadyForTest); PRINTF("update_image_state to kSwapType_ReadyForTest status: %i\n", status); if (status != 0) PRINTF("update_image_state(kSwapType_ReadyForTest): failed\n"); else NVIC_SystemReset(); break; case '3': status = bl_update_image_state(kSwapType_Permanent); PRINTF("update_image_state to kSwapType_Permanent status: %i\n", status); if (status != 0) PRINTF("update_image_state(kSwapType_Permanent): failed\n"); else NVIC_SystemReset(); break; case '4': status = bl_update_image_state(4); // PRINTF("update_image_state to kSwapType_Rollback status: %i\n", status); if (status != 0) PRINTF("update_image_state(kSwapType_Rollback): failed\n"); else NVIC_SystemReset(); break; case '5': // show swap state in swap meta get_image_swap_state(); break; case '6': Led_blink10times(); break; case 'r': NVIC_SystemReset(); break; } } } When download the APP, need to use the correct ota_header in the first 0x400 area, otherwise, swap will failed. const boot_image_header_t ota_header = { .tag = IMG_HDR_TAG, .load_addr = ((uint32_t)&ota_header) + BL_IMG_HEADER_SIZE, .image_type = IMG_TYPE_XIP, .image_size = 0, .algorithm = IMG_CHK_ALG_CRC32, .header_size = BL_IMG_HEADER_SIZE, .image_version = 0, .checksum = {0xFFFFFFFF}, }; This is a correct sample: Fig 12 Image size and checksum need to use the real APP image information, in the attached file, provide one image_header_padding.exe, it can input the none ota header image, then it will output the whole image which add the ota_header contains the image size and the image crc data in the first 0x400 range. 3.5 Test steps and result Prepare the none header APP1 evkmimxrt1060_APP1_0X60040400.bin, APP2 image evkmimxrt1060_APP2_0X60240400.bin, and put blhost.exe, image_header_padding.exe in the same folder. APP1 and APP2 just the printf version is different, one is version1, another is version2. Printf result: hello world + led blinky demo 1 hello world + led blinky demo 2 Attached OTAtest folder is used for test, but need to download the blhost.exe from the below link, and copy the blhost.exe to the OTAtest folder. https://www.nxp.com/webapp/sps/download/license.jsp?colCode=blhost_2.6.6&appType=file1&DOWNLOAD_ID=null Then run the following bat command: image_header_padding.exe evkmimxrt1060_APP1_0X60040400.bin 0x60040400 sleep 20 blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0 sleep 20 blhost.exe -u -t 1000000 -- flash-erase-region 0x6003c000 0x4000 sleep 50 blhost -u -t 5000 -- flash-erase-region 0x60040000 0x10000 sleep 50 blhost -u -t 5000 -- write-memory 0x60040000 boot_img_crc32.bin sleep 100 image_header_padding.exe evkmimxrt1060_APP2_0X60240400.bin 0x60040400 sleep 20 blhost -u -t 5000 -- flash-erase-region 0x60240000 0x10000 sleep 50 blhost -u -t 5000 -- flash-erase-region 0x6043b000 0x10000 sleep 50 blhost -u -t 5000 -- write-memory 0x60240000 boot_img_crc32.bin sleep 100 pause The function is to generate the APP1 with the correct ota_header, erase parititon 1,program APP1 to partition 1, generate the APP2 with the correct ota_header, erase partition 2 and scratch area, program APP2 to partition 2, Run the .bat file should in 5 seconds after reset, then use the ISP to connect it: blhost.exe -t 50000 -u 0x15a2,0x0073 -j -- get-property 1 0 ota_bootloader can use the ota_bootloader project download directly to the 0X60000000 area. After downloading, reset the chip, and wait for 5 seconds, the APP will run. This is the test result: Fig 13 From the test result, we can find, in the first time boot, APP1 running, image state: none Input 1, do the swap, will find the APP2 running, image state: undertest Input 3, select permanent, reset will find, still APP2 running, image state: permanent Input 4, choose rollback, reset will find APP1 running, image states: none Until now, finish the swap and rollback function. Input 6, will find the APP contains the SDRAM led blinky is working.          
View full article
Introduction Normal Cortex-M core-based MCUs generally have built-in parallel NOR Flash. The parallel NOR Flash is directly hung on the Cortex-M core high-performance AHB bus. If a well-known IDE supports the MCU, it should integrate the corresponding Flash driver algorithm which enables the developer to program and debug the MCU in the IDE. However, the i.MX RT series MCU doesn't contain the internal flash, how do developers debug these MCUs with online XIP (eXecute-In-Place)? Take easy, i.MXRT can support external parallel NOR and serial NOR to run the XIP, benefit from saving the number of pins, serial NOR Flash is most commonly used and FlexSPI supports XIP feature which makes online debug available. The article introduces the mechanism of debugging the external serial NOR flash with the RT MCU and illustrates the steps of modifying the flash driver algorithm of MCUXpresso. CoreSight Technical The i.MX RT series MCU is based on the Cortex-M core and the CoreSight Technical is a new debugging architecture launched by ARM in 2004 and is also a part of the core authorization, supports the debug and trace feature for Cortex-M core-based MCU. CoreSight is very powerful. It contains many debugging components (ie various protocols). The following figure is from the CoreSight Technical Introduction Manual, which shows the connections between various debugging components under the CoreSight architecture. Fig 1 CoreSight Technical This article does not mainly aim to introduce CoreSight technical. Therefore, for CoreSight, we only need to know that it in charge of the main debugging work and the CoreSight can access the system memory and peripheral register from the AMBA bus through the DAP component in real-time, definitely, it includes the code in the external serial Flash. FlexSPI module To implement debugging in serial Flash, the code must be XIP in serial Flash, that is, the CPU must be able to fetch instructions and data from any address in serial Flash in real-time. The serial Flash mentioned in this article generally refers to the 4-wire SPI Interface NOR Flash and the SPI mode can be Single/Dual/Quad/Octal. No matter which SPI mode is, the Flash is essentially serial Flash, and the address lines and data lines are not only shared but also serial. According to conventional knowledge, to implement the XIP, Flash should be a parallel bus interface and hung on AMBA, further, this parallel bus should have independent address lines and data lines, and the width of the address lines correspond to the size of Flash. So why can run XIP in serial Flash with i.MXRT? The answer is the FlexSPI peripheral. Figure 2 is the FlexSPI module block diagram. On the right side of the block diagram is the signal connection between FlexSPI and external serial Flash. The left side is the connection between FlexSPI and the internal bus of the i.MXRT system. There are two types of bus interface: 32bit IPS BUS (manual manipulate the FlexSPI register sends Flash reading and writing commands) and 64bit AHB BUS (FlexSPI translates the AHB access address and automatically sends the corresponding Flash reading and writing commands) which is the key feature enables the XIP available. Fig 2 FlexSPI module In the Reference manual, it lists detailed information about the AHB bus: - AHB RX Buffer implemented to reduce read latency. Total AHB RX Buffer size: 128 * 64 Bits - 16 AHB masters supported with priority for reading access - 4 flexible and configurable buffers in AHB RX Buffer - AHB TX Buffer implemented to buffer all write data from one AHB burst. AHB TX Buffer size: 8 * 64 Bits - All AHB masters share this AHB TX Buffer. No AHB master number limitation for Write Access. In addition, the AHB bus includes the below-enhanced features to optimize the reading of Serial Flash memory. - Cachable and Non-Cachable access - Prefetch Enable/Disable - Burst size: 8/16/32/64 bits - All burst type: SINGLE/INCR/WRAP4/INCR4/WRAP8/INCR8/WRAP16/INCR16 Debugging process of serial Flash Fig 3 illustrates the debugging process of serial Flash with the RT series MCU and in basic, the overview of the debugging process is not complicated. When you click IDE debugging icon, the Flash driver algorithm (executable file) pre-installed in the IDE will be downloaded to the internal FlexRAM of i.MXRT via the debugger firstly. The Flash driver algorithm provides FlexSPI initialization, erase and programming APIs, etc. Next, the debugger caches the application code (binary machine code) in FlexRAM in segments prior to calling the Flash programming API to implement the program work. After completing programming application code (from FlexRAM to Flash), CoreSight will take over the debugging work. At this time, the CPU can access the serial Flash that connects the FlexSPI module through the AHB bus, in another word, CoreSight can control and track code in real-time, and single-step debugging is available too in the IDE. Fig 3 Flash Driver of MCUXpresso IDE The latest version (11.3.1) of MCUXpresso IDE supports all RT series MCU (as the following figure shows), the developer should select a suitable flash driver file to apply to his board (Fig 5). Fig 4 MCUXpresso IDE Fig 5 Flash driver files As mentioned above, the RT series MCUs don't have an internal flash, so they must use an either external parallel or serial NOR. For IDE providers, it's too hard to provide enough flash drivers to fit all external NOR flashes, the workload is huge, so IDEs general provide the flash driver files for mainstream Serial NOR, especially, 4-wire SPI Interface NOR Flash, it means we need to modify or tune the flash driver to fit our specific application. Add new flash driver of MCUXpresso IDE Before start, we should realize that MCUXpresso IDE is different from MDK/IAR. The flash driver algorithms of MDK and IAR are independent of the specific debug tools and they are able to use with all supported debug tools (JLink/DAPLink, etc). For MCUXpresso IDE, the flash driver algorithms are only able to use with the CMSIS-DAP type debug tool. For instance, when you use JLink with MCUXPresso IDE, it will use the flash driver algorithm of Jlink instead of its own. There's a real case from a customer: He currently designs his new card reader module based on RT1024 and he plans to make a board without external RAM and Flash. In other words, he only utilizes the internal 4MB flash and 256KB FlexRAM which consist of SRAM_DTC(64KB), SRAM_ITC(64KB), SRAM_OC(128KB). So he wants to configure the 256KB RAM area as normal 256KB RAM without being allocated to ITCM and DTCM. He follows the thread to reconfigure the FlexRAM, but he still encounters the below problem (as Fig 6 shows ) when entering debug mode. Fig 6 According to the debug failure log, we can come to a conclusion that the flash drive file: MIMXRT1020.cfx needs to be updated, and the following steps illustrate how to do it. a) Select a source project There are some flash driver projects in the Examples/Flashdrivers/NXP subdirectory within the MCUXpresso IDE installation directory (as Fig 7 shows) and iMXRT folder contains some flash driver projects for external flash parts that work with the RT series MCU (as Fig 8 shows). Fig 7 Fig 8 Select the flash driver project which is the closest to the target as a prototype, in this case, we select the iMXRT1020_QSPI project, extract the project file and import them in the MCUXpresso IDE (as Fig 9). Fig 9 b) Modify pin assignment The RT1024 integrates a 4 MB QSPI flash as an "internal flash", it is connected to different FlexSPI pins versus to the default pins of the iMXRT1020_QSPI project just as the below table shows. FlexSPI pin RT1020 RT1024 FLEXSPI_A_DQS GPIO_SD_B1_05 GPIO_SD_B1_05 FLEXSPI_A_SS0_B GPIO_SD_B1_11 GPIO_AD_B1_05 FLEXSPI_A_SCLK GPIO_SD_B1_07 GPIO_AD_B1_01 FLEXSPI_A_DATA0 GPIO_SD_B1_08 GPIO_AD_B1_02 FLEXSPI_A_DATA1 GPIO_SD_B1_10 GPIO_AD_B1_04 FLEXSPI_A_DATA2 GPIO_SD_B1_09 GPIO_AD_B1_03 FLEXSPI_A_DATA3 GPIO_SD_B1_06 GPIO_AD_B1_00 So it needs to adjust the pin initialization in the BOARD_InitPins() function in pin_mux.c. /* FUNCTION ************************************************************************************************************ * * Function Name : BOARD_InitPins * Description : Configures pin routing and optionally pin electrical features. * * END ****************************************************************************************************************/ void BOARD_InitPins(void) { CLOCK_EnableClock(kCLOCK_Iomuxc); /* iomuxc clock (iomuxc_clk_enable): 0x03u */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_06_LPUART1_TX, /* GPIO_AD_B0_06 is configured as LPUART1_TX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B0_07_LPUART1_RX, /* GPIO_AD_B0_07 is configured as LPUART1_RX */ 0U); /* Software Input On Field: Input Path is determined by functionality */ IOMUXC_SetPinMux( IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS, /* GPIO_SD_B1_05 is configured as FLEXSPI_A_DQS */ 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_05 */ // IOMUXC_SetPinMux( // IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, /* GPIO_SD_B1_06 is configured as FLEXSPI_A_DATA03 */ // 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_06 */ // IOMUXC_SetPinMux( // IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, /* GPIO_SD_B1_07 is configured as FLEXSPI_A_SCLK */ // 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_07 */ // IOMUXC_SetPinMux( // IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, /* GPIO_SD_B1_08 is configured as FLEXSPI_A_DATA00 */ // 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_08 */ // IOMUXC_SetPinMux( // IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, /* GPIO_SD_B1_09 is configured as FLEXSPI_A_DATA02 */ // 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_09 */ // IOMUXC_SetPinMux( // IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, /* GPIO_SD_B1_10 is configured as FLEXSPI_A_DATA01 */ // 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_10 */ // IOMUXC_SetPinMux( // IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, /* GPIO_SD_B1_11 is configured as FLEXSPI_A_SS0_B */ // 1U); /* Software Input On Field: Force input path of pad GPIO_SD_B1_11 */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_00_FLEXSPI_A_DATA03, /* GPIO_AD_B1_00 is configured as FLEXSPI_A_DATA03 */ 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_00 */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_01_FLEXSPI_A_SCLK, /* GPIO_AD_B1_01 is configured as FLEXSPI_A_SCLK */ 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_01 */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_02_FLEXSPI_A_DATA00, /* GPIO_AD_B1_02 is configured as FLEXSPI_A_DATA00 */ 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_02 */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_03_FLEXSPI_A_DATA02, /* GPIO_AD_B1_03 is configured as FLEXSPI_A_DATA02 */ 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_03 */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_04_FLEXSPI_A_DATA01, /* GPIO_AD_B1_04 is configured as FLEXSPI_A_DATA01 */ 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_04 */ IOMUXC_SetPinMux( IOMUXC_GPIO_AD_B1_05_FLEXSPI_A_SS0_B, /* GPIO_AD_B1_05 is configured as FLEXSPI_A_SS0_B */ 1U); /* Software Input On Field: Force input path of pad GPIO_AD_B1_05 */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_B0_06_LPUART1_TX, /* GPIO_AD_B0_06 PAD functional properties : */ 0x10B0u); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: R0/6 Speed Field: medium(100MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_AD_B0_07_LPUART1_RX, /* GPIO_AD_B0_07 PAD functional properties : */ 0x10B0u); /* Slew Rate Field: Slow Slew Rate Drive Strength Field: R0/6 Speed Field: medium(100MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_05_FLEXSPI_A_DQS, /* GPIO_SD_B1_05 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_06_FLEXSPI_A_DATA03, /* GPIO_SD_B1_06 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_07_FLEXSPI_A_SCLK, /* GPIO_SD_B1_07 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_08_FLEXSPI_A_DATA00, /* GPIO_SD_B1_08 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_09_FLEXSPI_A_DATA02, /* GPIO_SD_B1_09 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_10_FLEXSPI_A_DATA01, /* GPIO_SD_B1_10 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ IOMUXC_SetPinConfig( IOMUXC_GPIO_SD_B1_11_FLEXSPI_A_SS0_B, /* GPIO_SD_B1_11 PAD functional properties : */ 0x10F1u); /* Slew Rate Field: Fast Slew Rate Drive Strength Field: R0/6 Speed Field: max(200MHz) Open Drain Enable Field: Open Drain Disabled Pull / Keep Enable Field: Pull/Keeper Enabled Pull / Keep Select Field: Keeper Pull Up / Down Config. Field: 100K Ohm Pull Down Hyst. Enable Field: Hysteresis Disabled */ } c) Modify linker file According to Fig 3, a flash driver should be downloaded into FlexRAM on the target MCU during the debuggingprocess, for the iMXRT1020_QSPI project, the flash driver needs to be downloaded to DTCM (0x2000_0000~0x2001_0000), however, to meet the customer's demand, the whole of FlexRAM is reconfigured to SRAM_OC in the ResetISR() function. In another word, there's no DTCM area to load the flash driver and it causes the above debug failure. So we need to use the SRAM_OC instead of DTCM to load the flash driver just like the below shows. In the FlashDriver_32Kbuffer.ld of iMXRT1020_QSPI project: /* * Linker script for NXP LPC546xx SPIFI Flash Driver (Messaged) */ MEMORY { /*SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = (64 * 1024)*/ SRAM (rwx) : ORIGIN = 0x20200000, LENGTH = (64 * 1024) } /* stack size : multiple of 8*/ __stack_size = (4 * 1024); /* flash image buffer size : multiple of page size*/ __cache_size = (32 * 1024); /* Supported operations bit map * 0x40 = New device info available after Init() call * This setting must match the actual target flash driver build! */ __opmap_val = 0x1000; /* Actual placement of flash driver code/data controlled via standard file */ INCLUDE "../../LPCXFlashDriverLib/linker/placement.ld" d) Recompile In the LPCXFlashDriverLib project, select the Release_SectorHashing option prior to clicking the Build icon to generate libLPCXFlashDriverLib.a file (as Fig 10 shows). Fig 10 Next, in the iMXRT1020_QSPI project, select the MIMXRT1020-EVK_IS25LP064 option (as Fig 11 shows), then click the Build icon to generate a new flash driver file that resides in ~\Examples\Flashdrivers\NXP\iMXRT\iMXRT1020_QSPI\iMXRT1020_QSPI\builds directory. Fig 11 Note: I've attached a test project which is based on the hello_world demo that comes from the RT1024's SDK library, in addition, the attachment also contains the new flash driver and corresponding debug script files, so please give it a try.  
View full article
Overview of i.MX RT1050         The i.MX RT1050 is the industry's first crossover processor and combines the high-performance and high level of integration on an applications processors with the ease of use and real-time functionality of a micro-controller. The i.MX RT1050 runs on the Arm Cortex-M7 core at 600 MHz, it means that it definitely has the ability to do some complicated computing, such as floating-point arithmetic, matrix operation, etc. For general MCU, they're hard to conquer these complicated operations.         It has a rich peripheral which makes it suit for a variety of applications, in this demo, the PXP (Pixel Pipeline), CSI (CMOS Sensor Interface), eLCDIF (Enhanced LCD Interface) allows me to build up camera display system easily Fig 1 i.MX RT series           It has a rich peripheral which makes it suit for a variety of applications, in this demo, the PXP (Pixel Pipeline), CSI (CMOS Sensor Interface), eLCDIF (Enhanced LCD Interface) allows me to build up camera display system easily Fig 2 i.MX RT1050 Block Diagram Basic concept of Compute Vision (CV)          Machine Learning (ML) is moving to the edge because of a variety of reasons, such as bandwidth constraint, latency, reliability, security, ect. People want to have edge computing capability on embedded devices to provide more advanced services, like voice recognition for smart speakers and face detection for surveillance cameras. Fig 3 Reason        Convolutional Neural Networks (CNNs) is one of the main ways to do image recognition and image classification. CNNs use a variation of multilayer perception that requires minimal pre-processing, based on their shared-weights architecture and translation invariance characteristics. Fig 4 Structure of a typical deep neural network         Above is an example that shows the original image input on the left-hand side and how it progresses through each layer to calculate the probability on the right-hand side. Hardware MIMXRT1050 EVK Board; RK043FN02H-CT(LCD Panel) Fig 5 MIMXRT1050 EVK board Reference demo code emwin_temperature_control: demonstrates graphical widgets of the emWin library. cmsis_nn_cifar10: demonstrates a convolutional neural network (CNN) example with the use of convolution, ReLU activation, pooling and fully-connected functions from the CMSIS-NN software library. The CNN used in this example is based on the CIFAR-10 example from Caffe. The neural network consists of 3 convolution layers interspersed by ReLU activation and max-pooling layers, followed by a fully-connected layer at the end. The input to the network is a 32x32 pixel color image, which is classified into one of the 10 output classes. Note: Both of these two demo projects are from the SDK library Deploy the neuro network mode Fig 6 illustrates the steps of deploying the neuro network mode on the embedded platform. In the cmsis_nn_cifar10 demo project, it has provided the quantized parameters for the 3 convolution layer, so in this implementation, I use these parameters directly, BTW, I choose 100 images randomly from the Test set as a round of input to evaluate the accuracy of this model. And through several rounds of testing, I get the model's accuracy is about 65% as the below figure shows. Fig 6 Deploy the neuro network mode Fig 7 cmsis_nn_cifar10 demo project test result The CIFAR-10 dataset is a collection of images that are commonly used to train ML and computer vision algorithms, it consists of 60000 32x32 color images in 10 classes, with 6000 images per class ("airplane", "automobile", "bird", "cat", "deer", "dog", "frog", "horse", "ship", "truck"). There are 50000 training images and 10000 test images. Embedded platform software structure         After POR, various components are initialized, like system clock, pin mux, camera, CSI, PXP, LCD and emWin, etc. Then control GUI will show up in the LCD, press the Play button will display the camera video in the LCD, once an object into the camera's window, you can press the Capture button to pause the display and run the model to identify the object. Fig8 presents the software structure of this demo. Fig 8 Embedded platform software structure Object identify Test The three figures present the testing result.   Fig 9 Fig 10 Fig 11 Furture work          Use the Pytorch framework to train a better and more complicated convolutional network for object recognition usage.
View full article