Zephyr Project Knowledge Base

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

Zephyr Project Knowledge Base

Discussions

Sort by:
If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. Some resources to help with developing and debugging Zephyr applications: MCUXpresso extension for Visual Studio Code VS Code Lab Guides: Building the Hello World sample Kconfig and compiler optimizations Debugging and Thread Awareness Devicetree and VS Code Devicetree Viewer Segger Tools: Webinar NXP and SEGGER: Debug, Visualize and Analyze Zephyr OS Applications with Ease Ozone debugger SystemView real-time analysis tool If RTT control block address is not automatically found, see Using Segger SystemView and RTT Golioth blog: Debugging with SEGGER Ozone and SystemView on Zephyr J-Link debug probe: Using J-Link with MIMXRT1060 or MIMXRT1064 Using J-Link with MIMXRT1060-EVKB or MIMXRT1040-EVK Using J-Link with MIMXRT1160-EVK or MIMXRT1170-EVK Using J-Link with MIMXRT1170-EVKB Percepio View for Zephyr RTOS and Tracealyzer for Zephyr MCUXpresso Config Tools, can generate board pinctrl files. FreeMASTER Run-Time Debugging Tool FreeMASTER Zephyr Sample Applications Return to Zephyr Knowledge Hub
View full article
If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. Bootloaders Zephyr includes the open-source MCUboot bootloader as a module, and makes it easy to use as a bootloader for Zephyr applications. MCUboot and Zephyr on NXP i.MX RT series Building a sample with MCUboot and Sysbuild, and  Zephyr app with MCUboot in VS Code.  More advanced MCUboot RAM Loading with Zephyr. Zephyr MCUBoot + TF-M Inter-Processor Communication (IPC) and Multicore Zephyr includes an IPC subsystem.  Zephyr also integrates the open-source OpenAMP framework for communication between cores using the RPMsg protocol. Zephyr OpenAMP multicore sample RT1170 Building a dual-core image Zephyr networking stack on i.MX RT1170 Cortex-M4 secondary core Multicore performance Power Management (PM) Zephyr includes a Power Management subsystem, supported on many NXP SOCs. Webinar: Accelerate Development with Zephyr OS Features and Modules NXP SmartWatch demo and webinar: minimizes power consumption on the i.MX RT500 PSA and Trusted Firmware (TF-M) Example TF-M PSA crypto on FRDM-RW612 Zephyr MCUBoot + TF-M Startup code and process For portability, Zephyr manages startup code that is not included in the application.  The SOC, memory, device drivers, and some subsystems are initialized before main(). Webinar: Application Portability Made Easy With Zephyr OS and NXP Adding custom startup code   Return to Zephyr Knowledge Hub
View full article
If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. One of the popular reasons developers choose Zephyr is the large offering of drivers and peripheral support.  The best place to look for the latest drivers and features supported on a hardware platform, is on the board’s documentation page.  For example, this Supported Features table lists the latest support for the FRDM-MCXN947 board.  Here are the links to these pages for all the boards with Zephyr support. NXP’s Hardware Abstraction Layer (HAL) is based on the MCUXpresso SDK drivers.  To learn more, see the blog Zephyr Software Code Reuse with NXP MCUXpresso SDK.  Most users want to use the Zephyr driver APIs in their application for portability.  But if a Zephyr driver is not supported on a platform, or if there is no Zephyr driver for a hardware peripheral, another option is Using MCUXpresso SDK drivers in Zephyr app. Peripheral Clocks: NXP has a large portfolio of boards supported for different SOCs with many peripheral options and multiple instance of peripherals.  Many of these instances cannot easily be tested when Zephyr support is added for a board.  Long term, NXP hopes clocks will be enabled and configured using the Clock Management Subsystem, but this is not adopted yet.  Most peripheral clocks are enabled in SOC or board source files.  One common issue Zephyr users have when enabling or adding a peripheral instance on their board, is that instance is not clocked properly.  Typically enabling the peripheral clock is simple once this is known.  Newer boards enable these clocks in the board.c file.  For example, frdm_mcxn947_init() enables these clocks for FRDM-MCXN947 board.  Some older SOCs enable the clocks in soc.c.  For example, clock_init() enables these clocks for the i.MX RT10xx SOCs. Below are some helpful resources for specific peripherals and drivers: Accelerators and Coprocessors PowerQuad Appnote AN13970 Running Zephyr RTOS on Cadence Tensilica HiFi 4 DSP Analog to Digital Converter (ADC) Zephyr sample die_temp_polling to measure temperature Displays Most displays are enabled in Zephyr as shields, which are add-on hardware modules.  See Zephyr’s list of shields. Typically a board page will document a display shield it has been tested with.  For example, the FRDM-MCXN947 board page includes the LCD_PAR_S035 display shield. The shield page gives instructions how to include that shield in the build, and add to the application.  For example, see the LCD_PAR_S035 shield page.  If building with VS Code, see the CMake wiki.  Zephyr has a couple samples that use displays, including the display driver sample and the LVGL demo. Direct Memory Access (DMA) When using a DMA, be aware of cache coherency, and make sure buffers accessed by DMA are not in cacheable memory.  This includes when using other drivers that use DMA, like I2S, SPI, UART, etc..  A good reference for placing buffers in non-cacheable memory is the spi_loopback test. Inter-Integrated Circuit Sound (I2S) The I2S drivers are tested using Zephyr’s i2s_speed test.  That is a loopback test, and some boards require changes to connect the signals for the test to pass, see the readme. Networking includes Ethernet MIMXRT1170-EVK Zephyr Network Performance Zephyr networking stack on i.MX RT1170 Cortex-M4 secondary core Serial Peripheral Interface (SPI) The SPI driver is tested with Zephyr’s spi_loopback test.  This test is also a good reference for the options to place DMA buffers in non-cacheable memory, see DMA above. With Zephyr’s SPI driver, the SPI Controller can drive the chip select signal using the hardware peripheral or by software in the driver using a GPIO.  To learn more, see Hardware chip select vs GPIO.  There are some simple SPI examples showing this, see the LPSPI hardware chip select example, and the LPSPI GPIO chip select example. The SPI timing parameters can be configured in devicetree, see the LPSPI timing parameter example. Universal Serial Bus (USB) USB Host As of 12/5/2024: Zephyr does not support USB Host today.  The USB maintainer has this RFC tracker for the planned enhancement to add USB Host support.  But today, there is only experimental Host APIs.  The USB Host stack has not been implemented yet, nor are any USB classes supported yet.  Progress and status can be tracked by following this RFC.  USB Device is supported, and Zephyr provides several sample applications   Return to Zephyr Knowledge Hub
View full article
Zephyr is enabled on the MIMXRT1170-EVK board and can run on both the primary Cortex-M7 and secondary Cortex-M4 cores.  This example shows how to run an Ethernet networking sample on the M4 core, using the dhcpv4_client sample.  By default for the M4 on this board, the code (.text) and data sections are linked to the Tightly Coupled Memories (TCMs) RAM_L and RAM_U (called sram0 and sram1 in the Zephyr devicetree).  But one of these TCMs is not large enough to place all of the code of a networking sample.  This example moves the M4 code to the internal 512 KB OCRAM1 using a devicetree overlay. This example also leverages Sysbuild and the M4 launcher feature.  Sysbuild builds both images for the M7 and M4.  The M7 boots first from flash, and runs a simple cm4_launcher app.  That app copies the M4 image from flash to RAM (OCRAM1 in this case) and then starts the M4.  This cm4_launcher app simplifies booting and testing apps on the M4. Requirements This example is enabled and tested with the following: MIMXRT1170-EVKB board Zephyr v4.2.0 Zephyr SDK v0.17.2 Connect an Ethernet cable to J32 for the 10/100M PHY DHCP example app Apply the attached patch to the Zephyr repository.  Some details about this patch: The mimxrt1170_evk Kconfig.defconfig is modified to define CONFIG_NET_L2_ETHERNET when building the the M4.  This improvement will be submitted to upstream Zephyr. Adds the sysbuild folder to the dhcp sample with the cm4_launcher to run on the M7 Modifies the M7 devicetree and Kconfig to prevent using resources that are used by the M4. Modifies the M4 linker settings to place the code (.text)  zephyr,flash  node in  ocram1 , and the data  zephyr,sram  node in  sram1  (RAM_U). Build and flash the app with CLI using these commands: west build -b mimxrt1170_evk//cm4 samples/net/dhcpv4_client/ --sysbuild --pristine west flash Reset the board after flashing. To build the app with NXP's MCUXpresso extension for VS Code, see the Sysbuild wiki.  You will also need to flash the cm4_launcher domain to the flash.  This MCUboot article has similar steps to enable sysbuild and flash the other domain. When both images are flashed, the RT1170 will boot and print this to the console: [00:00:00.051,000] <inf> phy_mii: PHY (0) ID 1CC816 [00:00:00.053,000] <inf> eth_nxp_enet_mac: Link is down *** Booting Zephyr OS build v4.2.0-1-g692f19148321 *** [00:00:00.053,000] <inf> net_dhcpv4_client_sample: Run dhcpv4 client [00:00:00.053,000] <inf> net_dhcpv4_client_sample: Start on ethernet: index=1 [00:00:03.153,000] <inf> phy_mii: PHY (0) Link speed 100 Mb, full duplex [00:00:03.153,000] <inf> eth_nxp_enet_mac: Link is up [00:00:03.170,000] <inf> net_dhcpv4: Received: 192.168.86.159 [00:00:03.170,000] <inf> net_dhcpv4_client_sample: Address[1]: 192.168.86.159 [00:00:03.170,000] <inf> net_dhcpv4_client_sample: Subnet[1]: 255.255.255.0 [00:00:03.170,000] <inf> net_dhcpv4_client_sample: Router[1]: 192.168.86.1 [00:00:03.170,000] <inf> net_dhcpv4_client_sample: Lease time[1]: 86400 seconds uart:~$ For more articles, see NXP's Zephyr Knowledge Hub.
View full article
FRDM to Innovate - On us! Thank you for stopping by the Zephyr Developer Summit! We loved sharing how FRDM makes development easier, and now, we’re giving you a complimentary FRDM board to continue exploring and innovating.  Your FRDM Board gives you access to: Comprehensive software and tools for rapid development Modular, quick-start FRDM & expansion boards with open design files and schematics Access to 140+ code snippets and tutorials through our Application Code Hub Ready to take your design further? Explore our online resources to help you design without bounds. Get your complimentary FRDM board by following these simple steps: 1.      Visit the FRDM Board page and add either FRDM-MCXN947, FRDM-MCXN236, FRDM-MCXA156 or FRDM-MCXA153 to your cart. 2.       Add Coupon Code (ATW22IDG) at checkout. You will need to register at nxp.com if you are not yet a user. 3.      Complete checkout and you will receive your complimentary board shortly. *The offer is valid for one board per user, for orders placed by December 31 st , 2025 on nxp.com. To learn more, please visit nxp.com/zephyr
View full article
Zephyr includes the open-source MCUboot bootloader as a module, and makes it easy to use as a bootloader for Zephyr applications.  A Zephyr app can be easily built to load with MCUboot.  Zephyr uses a tool called Sysbuild that also enables building the MCUboot bootloader and Zephyr app with the same build command.  To use Sysbuild with CLI, see Building a sample with MCUboot and Sysbuild.  A more advanced use-case is  MCUboot RAM Loading with Zephyr. This guide uses NXP's MCUXpresso extension for VS Code to build a sample app with MCUboot.  To get started with VS Code, see the Zephyr Knowledge Hub.  Basic knowledge of using VS Code to import and build applications is required before following these steps. To get started, import the Zephyr application into VS Code.  This example uses the hello_world sample: To enable Sysbuild for this project, start in the Projects view, right-click on the project, click the Configure menu, and click "Set Sysbuild".   A pop-up appears in the center of the top of the VS Code window.  Select the Enable option. To learn more, see Configuring Sysbuild in VS Code.   We also want to configure the app to build for MCUboot by setting the Cmake variable SB_CONFIG_BOOTLOADER_MCUBOOT=y.  To configure Cmake variables, Expand the project, and expand the Build Configurations.  Select the build configuration to edit, and click the pencil icon on the right.  Here we are editing the default "debug" configuration for the hello_world project.   In the field CMake Extra Args, add SB_CONFIG_BOOTLOADER_MCUBOOT="y" .  To learn more, see Cmake Variables in VS Code.   To build the project, right-click the project and select Pristine Build.  This builds two images: one for MCUboot, and another for the app hello_world. Debugging the app will not program the MCUboot image to the flash.  But we can flash either image to the board using VS Code.  In the Projects view, right-click the project and select Flash the Selected Target.   In the pop-up at the top of the window, select the zephyr.hex file in Domain: mcuboot.  VS Code will flash that zephyr.hex file to the board.   Now you we can debug or flash the app.  When the board boots, it prints similar to below.  This shows MCUboot boots first, finds the app image in slot0, and jumps to the hello_world app. *** Using Zephyr OS build v4.1.0-2827-gb0bf73a18c3c *** I: Starting bootloader I: Image index: 0, Swap type: none I: Bootloader chainload address offset: 0x14000 I: Image version: v0.0.0 I: Jumping to the first image slot *** Booting Zephyr OS build v4.1.0-2827-gb0bf73a18c3c *** Hello World! frdm_mcxn947/mcxn947/cpu0  
View full article
This article details using MCUboot's RAM Loading feature with Zephyr on an NXP i.MX RT microcontroller.  MCUboot is a popular open-source bootloader that easily integrates with Zephyr applications.  Using the RAM Load feature, the bootloader will find a valid image in flash, copy it to RAM, and jump to the app in RAM.  Therefore, the Zephyr app must be built to execute from the RAM region, but write the image to flash. These steps leverage Zephyr's Sysbuild system, which simplifies managing multiple images like this MCUboot bootloader and the application.  There are two examples provided that load the blinky sample to RAM: one loading to external SDRAM, and one loading to internal DTCM. Recommended Reading This article delves into the use of MCUboot, Sysbuild, memory maps, and RAM loading. If these topics are new to you, we recommend reviewing the following resources to build a solid foundation before exploring the details within this document. Sysbuild with MCUboot AN12437 i.MX RT Series Performance Optimization AN13970 RT Series Memory Relocation in Zephyr SW/HW Requirements Zephyr is very portable and these steps will help on other hardware platforms with simple tweaks.  But these steps were tested with the following: Zephyr v4.2 Zephyr SDK v0.17.2 MIMXRT1060-EVKC board using the default QSPI external flash.  The Zephyr build target is  mimxrt1060_evk@C//qspi . RT1060 Memory Map  The table below details the memory maps used in these examples.  Starting with the RT1060 default memory map in Zephyr v4.2, this is the address map if no changes are made, and RAM Loading is not used.  The partition map in the QSPI flash are common for MCUboot and the app, since all images must be stored in separate address ranges.  And this partition map is not changed in these examples.   zephyr,flash  and  zephyr,sram  are devicetree chosen nodes, and tell the linker where to place code/data in the memory map.   zephyr,flash  includes the executable code and read-only data, which are typically placed in flash, but these examples place in RAM.   zephyr,sram  is where the linker places writable data like the .data and .bss sections.  These examples modify the  zephyr,sram  location, and keep  zephyr,sram  of MCUboot and the app in different address ranges to avoid contention during the RAM loading. Region v4.2 Default SDRAM example DTCM example blinky zephyr,flash (code and rodata) slot0_partition 0x6002_0000 SDRAM 0x8000_0000 DTCM 0x2000_0000 blinky zephyr,sram (rwdata) SDRAM 0x8000_0000 SDRAM 0x8000_0000 DTCM 0x2000_0000 MCUboot zephyr,sram (rwdata) SDRAM 0x8000_0000 DTCM 0x2000_0000 SDRAM 0x8000_0000 FlexSPI QSPI flash (non-volatile boot mem) 0x6000_0000     boot_partition (for bootloader) 0x6000_0000     slot0_partition (for app image) 0x6002_0000     slot1_partition (for app image) 0x6032_0000       RAM Loading to SDRAM The attached ramload_sdram.patch applied to the Zephyr v4.2 repo will modify the blinky sample to be loaded to SDRAM by MCUboot. Note that NXP's i.MX RT development boards that include external SDRAM, like the MIMXRT1060-EVK, use SDRAM for the default  zephyr,sram  node.  The SDRAM is enabled and configured by the ROM bootloader before that bootloader boots any application, including the MCUboot secondary bootloader.  This configuration enables a Zephyr app to access the SDRAM immediately after booting.  The ROM bootloader is configured to do this by the DCD stored in flash with the boot image, see Memory details with Zephyr for more details.  Therefore, when MCUboot is used with SDRAM, the DCD is required in the MCUboot image. The sections below detail the changes made to MCUboot, the blinky sample, and to both domains using Sysbuild.  All these files are located in the repo folder samples/basic/blinky. Sysbuild changes for both domains The file sysbuild.conf is added to the app to configure Sysbuild for MCUboot.  This also enables the RAM Load feature used in building both MCUboot and the app. SB_CONFIG_BOOTLOADER_MCUBOOT=y SB_CONFIG_MCUBOOT_MODE_RAM_LOAD=y   MCUboot changes The file sysbuild/mcuboot.conf configures the MCUboot domain.  MCUboot will load the image stored in the slot partition to this address, which is the base address for SDRAM.  The RAM_SIZE is used during the copy, and should be scaled as needed. CONFIG_BOOT_IMAGE_EXECUTABLE_RAM_START=0x80000000 CONFIG_BOOT_IMAGE_EXECUTABLE_RAM_SIZE=131072 The file sysbuild/mcuboot.overlay modifies the devicetree for this bootloader.  Since MCUboot will load the app to SDRAM, the  zephyr,sram  node is moved to DTCM to avoid overwriting any MCUboot data.  The  zephyr,code-partition  node tells the linker to place the MCUboot bootloader code in the   boot_partition  in the flash. / {     chosen {         zephyr,sram = &dtcm; zephyr,code-partition = &boot_partition; }; };   Application changes The file boards/mimxrt1060_evk_mimxrt1062_qspi_C.overlay modifies the devicetree for this app, and places the executable code in SDRAM, to be loaded by MCUboot. / { chosen { zephyr,flash = &sdram0; }; };   The file boards/mimxrt1060_evk_mimxrt1062_qspi_C.conf adjusts the address used when programming the blinky signed image binary to flash.  Since the  zephyr,flash  node is placed in SDRAM, normally the "west flash" command would try to program the binary to 0x8000_0000, the base address of the SDRAM.  This Kconfig selects the address of the  slot0_partition  to store the blinky image in flash. CONFIG_FLASH_BASE_ADDRESS=0x60020000   Build and flash These steps use the Command Line Interface (CLI) to build and flash.  Another option is to use VS Code with NXP's MCUXpresso extension, see Zephyr app with MCUboot in VS Code. This build command uses Sysbuild to build both images for MCUboot and the blinky app.  This creates the folder ramload_blinky with all the generated files for both domains, which is used to flash the board. west build -b mimxrt1060_evk@C//qspi samples/basic/blinky -d ../../ramload_blinky --sysbuild --pristine This flash command uses Sysbuild to flash both images to the board, first the MCUboot image, then the signed blinky app image.  This example specifies using the JLink debug probe, or LinkServer is another option. west -v flash -d ../../ramload_blinky/ -r jlink   Console output from SDRAM Connect a terminal to the debug console.  After flashing, the LED will blink and the RT1060 will boot and print like this: *** Booting MCUboot v2.1.0-rc1-389-g4eba8087fa60 *** *** Using Zephyr OS build v4.2.0 *** I: Starting bootloader I: Primary slot: version=0.0.0+0 I: Image 0 Secondary slot: Image not found I: Image 0 RAM loading to 0x80000000 is succeeded. I: Image 0 loaded from the primary slot I: Bootloader chainload address offset: 0x80000000 I: Image version: v0.0.0 I: Jumping to the first image slot *** Booting Zephyr OS build v4.2.0 *** LED state: OFF LED state: ON   RAM Loading to DTCM The attached ramload_dtcm.patch modifies the repo to load the blinky sample to DTCM.  The patch is very similar to the SDRAM patch detailed above.  The same build and flash steps are used for this patch.  The console output is also very similar, but shows the difference in the load address: *** Booting MCUboot v2.1.0-rc1-389-g4eba8087fa60 *** *** Using Zephyr OS build v4.2.0 *** I: Starting bootloader I: Primary slot: version=0.0.0+0 I: Image 0 Secondary slot: Image not found I: Image 0 RAM loading to 0x20000000 is succeeded. I: Image 0 loaded from the primary slot I: Bootloader chainload address offset: 0x20000000 I: Image version: v0.0.0 I: Jumping to the first image slot *** Booting Zephyr OS build v4.2.0 *** LED state: OFF LED state: ON   Notes Working on this, I ran into some issues using other memory map options.  It seems there are some limitations with the imgtool settings with  CONFIG_MCUBOOT_BOOTLOADER_MODE_RAM_LOAD=y  .  The Zephyr code base seems to make some assumptions about where in RAM the image will be loaded.  For example, when using RAM Load, the imgtool utility must be called with the argument  --load-addr  and the address in RAM, which configures the boot header when signing the application image.  But this Cmake file assumes the load address is the base of the  zephyr,sram  node.  For that reason, the examples provided here place the  zephyr,sram  and  zephyr,flash  nodes for blinky in the same RAM.  Separating these nodes to different RAMs caused issues for me.  If more flexibility is required, one potential option is to modify the app's Cmake file using the needed imgtool settings to generate the needed signed binary for RAM Load.  Imgtool can also be called manually if needed.
View full article
This page is a summary of helpful resources that are frequently referenced by those learning and developing with Zephyr on NXP platforms.  If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. Installing Zephyr and Getting Started NXP provides the MCUXpresso extension for Visual Studio code, and this is the quickest option to learn and use Zephyr on NXP platforms.  Get started with this wiki, and the Zephyr lab guide for Installation and Preparation.  These guides leverage the MCUXpresso Installer, which can install all the tools and dependencies needed to develop and debug Zephyr applications.  For issues installing the tools and setting up the build environment, see this Installation and Troubleshooting FAQ.  Once installed, more Zephyr lab guides show the basics with VS Code to import examples, build and debug applications. VS Code or the MCUXpresso extension are not required to develop with Zephyr, and many users prefer using command line.  See Zephyr Project’s Getting Started guide for that option. NXP also provides a downstream ecosystem called the Zephyr Software Developement Kit (ZSDK).  To learn more, see Introduction to ZSDK Downstream and ZSDK Getting Started. Links to other Knowledge articles: Zephyr Project documentation Development Tools Device support in Zephyr Training – click the “Training” tab at top of the page Build and Configuration System, like Devicetree and Kconfig NXP Application Notes – click the “Documentation” tab at top of the page Getting Support / asking for Help: MCUXpresso for VS Code community forum Zephyr NXP Support community forum NXP repository of Zephyr demos and examples Custom boards and applications, and pinctrl Memory Peripherals and drivers Zephyr modules, subsystems and features
View full article
If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. Most of NXP's contributions to Zephyr occur in the upstream repository at https://github.com/zephyrproject-rtos/zephyr .  Zephyr support is enabled by boards, see the upstream supported boards for the latest list of boards.  Each board has a board document, which includes a Supported Features table of all the features currently supported on that board.  For example, this is the upstream FRDM-MCXN947 board page. NXP also provides a downstream ecosystem called the Zephyr Software Developement Kit (ZSDK).  Some devices/boards have additional support in the NXP ZSDK.  To review the NXP ZSDK support, see the release notes.  To learn more, see Introduction to ZSDK Downstream and ZSDK Getting Started. Connectivity Devices: For Wi-Fi and Bluetooth, the NXP ZSDK includes additional release notes.  This link is for the ZSDK release nxp-v4.1.0, and the bottom of the page links to the document "wireless-soc-features-and-release-notes-zephyr.pdf".  Refer to the latest release tag for the lastest documents.
View full article
If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. Custom board The Zephyr repository includes support for dozens of NXP development boards.  When creating a custom board, it is best to start with the closest development board using an SOC from the same family, clone that board folder, rename as the new board, and modify to match the hardware.  More resources for custom boards include: Zephyr Project Board Porting Guide NXP blog: Creating a Custom Zephyr Board for the i.MX RT685 See section "Generating a board pinctrl" on this page If changing memory settings from the cloned development board, see Memory details with Zephyr. With MCUXpresso for VS Code, as of v25.3.72, out-of-tree boards are not supported when importing Zephyr applications.  This feature will be added soon.  In the meantime, there is a workaround. Unsupported SOC part number A common challenge when creating a custom board is that not every SOC part number sold by NXP is supported in Zephyr today. Support in Zephyr is based on boards, not directly by SOCs.  A board name must be specified when building a Zephyr application.  Then the board files include the SOC used on that board.  These are the NXP boards supported in Zephyr.  The Zephyr documentation framework does not have similar pages for SOCs. NXP contributes Zephyr support for development boards.  One development board usually supports a family of SOCs.  The development board usually has the superset SOC on the board, which offers the most features/memory of that family.  For example, MIMXRT1060-EVK board is used to develop with the i.MX RT106x family, and uses the superset RT1062 part number.  Other part numbers in a family are very similar to the superset, but may lack some features, have less memory, or less pins in a smaller package. Since Zephyr support is based on boards, and the SOCs on the boards are supported, today there are many other similar SOC part numbers that are not directly supported in Zephyr.  Here are some options to manage this when creating a custom board: Base the custom board on the development board supported in Zephyr, and use the same SOC part number on the custom board.  That SOC is already available in Zephyr to enable the development board. Use an SOC in the same family on the circuit board, but configure the Zephyr custom board to use the superset SOC on the development board.  For example, the circuit board uses an RT1061 part number, but the custom board files use the same RT1062 part number from the MIMXRT1060-EVK.  The advantage of this option is Zephyr does not require any additional SOC support.  The superset likely has all the features and memory available for the SOC on the circuit board.  Then the custom board files can modify the devicetree and Kconfig by disabling peripherals that are not available, and reducing memory sizes as needed.  SOC pinctrl files are available for most SOCs in supported families, found in the HAL_NXP repo.  Usually the custom board can include the SOC pinctrl file for the exact part number used. Use an SOC in the same family, but contribute all the SOC files needed in Zephyr.  For example, the circuit board uses an RT1061 part number, so the developer adds the RT1061 part number option to the Zephyr repo, and configures the custom board to use that RT1061 part number.  This option requires more effort and some comfort with the Zephyr repo, but some Zephyr users may prefer this option.  And if a new SOC is enabled like this, it can be contributed upstream to the Zephyr repo. The SOC options discussed above assume a board for the SOC family is already supported in Zephyr, which enables at least one SOC in that family.  If trying to port Zephyr to a new family of SOCs with no board support, that can take significantly more effort.  To minimize porting effort, it is best to start with a family of SOCs already supported on a board. Pinctrl Zephyr uses pinctrl to configure the pins and pinmux settings of an SOC.  Typically, each board has a pinctrl file with the default pinctrl settings for that board.  For example, this is the mimxrt1060_evk-pinctrl.dtsi.  NXP also has pinctrl files for each SOC, like mimxrt1062dvl6a-pinctrl.dtsi.  The SOC pinctrl files are located in the HAL_NXP repo and provide all the pinmux options for each pin, which makes it easier and more readable to select the pinmux option in the board pinctrl file.  For the NXP boards, the board pinctrl file includes the SOC pinctrl file like this: #include <nxp/nxp_imx/rt/mimxrt1062dvl6a-pinctrl.dtsi> Generating a board pinctrl New board pinctrl files are usually created when creating a new board.  Board pinctrl files can always be created by hand.  But generating the file can be convenient, especially since NXP offers the Pins Tool included in the MCUXpresso Config Tool.  The Pins Tool has a GUI to help select all the desired signals used by the application, and configure the pinmux and pin settings.  Starting with release v25.03, the Config Tool can generate Zephyr board pinctrl files for the i.MX RT1xxx and MCX devices.  More devices supported in Zephyr will be added in later releases.  To learn how to generating a board pinctrl file, see the Config Tool User Guide. For other devices not yet supported in the Config Tool, NXP has a Python script to help generate a board pinctrl file.  These scripts will eventually be replaced by the Config Tool and deprecated.  The script uses the same Config Tool above to configure the pins of a board, and then extracts the pin information from a file and generates the board pinctrl file.  The scripts are included in the HAL_NXP repo and documented with this Readme. If generation is not an option, then the board pinctrl must be hand written.  The best option is to find a board pinctrl file for a similar SOC, and modify as needed. New out-of-tree application The Zephyr repository is full of samples and tests applications, which are helpful to learn how to use a driver, subsystem, or module.  When creating a new application, a new Git repo can be created for the app, and West can be used to pull in the Zephyr repo as a module.  Applications frequently use West’s T2 Star topology with Zephyr.  These example repos are a good reference when creating your application repo: Zephyr Project’s example-application repo, includes an out-of-tree board and driver NXP repository of Zephyr demos and examples NXP Pro Support repository of Zephyr examples   Return to Zephyr Knowledge Hub
View full article
NXP’s Hardware Abstraction Layer (HAL) is based on the MCUXpresso SDK drivers.  To learn more, see the blog Zephyr Software Code Reuse with NXP MCUXpresso SDK.  Most Zephyr users want to use the Zephyr driver APIs in their application for portability.  But if a Zephyr driver is not supported on a platform, or if there is no Zephyr driver for a hardware peripheral, another option is to use the MCUXpresso SDK driver directly in the application.  This article provides details, using the PUF driver as an example on the LPC55S69. NXP had a major update to the MCUXpresso SDK in v24.12 that restructured the SDK.  This new HAL was added in Zephyr after the Zephyr v4.1 release, in this Pull Request.  This article focuses on using drivers in this latest HAL.  For older versions of Zephyr, or if using an older SOC that is not supported in this latest HAL, see this older post.   HAL drivers with Zephyr support are included in an app using devicetree and Kconfig.  To include other drivers not managed by Zephyr, simply add a line in the application's CMakeLists.txt file enabling that driver.  The first line shown below instructs Cmake to include the PUF driver by setting the variable  CONFIG_MCUX_COMPONENT_driver.puf .  Note: be sure to set these variables before the find_package(Zephyr ...) line. set(CONFIG_MCUX_COMPONENT_driver.puf ON) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})   With the driver included in the build, the driver APIs can be used in the application.  This is a simple app using a PUF driver API: #include <fsl_puf.h> int main(void) { puf_config_t conf; PUF_GetDefaultConfig(&conf); return 0; }   To find the name of the Cmake variable to use for a driver, look in the mcuxsdk-core repo.   This is the Kconfig file for the PUF driver, and it defines the Kconfig symbol named MCUX_HAS_COMPONENT_driver.puf.  Add the CONFIG_ prefix to get the final symbol name CONFIG_MCUX_HAS_COMPONENT_driver.puf .
View full article
If you have any questions or issues related to these resources, please Ask a new question, and the NXP support team can address it there. When learning Zephyr, there are lots of questions about memory.  Where does the linker place code and data?  How does the application configure to use other memories? The default memory sections used by the linker are configured in the devicetree.  Typically the devicetree uses chosen nodes to configure these sections.  Here is an example from the board MIMXRT1060-EVK: chosen { zephyr,flash = &is25wp064; zephyr,sram = &sdram0; };   The names of these chosen nodes can be misleading.  zephyr,flash points to the node the linker uses for all the code (.text) and read-only data sections.  Typically this points to physical flash memory, like on this board it places in external QSPI flash, but it can be in memory that is not flash.  zephyr,sram points to the node the linker uses for all the .data and .bss sections.  This should be in RAM, but is not required to be in SRAM.  This board places in the external SDRAM.  The application can point these nodes to other memories that are best for that app.  Other common memory nodes used are &dtcm , &itcm , or &ocram .  Typically, these chosen nodes are set in the board devicetree file.  But when learning Zephyr and working with devicetree, it is best to confirm the devicetree settings in the generated devicetree files created during the build of the application, see Lab Guide: Devicetree and VS Code Devicetree Viewer.   i.MX RT memory Most memory questions come from those using the i.MX RT devices.  These MCUs are high-performance flashless devices with multiple internal and external memory options to maximize performance and flexibility for the application.  Some helpful resources specific to the i.MX RT devices: i.MX RT application notes: AN12437 i.MX RT Series Performance Optimization AN12077 Using the i.MX RT FlexRAM AN13970 RT Series Memory Relocation in Zephyr The bootloader in ROM requires the Flash Configuration Block (FCB) when booting.  And optionally the Device Configuration Data (DCD) or eXternal Memory Configuration Data (XMCD) can be added, typically used to enable SDRAM.  This post has more details about where to find these structures, and how they are included with the board. No SDRAM: the Zephyr support for RT development boards with external SDRAM typically place data in the SDRAM.  And the ROM bootloader will configure the SDRAM interface before the Zephyr app executes using the DCD or XMCD.  This post discusses removing the SDRAM for a custom board. Configuring FlexRAM, resizing ITCM, DTCM, or OCRAM, see AN13970 RT Series Memory Relocation in Zephyr   Relocating code to RAM Relocating code to RAM is a common requirement, like to maximize performance, or reduce power consumption.  With Zephyr, applications can relocate all the code, or part of the code to RAM.  Some helpful resources for relocation: AN13970 RT Series Memory Relocation in Zephyr Zephyr Code And Data Relocation APIs Example applications that relocate code: Simple example SDRAM_hello_world.zip that moves the entire app to SDRAM, and uses the ROM bootloader to load the RAM at boot, before the app executes. Zperf sample: this networking sample in Zephyr relocates the networking stack and Ethernet driver code to ITCM to improve performance when built for the MIMXRT1170-EVK.  The rest of code remains in the default external QSPI flash. NXP SmartWatch demo and webinar: relocates most code to internal SRAM to reduce power consumption, but leaves graphical assets in flash. Locating data to RAM With Zephyr, the default placement of all data, variables, and stacks go in the zephyr,sram node.  But some applications want some specific data to be placed elsewhere.  Like placing data in DTCM to maximize performance, placing a DMA buffer in non-cacheable memory, or moving large frame buffers for a display to external RAM.  Some helpful resources for specifying data placement include: The declaration of static variables can include linker section tags to place them in specific sections.  A reference showing this is the dma_mcux_edma.c driver, which place the dma_tcdpool structures in the __dtcm_noinit_section or __nocache sections. Another option for static variables is to use devicetree nodes in the variable declaration to place in a specific section.  One example to reference is NXP's Facial Detection demo.  This demo adds the chosen node zephyr,modelbuf in the devicetree, which points to the memory section node sramx .  To use this method, the memory section node requires the property zephyr,memory-region .  In the source code, the  model_input_buf buffer is declared with the zephyr_modelbuf node.  Then the linker places model_input_buf in the sramx section. The data and bss sections of entire source files or libraries can be relocated to other RAMs, see Zephyr Code And Data Relocation APIs. Zephyr can use a special pinned section to place the interrupt and main stacks in a different RAM section.  The simple example pinned_hello_world.zip pins the interrupt and main stacks in DTCM.   Other memory resources Example resizing memory nodes, leverages all SRAM in NXP LPC5500   Return to Zephyr Knowledge Hub
View full article
Zephyr Project Build and Configuration System Devicetree Zephyr Project Devicetree Webinar: Application Portability Made Easy With Zephyr OS and NXP VS Code Lab Guide: Devicetree and Devicetree Viewer Golioth blog: Zephyr for Hardware Engineers: GPIO Zephyr Project Devicetree HOWTOs Kconfig Zephyr Project Kconfig Webinar: Application Portability Made Easy With Zephyr OS and NXP VS Code Lab Guide: Kconfig and compiler optimizations   Return to Zephyr Knowledge Hub
View full article
These steps walk through building the Zephyr TF-M sample with PSA crypto for the FRDM-RW612 board using NXP's downstream Zephyr release.  This uses the v4.0.0 release.  Steps below are provided using CLI or the MCUXpresso extension for VS Code. Before starting, import/clone the downstream ZSDK repo at https://github.com/nxp-zephyr/nxp-zephyr using the release tag nxp-v4.0.0 .  These steps are using the JLink debug probe. Building and Flashing with CLI The TF-M samples use the non-secure (NS) board variant when building.  Build with this command below (this builds with LOTS of warnings): west build -b frdm_rw612//ns samples/tfm_integration/psa_crypto/ --pristine The build generates a file that merges both images into a HEX file named tfm_merged.hex.  The command below programs this HEX file to the board: west flash See below for the console output printed from this demo Reprogramming the flash in ISP mode Once this image is programmed in the flash, it interferes with the JLink debug probe, and reflashing the board will fail.  A simple workaround is to force the MCU in ISP mode at boot.  In ISP mode, the app firmware does not execute, and the JLink can erase and update the flash.   To enter ISP mode on the FRDM-RW612 board, hold down the ISP button SW3.  Then press and release the Reset button SW1.  The MCU is now in ISP mode and can be reflashed. VS Code: Build, Program, and Debug The current release of the MCUXpresso extension for VS Code is the prerelease of v24.11.51.  This release does not yet support out-of-tree boards, and will not provide the option to import the application for the NS board variant.  These steps will import for the default FRDM-RW612 variant, and then modify the VS Code file to use the NS variant. In VS Code, use the MCUXpresso Quickstart panel to Import Example from Repository. Select the board FRDM_RW612, and the template tfm_integration/psa_crypto.   Before building, the project needs to be modified to use the NS board variant.  Open the file CMakePresets.json:   Modify the board name to frdm_rw612//ns for the NS variant.  Save the file.   Build the project in VS Code.  This build has LOTS of warnings. The debugger is not aware that the tfm_merged.hex file is used to program the flash.  This file must first be programmed to the flash before using the debugger.  In the VS Quickstart Panel, launch the Flash Programmer, and select the Segger probe type to use with JLink.  Select the psa_crypto project, the PROGRAM tab, and browse to the tfm_merged.hex file generated in the sample build folder.  Then click Run.  This programs the firmware image to flash.   The app will now boot and run, and print the console output shown in the section below.  To reprogram the flash, see the ISP section above. With the image programmed in flash, VS Code can now debug the application.  Launch the VS Code debugger.  Once connected, you may need to click the Restart button to properly connect and halt at main().     Console output Once the board is programmed, the app will print the following: Booting TF-M v2.1.1 [WRN] This device was provisioned with dummy keys. This device is NOT SECURE [Sec Thread] Secure image initializing! [INF][PS] Encryption alg: 0x5500200 [INF][Crypto] Provision entropy seed... [INF][Crypto] Provision entropy seed... complete. *** Booting Zephyr OS build nxp-v4.0.0 *** [00:18:23.434,135] <inf> app: att: System IAT size is: 367 bytes. [00:18:23.434,145] <inf> app: att: Requesting IAT with 64 byte challenge. [00:18:23.439,264] <inf> app: att: IAT data received: 367 bytes. 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 D2 84 43 A1 01 26 A0 59 01 23 AA 3A 00 01 24 FF ..C..&.Y.#.:..$. 00000010 58 40 00 11 22 33 44 55 66 77 88 99 AA BB CC DD X@.."3DUfw...... 00000020 EE FF 00 11 22 33 44 55 66 77 88 99 AA BB CC DD ...."3DUfw...... 00000030 EE FF 00 11 22 33 44 55 66 77 88 99 AA BB CC DD ...."3DUfw...... 00000040 EE FF 00 11 22 33 44 55 66 77 88 99 AA BB CC DD ...."3DUfw...... 00000050 EE FF 3A 00 01 24 FB 58 20 A0 A1 A2 A3 A4 A5 A6 ..:..$.X ....... 00000060 A7 A8 A9 AA AB AC AD AE AF B0 B1 B2 B3 B4 B5 B6 ................ 00000070 B7 B8 B9 BA BB BC BD BE BF 3A 00 01 25 00 58 21 .........:..%.X! 00000080 01 D1 C4 11 B1 5F 2D F0 38 6A A3 00 6A 74 D6 B4 ....._-.8j..jt.. 00000090 4A EA DE 02 56 0A E8 DB 67 F0 75 2C B4 75 21 F5 J...V...g.u,.u!. 000000A0 A1 3A 00 01 24 FA 58 20 AA AA AA AA AA AA AA AA .:..$.X ........ 000000B0 BB BB BB BB BB BB BB BB CC CC CC CC CC CC CC CC ................ 000000C0 DD DD DD DD DD DD DD DD 3A 00 01 24 F8 3A 3B FF ........:..$.:;. 000000D0 FF FF 3A 00 01 24 F9 19 30 00 3A 00 01 24 FE 01 ..:..$..0.:..$.. 000000E0 3A 00 01 24 F7 71 50 53 41 5F 49 4F 54 5F 50 52 :..$.qPSA_IOT_PR 000000F0 4F 46 49 4C 45 5F 31 3A 00 01 25 01 77 77 77 77 OFILE_1:..%.wwww 00000100 2E 74 72 75 73 74 65 64 66 69 72 6D 77 61 72 65 .trustedfirmware 00000110 2E 6F 72 67 3A 00 01 24 FC 73 30 36 30 34 35 36 .org:..$.s060456 00000120 35 32 37 32 38 32 39 2D 31 30 30 31 30 58 40 7D 5272829-10010X@} 00000130 BF CA 23 43 CA 0F E7 45 53 C9 75 83 F0 EA 33 C8 ..#C...ES.u...3. 00000140 37 B9 35 5F 21 C7 C3 B3 2F 16 7A 91 94 CA 8D 13 7.5_!.../.z..... 00000150 2A 01 84 E7 C6 82 69 97 86 0C 7A 1C BD 98 9F 88 *.....i...z..... 00000160 A9 EA AB 0F DB F9 1D 9D C8 EE 5D D6 77 93 AF ..........].w.. [00:18:23.620,682] <inf> app: Persisting SECP256R1 key as #1 [00:18:23.635,930] <err> app: Already exists [00:18:23.636,006] <err> app: Function: 'crp_gen_key_secp256r1' [00:18:23.636,011] <err> app: Failed to generate key. [00:18:23.653,441] <inf> app: Calculating SHA-256 hash of value 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 50 6C 65 61 73 65 20 68 61 73 68 20 61 6E 64 20 Please hash and 00000010 73 69 67 6E 20 74 68 69 73 20 6D 65 73 73 61 67 sign this messag 00000020 65 2E e. 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 9D 08 E3 E6 DB 1C 12 39 C0 9B 9A 83 84 83 72 7A .......9......rz 00000010 EA 96 9E 1D 13 72 1E 4D 35 75 CC D4 C8 01 41 9C .....r.M5u....A. [00:18:23.702,711] <inf> app: Signing SHA-256 hash 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 15 A3 E4 C2 AF 1B D2 AF 28 31 2C 42 9B A6 41 06 ........(1,B..A. 00000010 13 B4 45 E7 5D A9 A2 1D 2A 82 72 78 A3 B7 57 5A ..E.]...*.rx..WZ 00000020 A5 81 F8 66 76 F0 DB 46 E2 67 2E 55 0A A7 F8 55 ...fv..F.g.U...U 00000030 13 F1 74 1C C9 05 36 AF 97 4B E1 8E 29 8B 86 0A ..t...6..K..)... [00:18:23.749,169] <inf> app: Verifying signature for SHA-256 hash [00:18:23.771,732] <inf> app: Signature verified. [00:18:23.911,110] <inf> app: Destroyed persistent key #1 [00:18:23.917,526] <inf> app: Generating 256 bytes of random data. 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 BB C4 36 83 E4 85 A1 90 C8 F5 43 E1 7D 70 FA 7E ..6.......C.}p.~ 00000010 2F 84 A2 98 F5 9E FB 9B F6 6F B1 FB 1C 4C 49 2D /........o...LI- 00000020 5C A0 24 3C A5 47 87 EA 6F B7 31 AA 07 53 59 89 \.$<.G..o.1..SY. 00000030 6E 7A FF 5B C3 FA B1 33 3D 67 08 F4 36 8F D2 96 nz.[...3=g..6... 00000040 BE 36 C6 36 84 C2 53 54 76 30 92 8F F6 AF 74 5A .6.6..STv0....tZ 00000050 63 4D 8F 64 ED 55 F9 5A 64 DC EF F1 44 69 78 45 cM.d.U.Zd...DixE 00000060 05 A3 70 AD 20 78 59 85 A2 FD 5F 05 08 6D 5A 80 ..p. xY..._..mZ. 00000070 19 16 52 9C EC C1 C8 EC FD 1B 4B 1E 1E 6C 7A 7F ..R.......K..lz. 00000080 D4 83 74 17 BC D5 76 08 D7 55 35 75 5E 07 DE 50 ..t...v..U5u^..P 00000090 11 0E 38 19 79 27 BB 42 B0 32 67 FC FE 18 10 0F ..8.y'.B.2g..... 000000A0 09 55 A3 6A B0 34 22 4C 23 24 DF 14 87 F1 1C 48 .U.j.4"L#$.....H 000000B0 0F 1E 75 A5 B4 C2 B4 D5 68 EB 8A D9 EE 92 FE 0D ..u.....h....... 000000C0 09 FC 1D 39 F1 A0 79 E0 01 BF C0 D7 F5 94 3A 17 ...9..y.......:. 000000D0 8F 83 39 E0 33 BA 82 C3 65 7C C0 D4 82 D5 56 5B ..9.3...e|....V[ 000000E0 44 C9 61 BC 75 58 3D 1D 6F B2 BB EE 2B 8C 97 E2 D.a.uX=.o...+... 000000F0 12 57 EA BF 0A FE 6E AA FF 03 D4 C6 0B 74 12 23 .W....n......t.# [00:18:24.035,192] <inf> app: Initialising PSA crypto [00:18:24.040,673] <inf> app: PSA crypto init completed [00:18:24.046,396] <inf> app: Persisting SECP256R1 key as #1 [00:18:24.193,132] <inf> app: Retrieving public key for key #1 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000 04 7B C3 8E 36 E3 11 88 C1 4E 36 4C 9E 37 41 3A .{..6....N6L.7A: 00000010 0B 1A 59 2E 2A AA C4 B6 FD E5 16 62 75 27 C7 49 ..Y.*......bu'.I 00000020 EA FC 9B 7A 06 9D 4A 1A F0 F8 18 C4 6D E1 DC FE ...z..J.....m... 00000030 52 59 EE 55 7F 38 83 CC CF 15 63 2B 16 CA 79 DA RY.U.8....c+..y. 00000040 7B { [00:18:24.245,819] <inf> app: Adding subject name to CSR [00:18:24.251,632] <inf> app: Adding subject name to CSR completed [00:18:24.258,199] <inf> app: Adding EC key to PK container [00:18:24.264,362] <inf> app: Adding EC key to PK container completed [00:18:24.271,223] <inf> app: Create device Certificate Signing Request [00:18:24.296,971] <inf> app: Create device Certificate Signing Request completd [00:18:24.304,898] <inf> app: Certificate Signing Request: -----BEGIN CERTIFICATE REQUEST----- MIHpMIGQAgEAMC4xDzANBgNVBAoMBkxpbmFybzEbMBkGA1UEAwwSRGV2aWNlIENl cnRpZmljYXRlMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEe8OONuMRiMFONkye N0E6CxpZLiqqxLb95RZidSfHSer8m3oGnUoa8PgYxG3h3P5SWe5VfziDzM8VYysW ynnae6AAMAoGCCqGSM49BAMCA0gAMEUCIQC9LqdaYIJqBw4Pvqyd5vrYnUmjLFhY LidxcY0g8x4LyAIgLUUnRyBduyCFFUl0RaXHrUbDarPLk35XO5kBnJxDfFQ= -----END CERTIFICATE REQUEST----- [00:18:24.346,162] <inf> app: Encoding CSR as json [00:18:24.351,600] <inf> app: Encoding CSR as json completed [00:18:24.357,605] <inf> app: Certificate Signing Request in JSON: {"CSR":"-----BEGIN CERTIFICATE REQUEST-----\nMIHpMIGQAgEAMC4xDzANBgNVBAoMBkxpbm} [00:18:24.400,811] <inf> app: Done.
View full article