UDOO Neo Full

Overview

UDOO Neo Full is an open source Arduino Uno compatible single board computer. It is equipped with an NXP® i.MX 6SoloX hybrid multicore processor composed of one ARM® Cortex-A9 core running up to 1 GHz and one Cortex-M4 core running up to 227 MHz for high CPU performance and real-time response. Zephyr was ported to run on the Cortex-M4 core only. In a future release, it will also communicate with the Cortex-A9 core (running Linux) via OpenAMP.

UDOO-Neo-Full

UDOO Neo Full (Credit: udoo.org)

Hardware

  • MCIMX6X MCU with a single Cortex-A9 (1 GHz) core and single Cortex-M4 (227 MHz) core
  • Memory
    • 1 GB RAM
    • 128 KB OCRAM
    • 256 KB L2 cache (can be switched into OCRAM instead)
    • 16 KB OCRAM_S
    • 32 KB TCML
    • 32 KB TCMU
    • 32 KB CAAM (secure RAM)
  • A9 Boot Devices
    • NOR flash
    • NAND flash
    • OneNAND flash
    • SD/MMC
    • Serial (I2C/SPI) NOR flash and EEPROM
    • QuadSPI (QSPI) flash
  • Display
    • Micro HDMI connector
    • LVDS display connector
    • Touch (I2C signals)
  • Multimedia
    • Integrated 2d/3d graphics controller
    • 8-bit parallel interface for analog camera supporting NTSC and PAL
    • HDMI audio transmitter
    • S/PDIF
    • I2S
  • Connectivity
    • USB 2.0 Type A port
    • USB OTG (micro-AB connector)
    • 10/100 Mbit/s Ethernet PHY
    • Wi-Fi 802.11 b/g/n
    • Bluetooth 4.0 Low Energy
    • 3x UART ports
    • 2x CAN Bus interfaces
    • 8x PWM signals
    • 3x I2C interface
    • 1x SPI interface
    • 6x multiplexable signals
    • 32x GPIO (A9)
    • 22x GPIO (M4)
  • Other
    • MicroSD card slot (8-bit SDIO interface)
    • Power status LED (green)
    • 2x user LED (red and orange)
  • Power
    • 5 V DC Micro USB
    • 6-15 V DC jack
    • RTC battery connector
  • Debug
    • pads for soldering of JTAG 14-pin connector
  • Sensor
    • 3-Axis Accelerometer
    • 3-Axis Magnetometer
    • 3-Axis Digital Gyroscope
    • 1x Sensor Snap-In I2C connector
  • Expansion port
    • Arduino interface

For more information about the MCIMX6X SoC and UDOO Neo Full board, see these references:

Supported Features

The UDOO Neo Full board configuration supports the following hardware features:

Interface Controller Driver/Component
NVIC on-chip nested vector interrupt controller
SYSTICK on-chip systick
UART on-chip serial port-polling; serial port-interrupt
GPIO on-chip general purpose input/output
COUNTER on-chip counter

The default configuration can be found in the defconfig file:

boards/arm/udoo_neo_full_m4/udoo_neo_full_m4_defconfig

Other hardware features are not currently supported by the port.

Connections and IOs

The UDOO Neo Full board was tested with the following pinmux controller configuration.

Board Name SoC Name Usage
J4 RX UART5_RX_DATA UART Console
J4 TX UART5_TX_DATA UART Console

System Clock

The MCIMX6X SoC is configured to use the 24 MHz external oscillator on the board with the on-chip PLL to generate core clock. PLL settings for M4 core are set via code running on the A9 core.

Serial Port

The MCIMX6X SoC has six UARTs. UART5 is configured for the M4 core and the remaining are used by the A9 core or not used.

Programming and Debugging

The M4 core does not have a flash memory and is not provided a clock at power-on-reset. Therefore it needs to be started by the A9 core. The A9 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 A9 can perform these steps at the bootloader level or after the Linux system has booted.

The M4 core can use up to 5 different RAMs (some other types of memory like a secure RAM are not currently implemented in Zephyr). These are the memory mappings for A9 and M4:

Region Cortex-A9 Cortex-M4 Size
TCML 0x007F8000-0x007FFFFF 0x1FFF8000-0x1FFFFFFF 32 KB
TCMU 0x00800000-0x00807FFF 0x20000000-0x20007FFF 32 KB
OCRAM_S 0x008F8000-0x008FBFFF 0x208F8000-0x208FBFFF 16 KB
OCRAM 0x00900000-0x0091FFFF 0x20900000-0x2091FFFF 128 KB
DDR 0x80000000-0xFFFFFFFF 0x80000000-0xDFFFFFFF 2048 MB (1536 for M4)

References

You have to choose which RAM will be used at compilation time. This configuration is done in the file boards/arm/udoo_neo_full_m4/udoo_neo_full_m4.dts.

