i.MX RT Crossover MCUs Knowledge Base

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 

i.MX RT Crossover MCUs Knowledge Base

讨论

排序依据:
RT1170 SBL ISP download SDRAM APP 1. Abstract NXP officially launched SBL and SFW for RT bootloader, which can well meet the requirements for secondary bootloader in regular use. Such as ISP, OTA, encryption and other functions. For specific SBL/SFW situations, you can view the application notes: https://www.nxp.com/docs/en/user-guide/MCUOTASBLSFWUG.pdf This article is mainly based on SBL and uses the ISP method to download user apps. Recently I encountered a case about RT1170 using the SBL ISP function to download APP. After configuring SBL, there is no problem in downloading simple SDK codes such as led_blinky and helloword. However, if you download the SDK GUI demo, such as vglite_examples\vector_freertos code, we find that the boot fails . The same applies to operations such as app offset, and the code size does not exceed 1MByte. However, SDK GUI demo uses SDRAM, so we speculated that it is related to SBL's SDRAM enablement. This article will explain how to use SBL ISP to download an app with SDRAM and make it boots OK. 2. Operation steps 2.1 SBL configuration and programming Firstly, Download SBL source code and unzip it: https://github.com/nxp-mcuxpresso/sbl Download the ARM GCC and install it, here is the gcc-arm-none-eabi-9-2019-q4-major-win32.exe link: https://developer.arm.com/-/media/Files/downloads/gnu-rm/9-2019q4/gcc-arm-none-eabi-9-2019-q4-major-win32-sha2.exe?revision=ba95cefa-1880-4932-94d4-ebf30ad3f619&rev=ba95cefa1880493294d4ebf30ad3f619&hash=B2513193FEEED9E850C62399EFF9DA04C0F0A809 The install path is: C:\Program Files (x86)\GNU Tools Arm Embedded\9 2019-q4-major\bin Open \sbl-master\target\evkmimxrt1170\ sblprofile.py, modify EXEC_PATH to the new installed ARM_GCC path: EXEC_PATH   = r'C:\Program Files (x86)\GNU Tools Arm Embedded\9 2019-q4-major\bin' This is the SBL configuration steps: (1). Open \sbl-master\target\evkmimxrt1170\ env.bat input: scons –menuconfig Fig 1 (2). Configure Single image OTA    MCU SBL core->[*]Enable single image function Fig 2 (3) Configure enable SDRAM Fig 3 Fig 4 Fig 5 After configuration, save the .config file, save and exit it. Fig 6 (4) Generate the sbl iar project In the window, input:  scons --ide=iar Then use IAR IDE to open \sbl-master\target\evkmimxrt1170\iar\sbl.eww You can see, the SDRAM DCD has been added now: Fig 7 (5) Configure the secure information Input the following command in the commander window: cd ..\..\component\secure\mcuboot\scripts Switch the commander path, then use the following command to generate the pub key and private key: python imgtool.py keygen -k xxxx_priv.pem -t rsa-2048-sign python imgtool.py getpub -k xxxx_priv.pem -o xxxx_pub.pem -t sign Fig 8 Open the file in path:sbl-master\component\secure\mcuboot\scripts\ xxxx_pub.c, copy the pub key information, and replay it to the file in path: \sbl-master\component\secure\mcuboot\sign-rsa2048-pub.c Then, it will update the SBL pub key information, now open the IAR project: \sbl-master\target\evkmimxrt1170\iar \sbl.eww Build the project, and use the debugger to download the SBL code to the MIMXRT1170-EVK board, I use the EVK on board debugger CMSIS DAP to download the sbl code.   2.2 APP configuration This document app is using the MCUXpresso IDE to import the SDK project: evkmimxrt1170_vector_freertos_cm7 Configure the flash start location to offset address:0X30100400 Fig 9 Delete the FCB and DCD header like this: Fig 10 Build the project, and generate the bin file:evkmimxrt1170_vector_freertos_cm7.bin, copy it to the SBL folder: sbl-master\component\secure\mcuboot\scripts Still in the commander window which you open the env.bat after you change the path previously: python imgtool.py sign --key xxxx_priv.pem --align 4 --version "1.1" --header-size 0x400 --pad-header --slot-size 0x100000 --max-sectors 32 evkmimxrt1170_vector_freertos_cm7.bin app2.bin This will help the app to add the header which matches the SBL requirement, and generate the app2.bin, which is the used app downloading file. 3. Test Result After the above configuration, it already downloads the SBL to the MIMXRT1170-EVK, and prepares the used app which contains the SDRAM, now use the MCUBootutility tool to download the app2.bin. Fig 11 Note, the Tools->Run Mode, should be SBL OTA mode. Find another USB cable to connect the EVK SDP J20 to the PC, after the EVK board reset, within the 5 seconds, connect the board by connection the MCUBootutility button “connect to SBL ISP”, then in the Fig 11, step 4, add the prepared app2.bin, step 3, input the address to: 0X30100000, then use step 5 to download the app. After app is downloaded, reset and exit the connection. Reset the board, wait 5 seconds, you will find the LCD can display the figure, it means the GUI code is working, and the printf log is: Fig 12 The board displays the result like this: Fig 13 At this point, the app with SDRAM has been successfully run in combination with SBL, indicating that the configuration of SBL with SDRAM is successful.        
查看全文
This demo code shows how to synchronize the PWM signals with another internal timer or an off-chip source. It allows you to achieve slower PWM frequencies than those that can be achieved with internal clocks as well as that multiple modules and multiple chips can be synchronized to each other. The idea is the following: The QTMR generates a PWM signal (external clock signal) which is routed through the XBAR to clocking the eFlexPWM, and at the same, the external clock signal is routed to an IO PAD in the first MCU. In a second MCU, an IO PAD is routed through the XBAR to clocking the eFlexPWM (see Figure 1).   Figure 1     The demo code (only MCU1 part so far) can me tested using the SDK for EVKB-IMXRT1050 v2.14.0. Probe the PWM signals using an oscilloscope: - At J24-1  GPIO_AD_B0_03  XBAR1_INOUT17 (QTMR PWM signal) - At J24-6  GPIO_SD_B0_00  FLEXPWM1_PWM0_A - At J24-3  GPIO_SD_B0_01  FLEXPWM1_PWM0_B Please remember weld resistors 0Ω at R280 R281.
查看全文
RT1170 Boundary Scan test based on lauterbach   1. Abstract Boundary Scan is a method of testing interconnections on circuit boards or internal sub-blocks of circuits. You can also debug and observe the pin status of the integrated circuit, measure the voltage or analyze the sub-modules inside the integrated circuit, and test based on the JTAG interface. NXP officials have provided two good application notes: AN13507 (LPC) and AN12919 (RT). Based on the reference application note test method, this article provides the boundary scan test results for NXP MIMXRT1170-EVK revC1. It can use Lauterbach to connect the chip and perform boundary scan to control the external pins. A script file is also provided. It can realize one-click connection to boundary scan and achieve level control of external pins. 2. RT1170 test details   2.1 Hardware platform Lauterbach:LA3050 MIMXRT1170-EVK rev C1: The hardware modification point is to remove the onboard resistors R187, R208, R195 and R78. The purpose is that J6 prohibits external circuits from interfering with JTAG related pins. Disconnect J5, J6, J7, J8, that is, disconnect the onboard debugger, and use an external Lauterbach connection to J1. The connection situation is as follows: Fig 1 RT1170 directly supports both SWD and JTAG by default, so unlike RT10XX which needs to modify the fuse to convert from SWD to JTAG, RT1170 can directly use the JTAG interface.   2.2 Software operation Download Lauderbach's supporting software and install it. After installation, open the TRACE32 ICD Arm USB. If the Lauderbach device is connected, the interface will open successfully. Fig 2 At this time, you can enter the relevant commands in the yellow box in the picture above. Here you need to prepare the .bsdl file of the chip, which is usually placed on the chip introduction page of nxp.com. For example, the link to the bsdl file of RT1170 is: https://www.nxp.com/downloads/en/bsdl/i.MXRT1170_BDSL.bsdl You can copy the i.MXRT1170_BSDL.bsdl file to the Lauderbach installation path: C:\T32 Next, enter the following command in the window to open the boundary scan window and the i.MXRT1170_BSDL.bsdl file: SYStem.Mode Down BSDL.RESet BSDL.ParkState Select-DR-Scan BSDL.state Here, it will open the window: Fig 3 Click FILE item, input the downloaded i.MXRT1170_BSDL.bsdl, then in the window.,input the commander: BSDL.SOFTRESET Fig 4 Click check->BYPASSall,IDCODEall,SAMPLEall, make sure the 3 methods can be passed. Fig 5 Fig 6 Fig 7 To test the output control situation, it need to do the following operation: BSDLSET 1.: instructions->EXTEXT, DR mode->Set Write, Fileter data->uncheck intern BSDL.state->Run: check SetAndRun, TwoStepDR, Click RUN. BSDLSET 1. Can control the related pins, eg, GPIO_AD_26 is on the on board D34 LED. 1 ON,0 OFF. Fig 8   2.3 Automation control command script As can be seen from Section 2.2, single-step operation requires manual typing of commands. In actual testing, the efficiency is very low, so scripting language can be used to directly implement automated command control. Below, taking RT1170 as an example, we provide a script to control the on-board D34 light on and off. In this way, when the TRACE32 software is opened, you only need to open the script directly, enter the debug mode, run it to the end with one click, and check the on-board light control status. Script language file, the suffix is .cmm, step: File->New Script, enter the following script command: ;system setup SYStem.Mode Down SYStem.CPU CortexM7 SYSTEM.CONFIG.DEBUGPORTTYPE JTAG SYStem.JtagClock 1MHz ;BSDL Settings BSDL.RESet BSDL.ParkState Select-DR-Scan BSDL.state ;configure boundary scan chain BSDL.FILE i.MXRT1170_BDSL.bsdl ;Check boundary scan chain BSDL.SOFTRESET BSDL.BYPASSall BSDL.IDCODEall BSDL.SAMPLEall ;Perform Sample test BSDL.RUN BSDL.SetAndRun ON BSDL.TwoStepDR ON BSDL.SET 1. BSDL.SET 1. IR EXTEST BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 0 WAIT 1.s BSDL.SET 1. PORT GPIO_AD_26 1 WAIT 1.s Function, the led will be blinking 5 times, duration is 1s. Save the script, then debug it. Fig 9 This is the video for the testing:   It can be seen that the onboard light D34 can automatically flash, indicating that the BSDL automatic test has been completed so far.          
查看全文
RT1050 FlexIO OV7670 with TFT LCDdisplay 1 Abstract Regarding the RT10XX flexIO collecting OV7670 camera data and displaying it on TFT LCD, in fact, the NXP official website has a very good application note AN12686, but the test is based on RT1010 and not EVK. It may be difficult for actual customers to test directly. When the author was supporting customers, I encountered customers who wanted to implement flexIO on RT1050 EVK to collect parallel port OV7670 data and display it on TFT LCD, which is the LCD with SPI interface, so this article gives the specific test results of the finished product, RT1050 flexIO and There are some differences between RT1010 flexIO. RT1010 flexIO has 8 shifters, but RT1050 only has 4 shifters, so some code modifications need to be made and transplanted to RT1050. Since it is going to run on MIMXRT1050-EVKB, you also need to consider the flexIO pins that can be used, modify the EVKB, and manually weld the relevant pins to configure the corresponding camera signals and LCD display signals. This article mainly comes from problems encountered by customers during testing, so it provides specific hardware connections, software code sharing, test finished product results, etc. 2. Software and hardware prepare Since AN12686 has given the principle in great detail, this article aims to give the differences and the specific conditions of working on RT1050-EVKB. 2.1 Hardware configuration The platform is based on MIMXRT1050-EVKB revA1, OV7670 module, 2.4-inch TFT LCD LCD SPI serial touch TFT color screen ILI9321, with a resolution of 240*320.     For the OV7670 module status and pin status, please check the article:    RT1050 CSI OV7670 camera eLCD display The camera module pins are as follows: Fig 1    TFT LCD picture: Fig 2 Pin No Signal Description 1 GND Power ground 2 VCC Power 3.3V 3 CLK SPI clock 4 MOSI SPI data 5 RES LCD reset 6 DC LCD data/commander select pin 7 BLK Backlight control switch, backlight is turned on by default, low level turns off the backlight 8 MISO Touch data reading 9 CS1 Display selection pin 10 CS2 Touch selection pin 11 PEN Touch interrupt signal For LCD, this article only uses the display part and does not use the rough mold part. Considering the pin layout of MIMXRT1050-EVKB, the application note flexIO1 is not used here, but FlexIO2 is selected. The actual RT1050-EVKB and OV7670 module and LCD connection pins are given below. The connection between the LCD signal pin and the MCU MIMXRT1050-EVKB RevA1 signal pin is as follows: LCD signal and pin MIMXRT1050-EVKB revA1 signal and pin GND P1 GND J24_7 3.3V VCC P2 3.3V J24_8 CLK P3 GPIO_AD_B1_15(SPI3_CLK) R98 MOSI P4 GPIO_AD_B1_14(SPI3_MOSI) R99 RES P5 GPIO_AD_B0_02(GPIO1_IO02) J24_2 DC P6 GPIO_AD_B1_10(GPIO01_IO26) J23_1 CS1 P9 GPIO_AD_B1_12(GPIO01_IO28) R100   OV7670 signal pin and MCU MIMXRT1050-EVKB RevA1 signal pin connection situation: 0V7670 signal and pin MIMXRT1050-EVKB revA1 signal and pin OV7670_D0 P3 GPIO_B0_05(FLEXIO2_D05) SW5_1 OV7670_D1 P4 GPIO_B0_06(FLEXIO2_D06) SW5.2 OV7670_D2 P5 GPIO_B0_07(FLEXIO2_D07) SW5_3 OV7670_D3 P6 GPIO_B0_08(FLEXIO2_D08) SW5_4 OV7670_D4 P7 GPIO_B0_09(FLEXIO2_D09) SW6_1 OV7670_D5 P8 GPIO_B0_10(FLEXIO2_D10) SW7_1 OV7670_D6 P9 GPIO_B0_11(FLEXIO2_D11) SW6_2 OV7670_D7 P10 GPIO_B0_12(FLEXIO2_D12) SW6_3 XCLK P11 GPIO_B0_13(FLEXIO2_D13) SW7_2 PCLK P12 GPIO_B0_14(FLEXIO2_D14) SW6_4 HREF(HS) P13 GPIO_B0_15(FLEXIO2_D15) R258/R324 VSYNC P14 GPIO_AD_B0_03(GPIO01_03) J24_1 I2C_SDA P15 GPIO_AD_B1_01(I2C1_SDA) J23_5 I2C_SCL P16 GPIO_AD_B1_00(I2C1_SCLK) J23_6 PWDN P1 GPIO_AD_B1_02(GPIO1_IO18) J22_7 RESET P2 GPIO_AD_B1_03(GPIO1_IO19) J22_8 3.3V P18 3.3V J22_7 GND P17 GND J22_8 In order to reduce the impact of the signal, MIMXRT1050-EVKB removes R323, R316, R309, and D6 on the board. The physical connection situation is as follows: Fig 3 2.2 Software configuration Since the flexIO of RT1050 is different from the 8 shifters of RT1010, the DMA configuration needs to be modified. The difference code of flexio_ov7670 is as follows:   static FLEXIO_CAMERA_Type s_FlexioCameraDevice = { .flexioBase = BOARD_CAMERA_FLEXIO_INST, .datPinStartIdx = BOARD_CAMERA_FLEXIO_DATA_PIN_START_INDEX, .pclkPinIdx = BOARD_CAMERA_FLEXIO_PCLK_PIN_INDEX, .hrefPinIdx = BOARD_CAMERA_FLEXIO_HREF_PIN_INDEX, .shifterStartIdx = 0U, .shifterCount = 4, .timerIdx = 0U, }; static void configDMA(void) { uint32_t soff, smod = 0u, size=0u; while(1u << size < DMA_TRSF_SIZE) /* size = log2(DMA_TRSF_SIZE) */ { size++; } if(DMA_TRSF_SIZE == DMA_MINOR_LOOP_SIZE) { soff = 0u; } else { soff = DMA_TRSF_SIZE; while(1u << smod < DMA_MINOR_LOOP_SIZE) /* smod = log2(DMA_MINOR_LOOP_SIZE) */ { smod++; } } /* Configure DMA TCD */ DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].SADDR = FLEXIO_CAMERA_GetRxBufferAddress(&s_FlexioCameraDevice); DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].SOFF = soff; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].ATTR = DMA_ATTR_SMOD(smod) | DMA_ATTR_SSIZE(size) | DMA_ATTR_DMOD(0u) | DMA_ATTR_DSIZE(size); DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].NBYTES_MLNO = 16; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].SLAST = 0u; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].DADDR = (uint32_t)(*pFlexioCameraFrameBuffer); DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].DOFF = 8; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].CITER_ELINKNO = DMA_MAJOR_LOOP_SIZE; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].DLAST_SGA = -OV7670_FRAME_BYTES; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].CSR = 0u; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].CSR |= DMA_CSR_DREQ_MASK; DMA0->TCD[FLEXIO_CAMERA_DMA_CHN].BITER_ELINKNO = DMA_MAJOR_LOOP_SIZE; /* Configure DMA MUX Source */ DMAMUX->CHCFG[FLEXIO_CAMERA_DMA_CHN] = DMAMUX->CHCFG[FLEXIO_CAMERA_DMA_CHN] & (~DMAMUX_CHCFG_SOURCE_MASK) | DMAMUX_CHCFG_SOURCE(FLEXIO_CAMERA_DMA_MUX_SRC); /* Enable DMA channel. */ DMAMUX->CHCFG[FLEXIO_CAMERA_DMA_CHN] |= DMAMUX_CHCFG_ENBL_MASK; } The code structure adopts: the camera uses flexIO mode to collect DMA transfer. After collecting one frame, DMA stores the data into the buffer, and then displays one frame of data uniformly on the LCD. Since there are many configuration codes for flexIO OV7670 and LCD SPI, we will not explain them one by one here. Please check the attached code source code for details. There is a header file of horsepic.h in the code. This file is a 320*240 RGB565 picture of a horse. It is used to test the LCD display separately. Usually after connecting the LCD, you need to test the LCD display separately. You can use a fixed picture to get the display. , here is the method of converting the picture into a C array: First adjust the picture to the LCD resolution size, and then convert it through the LVGL online conversion tool, select CF_RGB565A8, but the RGB565 generated by this format will have 1 more byte each, you can do it yourself After deletion, it can be called by code: https://lvgl.io/tools/imageconverter Display horse picture code: convert8to16(); ILI9341_FillPic(0, 0, OV7670_FRAME_WIDTH-1u, OV7670_FRAME_HEIGHT-1u, (uint16_t *)(horse16)); Display result: Fig 4 3 Test result and summarize    About RT1050-EVKB, use flexIO to collect OV7670 data and display the situation through TFT LCD. Please check the video for the specific code situation. Check the attached source code. You can see from the video results that the flexIO OV7670 camera data can be successfully displayed and the code can successfully run the function.
查看全文
  RT1050 CSI OV7670 camera eLCD display 1.Abstract OV7670 is a CMOS VGA image sensor with small size and low operating voltage. It is controlled by the SCCB bus and can output 8-bit image data of various resolutions with a frame rate of up to 30 frames/second and low cost. This article mainly implements the use of CSI on RT10XX to obtain OV7670 camera data, and displays it using the eLCDIF display module that comes with RT10XX. The camera and display use RGB565 format. The camera resolution configuration is QVGA 320*240, the LCD is NXP official EVKB matching LCD RK043FN02H, the resolution is 480*272, and the frame rate is 30FPS. This article is based on NXP official RT1050 SDK: SDK_2_14_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\csi\rgb565 Porting the OV7670 driver to implement the CSI method to collect OV7670 image data and display it on the LCD through the eLCDIF module   2. Principle explanation    Here is a brief explanation of relevant knowledge. 2.1 RGB565 Color mode As a basic color coding format for images, RGB565 refers to a pixel that occupies 2 bytes of data and is usually used in images and display devices. R red, G green, B blue, the actual display can obtain different other colors according to the configuration of the three primary colors. Each pixel bit can display 65536 (2^16) colors. The specific allocation is as follows:   Fig 1 From the above figure, we can know that the 2-byte data displayed in pure red, green and blue is: Red: 0xf800, Green: 0X07E0, Blue: 0X001F 2.2 OV7670 camera hardware and waveform situation The OV7670 module used is as follows: Fig 2 Pin situation No Signal Description 1 PWDN Power consumption selection mode, pull down for normal use 2 RET Reset port, pull high for normal use 3 D0 Data port output bit 0 4 D1 Data port output bit 1 5 D2 Data port output bit 2 6 D3 Data port output bit 3 7 D4 Data port output bit 4 8 D5 Data port output bit 5 9 D6 Data port output bit 6 10 D7 Data port output bit 7 11 XLK Clock signal input signal 12 PLK Pixel clock output signal 13 HS Horizontal synchronization signal output signal 14 VS Frame sync clock output signal 15 SDA SCCB Interface data control 16 SCL SCCB Interface clock control 17 GND GND 18 3.3V 3.3V power RGB565 output data timing: Fig 3 2.2 CSI frame synchronization signal timing waveform Fig 4 2.3 LCD display wave Fig 5 Therefore, the data of OV7670 is obtained through CSI and then stored in the buffer. The eLCDIF then retrieves the data from the buffer and displays it on the LCD screen to display the real-time collection and reality of the camera data. 3 Software and hardware realize    The test platform is based on NXP MIMXRT1050-EVKB revA1 version: https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/i-mx-rt1050-evaluation-kit:MIMXRT1050-EVK LCD为:https://www.nxp.com/part/RK043FN02H-CT#/ 3.1 Hardware connection As can be seen from Figure 2, the universal module purchased is a 2.54mm direct plug mode, but the CSI interface used on the MIMXRT1050-EVKB board is an FPC interface, so an adapter board is required to switch from FPC to 2.54mm direct plug mode. The wiring diagram is as follows:    Fig 6 The actual overall hardware connection situation is as follows: Fig 7 3.2 Software prepare Regarding the SDK driver of OV7670, the RT SDK does not provide it directly, but the FRDM-K82 SDK provides relevant drivers that can be transplanted to the RT1050 SDK.       SDK version:SDK_2_14_0_EVKB-IMXRT1050\boards\evkbimxrt1050\driver_examples\csi\rgb565 The code replaces the original OV7725 code, replaces the relevant driver with the OV7670 driver, modifies the OV7670 code, matches it to the RT1050 CSI code, and adds IO signal control for OV7670 RST and PWDN. The reason for adding RST and PWDN control is that it was found Some modules, if the RST pin is not closed and delayed to open, will cause the problem of unsuccessful acquisition. However, with the addition of RST and PWDN control, currently OV7670 from different manufacturers can successfully acquire and display stably. For the specific OV7670 code, you can view the attached source code. The camera initialization code is as follows:   static void APP_InitCamera(void) { const camera_config_t cameraConfig = { .pixelFormat = kVIDEO_PixelFormatRGB565, .bytesPerPixel = APP_BPP, .resolution = FSL_VIDEO_RESOLUTION(320, 240), /* Set the camera buffer stride according to panel, so that if * camera resoution is smaller than display, it can still be shown * correct in the screen. */ .frameBufferLinePitch_Bytes = DEMO_BUFFER_WIDTH * APP_BPP, .interface = kCAMERA_InterfaceGatedClock, .controlFlags = DEMO_CAMERA_CONTROL_FLAGS, .framePerSec = 30, }; memset(s_frameBuffer, 0, sizeof(s_frameBuffer)); BOARD_InitCameraResource(); CAMERA_RECEIVER_Init(&cameraReceiver, &cameraConfig, NULL, NULL); if (kStatus_Success != CAMERA_DEVICE_Init(&cameraDevice, &cameraConfig)) { PRINTF("Camera device initialization failed\r\n"); while (1) { ; } } CAMERA_DEVICE_Start(&cameraDevice); /* Submit the empty frame buffers to buffer queue. */ for (uint32_t i = 0; i < APP_FRAME_BUFFER_COUNT; i++) { CAMERA_RECEIVER_SubmitEmptyBuffer(&cameraReceiver, (uint32_t)(s_frameBuffer[i])); } } The resolution here is QVGA 320*240, which does not match the 480*272 of the LCD, but it does not matter. In fact, the size of 320*240 is displayed in the LCD. If you want to display it to 480*272, you can also configure the size through PXP. For more code details, see the attached code package. 4. Summary This article aims to provide a demo of RT OV7670 CSI+eLCDIF acquisition and display. let’s go directly to the finished product effect video. You can see that the relative display is relatively clear, and the refresh effect is also good.
