Part 1
요약·해설
표 3개 19행, 공식 이미지, 8개 코드 블록과 전체 DT 변환 절차를 보존했습니다.
Cortex-A7
200MHz M4
OpenAMP RPMsg
J-Link
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
1E55231AF4D9221E71A8097284D05A7120EB8613F6BA092E49428361F2853B98
.. _colibri_imx7d:
NXP i.MX 7 Computer on Module - Colibri iMX7
############################################
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.
.. image:: ../../../../../../../boards/toradex/colibri_imx7d/doc/colibri_imx7d.jpg
:align: center
:alt: Colibri-iMX7
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
Part 3
한국어 전문 번역

개요
i.MX7 SoC는 single/dual Cortex-A7과 single Cortex-M4로 구성된 hybrid multi-core processor입니다. Zephyr는 M4 core에서 실행되며 원문은 이후 release에서 Linux가 동작하는 A7과 RPMsg로 통신할 예정이라고 설명합니다.
하드웨어
- i.MX7 single/dual Cortex-A7 800MHz/1.0GHz와 single Cortex-M4 200MHz
- A7 RAM 256MB·512MB·1GB, M4 RAM TCML/TCMU/OCRAM_S 각 32KB·OCRAM 128KB·DDR 256MB
- A7 Flash 4Gb eMMC와 512Mb NAND
- RGB 1920x1080x24bpp display와 4-wire resistive touch
- parallel camera, stereo line-in/headphone-out, mono microphone
- USB 2.0 OTG·host, 10/100 Ethernet, I2C 4개, SPI 4개, UART 7개, IrDA, PWM 20개, GPIO 최대 125개, 12-bit analog input 4개, SDIO/SD/MMC 2개, CAN 2개
Cortex-M4 지원 기능
| 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 |
기본 설정은 boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4_defconfig에 있으며, 표에 없는 기능은 현재 port에서 지원하지 않습니다.
연결과 I/O
| 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
M4 core는 200MHz로 동작합니다.
Serial port
7개 UART 중 UART2를 console로 사용하며 나머지는 사용하거나 시험하지 않았습니다.
Programming과 debugging 구조
Colibri iMX7D에는 M4용 QSPI Flash가 없으므로 A7이 M4 binary를 RAM에 적재하고 M4를 reset 상태로 만든 뒤 Program Counter와 Stack Pointer를 설정하고 reset을 해제해야 합니다. 이 절차는 bootloader 또는 Linux 부팅 후에 수행할 수 있습니다.
| Region | Cortex-A7 | Cortex-M4 (System Bus) | Cortex-M4 (Code Bus) | Size |
|---|---|---|---|---|
| DDR | 0x80000000-0xFFFFFFFF | 0x80000000-0xDFFFFFFF | 0x10000000-0x1FFEFFFF | 2048MB (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 |
Compile 시 boards/toradex/colibri_imx7d/colibri_imx7d_mcimx7d_m4.dts의 zephyr,flash(CONFIG_XIP=y)와 zephyr,sram으로 사용할 RAM을 선택합니다.
"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
U-Boot에서 Cortex-M4 시작
zephyr.bin을 SD card 첫 EXT partition에 복사하고 U-Boot를 중단한 뒤 compile 때 선택한 memory에 맞는 environment command를 실행합니다.
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 사이 RPMsg IPC
i.MX7D는 subsys/ipc/openamp_rsc_table sample과 rpmsg_tty를 지원합니다. M4 boot는 Linux kernel의 remoteproc framework가 전담합니다. 원문 시험 환경은 Toradex LTS BSP 6.6.0 Minimal Open Embedded image와 upstream Linux 6.1.83입니다.
필요한 kernel module은 imx_rproc, virtio_rpmsg_bus, rpmsg_tty(rpmsg_core 필요)입니다. Linux device tree에서 MU_A를 enable하고, Linux가 접근하지 않을 M4 memory를 reserve하며, driver용 M4 remoteproc node를 정의해야 합니다.
현재 DTB에서 device tree 재구성
U-Boot의 fdtfile을 확인하고 DTB를 DTS로 변환한 뒤 mailbox와 reset controller phandle을 찾습니다. 가장 큰 기존 phandle 다음 값들로 shared memory를 만들고 imx7d-cm4 node에 연결한 후 DTB를 다시 생성합니다. 아래 코드는 원문의 전체 절차입니다.
#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
Linux에서 module과 M4 firmware 시작
#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
J-Link debugging
J-Link Tools와 NXP iMX7D CortexM4 connection script를 설치합니다. 다음 script는 zephyr.bin에서 PC와 SP를 읽습니다.
#!/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-pc-sp.sh zephyr.bin의 원문 예:
pc=00900f01
sp=00905020J-Link command-line tool을 실행합니다.
/usr/bin/JLinkExe -device Cortex-M4 -if JTAG -speed 4000 -autoconnect 1 -jtagconf -1,-1 -jlinkscriptfile iMX7D_Connect_CortexM4.JLinkScript필요한 순서는 M4 reset, 선택한 TCML·TCMU·OCRAM·OCRAM_S·DDR 주소에 binary 적재, PC 설정, SP 설정, reset 해제입니다. OCRAM 예시는 다음과 같습니다.
w4 0x3039000C 0xAC
loadfile zephyr.bin,0x00900000
w4 0x00180000 00900f01
w4 0x00180004 00905020
w4 0x3039000C 0xAA
참고 자료
- Colibri Evaluation Board
- Colibri Evaluation Board datasheet
- Colibri iMX7
- Colibri iMX7 user guide
- Colibri iMX7 datasheet
- i.MX 7 Dual datasheet
- i.MX 7 Dual reference manual
- J-Link Tools
- NXP iMX7D Connect CortexM4.JLinkScript
- Loading code on Cortex-M4 from Linux
- J-Link iMX7D instructions
- Toradex memory area guide
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.