507 lines
17 KiB
ReStructuredText
507 lines
17 KiB
ReStructuredText
.. zephyr:board:: colibri_imx7d
|
|
|
|
Overview
|
|
********
|
|
|
|
The i.MX7 SoC is a Hybrid multi-core processor composed by Single/Dual Cortex A7
|
|
core and Single Cortex M4 core.
|
|
Zephyr was ported to run on the M4 core. In a later release, it will also
|
|
communicate with the A7 core (running Linux) via RPmsg.
|
|
|
|
Hardware
|
|
********
|
|
|
|
- i.MX7 Single/Dual Cortex A7 (800MHz/1.0GHz) core and Single Cortex M4 (200MHz) core
|
|
|
|
- Memory
|
|
|
|
- RAM -> A7: 256MB, 512MB and 1GB
|
|
- RAM -> M4: 3x32KB (TCML, TCMU, OCRAM_S), 1x128KB (OCRAM) and 1x256MB (DDR)
|
|
- Flash -> A7: 4Gb eMMC and 512Mb NAND
|
|
|
|
- Display
|
|
|
|
- RGB 1920x1080x24bpp
|
|
- 4-wire Resistive touch
|
|
|
|
- Multimedia
|
|
|
|
- 1x Camera Parallel Interface
|
|
- 1x Analog Audio Line in (Stereo)
|
|
- 1x Analog Audio Mic in (Mono)
|
|
- 1x Analog Audio Headphone out (Stereo)
|
|
|
|
- Connectivity
|
|
|
|
- USB 2.0 OTG (High Speed)
|
|
- USB 2.0 host (High Speed)
|
|
- 10/100 Mbit/s Ethernet PHY
|
|
- 4x I2C
|
|
- 4x SPI
|
|
- 7x UART
|
|
- 1x IrDA
|
|
- 20x PWM
|
|
- Up to 125 GPIO
|
|
- 4x Analog Input (12 Bit)
|
|
- 2x SDIO/SD/MMC (8 Bit)
|
|
- 2x CAN
|
|
|
|
For more information about the i.MX 7 SoC, Colibri iMX7 Computer on Module
|
|
and Colibri Evaluation Board, see these references:
|
|
|
|
- `i.MX 7 Series Website`_
|
|
- `i.MX 7 Dual Datasheet`_
|
|
- `i.MX 7 Dual Reference Manual`_
|
|
- `Colibri iMX7 Website`_
|
|
- `Colibri iMX7 User Guide`_
|
|
- `Colibri iMX7 Datasheet`_
|
|
- `Colibri Evaluation Board Website`_
|
|
- `Colibri Evaluation Board Datasheet`_
|
|
|
|
Supported Features
|
|
==================
|
|
|
|
The Colibri iMX7D Computer on Module with Colibri Evaluation Board configuration
|
|
supports the following hardware features on the Cortex M4 Core:
|
|
|
|
+-----------+------------+-------------------------------------+
|
|
| Interface | Controller | Driver/Component |
|
|
+===========+============+=====================================+
|
|
| NVIC | on-chip | nested vector interrupt controller |
|
|
+-----------+------------+-------------------------------------+
|
|
| SYSTICK | on-chip | systick |
|
|
+-----------+------------+-------------------------------------+
|
|
| GPIO | on-chip | gpio |
|
|
+-----------+------------+-------------------------------------+
|
|
| I2C | on-chip | i2c |
|
|
+-----------+------------+-------------------------------------+
|
|
| PWM | on-chip | pwm |
|
|
+-----------+------------+-------------------------------------+
|
|
| UART | on-chip | serial port-polling; |
|
|
| | | serial port-interrupt |
|
|
+-----------+------------+-------------------------------------+
|
|
|
|
The default configuration can be found in the defconfig file:
|
|
|
|
:zephyr_file:`boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4_defconfig`
|
|
|
|
Other hardware features are not currently supported by the port.
|
|
|
|
Connections and IOs
|
|
===================
|
|
|
|
The Colibri iMX7D Computer on Module with Colibri Evaluation Board
|
|
was tested with the following pinmux controller configuration.
|
|
|
|
+---------------+-----------------+---------------------------+
|
|
| Board Name | SoC Name | Usage |
|
|
+===============+=================+===========================+
|
|
| UART_B RXD | UART2_TXD | UART Console |
|
|
+---------------+-----------------+---------------------------+
|
|
| UART_B TXD | UART2_RXD | UART Console |
|
|
+---------------+-----------------+---------------------------+
|
|
| SODIMM_135 | GPIO1_IO02 | LED0 |
|
|
+---------------+-----------------+---------------------------+
|
|
| SODIMM_133 | GPIO2_IO26 | SW0 |
|
|
+---------------+-----------------+---------------------------+
|
|
| SODIMM_194 | I2C4_SDA | I2C_SDA |
|
|
+---------------+-----------------+---------------------------+
|
|
| SODIMM_196 | I2C4_SCL | I2C_SCL |
|
|
+---------------+-----------------+---------------------------+
|
|
| SODIMM_59 | PWM1/GPIO1_IO08 | PWM |
|
|
+---------------+-----------------+---------------------------+
|
|
|
|
System Clock
|
|
============
|
|
|
|
The M4 Core is configured to run at a 200 MHz clock speed.
|
|
|
|
Serial Port
|
|
===========
|
|
|
|
The iMX7D SoC has seven UARTs. The number 2 is configured for the console and
|
|
the remaining are not used/tested.
|
|
|
|
Programming and Debugging
|
|
*************************
|
|
|
|
The Colibri iMX7D doesn't have QSPI flash for the M4 and it needs to be started by
|
|
the A7 core. The A7 core is responsible to load the M4 binary application into the
|
|
RAM, put the M4 in reset, set the M4 Program Counter and Stack Pointer, and get
|
|
the M4 out of reset.
|
|
The A7 can perform these steps at bootloader level or after the Linux system has
|
|
booted.
|
|
|
|
The M4 can use up to 5 different RAMs. These are the memory mapping for A7 and M4:
|
|
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
| Region | Cortex-A7 | Cortex-M4 (System Bus) | Cortex-M4 (Code Bus) | Size |
|
|
+============+=======================+========================+=======================+======================+
|
|
| DDR | 0x80000000-0xFFFFFFFF | 0x80000000-0xDFFFFFFF | 0x10000000-0x1FFEFFFF | 2048MB (less for M4) |
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
| OCRAM | 0x00900000-0x0091FFFF | 0x20200000-0x2021FFFF | 0x00900000-0x0091FFFF | 128KB |
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
| TCMU | 0x00800000-0x00807FFF | 0x20000000-0x20007FFF | | 32KB |
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
| TCML | 0x007F8000-0x007FFFFF | | 0x1FFF8000-0x1FFFFFFF | 32KB |
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
| OCRAM_S | 0x00180000-0x00187FFF | 0x20180000-0x20187FFF | 0x00000000-0x00007FFF | 32KB |
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
| QSPI Flash | | | 0x08000000-0x0BFFFFFF | 64MB |
|
|
+------------+-----------------------+------------------------+-----------------------+----------------------+
|
|
|
|
|
|
References
|
|
==========
|
|
|
|
- `i.MX 7 Dual Reference Manual`_ from page 190 (section 2.1.2 and 2.1.3)
|
|
- `Toradex Wiki`_
|
|
|
|
|
|
At compilation time you have to choose which RAM will be used. This configuration is
|
|
done in the file :zephyr_file:`boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.dts`
|
|
with "zephyr,flash" (when CONFIG_XIP=y) and "zephyr,sram"
|
|
properties. The available configurations are:
|
|
|
|
.. code-block:: none
|
|
|
|
"zephyr,flash"
|
|
- &ddr_code
|
|
- &tcml_code
|
|
- &ocram_code
|
|
- &ocram_s_code
|
|
- &ocram_pxp_code
|
|
- &ocram_epdc_code
|
|
|
|
"zephyr,sram"
|
|
- &ddr_sys
|
|
- &tcmu_sys
|
|
- &ocram_sys
|
|
- &ocram_s_sys
|
|
- &ocram_pxp_sys
|
|
- &ocram_epdc_sys
|
|
|
|
|
|
Below you will find the instructions to load and run Zephyr on M4 from A7 using u-boot.
|
|
|
|
Copy the compiled zephyr.bin to the first EXT partition of the SD card and plug into the
|
|
board. Power it up and stop the u-boot execution.
|
|
Set the u-boot environment variables and run the zephyr.bin from the appropriated memory
|
|
configured in the Zephyr compilation:
|
|
|
|
.. code-block:: console
|
|
|
|
setenv bootm4 'ext4load mmc 0:1 $m4addr $m4fw && dcache flush && bootaux $m4addr'
|
|
# TCML
|
|
setenv m4tcml 'setenv m4fw zephyr.bin; setenv m4addr 0x007F8000'
|
|
setenv bootm4tcml 'run m4tcml && run bootm4'
|
|
run bootm4tcml
|
|
# TCMU
|
|
setenv m4tcmu 'setenv m4fw zephyr.bin; setenv m4addr 0x00800000'
|
|
setenv bootm4tcmu 'run m4tcmu && run bootm4'
|
|
run bootm4tcmu
|
|
# OCRAM
|
|
setenv m4ocram 'setenv m4fw zephyr.bin; setenv m4addr 0x00900000'
|
|
setenv bootm4ocram 'run m4ocram && run bootm4'
|
|
run bootm4ocram
|
|
# OCRAM_S
|
|
setenv m4ocrams 'setenv m4fw zephyr.bin; setenv m4addr 0x00180000'
|
|
setenv bootm4ocrams 'run m4ocrams && run bootm4'
|
|
run bootm4ocrams
|
|
# DDR
|
|
setenv m4ddr 'setenv m4fw zephyr.bin; setenv m4addr 0x80000000'
|
|
setenv bootm4ddr 'run m4ddr && run bootm4'
|
|
run bootm4ddr
|
|
|
|
M4<->Linux IPC using RPMSG
|
|
**************************
|
|
|
|
The IMX7D soc supports the subsys/ipc/openamp_rsc_table sample to demonstrate the
|
|
usage of rpmsg_tty as an inter processor communication.
|
|
|
|
The board configuration is provided for the colibri_imx7d board.
|
|
The boot process of the M4 core is handled solely by the Linux kernel using the RPROC
|
|
framework.
|
|
|
|
The sample was tested with Toradex's LTS BSP 6.6.0 Minimal Open Embedded image with
|
|
upstream Linux kernel 6.1.83.
|
|
|
|
Required kernel modules must be loaded for RPMSG to work:
|
|
|
|
- imx_rproc
|
|
- virtio_rpmsg_bus
|
|
- rpmsg_tty (requiring rpmsg_core)
|
|
|
|
You need to modify your Linux device tree to add the M4 definitions:
|
|
|
|
- Enable MU_A
|
|
- Reserve memory areas for the M4 so Linux won't touch them.
|
|
- Define the M4 remoteproc node for the drivers.
|
|
|
|
If you have not downloaded the BSP sources, you can modify the board's device tree
|
|
from its currently loaded dtb file.
|
|
|
|
|
|
.. code-block:: none
|
|
|
|
#Check the which fdtfile is loaded for your board in U-boot
|
|
printenv
|
|
#For a Colibri_imx7d on Viola Carrier on BSP 6.6.0
|
|
fdtfile = imx7d-colibri-emmc-eval-v3.dtb
|
|
|
|
#Copy this file to your Linux PC through SSH from /boot
|
|
#Convert the dtb into a dts
|
|
dtc -I dtb -O dts -f imx7d-colibri-emmc-eval-v3.dtb -o imx7d-colibri-emmc-eval-v3.dts
|
|
|
|
#You need to find the following phandle numbers:
|
|
# reset-controller
|
|
# mailbox@30aa0000
|
|
|
|
#Note down the phandle value (0xbd)
|
|
grep -A10 "mailbox@30aa0000 {" imx7d-colibri-emmc-eval-v3.dts
|
|
# outputs your DTS's mailbox definition
|
|
# mailbox@30aa0000 {
|
|
# compatible = "fsl,imx7s-mu\0fsl,imx6sx-mu";
|
|
# reg = <0x30aa0000 0x10000>;
|
|
# interrupts = <0x00 0x58 0x04>;
|
|
# clocks = <0x01 0x1b1>;
|
|
# #mbox-cells = <0x02>;
|
|
# status = "disabled";
|
|
# phandle = <0xbd>;
|
|
# };
|
|
|
|
#Note down the phandle value (0x32)
|
|
grep -A8 "reset-controller@30390000 {" imx7d-colibri-emmc-eval-v3.dts
|
|
# outputs your DTS's reset-controller definition
|
|
# reset-controller@30390000 {
|
|
# compatible = "fsl,imx7d-src\0syscon";
|
|
# reg = <0x30390000 0x10000>;
|
|
# interrupts = <0x00 0x59 0x04>;
|
|
# #reset-cells = <0x01>;
|
|
# phandle = <0x32>;
|
|
# };
|
|
|
|
#Node down the biggest phandle value
|
|
grep "phandle = <" imx7d-colibri-emmc-eval-v3.dts | sort -r | head -1
|
|
# outputs your DTS's largest phandle definition
|
|
# phandle = <0xca>;
|
|
|
|
#Now we can add our nodes to the .dts file:
|
|
cp imx7d-colibri-emmc-eval-v3.dts imx7d-m4.dts
|
|
nano imx7d-m4.dts
|
|
|
|
#Modify MU_A node to enable it
|
|
mailbox@30aa0000 {
|
|
compatible = "fsl,imx7s-mu\0fsl,imx6sx-mu";
|
|
reg = <0x30aa0000 0x10000>;
|
|
interrupts = <0x00 0x58 0x04>;
|
|
clocks = <0x01 0x1b1>;
|
|
#mbox-cells = <0x02>;
|
|
status = "okay";
|
|
phandle = <0xbd>;
|
|
};
|
|
|
|
#Add these definitions under / { } just before the __symbols__
|
|
#Disgard the comments with #-->
|
|
reserved-memory {
|
|
#address-cells = <0x01>;
|
|
#size-cells = <0x01>;
|
|
ranges;
|
|
|
|
vdev0buffer0@90002000 {
|
|
compatible = "shared-dma-pool";
|
|
reg = <0x90002000 0x8000>;
|
|
no-map;
|
|
phandle = <0xcb>; #--> biggest phandle +1
|
|
};
|
|
|
|
vdev0vring0@90000000 {
|
|
compatible = "shared-dma-pool";
|
|
reg = <0x90000000 0x1000>;
|
|
no-map;
|
|
phandle = <0xcc>; #--> biggest phandle +2
|
|
};
|
|
|
|
vdev0vring1@90001000 {
|
|
compatible = "shared-dma-pool";
|
|
reg = <0x90001000 0x1000>;
|
|
no-map;
|
|
phandle = <0xcd>; #--> biggest phandle +3
|
|
};
|
|
|
|
cm4tcmcode@7f8000 {
|
|
compatible = "shared-dma-pool";
|
|
reg = <0x7f8000 0x8000>;
|
|
no-map;
|
|
phandle = <0xce>; #--> biggest phandle +4
|
|
};
|
|
|
|
cm4sramcode@900000 {
|
|
compatible = "shared-dma-pool";
|
|
reg = <0x900000 0x40000>;
|
|
no-map;
|
|
phandle = <0xcf>; #--> biggest phandle +5
|
|
};
|
|
|
|
cm4reserved@8ff00000 {
|
|
compatible = "shared-dma-pool";
|
|
reg = <0x8ff00000 0x100000>;
|
|
no-map;
|
|
phandle = <0xd0>; #--> biggest phandle +6
|
|
};
|
|
};
|
|
|
|
imx7d-cm4 {
|
|
compatible = "fsl,imx7d-cm4";
|
|
mbox-names = "tx\0rx\0rxdb";
|
|
mboxes = <0xbd 0x00 0x00 0xbd 0x01 0x00 0xbd 0x03 0x00>; #--> MU_A phandle (0xbd)
|
|
memory-region = <0xcb 0xcc 0xcd 0xce 0xcf 0xd0>; #--> All the previously defined phandles
|
|
syscon = <0x32>; #--> phandle for the reset-controller
|
|
clocks = <0x01 0x42>;
|
|
};
|
|
|
|
#Recompile the dts into a dtb
|
|
dtc -I dts -O dtb -f imx7d-m4.dts -o imx7d-m4.dtb
|
|
|
|
#Copy the new dtb to /boot on the Colibri IMX7 board
|
|
#Start in U-boot and update the device-tree
|
|
setenv fdtfile imx7d-m4.dtb
|
|
saveenv
|
|
boot
|
|
|
|
When the OS has finished booting with your new device tree you can enable
|
|
the drivers and start the M4 core.
|
|
|
|
.. code-block:: console
|
|
|
|
#Copy zephyr_openamp_rsc_table.elf to /lib/firmware on your board
|
|
$ modprobe imx_rproc
|
|
$ modprobe virtio_rpmsg_bus
|
|
$ modprobe rpmsg_tty
|
|
|
|
#Request RPROC to load the M4 image
|
|
$ echo stop > /sys/class/remoteproc/remoteproc0/state
|
|
$ echo zephyr_openamp_rsc_table.elf > /sys/class/remoteproc/remoteproc0/firmware
|
|
$ echo start > /sys/class/remoteproc/remoteproc0/state
|
|
|
|
#dmesg will detail the boot process:
|
|
$ dmesg
|
|
[ 497.120499] remoteproc remoteproc0: stopped remote processor imx-rproc
|
|
[ 497.138938] remoteproc remoteproc0: powering up imx-rproc
|
|
[ 497.168735] remoteproc remoteproc0: Booting fw image zephyr_openamp_rsc_table.elf, size 1267076
|
|
[ 497.184826] rproc-virtio rproc-virtio.1.auto: assigned reserved memory node vdev0buffer0@90002000
|
|
[ 497.221395] virtio_rpmsg_bus virtio0: rpmsg host is online
|
|
[ 497.233806] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x400
|
|
[ 497.236666] rproc-virtio rproc-virtio.1.auto: registered virtio0 (type 7)
|
|
[ 497.259822] remoteproc remoteproc0: remote processor imx-rproc is now up
|
|
[ 497.293913] virtio_rpmsg_bus virtio0: creating channel rpmsg-client-sample addr 0x401
|
|
[ 497.308388] rpmsg_client_sample virtio0.rpmsg-client-sample.-1.1025: new channel: 0x401 -> 0x401!
|
|
[ 497.337969] virtio_rpmsg_bus virtio0: creating channel rpmsg-tty addr 0x402
|
|
|
|
$ ls /dev | grep ttyRPMSG
|
|
ttyRPMSG0 -> used for zephyr shell interface
|
|
ttyRPMSG1 -> used for sample interface
|
|
|
|
|
|
Debugging
|
|
=========
|
|
|
|
Download and install `J-Link Tools`_ and `NXP iMX7D Connect CortexM4.JLinkScript`_.
|
|
|
|
To run Zephyr Binary using J-Link create the following script in order to
|
|
get the Program Counter and Stack Pointer from zephyr.bin.
|
|
|
|
get-pc-sp.sh:
|
|
|
|
.. code-block:: console
|
|
|
|
#!/bin/sh
|
|
|
|
firmware=$1
|
|
|
|
pc=$(od -An -N 8 -t x4 $firmware | awk '{print $2;}')
|
|
sp=$(od -An -N 8 -t x4 $firmware | awk '{print $1;}')
|
|
|
|
echo pc=$pc
|
|
echo sp=$sp
|
|
|
|
|
|
Get the SP and PC from firmware binary: ``./get-pc-sp.sh zephyr.bin``
|
|
|
|
.. code-block:: console
|
|
|
|
pc=00900f01
|
|
sp=00905020
|
|
|
|
Plug in the J-Link into the board and PC and run the J-Link command line tool:
|
|
|
|
.. code-block:: console
|
|
|
|
/usr/bin/JLinkExe -device Cortex-M4 -if JTAG -speed 4000 -autoconnect 1 -jtagconf -1,-1 -jlinkscriptfile iMX7D_Connect_CortexM4.JLinkScript
|
|
|
|
The following steps are necessary to run the zephyr.bin:
|
|
1. Put the M4 core in reset
|
|
2. Load the binary in the appropriate addr (TMCL, TCMU, OCRAM, OCRAM_S or DDR)
|
|
3. Set PC (Program Counter)
|
|
4. Set SP (Stack Pointer)
|
|
5. Get the M4 core out of reset
|
|
|
|
Issue the following commands inside J-Link commander:
|
|
|
|
.. code-block:: console
|
|
|
|
w4 0x3039000C 0xAC
|
|
loadfile zephyr.bin,0x00900000
|
|
w4 0x00180000 00900f01
|
|
w4 0x00180004 00905020
|
|
w4 0x3039000C 0xAA
|
|
|
|
With these mechanisms, applications for the ``colibri_imx7d/imx7d/m4`` board
|
|
configuration can be built and debugged in the usual way (see
|
|
:ref:`build_an_application` and :ref:`application_run` for more details).
|
|
|
|
References
|
|
==========
|
|
|
|
- `Loading Code on Cortex-M4 from Linux for the i.MX 6SoloX and i.MX 7Dual/7Solo Application Processors`_
|
|
- `J-Link iMX7D Instructions`_
|
|
|
|
.. _Colibri Evaluation Board Website:
|
|
https://www.toradex.com/products/carrier-board/colibri-evaluation-carrier-board
|
|
|
|
.. _Colibri Evaluation Board Datasheet:
|
|
https://docs.toradex.com/102284-colibri-evaluation-board-datasheet.pdf
|
|
|
|
.. _Colibri iMX7 Website:
|
|
https://www.toradex.com/computer-on-modules/colibri-arm-family/nxp-freescale-imx7
|
|
|
|
.. _Colibri iMX7 User Guide:
|
|
https://developer.toradex.com/products/colibri-imx7
|
|
|
|
.. _Colibri iMX7 Datasheet:
|
|
https://docs.toradex.com/103125-colibri-arm-som-imx7-datasheet.pdf
|
|
|
|
.. _i.MX 7 Series Website:
|
|
https://www.nxp.com/products/processors-and-microcontrollers/applications-processors/i.mx-applications-processors/i.mx-7-processors:IMX7-SERIES?fsrch=1&sr=1&pageNum=1
|
|
|
|
.. _i.MX 7 Dual Datasheet:
|
|
https://www.nxp.com/docs/en/data-sheet/IMX7DCEC.pdf
|
|
|
|
.. _i.MX 7 Dual Reference Manual:
|
|
https://www.nxp.com/webapp/Download?colCode=IMX7DRM
|
|
|
|
.. _J-Link Tools:
|
|
https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack
|
|
|
|
.. _NXP iMX7D Connect CortexM4.JLinkScript:
|
|
https://wiki.segger.com/images/8/86/NXP_iMX7D_Connect_CortexM4.JLinkScript
|
|
|
|
.. _Loading Code on Cortex-M4 from Linux for the i.MX 6SoloX and i.MX 7Dual/7Solo Application Processors:
|
|
https://www.nxp.com/docs/en/application-note/AN5317.pdf
|
|
|
|
.. _J-Link iMX7D Instructions:
|
|
https://wiki.segger.com/IMX7D
|
|
|
|
.. _Toradex Wiki:
|
|
https://developer.toradex.com/knowledge-base/freertos-on-the-cortex-m4-of-a-colibri-imx7#Memory_areas
|