查看全文
LittleFS is a file system used for microcontroller internal flash and external NOR flash. Since it is more suitable for small embedded systems than traditional FAT file systems, more and more people are using it in their projects. So in addition to NOR/NAND flash type storage devices, can LittleFS be used in SD cards? It seems that it is okay too. This article will use the littlefs_shell and sdcard_fatfs demo project in the i.mxRT1050 SDK to make a new littefs_shell project for reading and writing SD cards. This experiment uses MCUXpresso IDE v11.7, and the SDK uses version 2.13. The littleFS file system has only 4 files, of which the current version shown in lfs.h is littleFS 2.5. The first step, of course, is to add SD-related code to the littlefs_shell project. The easiest way is to import another sdcard_fatfs project and copy all of the sdmmc directories into our project. Then copy sdmmc_config.c and sdmmc_config.h in the /board directory, and fsl_usdhc.c and fsl_usdhc.h in the /drivers directory. The second step is to modify the program to include SD card detection and initialization, adding a bridge from LittleFS to SD drivers. Add the following code to littlefs_shell.c. extern sd_card_t m_sdCard; status_t sdcardWaitCardInsert(void) { BOARD_SD_Config(&m_sdCard, NULL, BOARD_SDMMC_SD_HOST_IRQ_PRIORITY, NULL); /* SD host init function */ if (SD_HostInit(&m_sdCard) != kStatus_Success) { PRINTF("\r\nSD host init fail\r\n"); return kStatus_Fail; } /* wait card insert */ if (SD_PollingCardInsert(&m_sdCard, kSD_Inserted) == kStatus_Success) { PRINTF("\r\nCard inserted.\r\n"); /* power off card */ SD_SetCardPower(&m_sdCard, false); /* power on the card */ SD_SetCardPower(&m_sdCard, true); // SdMmc_Init(); } else { PRINTF("\r\nCard detect fail.\r\n"); return kStatus_Fail; } return kStatus_Success; } status_t sd_disk_initialize() { static bool isCardInitialized = false; /* demostrate the normal flow of card re-initialization. If re-initialization is not neccessary, return RES_OK directly will be fine */ if(isCardInitialized) { SD_Deinit(&m_sdCard); } if (kStatus_Success != SD_Init(&m_sdCard)) { SD_Deinit(&m_sdCard); memset(&m_sdCard, 0U, sizeof(m_sdCard)); return kStatus_Fail; } isCardInitialized = true; return kStatus_Success; } In main(), add these code if (sdcardWaitCardInsert() != kStatus_Success) { return -1; } status = sd_disk_initialize(); Next, create two new c files, lfs_sdmmc.c and lfs_sdmmc_bridge.c. The call order is littlefs->lfs_sdmmc.c->lfs_sdmmc_bridge.c->fsl_sd.c. lfs_sdmmc.c and lfs_sdmmc_bridge.c acting as intermediate layers that can connect the LITTLEFS and SD upper layer drivers. One of the things that must be noted is the mapping of addresses. The address given by littleFS is the block address + offset address. See figure below. This is a read command issued by the ‘mount’ command. The block address refers to the address of the erased sector address in SD. The read and write operation uses the smallest read-write block address (BLOCK) of SD, as described below. Therefore, in lfs_sdmmc.c, the address given by littleFS is first converted to the byte address. Then change the SD card read-write address to the BLOCK address in lfs_sdmmc_bridge.c. Since most SD cards today exceed 4GB, the byte address requires a 64-bit variable. Finally, the most important step is littleFS parameter configuration. There is a structure LittlsFS_config in peripherals.c, which contains not only the operation functions of the SD card, but also the read and write sectors and cache size. The setup of this structure is critical. If the setting is not good, it will not only affect the performance, but also cause errors in operation. Before setting it up, let's introduce some of the general ideal of SD card and littleFS. The storage unit of the SD card is BLOCK, and both reading and writing can be carried out according to BLOCK. The size of each block can be different for different cards. For standard SD cards, the length of the block command can be set with CMD16, and the block command length is fixed at 512 bytes for SDHC cards. The SD card is erased sector by sector. The size of each sector needs to be checked in the CSD register of the SD card. If the CSD register ERASE_BLK_EN = 0, Sector is the smallest erase unit, and its unit is "block". The value of sector size is equal to the value of the SECTOR_SIZE field in the CSD register plus 1. For example, if SECTOR_SIZE is 127, then the minimum erase unit is 512*(127+1)=65536 bytes. In addition, sometimes there are doubts, many of the current SD cards actually have wear functions to reduce the loss caused by frequent erasing and writing, and extend the service life. So in fact, delete operations or read and write operations are not necessarily real physical addresses. Instead, it is mapped by the SD controller. But for the user, this mapping is transparent. So don't worry about this affecting normal operation. LittleFS is a lightweight file system that has power loss recovery and dynamic wear leveling compared to FAT systems. Once mounted, littleFS provides a complete set of POSIX-like file and directory functions, so it can be operated like a common file system. LittleFS has only 4 files in total, and it basically does not need to be modified when used. Since the NOR/NAND flash to be operated by LittleFS is essentially a block device, in order to facilitate use, LittleFS is read and written in blocks, and the underlying NOR/NAND Flash interface drivers are carried out in blocks. Let's take a look at the specific content of LittleFS configuration parameters. const struct lfs_config LittleFS_config = { .context = (void*)0, .read = lfs_sdmmc_read, .prog = lfs_sdmmc_prog, .erase = lfs_sdmmc_erase, .sync = lfs_sdmmc_sync, .read_size = 512, .prog_size = 512, .block_size = 65536, .block_count = 128, .block_cycles = 100, .cache_size = 512, .lookahead_size = LITTLEFS_LOOKAHEAD_SIZE }; Among them, the first item (.context) is not used in this project, and is used in the original project to save the offset of the file system stored in Flash. Items two (.read) through five (.sync) point to the handlers for each operation. The sixth item (.read_size) is the smallest unit of read operation. This value is roughly equal to the BLOCK size of the SD card. In the SD card driver, this size has been fixed to 512. So for convenience, it is also set to 512. The seventh item (.prog_size) is the number of bytes written each time, which is 512 bytes like .read_size. The eighth item is .block_size. This can be considered to be the smallest erase block supported by the SD card when performing an erase operation. Here the default value is not important, you need to set it in the program according to the actual value after the SD card is initialized. The card used in this experiment is 64k bytes as an erase block, so 65536 is used directly here. Item 9 (.block_count) is used to indicate how many erasable blocks there are. Multiply the .block_size to get the size of the card. If the card is replaceable, it needs to be determined according to the parameters after the SD card is initialized. The tenth item (.block_cycles) is the number of erase cycles per block. Item 11 (.cache_size) is about the cache buffer. It feels like bigger is better, but actually modifies this value won't work. So still 512. Item 12 (lookahead_size), littleFS uses a lookahead buffer to manage and allocate blocks. A lookahead buffer is a fixed-size bitmap that records information about block allocations within an area. The lookahead buffer only records the information of block allocations in one area, and when you need to know the allocation of other regions, you need to scan the file system to find allocated blocks. If there are no free blocks in the lookahead buffer, you need to move the lookahead buffer to find other free blocks in the file system. The lookahead buffer position shifts one lookahead_size at a time. Use the original value here.  That’s all for the porting work. We can test the project now. You can see it works fine. The littleFS-SD project can read/write/create folder and erase. And it also support append to an exist file. But after more testing, a problem was found, if you repeatedly add->-close->-add-> close a file, the file will open more and more slowly, even taking a few seconds. This is what should be added and is not written directly in the last block of the file, but will apply for a new block, regardless of whether the previous block is full or not. See figure below. The figure above prints out all the read, write, and erase operations used in each write command. You can see that each time in the lfs_file_open there is one more read than the last write operation. In this way, after dozens or hundreds of cycles, a file will involve many blocks. It is very time-consuming to read these blocks in turn. Tests found that more than 100 read took longer than seconds. To speed things up, it is recommended to copy the contents of one file to another file after adding it dozens of times. In this way, the scattered content will be consolidated to write a small number of blocks. This can greatly speed up reading and writing.
查看全文
RT10XX RT-UFL modification for QSPI QE and DQS factor 1. Abstract Recently, a customer used a QSPI flash (Puya simi P25Q16H) as XIP memory in the RT1050 project, but always encountered the phenomenon that the first time download failed, the download succeeded again after powering on again, and the app could run. To the program algorithm, they use the RT-UFL. After analysis, this situation is usually related to the fact that the QE of the new QSPI flash is not enabled. Therefore, based on the QE position of the QSPI flash used by the customer, the author specially enabled the corresponding QE in the SDK flexspi_nor_polling_transfer code, let the customer try to run it in RAM to check whether still have the program issues after enabling QE in the new QSPI flash. However, the customer even can’t run flexspi_nor_polling_transfer project. According to the customer's previous description, the hardware can run RAM code, and the first flash download does not work, but it can run after re-downloading, so the hardware works. Based on the phenomenon, it is initially speculated that the new problem may be related to FlexSPI DQS being occupied. Under normal circumstances, it is recommended to leave FlexSPI DQS floating. Because the project flexSPI frequency given to customers is 120Mhz, if DQS is used, the internal sampling clock source of FlexSPI read data is: Read strobe provided by memory device and input from DQS pad. This method will have problems. So asked the customer to confirm the hardware again. The result is DQS is used as a control pin for other circuits on the customer's board. Usually there are two points to note in this situation: First, the FlexSPI clock is controlled within 60MHz. Second, the internal sampling clock source configuration of FlexSPI read data is: Dummy read strobe generated by FlexSPI controller and looped back internally (FlexSPIn_MCR0[RXCLKSRC] = 0x0)      Therefore, this article focuses on how to prepare the test code for the corresponding QE position based on the QSPI flash used by the customer, consider the operation when DQS is enabled, modify and test the RT-UFL downloading algorithm. 2. Hardware and software prepare To reproduce the customer issues, need to prepare the related software, hardware, and the flash programming flashdriver, and the code for testing the QE situation. 2.1 Hardware prepare MIMXRT1050-EVKB, modify the on board resistor, from the default hyperflash to QSPI flash. The modification points: USE QSPI FLASH(Mount R153~R158, DNP R356,R361~R366)。 Remove the on board U33 ISSI QSPI flash, burn the new QSPI flash with customer used Puya simi P25Q16H. Customer is using JLINK, so prepare JLINK plus for downloading. 2.2 flexspi_nor_polling_transfer software prepare SDK2.14.0 code:flexspi_nor_polling_transfer, used to test the QE situation. App project: led_blinky RT-UFL program algorithm code: https://github.com/JayHeng/RT-UFL JLINK driver: used JLINKV768B, higher version is also OK. 2.2.1 P25Q16H QE position Fig 1    We can see, it is still the typical Status register bit 9. The related LUT write and read commander is: Fig 2 We can see that for writing, it is command 0X01, and 2 consecutive bytes need to be written. But for the read command, the commands for the two status register bytes are separate. So you need to pay attention to this when operating the QE bit. 2.2.2 flexspi_nor_polling_transfer code prepare This code is mainly used to test the QE enablement and disabling, and the erase, write and read functions of external flash. The code modification points include: modifying the LUT command to comply with P25Q16H; adding QE read, write and erase functions; modifying the frequency of flexSPI and the situation of DQS loopback internal. The relevant code is as follows: LUT related commander: flexspi_nor_polling_transfer.c const uint32_t customLUT[CUSTOM_LUT_LENGTH] = { /* 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), /* 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), /* Fast read quad mode - SDR */ [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0xEB, kFLEXSPI_Command_RADDR_SDR, kFLEXSPI_4PAD, 0x18), [4 * NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD + 1] = FLEXSPI_LUT_SEQ( kFLEXSPI_Command_DUMMY_SDR, kFLEXSPI_4PAD, 0x06, kFLEXSPI_Command_READ_SDR, kFLEXSPI_4PAD, 0x04), /* 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),//0xD7 /* 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), /* Read status register */ [4 * NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1] = FLEXSPI_LUT_SEQ(kFLEXSPI_Command_SDR, kFLEXSPI_1PAD, 0x35, 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),//0xC7 }; flexspi_nor_flash_ops.c: QE read and write status_t flexspi_nor_enable_quad_mode(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; status_t status; uint32_t writeValue = FLASH_QUAD_ENABLE; #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_cache_status_t cacheStatus; flexspi_nor_disable_cache(&cacheStatus); #endif /* Write enable */ status = flexspi_nor_write_enable(base, 0); if (status != kStatus_Success) { return status; } /* Enable quad mode. */ flashXfer.deviceAddress = 0; flashXfer.port = FLASH_PORT; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG; flashXfer.data = &writeValue; flashXfer.dataSize = writeValue <= 0xFFU ? 1 : 2; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } status = flexspi_nor_wait_bus_busy(base); /* Do software reset. */ FLEXSPI_SoftwareReset(base); #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_nor_enable_cache(cacheStatus); #endif return status; } status_t flexspi_nor_disable_quad_mode(FLEXSPI_Type *base) { flexspi_transfer_t flashXfer; status_t status; uint32_t writeValue = 0x0;//FLASH_QUAD_ENABLE; #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_cache_status_t cacheStatus; flexspi_nor_disable_cache(&cacheStatus); #endif /* Write enable */ status = flexspi_nor_write_enable(base, 0); if (status != kStatus_Success) { return status; } /* Enable quad mode. */ flashXfer.deviceAddress = 0; flashXfer.port = FLASH_PORT; flashXfer.cmdType = kFLEXSPI_Write; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_WRITESTATUSREG; flashXfer.data = &writeValue; flashXfer.dataSize = 2; status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } status = flexspi_nor_wait_bus_busy(base); /* Do software reset. */ FLEXSPI_SoftwareReset(base); #if defined(CACHE_MAINTAIN) && CACHE_MAINTAIN flexspi_nor_enable_cache(cacheStatus); #endif return status; } status_t flexspi_nor_QE_register(FLEXSPI_Type *base, uint32_t *QEvalue) { /* Wait status ready. */ bool isBusy; uint32_t readValue; status_t status; flexspi_transfer_t flashXfer; flashXfer.deviceAddress = 0; flashXfer.port = FLASH_PORT; flashXfer.cmdType = kFLEXSPI_Read; flashXfer.SeqNumber = 1; flashXfer.seqIndex = NOR_CMD_LUT_SEQ_IDX_READSTATUSREG1; flashXfer.data = &readValue; flashXfer.dataSize = 1; do { status = FLEXSPI_TransferBlocking(base, &flashXfer); if (status != kStatus_Success) { return status; } if (FLASH_BUSY_STATUS_POL) { if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { isBusy = true; } else { isBusy = false; } } else { if (readValue & (1U << FLASH_BUSY_STATUS_OFFSET)) { isBusy = false; } else { isBusy = true; } } *QEvalue = readValue; } while (isBusy); return status; } QE position:App.h #define FLASH_QUAD_ENABLE 0X0200 QE operation:flexspi_nor_polling_transfer.c PRINTF("Get the QE bit value before QE enable!\r\n"); uint32_t QEvalue=0; status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue); if (status != kStatus_Success) { return status; } PRINTF("QE=%X!\r\n",(uint8_t)QEvalue); #if 1 status = flexspi_nor_disable_quad_mode(EXAMPLE_FLEXSPI); if (status != kStatus_Success) { return status; } PRINTF("Get the QE bit value after QE disable!\r\n"); status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue); if (status != kStatus_Success) { return status; } PRINTF("QE=%X!\r\n",(uint8_t)QEvalue); #endif PRINTF("Enable the QE bit value !\r\n"); /* Enter quad mode. */ status = flexspi_nor_enable_quad_mode(EXAMPLE_FLEXSPI); if (status != kStatus_Success) { return status; } status = flexspi_nor_QE_register(EXAMPLE_FLEXSPI, &QEvalue); if (status != kStatus_Success) { return status; } PRINTF("QE=%X!\r\n",(uint8_t)QEvalue); FlexSPI frequency modification:flexspi_nor_polling_transfer.c,app.h flexspi_device_config_t deviceconfig = { .flexspiRootClk = 60000000, .flashSize = FLASH_SIZE, .CSIntervalUnit = kFLEXSPI_CsIntervalUnit1SckCycle, .CSInterval = 2, .CSHoldTime = 3, .CSSetupTime = 3, .dataValidTime = 0, .columnspace = 0, .enableWordAddress = 0, .AWRSeqIndex = 0, .AWRSeqNumber = 0, .ARDSeqIndex = NOR_CMD_LUT_SEQ_IDX_READ_FAST_QUAD, .ARDSeqNumber = 1, .AHBWriteWaitUnit = kFLEXSPI_AhbWriteWaitUnit2AhbCycle, .AHBWriteWaitInterval = 0, }; static inline void flexspi_clock_init(void) { const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U}; CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll); CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 24); /* Set PLL3 PFD0 clock 360MHZ. */ CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */ CLOCK_SetDiv(kCLOCK_FlexspiDiv, 5); /* flexspi clock 60M. */ } Loop back internally:app.h #define EXAMPLE_FLEXSPI_RX_SAMPLE_CLOCK kFLEXSPI_ReadSampleClkLoopbackInternally 2.2.3 flexspi_nor_polling_transfer testing after modification Download the modified code to RT1050 RAM and run the results as follows:    Fig 3 From the figure, we can see, QE can normally implement the functions of reading, writing, erasing, and reading. It is read as 2 here which QE is enabled for the first time, because the QSPI in this article has been operated previously. If it is a new chip, it will read 0 by default, which means that QE is not enabled. And it can be seen that after modification, it can accurately erase, program, and read external flash, indicating that the current code modification is successful. LUT, QE position, DQS consideration (60Mhz+loopback internal) are all working. 2.3 APP prepare Use the led_blinky code in the SDK to mainly modify the frequency of FCB and readSampleClkSrc. evkbimxrt1050_flexspi_nor_config.c is modified as follows:    const flexspi_nor_config_t qspiflash_config = { .memConfig = { .tag = FLEXSPI_CFG_BLK_TAG, .version = FLEXSPI_CFG_BLK_VERSION, .readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally, .csHoldTime = 3u, .csSetupTime = 3u, .controllerMiscOption = (1u << kFlexSpiMiscOffset_SafeConfigFreqEnable), .deviceType = kFlexSpiDeviceType_SerialNOR, .sflashPadType = kSerialFlash_4Pads, .serialClkFreq = kFlexSpiSerialClk_60MHz, .sflashA1Size = 8u * 1024u * 1024u, … }   This code will be used to test the new modified program flashdriver in debug mode, compile the project, generate the .srec, used for the JFLASH method flash program.   3. RT-UFL JLINK flash algorithm modification After downloading the super download algorithm RT-UFL, you need to modify the super download algorithm based on the two factors mentioned above: First, QE is enabled; second, DQS is used. For the solution in this article, RT-UFL still uses option ROM to initialize flexSPI. According to the options description, choose: OPTION 0: 0xc0000201 OPTION 1:0x0 Just like this situation: Fig 4 3.1 RT-UFL code modification Here, use the keil project: \RT-UFL-1.0\build\mdk The code modification is as follows: Ufl_main.c: ufl_set_target_property1 case kChipId_RT105x: uflTargetDesc->flexspiInstance = MIMXRT105X_1st_FLEXSPI_INSTANCE; uflTargetDesc->flexspiBaseAddr = MIMXRT105X_1st_FLEXSPI_BASE; uflTargetDesc->flashBaseAddr = MIMXRT105X_1st_FLEXSPI_AMBA_BASE; //p25q16h QESet bit 1 in Status Register 2 {.option0.U = 0xc0000201, .option1.U = 0x00000000}, uflTargetDesc->configOption.option0.U = 0xc0000201; uflTargetDesc->configOption.option1.U = 0x0; Ufl_romapi.c: readSampleClkSrc configuration status_t flexspi_nor_auto_config(uint32_t instance, flexspi_nor_config_t *config, serial_nor_config_option_t *option) { // Wait until the FLEXSPI is idle register uint32_t delaycnt = 10000u; while(delaycnt--) { } status_t status = flexspi_nor_get_config(instance, config, option); if (status != kStatus_Success) { return status; } config->memConfig.readSampleClksrc=kFlexSPIReadSampleClk_LoopbackInternally; //For DQS is used by other circuit return flexspi_nor_flash_init(instance, config); } FlashDev.c struct FlashDevice const FlashDevice = { FLASH_DRV_VERS, // Driver Version, do not modify! "MIMXRT_FLEXSPI", // Device Name EXTSPI, // Device Type 0x60000000, // Device Start Address 0x00800000, // Device Size in Bytes (8mB) 256, // Programming Page Size 0, // Reserved, must be 0 0xFF, // Initial Content of Erased Memory 100, // Program Page Timeout 100 mSec 5000, // Erase Sector Timeout 5000 mSec // Specify Size and Address of Sectors 0x1000, 0x00000000, // Sector Size 4kB (256 Sectors) SECTOR_END }; FlashOS.h: it will generate the UFL_L0 type, to define the flash page, sector size #define FLASH_DRV_SIZE_OPT (0) #if (FLASH_DRV_SIZE_OPT == 0) #define FLASH_DRV_PAGE_SIZE (0x100) #define FLASH_DRV_SECTOR_SIZE (0x1000) #elif (FLASH_DRV_SIZE_OPT == 1) #define FLASH_DRV_PAGE_SIZE (0x200) #define FLASH_DRV_SECTOR_SIZE (0x1000) #elif (FLASH_DRV_SIZE_OPT == 2) #define FLASH_DRV_PAGE_SIZE (0x200) #define FLASH_DRV_SECTOR_SIZE (0x10000) #endif Compile the code, it will get flashdriver firmware:MIMXRT_FLEXSPI_UV5_UFL.FLM Rename it to:MIMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM 3.2 JLINK driver flashdriver update After installing the JLINK driver,  modify it to use the RT-UFL algorithm.   According to this article, the driving algorithm of JLINK is modified to RT-UFL algorithm: https://www.cnblogs.com/henjay724/p/14942574.html   In fact, just copy: RT-UFL-1.0\RT-UFL-1.0\algo\SEGGER\JLink_Vxxx To the installed JLINK path: C:\Program Files\SEGGER\JLINKV768B   But this article need to based on this to add the modified flash algorithm for P25Q16H, the modification points are: (1)Copy attached file RT1050_P25Q16H_JLINK\program\ JLinkDevices.xml to: C:\Program Files\SEGGER\JLINKV768B Fig 5 The .xml modification is as follows, add the P25Q16H item and it’s algorithm: Fig 6 Note: device name is MIMXRT1050_UFL_P25Q16H (2) CopyRT1050_P25Q16H_JLINK\program\ IMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM to:C:\Program Files\SEGGER\JLINKV768B\Devices\NXP\iMXRT_UFL Fig 7 This MIMXRT_FLEXSPI_UV5_UFL_P25Q16H.FLM is the modified flashdriver algorithm in the above. (3)run C:\Program Files\SEGGER\JLINKV768B\JLinkDLLUpdater.exe, update the modified driver to the IDE IAR 3.3 Flashdriver algorithm downloading test For MIMXRT1050-EVKB, to use external JLINK, you need to disconnect J33 on the EVKB board and plug JTAG into J21. 3.3.1 Use JFLASH downloading test First, use the previously modified EVKB-IMXRT1050-flexspi_nor_polling_transfer, disable the QE bit, to simulate the new QSPI flash chip. The test is as follows:   Fig 8 JFlash test result is: Fig 9 We can see, use the Jflash with new flashdriver, can program the flash successfully. 3.3.2 led_blinky app debug test Disable the QE bit, to simulate the new QSPI flash chip, the test as Fig 8. APP demo use the IAR project(customer use it), option select JLINK: Fig 10 Fig 11 It should be noted here that the device is selected as the modified super download algorithm device name. The method is as follows. The settings->xxx.jlink generated by IAR debug is modified as follows: Fig 12 Two points: override =1, and device is the new modified algorithm device name. Debug test result: Fig 13 We can see that the algorithm can be successfully debugged and the algorithm is also modified by UFL. Run it at full speed and you can see the on board LED is flashing. It means that all flash driver algorithms, hardware, and codes already support the new P25Q16H QSPI flash. 4. Summary When using a new QSPI flash, first need to pay attention to the position of QE and whether DQS is used, and then prepare the corresponding RT-UFL programming algorithm. The UFL algorithm can usually support most flash chips by default. When QE and DQS are used, they only need to fine-tune the algorithm to support the new QSPI flash. Therefore, this article has successfully solved the problem of burning customer projects after modifying the algorithm. For other QSPI flash, you can also use the method in this article to modify the burning algorithm accordingly to ensure that it meets your own project needs.  
查看全文
RT1170 AVB fresh tasting 1 Abstract AVB (Audio Video Bridging) is the audio and video bridging technology. AVB is also a time-sensitive network. It is mainly used to solve audio and video transmission problems within the local area network: delay problems and synchronization problems. AVB consists of a series of IEEE standards aimed at efficiently transmitting audio and video data in a local area network. The protocol of AVB is as follows: Fig 1 AVB is mainly a link layer protocol and coexists with the traditional TCP/IP protocol.     AVB related protocols include: gPTP (IEEE 802.1AS-2020): Precision time synchronization protocol AVTP (IEEE 1722-2016): Audio and video transmission protocol FQTSS (IEEE 802.1Q-2018, section 34): Credit Based Shaper protocol SRP (IEEE 802.1Q-2018, section 35) :Stream Reservation Protocol AVDECC (IEEE 1722.1-2013): Audio and video management protocol EST (IEEE 802.1Qbv-2015) FP (IEEE 802.3br-2016/IEEE 802.1Qbu-2016) The topology diagram of AVB is as follows: Fig 2 End Station:Listener andTalker Listener: Node that accepts audio and video data Talker: Node that outputs audio and video data AV Bridge:AVB bridge The purpose of this article is not to talk about the AVB protocol. As a first-time experience of AVB with RT1170, it mainly explains how to use the officially provided AVB/TSN protocol stack to implement the AVB audio data transmission function on the NXP MIMXRT1170-EVK board.。 2 .RT1170 AVB testing 2.1 Hardware prepare    2*MIMXRT1170-EVK REV C4,one is Talker,another is Listener.    Pin modification: remove R228, R234, R232, R229 resistor    Board default configuration:      J27:1-2      J5,J6,J7,J8:short connect      J38:5-6      SW1: 1-OFF,2-OFF,3-ON,4-OFF      SW2: 1-OFF,2-OFF,3-OFF,4-OFF,5-OFF,6-OFF,7-OFF,8-OFF,9-OFF,10-OFF      J11: code downloading and vcom port      J4  : 1G ENET, used for AVB communication Fig 3   2.2 Software tool prepare 2.2.1 Related code SDK_2_13_0_MIMXRT1170-EVK: https://mcuxpresso.nxp.com/en/builder?hw=MIMXRT1170-EVK&rel=667 Download the corresponding SDK according to the system which you need to use (windows/linux). For example, download the Linux version for Linux, and download the windows version for windows. This article takes the Linux compilation system as an example, so download the SDK Linux version. genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0.zip: https://mcuxpresso.nxp.com/en/dashboard?download=84124a72b3f5916f99168a06ef287f2f genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0 file includes: Fig 4 Binaries:include RT1170 AVB/TSN bin file, RT1050 AVB bin file. Doc:AVB/TSN stack related document, very important, recommend to read it at first. Genavb-apps-freertos-5_6_0:GenAVB/TSN app examples genavb-sdk –5_6_0.tar.gz GenAVB/TSN SDK supported configuration and device .patch:GenAVB/TSN patch to RT1170,RT1050 SDK   2.2.2 Related software tool Linux platform CMake (>= 3.10.2, tested with 3.16.3) make unzip patch Windows platform CMake (>= 3.10, tested with 3.22.1) minGW-w64 (tested with 4.3.5) 7zip Git with git bash (necessary for patch utility) This document use the linux ubuntu platform, the software version is: Fig 5 A small experience sharing, as the used Ubuntu version is lower, then the installed cmake version is also low, when install the cmake 3.16.3, meet some issues, here share the experience: At first, download cmake-3.16.3-Linux-x86_64.tar.gz: https://github.com/Kitware/CMake/releases/download/v3.16.3/cmake-3.16.3-Linux-x86_64.tar.gz unzip cmake-3.16.3-Linux-x86_64.tar.gz to get cmake-3.16.3-Linux-x86_64: tar -zxvf cmake-3.16.3-Linux-x86_64.tar.gz Add the linker to /usr/bin/cmake: sudo ln -s /home/nxa07323/TSN_GENAVB/cmake-3.16.3-Linux-x86_64/bin/cmake /usr/bin/cmake In /usr/bin/cmake path, use:ls -al, we can see the link information: Fig 6 After the above operation, use : cmake –version We can see the cmake version is cmake 3.16.3, which Fig 5 shows. 2.2.2 Code configuration   To build the AVB code, it also needs to use the RT1170 SDK, the steps are:   Unzip genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0.zip and SDK_2_13_0_MIMXRT1170-EVK_linux.zip Fig 7   Enter SDK_2_13_0_MIMXRT1170-EVK_linux folder path, add genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/ mcuxpresso-sdk-SDK_2_13_0_MIMXRT1170-EVK-5_6_0.patch  Patch add commander is: $ patch -p1 < path/to/mcuxpresso-sdk-SDK_2_13_0_MIMXRT1170-EVK-5_6_0.patch   The real operation command is: patch -p1 < /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/mcuxpresso-sdk-SDK_2_13_0_MIMXRT1170-EVK-5_6_0.patch Fig 8    Add the linker for the SDK and AVB SDK, the structure is: genavb-apps-freertos-5_6_0 ├── boards │ ├── evkbimxrt1050 │ │ ├── demo_apps │ │ └── mcu-sdk -> /path/to/SDK_2_13_0_EVKB-IMXRT1050 (required for RT1052) │ ├── evkmimxrt1170 │ │ ├── demo_apps │ │ └── mcu-sdk -> /path/to/SDK_2_13_0_MIMXRT1170-EVK (required for RT1176) │ └── src │ └── demo_apps └── gen_avb -> /path/to/genavb-sdk-5_6_0 To the RT1170, it contains 2 link: 1)Add the SDK path for the avb sdk board level $ cd path/to/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170 $ ln -s path/to/SDK_2_13_0_MIMXRT1170-EVK mcu-sdk The used situation: For path /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170 It needs to add the SDK path link: /home/nxa07323/avbdoc/SDK_2_13_0_MIMXRT1170-EVK_linux Firstly, unzip the genavb-apps-freertos-5_6_0.tar.gz: tar -zxvf genavb-apps-freertos-5_6_0.tar.gz Fig 9 The commander is: cd /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170 ln -s /home/nxa07323/avbdoc/SDK_2_13_0_MIMXRT1170-EVK_linux mcu-sdk Fig 10   We can see, in the path genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170, already add the SDK path with link, the name is: mcu-sdk. 2)Add the GENAVB/TSN SDK path link to AVB app top level $ cd path/to/genavb-apps-freertos-5_6_0/ $ ln -s path/to/genavb-sdk-5_6_0 gen_avb To /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/ Add the AVB SDK path link:/home/nxa07323/avbdoc/SDK_2_13_0_MIMXRT1170-EVK_linux Unzip genavb-sdk-5_6_0.tar.gz: tar -zxvf genavb-sdk-5_6_0.tar.gz Fig 11 Link commander: cd /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0 ln -s /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-sdk-5_6_0 gen_avb Fig 12 We can see, /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0 path link also added, the name is gen_avb. 2.3 code build   The build file path: genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170/demo_apps/avb_tsn/avb_audio_app/armgcc use build_release.sh file for the linux version. Commander: ./build_release.sh Fig 13 Result: Fig 14 We can see, the avb_app.bin already be generated. File path: /home/nxa07323/avbdoc/genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0/genavb-apps-freertos-5_6_0/boards/evkmimxrt1170/demo_apps/avb_tsn/avb_audio_app/armgcc/release Open avb_app.bin file: Fig 15     We can see, the generated bin file’s RT1170 QSPI FCB. 2.4 Code programming 2.4.1 MSD downloading method     By referring the doc: genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0\doc\NXP_GenAVB_TSN_Stack_FreeRTOS_Eval_User_s_Guide-5_6_rev0.pdf, It is recommended to use the MSD method and directly copy app_avb.bin to the MSD of EVK. However, in the actual test, since there is no information for successful burning progress after copying, it is easy to cause problems. For example, after copying the bin file to the MSD disk (it seems that the copy has been completed), reset or power off the board, but the burning has not actually been completed. At this time, there will be a problem that the code has not been successfully burned, and AVB cannot be successfully run. Therefore, if you use the MSD method, after copying to the MSD, it is best to wait for a period of time to ensure that the code is successfully burned, such as 30s. Fig 16 However, after many tests, the MSD method cannot perform chip mass erase. For example, some filesystem configurations of AVB have been made, but the code needs to be re-downloaded for reconfiguration. It is found that even if app_avb.bin is burned again, the previous AVB configuration is still exists, so if you need a new system file configuration, it is recommended to perform a full chip erase first and then use this method to burn, or directly use the serial download mode to burn.     In addition, some customers may update EVK's opensda version, and sometimes the updated opensda may not have MSD. In this way, it is also recommended to use the following serial download MCUBootutility method to burn.    2.4.2 MCUBootutility downloading method At first, EVK enter the serial download mode: SW1:1-OFF,2-OFF,3-OFF,4-ON Use two USB cable to connect the J11 and J20 SDP, then power off and power on the board or reset the board to enter the serial download mode. MCUBootutility tool download link: https://github.com/JayHeng/NXP-MCUBootUtility/releases/tag/v5.3.0 Tool related document: https://github.com/JayHeng/NXP-MCUBootUtility   Use the generated avb_app.bin file, and burn it to the MIMXRT1170-EVK board: Fig 17 It should be noted here that from Figure 15 you can see that the bin file stores the FCB starting from 0, but for the MIMXRT1170 chip, the FCB storage is offset by 0X400, so the burning position of avb_app.bin needs to start from 0X30000400. Follow the 7-steps in Figure 17 to burn the bin file. After burning in this way, change SW1 of EVK to: 1-OFF, 2-OFF, 3-ON, 4-OFF, which is the internal boot mode.   AVB testing requires two MIMXRT1170-EVK development boards. The codes burned on the two boards are the same, avb_app.bin is burned in both.   After restarting and testing, you will find that the old filesystem has also been cleared. At this time, you can configure a new system file again.     2.5 talker listener configuration   Two MIMXRT1170-EVK board, one as AVB Talker, another as AVB Listener. Because the programmed app is the same, then just need to use the filesystem to configure which EVK is talker, which is listener.   This document use 2 EVK, and with the back-to-back method, the connection is: Fig 18 Talker: collect the Mic audio data, then transfer to the Listener through the AVB network Listener:receive the talker audio data, play the talker mic audio data through Audio Out J33 2.5.1 Talker filesystem configuration Talker related configuration commander is: ---------------------------------------- cd .. ls mkdir avb_app write avb_app/mclock_role 0 mkdir avdecc write avdecc/btb_mode 0 mkdir fgptp write fgptp/gmCapable 1 mkdir port0 write port0/hw_addr 00:22:33:44:55:66 ----------------------------------------------- The description for the talker configuration: avb_app/mclock_role=0, Media Clock Master. avdecc/btb_mode=0, avdecc back-to-back mode fgptp/gmCapable=1,gPTP grand master port0/hw_addr=00:22:33:44:55:66, configure the hardware address For hw_addr, it should be noted that the first byte must be 00. The author previously configured it as 11, but the communication was always unsuccessful. Through EVK's J11 serial port configuration, after powering on, you can see that the terminal prints a lot of data. First, you need to enter the shell and press the ISERT key. At this time, the terminal will appear >>. For specific shell commands, you can view the documentation: NXP_GenAVB_TSN_Stack_FreeRTOS_Eval_User_s_Guide-5_6_rev0.pdf, Chapter 6.1.1 Filesystem commands The mainly used commander is: write: write a file with a given string cat: print the content of a file ls: list all files and directories in the current directory rm: remove a file or a directory (if it is empty) cd: change directory pwd: print working directory mkdir: create a directory The following picture is for the shell entry and the file system configuration: Fig 19  According to the Talker command mentioned above, configure the talker file system: Fig 20   Until now, the talker filesystem is configured. 2.5.2 Listener filesystem configuration   Listener related commander is: ------------------------------- cd .. ls mkdir avb_app write avb_app/mclock_role 1 mkdir avdecc write avdecc/btb_mode 1 write avdecc/talker_id 0x00049f4455660000 ------------------------------------------ The description for the listener configuration: avb_app/mclock_role =1, Media Clock Slave. avdecc/btb_mode=1, avdecc fast-connect back-to-back mode avdecc/talker_id =0x00049f4455660000,for fast connect mode configure the talker entity id。 Entity id configuration rule is: eui[0] = 0x00; eui[1] = 0x04; eui[2] = 0x9f; eui[3] = mac_addr[3]; eui[4] = mac_addr[4]; eui[5] = mac_addr[5]; eui[6] = 0x00; eui[7] = 0x00; mac_addr is determined by the hw_addr, eg, talker configure the hw_addr to: 00:22:33:44:55:66, this is the mac_addr[0-5] Then talker_id: eui[0] = 0x00; eui[1] = 0x04; eui[2] = 0x9f; eui[3] = mac_addr[3]=44; eui[4] = mac_addr[4]=55; eui[5] = mac_addr[5]=66; eui[6] = 0x00; eui[7] = 0x00; talker_id =0x00049f4455660000。 Next, configure the Listener file system: Press the computer's insert button to enter shell mode, and then do the filesystem configuration commander input: Fig 21   Until now, the Listener filesystem configuration is finished. 2.6 Test Result Let's start the connection test. Find a network cable to connect two MIMXRT1170-EVK boards, which is the 1G network port J4 of the Talker and the listener. Listener's J33 is inserted into the earphone to listen to the microphone audio data sent from the talker board. Connection picture is as follows: Fig 22 The test result is, when two board power on, after the short time sync, the audio sound collected from the Talker microphone can be heard in the Listener's headphones, indicating that the RT1170 AVB communication is working. Partial log diagrams are given below. The complete logs of talker and listener can be viewed in the attachment. Fig 23 Fig 24 Fig 25 Fig 26 3.Summarization After several testing, we can realize the RT1170 AVB audio transfer function. If the customer don’t want to build the project, just want to do the simple testing, they also can use the AVB/TSN stack’s generated bin file, the path is: \genavb_tsn-mcuxpresso-SDK_2_13_0-5_6_0\binaries\genavb-avb_audio_app-evaluation-freertos_rt1176-5_6_0.tar\genavb-avb_audio_app-evaluation-freertos_rt1176-5_6_0\release\ avb_app.bin This document is just the AVB tasting, for the deeper knowledge, will learn and share it later. Meet issues during the testing: 1). The cmake install during the linux build, which can be found from chapter 2.2.2 Related software tool 2). The printf log is messing, in Tera Term, use the 115200 baudrate to printf, the default printf log is miss order, it is difficult to the detail content, just like this: Fig 27 Solution: Fig 28 Fig 29 After the above configuration, we can see the log is in order. 3). Board programming, at first use the MSD to download the code, but didn’t wait the 30s, then do the power off or the reset, it always causes MSD burning failure, and the generated avb_app.bin , didn’t find the FCB location is not do the 0x400 offset when use the mcubootutility, It also meet issues. So when use the mcubootutility, need to burn from 0x30000400, please refer to chapter 2.4 Code programming 4). Talker filesystem configuration for port0/hw_addr, the first bytes should be 0X00, if none 0, it will have the AVB communication issues, after modify the first byte to the 0X00 in hw_addr, the issue is solved.  
查看全文
Note: for similar EVKs, see: Using J-Link with MIMXRT1060-EVKB or MIMXRT1040-EVK Using J-Link with MIMXRT1060-EVK or MIMXRT1064-EVK Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK This article provides details using a J-Link debug probe with this EVK.  There are two options: the onboard MCU-Link debug probe can be updated with Segger J-Link firmware, or an external J-Link debug probe can be attached to the EVK.  Using the onboard debug circuit is helpful as no other debug probe is required.  This article details the steps to use either J-Link option. MIMXRT1170-EVKB jumper locations   Using external J-Link debug probe Segger offers several J-Link probe options.  To use one of these probes with these EVKs, configure the EVK with these settings: Install a jumper on JP5, to disconnect the SWD signals from the onboard debug circuit.  This jumper is open by default. Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Connect the J-Link probe to J1, 20-pin dual-row 0.1" header.   Using onboard MCU-Link with J-Link firmware Install the MCU-Link Installer for the drivers and firmware update tool Disconnect any USB cables from the EVK Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Install a jumper at JP3 to force the MCU-Link in ISP mode Connect a USB cable to J86, to the MCU-Link debugger Go to the scripts directory in the MCU-Link software package installation and run the program_JLINK.cmd (Windows) or program_JLINK (Linux/MacOS) script by double-clicking it. Follow the onscreen instructions.  In Windows, this script is typically installed at C:\nxp\MCU-LINK_installer_3.122\scripts\program_JLINK.cmd Unplug the USB cable at J86 Remove the jumper at JP3 Plug the USB cable back in to J86.  Now the MCU-Link debugger should boot as a JLink. Remove jumper JP5, to connect the SWD signals from the MCU-Link debugger.  This jumper is open by default.  
查看全文
RT Linux SDK build based on Ubuntu 1. Abstract The SDK of NXP MIMXRT products can support three operation systems: windows, Linux, and macOS. Usually, the vast majority of users use the windows version combined with IDE compilation, and the documentation is relatively complete. However, for the Linux version, although the SDK is downloaded, it also contains documents, but the documents are the same as those of windows, not for Linux. Therefore, when a small number of customers use Ubuntu Linux to compile, they suffer from no documentation reference, especially for novices, it is difficult to use.      This article will implement the build of RT1060 linux version SDK based on Ubuntu. 2. Tool preparation You need to prepare a computer with Ubuntu system. Windows can install a virtual machine with Ubuntu system. This article uses the Ubuntu system of the web server. Tools required for testing: Ubuntu system cmake ARMGCC: ARGCC for ARM Cortex M core SDK: SDK_2_13_1_EVK-MIMXRT1060_linux.zip EVK: MIMXRT1060-EVK This article takes MIMXRT1060-EVK SDK as an example, and the situation of other RT development boards with Linux SDK is the same. 2.1 SDK downloading     Download link: https://mcuxpresso.nxp.com/en/builder?hw=EVK-MIMXRT1060 Fig 1 Download the SDK code, named as: SDK_2_13_1_EVK-MIMXRT1060_linux.zip If you download it under Windows, you need to copy the SDK to the Ubuntu system. Here you can use FileZilla or MobaXterm to transfer the file. Because I use the web server Ubuntu, it is based on MobaXterm. This software is free to use, and the download link is: https://mobaxterm.mobatek.net/ Put the downloaded SDK into the Ubuntu folder, in MobaXterm, drag the file can realize the file transfer from Windows to Ubuntu: Fig 2 Unzip SDK, the commander is: unzip SDK_2_13_1_EVK-MIMXRT1060_linux.zip -d ./SDK_2_13_1_EVK-MIMXRT1060_linux Fig 3 Fig 4 It can be seen that the SDK has been successfully unzipped to the SDK_2_13_1_EVK-MIMXRT1060_linux folder. At this point, the Linux SDK is ready to use. 2.2 ARMGCC install and configuration Download ARMGCC, as you can see from the release note of the SDK, the supported GCC Arm Embedded version: GCC Arm Embedded, version is 10.3-2021.10   Download link:https://developer.arm.com/downloads/-/gnu-rm Download the file: gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2  Copy it to the Ubuntu, and unzip it, the unzip commander is: tar -xjvf gcc-arm-none-eabi-10.3-2021.10-x86_64-linux.tar.bz2 Fig 5 Fig 6 You can see that ARMGCC has been decompressed. Configure the environment variables below and add ARMGCC_DIR to /etc/profile: Add the path at the end of the profile to save and exit: export ARMGCC_DIR=/home/nxa07323/rtdoc/gcc-arm-none-eabi-10.3-2021.10/ export PATH=$PATH:/home/nxa07323/rtdoc/gcc-arm-none-eabi-10.3-2021.10/bin/ Fig 7 Valid profile, and check the ARMGCC_DIR is really valid. source /etc/profile echo $ARMGCC_DIR Fig 8 Until now, ARMGCC is ready to use! 2.3 cmake download and install Build also need the cmake tool, so use the following command to install cmake and check whether the installation is successful: sudo apt-get install cmake cmake –version Fig 9 Cmake is also ready! 3. Testing All the tools are ready, let’s start compiling the code, here we take hello_world as an example to compile an executable file downloaded to Flash. 3.1 Executable file Compilation Enter the hello_world gcc path of the SDK: Fig10 It can be seen that there are many files under the armgcc folder, which are compilable files that generate different images: build_debug,build_release:the linker file is RAM linker, where text and data section is put in internal TCM. build_flexspi_nor_debug, build_flexspi_nor_release: The linker file is flexspi_nor linker, where text is put in flash and data put in TCM. build_flexspi_nor_sdram_debug, build_flexspi_nor_sdram_release: The linker file is flexspi_nor_sdram linker, where text is put in flash and data put in SDRAM. build_sdram_debug, build_sdram_release: The linker file is SDRAM linker, where text is put in internal TCM and data put in SDRAM. build_sdram_txt_debug, build_sdram_txt_release: The linker file is SDRAM_txt linker, where text is put in SDRAM and data put in OCRAM. Now, compile build_flexspi_nor_debug.sh, this script will generate flash .elf file, the command is: ./build_flexspi_nor_debug.sh Fig 11 The compiled .elf is placed in the flexspi_nor_debug folder: Fig 12 Convert the hello_world.elf file to hex and bin for the RT board burning, conversion command is: arm-none-eabi-objcopy -O ihex hello_world.elf hello_world.hex arm-none-eabi-objcopy -O binary hello_world.elf hello_world.bin Fig 13 3.2 Code Downloading Test The generated files hello_world.hex and hello_world.bin are the executable files, which can be downloaded to the EVK board through MSD, serial downloader, or debugger software. Open the bin file to view: Fig 14 As you can see, this file is an app executable file with FCB. Here use the MCUbootUtility tool to download, and the EVK board enters the serial download mode: SW7 1-OFF, 2-OFF, 3-OFF, 4-ON Fig 15 After the downloading is finished, EVK board enter the internal boot mode: SW7 1-OFF,2-OFF,3-ON,4-OFF Fig 16 We can see, the printf works, it means the Ubuntu Linux build the file works OK. 3.3 Code configuration Some customers may think that the executable files to be loaded by some of our tools do not need FCB, so how to realize to generate the app without FCB Linux, here we need to modify the flags.cmake file, the path is:     /home/nxa07323/rtdoc/SDK_2_13_1_EVK-MIMXRT1060_linux/boards/evkmimxrt1060/demo_apps/hello_world/armgcc Configure BOOT_HEADER_ENABLE=0: Default is BOOT_HEADER_ENABLE=1(Fig 17), modified to Fig 18: Fig 17                              Fig18 Build again, to generate the .bin, check the .bin file: Fig 19 We can see that this file is a pure app file that does not contain FCB+IVT. It can be used in occasions that do not require FCB. Until now, the RT1060 Linux version of the SDK can be compiled to generate an executable file under Ubuntu, and the function is normal after the function test.            
查看全文
1.Introduction Recently, some customers need the RT1170 LWIP socket client, so this post is mainly share the socket client code which is based on the RT1170 SDK, it is just a simple demo, which also give the test result based on the NXP official EVKB board. 2. Code modification Platform: MIMXRT1170-EVKB SDK_2_13_1_MIMXRT1170-EVKB MCUXpresso IDE v11.7.1 Code is based on the SDK project : lwip_ping_freertos_cm7. This project already add the socket related file, so the modification is simple, just need to add the socket related header file and the app function. The modification is: Add socket server IP address, port, and the message which want to sendout. #define INIT_THREAD_STACKSIZE 1024 /*! @brief Priority of the temporary lwIP initialization thread. */ #define INIT_THREAD_PRIO DEFAULT_THREAD_PRIO #define HOST_NAME "192.168.0.100" #define BUF_LEN 100 uint8_t senddata[]= "Socket client test"; #define PORT 54321 #define IP_ADDR "192.168.0.100" Comment the ping code calling in stack_init API. //  ping_init(&netif_gw); Add the socket client thread: sys_thread_new("socketclient", socketclient_thread, NULL, DEFAULT_THREAD_STACKSIZE, DEFAULT_THREAD_PRIO); The thread code is: static void socketclient_thread(void *arg) { int sock = -1,rece; struct sockaddr_in client_addr; char* host_ip; ip4_addr_t dns_ip; err_t err; uint32_t *pSDRAM= pvPortMalloc(BUF_LEN);// host_ip = HOST_NAME ; PRINTF("host name : %s , host_ip : %s\r\n",HOST_NAME,host_ip); // while(1) // { PRINTF("Start server Connect !\r\n"); // create connection sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { PRINTF("Socket error\n"); vTaskDelay(10); // continue; } client_addr.sin_family = AF_INET; client_addr.sin_port = htons(PORT); client_addr.sin_addr.s_addr = inet_addr(host_ip); memset(&(client_addr.sin_zero), 0, sizeof(client_addr.sin_zero)); if (connect(sock, (struct sockaddr *)&client_addr, sizeof(struct sockaddr)) == -1) { PRINTF("Connect failed!\r\n"); closesocket(sock); vTaskDelay(10); // continue; } PRINTF("Connect to server successful!\r\n"); // PRINTF("\r\n************************************************************\n\r"); // PRINTF("\r\n Begin write\n\r"); write(sock,senddata,sizeof(senddata)); while (1) { //receive data rece = recv(sock, (uint8_t*)pSDRAM, BUF_LEN, 0);//BUF_LEN if (rece <= 0) break; PRINTF("recv %d len data\r\n",rece); PRINTF("%.*s\r\n",rece,(uint8_t*)pSDRAM); write(sock,pSDRAM,rece); } //rec data process memset(pSDRAM,0,BUF_LEN); closesocket(sock); vTaskDelay(10000);//about 10s //10000 // } }   3. Test Result Firstly, use the PC to configure the ENET IP for the server:     192.168.0.100   After configuration, customer can use the TCP test tool, eg:USR-TCP232-Test, which is configured to the TCP server, local IP is:192.168.0.100, host port is:54321, then enter the listen mode:   After the code download to the MIMXRT1170-EVKB, and run it, we can see, the server can detect the connected client IP:192.168/0.102, after the client connect to the server, it will send out the message: “socket client test”, then the server can send out the message to the client, the client will use the UART printf it, also loop back to the server again. This is the test result video: Code attached:evkbmimxrt1170_lwip_socket_client_freertos_cm7.7z  
查看全文
NXP Updated the Hardware Development Guide for the MIMXRT1160/1170 Processor (MIMXRT1170HDUG) The main difference is: Updated capacitance value of VDDA_1P8_IN in Table 1 and Table 2 From 0.1uF to 1uF     This will help improve the robustness of the circuit at low temperatures.
查看全文
RT106X secure JTAG test and IDE debug 1 Introduction     Regarding the usage of RT10XX Secure JTAG, the nxp.com has already released a very good application note AN12419 Secure JTAG for i.MXRT10xx: https://www.nxp.com/docs/en/application-note/AN12419.pdf This application note talks about the principle of Secure JTAG, how to modify the fuse to implement the Secure JTAG function, and the content of the related JLINKscript file, and then gives the use of JLINK commander to realize the identification of the ARM core. Usually, if the ARM core can be identified, it indicates that Secure JTAG connection has been passed. But in practical usage, I found many customers encounter the different issues, for example, the Secure JTAG could not find the ARM core directly, or the core identify is not stable, and some customers asked how to use common IDEs, such as MCUXPresso, IAR , MDK to add this Secure JTAG function to realize  Secure JTAG debugging.   For the test of secure JTAG, it also needs the cost, because the fuse needs to be modified. If the position of the fuse is accidentally modified, it may cause irreversible problems. Due to the different situations of customers, I also done more tests, borrowing boards with chip socket which can replace the different RT chip, I have tested RT1050, RT1060, RT1064, but in practical usage, there are still some customers mentioned that it will be reproduced on the EVK, so I also tested the secure JTAG function on the RT1060 and RT1064 EVK     This article will share all the previous relevant experience, so that latecomers can have a reference when encountering similar problems, and avoid unnecessary minefields. This document used the platform: MIMXRT1064-EVK revA: RT1060-EVK, RT1050-EVKB is similar SDK_2_13_0_EVK-MIMXRT1064 MCUXpresso IDE v11.7.1_9221 MDK V5.36: higher reversion is the same IAR 9.30.1: higher reversion is the same Segger JLINK plus JLINK driver version:V788D NXP-MCUBootUtility-5.1.0 2 RT1064 secure JTAG modification Under normal circumstances, it is not recommended for customers to burn all the related fuses directly and then test it directly. I usually proceeds step by step, hardware layout, to ensure that it can support JTAG, and then save the original read of the fuse, burn JTAG, test JTAG, and finally Burn and test other fuses for secure JTAG.    2.1 MIMXRT1064-EVK Hardware modification For RT10XX EVK, the board default situation is the same as the chip situation, which supports SWD. The JTAG pin is connected to other hardware modules from the hardware, so it will affect JTAG function. When it is determined to use JTAG function, the circuit needs to be modified, just like MIMXRT105060HDUG has said:    (1). Burn fuse DAP_SJC_SWD_SEL from ‘0’ to ‘1’ to choose JTAG. (2). DNP R323,R309,R152 to isolate JTAG multiplexed signals. (3). Keep off J47 to J50 to isolate board level debugger.     So, to the MIMXRT1064-EVK board, just need to remove R323, R309, R152, disconnect J47,J48,J49,J50, which is used to disconnect the on board debugger, then use the external Segger JLINK JTAG interface to connect the MIMXRT1064-EVK on board J21. 2.2 Original fuse map read First, the MIMXRT1064-EVK board enters the serial download mode, SW7: 1-OFF, 2-OFF, 3-OFF, 4-ON. Use MCUBootUtility tool to connect EVK, and read the initial fuse map, the situation is as follows:     Fig 1 2.3 JTAG Modification and test    Modify fuse to realize SWD to JTAG: 0X460[19] DAP_SJC_SWD_SEL=1   Fig 2     Use the JLINK commander, JTAG method to connect the board, to find the ARM CM7 core: Fig 3     If the ARM CM7 core can’t be identified, it means the hardware still have issues, or the fuse modified bit is not correct, just do the double check, make sure the ARM core can be found, then go to the next steps. 2.4 Secure JTAG Modification     Modify fuse bit to realize Secure JTAG:     0X460[23:22]:JTAG_SMODE =1     0X460[26]: KTE_FUSE=1     0X610,0X600 burn key: 0xedcba987654321, user also can burn with other custom keys, but need to record it, as the JLINKScript needs to use it.   Fig 4 In the above picture, the secure JTAG fuse and key fuse is finished, at last, to burn fuse 0X400[6]: SJC_RESP_LOCK=1, which is used to close the write and read to secret response key: Fig 5 Here, we can see, the 0X600,0X610 key area is shadow. Now, record the UUID0, UUID1, it will use the script to read out to check the UUID correction or not. 2.5 Secure JTAG JLINK commander test Because during the secure JTAG connection process, the JTAG_MOD pin needs to be pulled low and high, so a wire needs to be connected to pull JTAG_MOD low and high. MIMXRT1064-EVK can use J25_4, which is 3.3V, and JTAG_MOD signal point can use TP11 test point. By default, JTAG_MOD is pulled low. When it needs to be pulled high, it can be connected to J25_4.         During the test, it will need to use the JLINKScript, the content is as follows, also can check  the attached NXP_RT1064_SecureJTAG.JlinkScript file: int InitTarget(void) { int r; int v; int Key0; int Key1; JLINK_SYS_Report("***********************************************"); JLINK_SYS_Report("J-Link script: InitTarget() *"); JLINK_SYS_Report("NXP iMXRT, Enable Secure JTAG *"); JLINK_SYS_Report("***********************************************"); JLINK_SYS_MessageBox("Set pin JTAG_MOD => 1 and press any key to continue..."); // Secure response stored @ 0x600, 0x610 in eFUSE region (OTP memory) Key0 = 0x87654321; Key1 = 0xedcba9; JLINK_CORESIGHT_Configure("IRPre=0;DRPre=0;IRPost=0;DRPost=0;IRLenDevice=5"); CPU = CORTEX_M7; JLINK_SYS_Sleep(100); JLINK_JTAG_WriteIR(0xC); // Output Challenge instruction // Readback Challenge, Shift 64 dummy bits on TDI, TODO: receive Challenge bits on TDO JLINK_JTAG_StartDR(); JLINK_SYS_Report("Reading Challenge ID...."); JLINK_JTAG_WriteDRCont(0xffffffff, 32); // 32-bit dummy write on TDI / read 32 bits on TDO v = JLINK_JTAG_GetU32(0); JLINK_SYS_Report1("Challenge UUID0:", v); JLINK_JTAG_WriteDREnd(0xffffffff, 32); v = JLINK_JTAG_GetU32(0); JLINK_SYS_Report1("Challenge UUID1:", v); JLINK_JTAG_WriteIR(0xD); // Output Response instruction JLINK_JTAG_StartDR(); JLINK_JTAG_WriteDRCont(Key0, 32); JLINK_JTAG_WriteDREnd(Key1, 24); JLINK_SYS_MessageBox("Change pin JTAG_MOD => 0, press any key to continue..."); return 0; }   SecJtag.bat file content is: jlink.exe -JLinkScriptFile NXP_RT1064_SecureJTAG.JlinkScript -device MIMXRT1064XXX6A -if JTAG -speed 4000 -autoconnect 1 -JTAGConf -1,-1 This command is mainly used the JLINK commander and JLINKScript to realize the Secure JTAG connection. When test it, put the SecJtag.bat, JLink.exe, and NXP_RT1064_SecureJTAG.JlinkScript 3 files in the same folder. For testing, can change the board mode to the internal boot mode, SW7:1-OFF,2-OFF, 3-ON, 4-OFF. Run SecJtag.bat, the test situation is: It indicates to connect JTAG_MOD to higher level   Fig 6 Here, use the wire to connect the J25_4 and TP11, which is connect the JTAG_MOD=1, then click OK, go to the next step:   Fig 7 It can be seen here that the correct UUID has been recognized, which is consistent with the UUID read by MCUBootutility above. Many customers cannot read the correct UUID here, indicating that there is a problem with hardware modification, or fuse modification, or another. Or in the case, the JTAG pin in the app is not enabled, which will be described in detail later. Here disconnect the connection between TP11 and J25_4, the default is JTAG_MOD=0, click OK to continue Fig 8 Here, we can see, the ARM CM7 core is found, it means this hardware platform already realize the Secure JTAG connection. Now, can use the IDEs to do the debugging. 3. Secure JTAG debug function in 3 IDEs This chapter aims at how to use secure JTAG function in RT10XX three commonly used IDEs: MCUXpresso, IAR, MDK,  to implement secure JTAG code debug operation.    3.1 Software code prepare This article selects the SDK hello_world project as the test demo: SDK_2_13_0_EVK-MIMXRT1064\boards\evkmimxrt1064\demo_apps\hello_world     Two points should be noted here:  Do not use led_blinky directly, because the led control pin GPIO_AD_B0_09 used by the code is JTAG_TDI, which will cause the Secure JTAG connection to fail after downloading this code, because the pin function of JTAG has been changed. Add the pin configuration for JTAG in app code pinmux.c, otherwise there will be a phenomenon due to the lack of JTAG pin configuration, to the empty RT1064, which the chip that has not burned the code can use Secure JTAG connection, but once the code is burned, the connection will be failed. Add the following code to Pinmux.c: IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_11_JTAG_TRSTB, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_06_JTAG_TMS, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_07_JTAG_TCK, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_09_JTAG_TDI, 0U); IOMUXC_SetPinMux(IOMUXC_GPIO_AD_B0_10_JTAG_TDO, 0U); 3.2 MCUXpresso Secure JTAG debug    Use MCUXpresso IDE to import the SDK hello world demo, modify the pinmux.c, which add the JTAG pin function configuration.    Configure MCUXPresso ID’s debugger JLinkGDBServerCL.exe version as your used JLINK driver version, Window->preferences Fig 9 Run->Debug configurations, configure to JTAG, choose device as MIMXRT1064xxx6A, add the JLINKscriptfile   Fig10   Fig 11 Connect JTAG_MOD=1, which is connect TP11 to J25_4, connect OK.   Fig 12 We can see, it already gets the correct UUID, it also requires connect JTAG_MOD=0, here just leave the TP11 floating, then connect OK:   Fig 13 It can be seen that at this time, it has successfully entered the debug mode and can do debugging. For details, you can check the MCUXpresso11_7_1_MIMXRT1064_SJTAG.mp4 file in the attachment. The test experience here is that MCUXpresso V11.7.1 is found to be a bit unstable and needs to be tried a few more times, but the download of the higher version V11.8.0 version is very stable. If you can get a version higher than V11.7.1, it is recommended to use a higher version of MCUXpresso IDE . 3.3 IAR Secure JTAG debug Some customers need to use the IAR IDE to debug Secure JTAG function, you can use the hello world in the SDK demo, modify pinmux.c to add the JTAG pin configuration code.     The difference is:   (1) Run JLINK driver:JLinkDLLUpdater.exe   Fig 14 Just to refresh the JLINK driver to the IAR,MDK IDE. (2) Modify the file name of JLINKscript to be consistent with the name of the demo, and put it under the settings folder of the project folder. For example, the routine here is hello_world_flexspi_nor_debug, and the file name of JlinkScript is required: hello_world_flexspi_nor_debug.JlinkScript, so that IAR will automatically call the corresponding JlinkScript file   Fig15 (3) Configure IAR debugger as JLINK JTAG   Fig 16                                          Fig 17 Click debug button to enter debug mode:   Fig 18 It needs to set JTAG_MOD=1, just to connect TP11 to J25_4.   Fig 19 It needs to set JTAG_MOD=0, just leave the TP11 floating, click OK to continue.   Fig 20 We can see, the IAR already can do the secure JTAG debugging. 3.4 MDK Secure JTAG debug   For the MDK secure JTAG configuration, the basic requirement is:     (1) Modify pinmux.c code to enable the JTAG pin function     (2) Run JLINK driver, JLinkDLLUpdater.exe,refresh the driver to MDK     (3) JlinkScript file name changed to JLinkSettings.JlinkScript, copy it to the folder in the mdk project, then the MDK will call the JLINKscript file automatically   Fig 21       (4) Modify debugger to JLINK, then modify the interface to JTAG   Fig 22   Fig 23 So far, the Secure JTAG related configuration of MDK has been completed. From theory, it can be directly debugged to run. But I found some problems after many tests. For the code of RAM (hello_world debug), it is no problem to be able to perform secure JTAG debug, but for the code of flash (hello_world_flexspi_nor_debug), there is no problem through secure jtag download, but the debug will run the program abnormal, check the memory data in the flash, also get the wrong data     Fig 24 We can see, UUID also correct, normally, this issue is related to the flashloader during downloading, however, the flashloader of JLINK has not been directly accessed, so I tried to use RT-UFL as the flashloader, and the debugger was successful. If customers encounter similar problems when want to use the MDK to do the secure JTAG debugging, they can use RT-UFL as the flashloader. The reference document is: https://www.cnblogs.com/henjay724/p/13951686.html https://www.cnblogs.com/henjay724/p/15465655.html To summarize it here, copy the iMXRT_UFL file to the JLINK driver folder: C:\Program Files\SEGGER\JLINK\Devices\NXP Copy JLinkDevices.xml to folder: C:\Program Files\SEGGER\JLINK The Jlinkscript file add is the same as the Figure 21. Modify the JlinkSettings.ini file, device is MIMXRT1064_UFL, override =1.   Fig 25 Delete the program algorithm, will use the RT-UFL algorithm   Fig 26 Uncheck update target before Debugging   Fig 27 Enter debug mode:   Fig 28 Configure JTAG_MOD=1, connect TP11 to J25_4, click OK to continue:   Fig 29 Leave the TP11 as floating, click OK to enter the debug mode, the result is:   Fig 30 We can see, after changing the flashloader to the RT-UFL, MDK project Secure JTAG debug also works OK, the attachment also share the RT-UFL related files.  4. Summary For Secure JTAG, you need to modify the hardware to support JTAG function, modify the fuse to support secure JTAG, and modify the code pins to enable the JTAG function. For the IDE debug, you need to configure the relevant interface as JTAG and add the correct JlinkScriptfile, so that the secure JTAG function can be successfully run , and perform IDE code debugging. Attachments: evkmimxrt1064_hello_world_SJTAG.zip:MCUXpresso project EVK-MIMXRT1064-hello_world_iar.7z:IAR project EVK-MIMXRT1064-hello_world_mdk.7z:MDK project File\ NXP_RT1064_SecureJTAG.JlinkScript, JLINK script File\ SecJtag.bat, associate with JLink.exe and NXP_RT1064_SecureJTAG.JlinkScript to realize JLINK Commander connection, which will find the ARM core. File\ RT-UFL: RT ultra flashloader algorithm, source:https://github.com/JayHeng/RT-UFL   Here, really thanks so much for our expert @juying_zhong 's help with the Secure JTAG patient guide during my testing road!
查看全文
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.
查看全文
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.
查看全文
This article will help you understand in detail the necessary steps to connect an external SRAM memory to the RT devices with the SEMC module. This document is focused on RT1170 however a lot of this information can also be followed for other RT devices with the SEMC module, please consult limitations on the specific device Reference Manual. In this post, there is attached an example of this, since the EVK does not contain an SRAM a specific memory is not used for this. This is a theoretical approach to how to set this kind of memory. The user needs to set specific parameters for the memory to be used.   The SEMC is a multi-standard memory controller optimized for both high performance and low pin count. It can support multiple external memories in the same application with shared address and data pins. The interface supported includes SDRAM, NOR Flash, SRAM, and NAND Flash, as well as the 8080 display interface. Features The SEMC includes the following features: SRAM interface Supports SRAM and Pseudo SRAM Supports 8/16 bit modes Supports ADMUX, AADM, and Non-ADMUX modes Up to 4 Chip Select (CS) Up to 4096Mb memory size NOTE For 16-bit devices, up to 4096Mb memory size For 8-bit devices, up to 2048Mb memory size For more detailed features on supported memories of this module please consult Reference Manual How to set SRAM It is important to mention that RT1170 supports ASYNC and SYNC mode on the SRAM however SYNC mode is not supported in all RT devices, e.g. RT1050 does not support SRAM SYNC mode. It is important to consider the pin mux for these devices, for this you can refer to table 29-7 for the RT1170. Please consider that pins controlled through the IOCR register should be static. This means that if you configure, for example, SEMC_ADDR08 to be CE on the SRAM it cannot be used in the same application as A8 in an SDRAM. Let´s go step by step on how to configure the parameters and where to find that information:   Configure MCR[DQSMD] bit to select the read clock source for synchronous mode. Suggest setting it with 0x1 to reach high clock frequency. config.dqsMode = kSEMC_Loopbackdqspad; Configure the IOCR register to choose CS pins. For this, you can refer to table 29-6. I suggest using CSX pins for CS signals of the SRAM. The Init function from the SDK sets this register incorrectly so write this register outside the function SEMC->IOCR |= 0x00908BB6; // A8:CE#0, CSX0:A24, CSX1:A25, CSX2:CE#1, RDY:CE#2 Optional Configure BMCR registers for bus access efficiency, the arbitration adopts a weight-based algorithm where the weights are obtained from BMCR registers. A score is calculated and the command with the highest score is served first. The score is calculated with the following formula: SCORE = QOS*WQOS + AGE*WAGE/4 + WSH + WRWS Where : - QOS stands for AxQOS of AXI bus-WQOS is the weight factor of QOS. -AGE stands for the wait period for each command -WAGE is the weight factor of AGE. -WSH stands for the weight of slave hit without read/write switch scenario. -WRWS stands for the weight of the slave hit with read/write switch scenario. This is used when you have multiple devices connected to the module and you want to assign access priorities to the different devices.   Configure Base Register 6/9/10/11 with base address, memory size, and valid information. BRx[BA]: In this field, you set the address where the SRAM is going to be located. You can refer to the specific device memory map. In the example, I used 0x9000_0000 but you can use any SEMC location as long it does not overlap with other memory spaces. BRx[MS]: Here you specify the size of the SRAM. [Image from register] BRx[VLD] must be 1 so the memory can be accessed. //VLD is always set to 1 in the SRAM Init function of the SDK sram_config.address = SRAM_BASE;// Base address 0x90000000 (BR6[BA]) sram_config.memsize_kbytes = 0x10000;// SRAM0 space size 64MB (BR6[MS])   Configure INTEN and INTR registers if need to generate interrupts. You can use the function "SEMC_EnableInterrupts()" Configure SRAM Control Register with parameters obtained from the specific SRAM device. These registers contain the timings for the memory used. These values are obtained from the memory datasheet. sram_config.addrPortWidth = 8;// Port width (SRAMCR0[COL])Don't care in SRAM. sram_config.advActivePolarity = kSEMC_AdvActiveLow;//ADV# polarity //(SRAMCR0[ADVP])Don't care if not use ADV. sram_config.addrMode = kSEMC_AddrDataNonMux;//Non Mux mode(SRAMCR0[AM]) sram_config.burstLen = kSEMC_Nor_BurstLen1;//Burst length (SRAMCR0[BL]) sram_config.portSize = kSEMC_PortSize16Bit;//Port size 16bit (SRAMCR0[PS]) sram_config.syncMode = kSEMC_AsyncMode;// ASYNC mode (SRAMCR0[SYNCEN]) sram_config.waitEnable = true;// WAIT enable (SRAMCR0[WAITEN]) sram_config.waitSample = 0;// WAIT sample (SRAMCR0[WAITSP]) sram_config.advLevelCtrl = kSEMC_AdvHigh;// ADV# level control(SRAMCR0[ADVH]) //Don't care if not use ADV. sram_config.tCeSetup_Ns = 20;//CE#setup time[nsec](SRAMCR1[CES])Need tuning. sram_config.tCeHold_Ns = 20;// CE#hold time [nsec](SRAMCR1[CEH]) Need tuning. sram_config.tCeInterval_Ns = 20;//CE#interval time[nsec](SRAMCR2[CEITV]) Need //tuning. sram_config.readHoldTime_Ns = 20;//Read hold time[nsec](SRAMCR2[RDH])Only for //SYNC mode. sram_config.tAddrSetup_N s= 20;//ADDRsetup time[nsec](SRAMCR1[AS])Need tuning. sram_config.tAddrHold_Ns = 20;//ADDRhold time[nsec](SRAMCR1[AH]) Need tuning. sram_config.tWeLow_Ns = 20;//WE low time [nsec] (SRAMCR1[WEL]) Need tuning. sram_config.tWeHigh_Ns = 20;//WE high time [nsec] (SRAMCR1[WEH]) Need tuning. sram_config.tReLow_Ns = 20;// RE low time [nsec] (SRAMCR1[REL]) Need tuning. sram_config.tReHigh_Ns = 20;// RE high time[nsec](SRAMCR1[REH]) Need tuning. sram_config.tTurnAround_Ns = 20;//Turnaround time[nsec](SRAMCR2[TA])Need //tuning but don't set it to be 0. sram_config.tAddr2WriteHold_Ns = 20;//Address to write data hold time [nsec] (SRAMCR2[AWDH]) Need tuning. sram_config.tWriteSetup_Ns = 20;//Write Data setup time[nsec](SRAMCR2[WDS]) //Only for SYNC mode. sram_config.tWriteHold_Ns= 20;//Write Data hold time [nsec] (SRAMCR2[WDH]) //Only for SYNC mode. sram_config.latencyCount = 20;//Latency count[nsec](SRAMCR2[LC]) Only for //SYNC mode. sram_config.readCycle = 20;// read time[nsec](SRAMCR2[RD])Only for SYNC mode. sram_config.delayChain = 20;// typically not used in SRAM. (DCCR [SRAMXVAL], //DCCR [SRAMXEN], DCCR [SRAM0VAL], DCCR [SRAM0EN]) ​ These values are for reference and do not suggest the exact values for a specific SRAM. Initialize the SRAM device by IP command registers (IPCR0/1/2, IPCMD, and IPTXDAT) if needed.  Notes: -Configure independent timing for SRAM device 0 and device 1/2/3 -Configure SRAM device 0 timing with register SRAMCR0~SRAMCR3 -Configure SRAM decive1/2/3 timing with register SRAMCR4~SRAMCR6
查看全文
Wireless module combinations from Tables 2 and 3 are not updated with the latest SDK 2.12.1 in the user manual UM11441. Major updates in Table 2 and Table 3: u-blox modules are supported only on rt1060 Murata modules are only tested with i.MX RT1060 EVKB and i.MX RT1040 EVK platforms Modified Murata modules names Renamed i.MX RT685S EVK to IMXRT685-AUD-EVK Please refer to the attached PDF for updated information.
查看全文
Note: for similar EVKs, see: Using J-Link with MIMXRT1170-EVKB Using J-Link with MIMXRT1060-EVKB or MIMXRT1040-EVK Using J-Link with MIMXRT1060-EVK or MIMXRT1064-EVK This article provides details using a J-Link debug probe with either of these EVKs.  There are two options: the onboard debug circuit can be updated with Segger J-Link firmware, or an external J-Link debug probe can be attached to the EVK.  Using the onboard debug circuit is helpful as no other debug probe is required.  Appnote AN13206 has more details on this, and the comparison of the firmware options for the debug circuit.  This article details the steps to use either J-Link option.   Using external J-Link debug probe Segger offers several J-Link probe options.  To use one of these probes with these EVKs, configure the EVK with these settings: Remove jumpers J6 and J7, to disconnect the SWD signals from the onboard debug circuit.  These jumpers or installed by default. Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Connect the J-Link probe to J1, 20-pin dual-row 0.1" header.   Using onboard debug circuit with J-Link firmware Disconnect any USB cables from the EVK Power the EVK: the default option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  The green LED D16 next to SW5 will be lit when the EVK is properly powered. Short jumper J22 to force the debug circuit in DFU mode Connect a USB cable to J11, to the on-board debugger Follow Appnote AN13206 to program the J-Link firmware to the EVK Unplug the USB cable at J11 Remove the jumper at J22 Plug the USB cable back in to J11.  Now the on-board debugger should boot as a JLink. Install jumpers J6 and J7, to connect the SWD signals from onboard debug circuit.  These jumpers or installed by default. Note: with the JLink firmware loaded, USB J11 is no longer an option to power the EVK.  Another option is connecting the power supply to barrel jack J43, and setting power switch SW5 to On position (3-6).  For this power option, jumper J38 needs to short 1-2, which is the default setting. 
查看全文
Abstract Today I'd like to discuss a scenario that I will encounter in practical application. In the design phase, the Serial Nor flash is usually used as a code storage device for RT series MCUs, such as QSPI, HyperFlash, etc, as these devices all support XIP features. The flash usually is not only occupied by the code but also used to store data, such as device parameters, and log information, and even used as a file system. So we need to evaluate Flash's size. Is there any constraint to the manipulation of data space in the secure boot mode? And how to keep the data confidential? We'll talk about it below and let's get started. Secure boot mode HAB boot The bootable image is plaintext, and it may be changed after the writing operation of the FlexSPI module. If the digest algorithm obtains the different values will lead to the verification process fails, as the writing operation destroys the integrity of the data, regarding confidentiality, data is stored in plaintext in Serial Nor flash under HAB boot.   Fig1 Signature and verification process Encrypted XIP boot mode After enabling the Encrypted XIP boot mode, what is the impact on FlexSPI's read and write data operations? The first point is that the read data will be treated as encrypted data and decrypted by the BEE or OTFAD module. However, if a write operation is performed, the BEE or OTFAD module will be bypassed, in another word, the data will be written directly to the Serial Nor flash. in a short, it is not affected by the Encrypted XIP boot mode. 1) Read operation As shown in Fig 2, the encrypted code and data stored in Serial Nor flash need to be decrypted before they are sent to the CPU for execution. This is also the implementation mechanism of the Encrypted XIP boot mode. To enable the encrypted XIP boot mode, it needs to burn the keys to eFuse, after that, eFuse is impossible to restore, so the test cost seems a bit high, so I recommend you refer to the source code of the 《How to Enable the On-the-fly Decryption》application note to dynamically configure the key of the BEE module and read the encrypted array by DCP from Flash, then compare to plaintext array to verify BEE module participle the decryption flow. Fig 2 2) Write operation Modify the source code of the above application note, define s_nor_program_buffer [256], then set the values through the following code, and burn them to the 20th sector, the offset address is 0x14000. for (i = 0; i < 0xFFU; i++) { s_nor_program_buffer[i] = i; } status = flexspi_nor_flash_page_program(EXAMPLE_FLEXSPI, EXAMPLE_SECTOR * SECTOR_SIZE, (void *)s_nor_program_buffer); if (status != kStatus_Success) { PRINTF("Page program failure !\r\n"); return -1; } DCACHE_InvalidateByRange(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE, FLASH_PAGE_SIZE); memcpy(s_nor_read_buffer, (void *)(EXAMPLE_FLEXSPI_AMBA_BASE + EXAMPLE_SECTOR * SECTOR_SIZE), sizeof(s_nor_read_buffer)); for(uint32_t i = 0; i < 256; i++) { PRINTF("The %d data in the second region is 0x%x\r\n", i, s_nor_read_buffer[i]); } After the programming finishes, connect to Jlink and use J-flash to check whether the burned array is correct. The results prove that the write operation will bypass the BEE or OTFAD module and write the data directly to the Serial Nor flash, which is consistent with Fig 2. Fig3 Sensitive data preservation As mentioned at the beginning, in the real project, we may need to use Flash to store data, such as device parameters, log information, or even as a file system, and the saved data is usually a bit sensitive and should prevent being easily obtained by others. For example, in SLN-VIZNAS-IoT, there is a dedicated area for storing facial feature data. Fig 4 Although the purely facial feature data is only meaningful for specific recognition algorithms, in another word, even if a third-party application obtains the original data, it is useless for hackers. In the development of real face recognization projects, it is usually to declare other data items associated with facial feature data, such as name, age, preferences, etc, as shown below: typedef union { struct { /*put char/unsigned char together to avoid padding*/ unsigned char magic; char name[FEATUREDATA_NAME_MAX_LEN]; int index; // this id identify a feature uniquely,we should use it as a handler for feature add/del/update/rename uint16_t id; uint16_t pad; // Add a new component uint16_t coffee_taste; /*put feature in the last so, we can take it as dynamic, size limitation: * (FEATUREDATA_FLASH_PAGE_SIZE * 2 - 1 - FEATUREDATA_NAME_MAX_LEN - 4 - 4 -2)/4*/ float feature[0]; }; unsigned char raw[FEATUREDATA_FLASH_PAGE_SIZE * 2]; } FeatureItem; // 1kB After enabling the Encrypted XIP boot mode, the above write operation test has proved that FlexSPI's write operation will program the data into Serial Nor flash directly, but during the reading process, the data will be decrypted by BEE or OTFAD, so we'd better use DCP or other modules to encrypt the data prior to writing, otherwise, the read operation will get the values that the plaintext goes through the decryption calculation. The risk of leakage Assume XIP encrypted boot is enabled, and whether it's okay to send the encrypted bootable image sent to the OEM for mass production. Moreover, is it able to allow the customers to access the encrypted bootable image without worrying about application image leakage? In order to verify the above guesses, I do the following testing on MIMXRT1060-EVK. Select the XIP encrypted mode in the MCUXpresso Secure Provisioning tool to generate and burn the bootable image of the Blink LED; Fig5 Observe the burned image through NXP-MCUBootUtility, you can find that the ciphertext image is very messy when compared to the plaintext image on the right border, so it seems like the NXP-MCUBootUtility can't obtain the plaintext image; Fig 6 Let's observe the ciphertext image in another way, read them through the pyocd command, as shown below; Fig 7 Open then 9_21_readback.Bin and compare it with the plain text image on the right border, they are the same actually, in other words, the plaintext image was leaked. Fig 8 Explanation As the above Fig 2 shows, the encrypted code and data stored in Serial Nor flash need to be decrypted before they are sent to the CPU for execution. When Jlink connects to the target MCU, it will load the corresponding flash driver algorithm to run in the FlexRAM. If the flash driver algorithm detects the boot type of the MCU just like the following code, then configures the BEE or OTFAD module according to the detecting result, after that, when reading the ciphertext in the Nor Flash, the data will be automatically decrypted. status = SLN_AUTH_check_context(SLN_CRYPTO_CTX_1); configPRINTF(("Context check status %d\r\n", status)); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a crash if (SLN_AUTH_NO_CONTEXT == status) { configPRINTF(("Ensuring context...\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a crash // Load crypto contexts and make sure they are valid (our own context should be good to get to this point!) status = bl_nor_encrypt_ensure_context(); if (kStatus_Fail == status) { configPRINTF(("Failed to load crypto context...\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a crash // Double check if encrypted XIP is enabled if (!bl_nor_encrypt_is_enabled()) { configPRINTF(("Not running in encrypted XIP mode, ignore error.\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a // crash // No encrypted XIP enabled, we can ignore the bad status status = kStatus_Success; } } else if (kStatus_ReadOnly == status) // Using this status from standard status to indicate that we need to split PRDB { volatile uint32_t delay = 1000000; // Set up context as needed for this application status = bl_nor_encrypt_split_prdb(); configPRINTF(("Restarting BOOTLOADER...\r\n")); while (delay--) ; // Restart DbgConsole_Deinit(); NVIC_DisableIRQ(LPUART6_IRQn); NVIC_SystemReset(); } } else if (SLN_AUTH_OK == status) { configPRINTF(("Ensuring context...\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a crash // We will check to see if we need to update the backup to the reduced scope PRDB0 for bootloader space status = bl_nor_encrypt_ensure_context(); if (kStatus_Fail == status) { configPRINTF(("Failed to load crypto context...\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a crash // Double check if encrypted XIP is enabled if (!bl_nor_encrypt_is_enabled()) { configPRINTF(("Not running in encrypted XIP mode, ignore error.\r\n")); // No encrypted XIP enabled, we can ignore the bad status status = kStatus_Success; } } else if (kStatus_Success == status) // We have good PRDBs so we can update the backup { bool isMatch = false; bool isOriginal = false; configPRINTF(("Checking backup context...\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before a crash // Check if we have identical KIBs and initial CTR status = bl_nor_crypto_ctx_compare_backup(&isMatch, &isOriginal, SLN_CRYPTO_CTX_0); if (kStatus_Success == status) { if (isMatch && isOriginal) { configPRINTF(("Updating backup context with valid address space...\r\n")); // DEBUG_LOG_DELAY_MS(1000); // Optional delay, enable for debugging to ensure log is printed before // a crash // Update backup PRDB0 status = SLN_AUTH_backup_context(SLN_CRYPTO_CTX_0); } } } } How to handle Now we already understand the cause of the leak, we must prohibit external tools from loading flashloader or flash driver algorithms into the FlexRAM to run, so in addition to disabling the Debug port, we also need to disable the Serial download method to prevent the hackers take advantage of the Serial Downloader method to make the ROM code load a special flashloader to run in RAM, then configure the BEE or OTFAD module prior to reading the image. However, compared to simply prohibiting the debug port, I'd highly recommend you select the Secure Debug method, because the debug feature requirement is important to return/filed testing, Secure Debug just is like adding a sturdy lock to the debug port, and only the authorized one can open this lock to enter the debugging mode successfully. Reference AN12852:How to Enable the On-the-fly Decryption 《The trust chain of HAB boot》
查看全文
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  
查看全文