If you want to have the code placed in the subregion of a memory, which will likely be the case when using DDR, select “zephyr,flash=&flash” and set the DT_FLASH_SIZE macro to determine the region size and DT_FLASH_ADDR to determine the address where the region begins.

If you want to have the data placed in the subregion of a memory, which will likely be the case when using DDR, select “zephyr,sram=&sram” and set the DT_SRAM_SIZE macro to determine the region size and DT_SRAM_ADDR to determine the address where the region begins.

Otherwise set “zephyr,flash” and/or “zephyr,sram” to one of the predefined regions:

"zephyr,flash"
- &tcml
- &ocram_s
- &ocram
- &ddr

"zephyr,sram"
- &tcmu
- &ocram_s
- &ocram
- &ddr

Below you will find the instructions how a Linux user space application running on the A9 core can be used to load and run Zephyr application on the M4 core.

The UDOOBuntu Linux distribution contains a udooneo-m4uploader [6] utility, but its purpose is to load UDOO Neo “Arduino-like” sketches, so it doesn’t work with Zephyr applications in most cases. The reason is that there is an exchange of information between this utility and the program running on the M4 core using hardcoded shared memory locations. The utility writes a flag which is read by the program running on the M4 core. The program is then supposed to end safely and write the status to the shared memory location for the main core. The utility then loads the new application and reads its status from the shared memory location to determine if it has successfully launched. Since this functionality is specific for the UDOO Neo “Arduino-like” sketches, it is not implemented in Zephyr. However Zephyr applications can support it on their own if planned to be used along with the UDOOBuntu Linux running on the A9 core. The udooneo-uploader utility calls another executable named mqx_upload_on_m4SoloX which can be called directly to load Zephyr applications. Copy the Zephyr binary image into the Linux filesystem and invoke the utility as a root user:

mqx_upload_on_m4SoloX zephyr.bin

If the output looks like below, the mqx_upload_on_m4SoloX could not read the status of the stopped application. This is expected if the previously loaded application is not a UDOO Neo “Arduino-like” sketch and ignores the shared memory communication:

UDOONeo - mqx_upload_on_m4SoloX 1.1.0
UDOONeo - Waiting M4 Stop, m4TraceFlags: 00000000
UDOONeo - Waiting M4 Stop, m4TraceFlags: 00000000
UDOONeo - Waiting M4 Stop, m4TraceFlags: 00000000
UDOONeo - Waiting M4 Stop, m4TraceFlags: 00000000
UDOONeo - Failed to Stop M4 sketch: reboot system !

In such situation, the mqx_upload_on_m4SoloX utility has reset the trace flags, so it will succeed when called again. Then it can have this output below:

UDOONeo - mqx_upload_on_m4SoloX 1.1.0
UDOONeo - FILENAME = zephyr.bin; loadaddr = 0x84000000
UDOONeo - start - end (0x84000000 - 0x84080000)
UDOONeo - Waiting M4 Run, m4TraceFlags: 000001E0
UDOONeo - M4 sketch is running

Or the one below, if the utility cannot read the status flag that the M4 core applications has started. It can be ignored as the application should be running, the utility just doesn’t know it:

UDOONeo - mqx_upload_on_m4SoloX 1.1.0
UDOONeo - FILENAME = zephyr.bin; loadaddr = 0x84000000
UDOONeo - start - end (0x84000000 - 0x84080000)
UDOONeo - Waiting M4 Run, m4TraceFlags: 00000000
UDOONeo - Waiting M4 Run, m4TraceFlags: 00000000
UDOONeo - Waiting M4 Run, m4TraceFlags: 00000000
UDOONeo - Waiting M4 Run, m4TraceFlags: 00000000
UDOONeo - Failed to Start M4 sketch: reboot system !

The stack pointer and the program counter values are read from the binary. The memory address where binary will be placed is calculated from the program counter as its value aligned to 64 KB down, or it can be provided as a second command line argument:

mqx_upload_on_m4SoloX zephyr.bin 0x84000000

It is necessary to provide the address if the binary is copied into a memory region which has different mapping between the A9 and the M4 core. The address calculated from the stack pointer value in the binary file would be wrong.

It is possible to modify the mqx_upload_on_m4SoloX utility source code to not exchange the information with the M4 core application using shared memory.

It is also possible to use the imx-m4fwloader [7] utility to load the M4 core application.

One option applicable in UDOOBuntu Linux is to copy the binary file into the file /var/opt/m4/m4last.fw in the Linux filesystem. The next time the system is booted, Das U-Boot will load it from there.

Another option is to directly use Das U-Boot to load the code.

Debugging

The UDOO Neo Full board includes pads for soldering the 14-pin JTAG connector. Zephyr applications running on the M4 core have only been tested by observing UART console output.