Using the System

Boot Devices

The i.MX8MM SoM has the two boot pins on the SoC (BOOT_MODE0 and BOOT_MODE1) unconnected by default, which means the boot mode is set to "00". The BootROM will use the manufacture-mode to look for a bootable image on the SD-card. If none is found, it will fall back to serial loader mode, where it expects an image to be loaded via USB-OTG1 (which is on the micro USB connector on the demo board).

To select other boot devices such as the SPI NOR flash or the eMMC, you need to program the OTP fuses accordingly.

The default setup for production devices from Kontron is that the fuses are set to boot from the SD card (SD2) as primary boot device. The SPI NOR is set as fallback boot device if no SD card is available.

If you order SoMs from Kontron and you need a different setup, please supply the necessary information with your order.

The following table shows the default configuration from Kontron in the first row and below other possibilities for boot device configurations as example.

Fuse/Register Name Offset Value Description
BOOT_CFG
BOOT_CFG_PARAMETER
0x470
0x480
0x18001410
0x03000010
Boot from SD (SD2, 4bit buswidth, 3.3V), set BT_FUSE_SEL,
Use SPI NOR as fallback (eCSPI1, CS0)
BOOT_CFG
BOOT_CFG_PARAMETER
0x470
0x480
0x18000060
0x00000000
Boot from SPI NOR (eCSPI1, CS0), set BT_FUSE_SEL, No fallback
BOOT_CFG
BOOT_CFG_PARAMETER
0x470
0x480
0x18002020
0x03000010
Boot from eMMC (SD1, 8bit buswidth, 3.3V), set BT_FUSE_SEL, Use SPI NOR as fallback (eCSPI1, CS0)
BOOT_CFG
BOOT_CFG_PARAMETER
0x470
0x480
0x18002020
0x00000000
Boot from eMMC (SD1, 8bit buswidth, 3.3V), set BT_FUSE_SEL, No fallback

SPI NOR Boot

The U-Boot configuration for the Kontron i.MX8MM SoM creates two image: flash.bin for the SPL and u-boot.itb for TF-A and U-Boot proper (see also "Boot Chain Overview").

Here is an example of how to write the two images to the SPI NOR from within the bootloader (running from SD-card). The two image files are expected to be stored on a FAT partition of the SD-card.

Info

It is recommended to flash the Bootloader with ptool or swupdate because you don't have to take care of memory offsets. This is explained in the chapter Flash-Layout


Probing the SPI NOR

=> sf probe
SF: Detected mx25r1635f with page size 256 Bytes, erase size 4 KiB, total 2 MiB

Erasing the whole flash

=> sf erase 0 0x200000
SF: 2097152 bytes @ 0x0 Erased: OK

Loading the SPL image

=> fatload mmc 1:1 0x40000000 flash.bin
242688 bytes read in 23 ms (10.1 MiB/s)

Writing the SPL image (offset: 1 KiB)

=> sf write 0x40000000 0x400 ${filesize}
device 0 offset 0x400, size 0x3b400
SF: 242688 bytes @ 0x400 Written: OK

Loading the U-Boot image

=> fatload mmc 1:1 0x40000000 u-boot.bin
679544 bytes read in 43 ms (15.1 MiB/s)

Writing the U-Boot image (offset: 320 KiB)

=> sf write 0x40000000 0x50000 ${filesize}
device 0 offset 0x50000, size 0xa5e78
SF: 679544 bytes @ 0x50000 Written: OK

Qt Applications and Backends

To make use of the GPU for your QtQuick applications, we recommend to use the eglfs_kms backend.

Using the DIOs

The 4 DIOs of the BL i.MX8MM (N801x S) are shown below. They can be accessed in the operating system using commands from the libgpiod library. The GPIOs in the operating system are grouped by so called gpiochip devices.

Note: The counting in the OS starts at 0 whereas the GPIO names/numbers (column "Accessible via") start at 1. This does not apply to latter, the "IOxx" part. The number behind "IO" denotes the GPIO offset number within each gpiochip device when using libgpiod. See below for examples.

DIO - GPIO overview:

DIO Name Direction GPIO Name GPIO Device GPIO Offset Connector
DIO1 output GPIO1_IO03 gpiochip0 3 X13 - Pin 1
DIO1 input GPIO1_IO06 gpiochip0 6 X13 - Pin 1
DIO2 output GPIO1_IO07 gpiochip0 7 X13 - Pin 3
DIO2 input GPIO1_IO08 gpiochip0 8 X13 - Pin 3
DIO3 output GPIO1_IO09 gpiochip0 9 X13 - Pin 5
DIO3 input GPIO1_IO10 gpiochip0 10 X13 - Pin 5
DIO4 output GPIO1_IO011 gpiochip0 11 X13 - Pin 7
DIO4 input GPIO5_IO02 gpiochip4 2 X13 - Pin 7

Examples

DIO as Outputs

With the gpioset command from the libgpiod library package, a GPIO can be configured as an output and its state can be set at the same time. The command needs the gpiochip number or name and then the GPIO offset number that should be changed.

Configure DIO1 (GPIO1_IO03) as an output and setting it to 1 (High, On).

root@kontron-mx8mm:/# gpioset gpiochip0 3=1

Setting DIO1 (GPIO1_IO03) to 0 (Low, Off).

root@kontron-mx8mm:/# gpioset gpiochip0 3=0

Configure DIO4 (GPIO1_IO011) as an output and setting it to 1 (High, On).

root@kontron-mx8mm:/# gpioset gpiochip0 11=1

Setting DIO4 (GPIO1_IO011) to 0 (Low, Off).

root@kontron-mx8mm:/# gpioset gpiochip0 11=0

DIO as Inputs

To read the current value of an DIO and configuring it as an input at the same time, the gpioget command from the libgpiod library package can be used.

Configure DIO1 (GPIO1_IO06) as an input and read the current value.

root@kontron-mx8mm:/# gpioget gpiochip0 6

Configure DIO2 (GPIO1_IO08) as an input and read the current value.

root@kontron-mx8mm:/# gpioget gpiochip0 8

Configure DIO3 (GPIO1_IO10) as an input and read the current value.

root@kontron-mx8mm:/# gpioget gpiochip0 10

Configure DIO4 (GPIO5_IO02) as an input and read the current value.

root@kontron-mx8mm:/# gpioget gpiochip4 2

If you want to see the change of an input, the command watch can help. In the following example we are watching DIO4 using the gpioget command to read the current value of the input. With "-n 1" we can set the update interval to 1 second.

root@kontron-mx8mm:/# watch -n 1 gpioget 4 2

To see all available gpiochip devices and known GPIO offsets (lines) the command gpioinfo prints out all available devices.

root@kontron-mx8mm:/# gpioinfo
gpiochip0 - 32 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
....

gpiochip1 - 32 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
        line   2:      unnamed       unused   input  active-high
....

gpiochip2 - 32 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
....

gpiochip3 - 32 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
....


gpiochip4 - 32 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
...

If you just want to see the GPIO info of a particular gpiochip device, adding the name of the device behind the getinfo command prints out only the information for the given device.

For example to display only the information for gpiochip0 device:

root@kontron-mx8mm:/# gpioinfo gpiochip0
gpiochip0 - 32 lines:
        line   0:      unnamed       unused   input  active-high
        line   1:      unnamed       unused   input  active-high
        line   2:      unnamed       unused   input  active-high
        line   3:      unnamed       unused   input  active-high
...

Using Serial Devices

The serial devices on the i.MX8 usually have a name like ttymxc and the number at the end corresponds to a UART device. Below is a table with the different UARTs of the i.MX8, what type they are and how each serial device can be accessed, meaning which tty device corresponds to which UART.

UART Type Accessible via Connector
UART 1 RS232 /dev/ttymxc0 X11
UART 2 RS485 /dev/ttymxc1 X12
UART 3 UART/TTL (Debug UART) /dev/ttymxc2 X3 (USB Mini-B)

To be able to use UART1 and and UART2, they have to be configured before their first use. They have to be switched from terminal emulator (canonical mode) to "raw". Only this way the user can access the devices and send and receive data.

Note: UART3 does not need to be configured, this is done automatically at the start through the bootloader. Do not try to reconfigure this interface, otherwise it might not be possible to establish any debug connection with the board / OS.

Configure UART1 (RS232)

After logging in via the Debug Console the following command needs to be executed in order to get the RS232 (ttymxc0) ready for use.

root@kontron-mx8mm:/# stty -F /dev/ttymxc0 raw -echo -echoe -echok 9600

This command switches UART1 but also sets a baud rate of 9600 at the same time.

Configure UART2 (RS485)

After logging in via the Debug Console the following command needs to be executed in order to get the RS485 (ttymxc1) ready for use. Remember when using this interface, that communication can only be half duplex. Only one device is allowed to communicate at any given time, otherwise data will be lost.

root@kontron-mx8mm:/# stty -F /dev/ttymxc1 raw -echo -echoe -echok 9600

This command switches UART1 but also sets a baud rate of 9600 at the same time.

Examples

Following are some examples on how to use the serial ports on the BL i.MX8MM (N801x S) and how to configure them.

RS232 communication

This example assumes that the RS232 interface of the BL i.MX8MM (N801x S) is wired to another devices RS232 interface, remember to swap the Rx and Tx lines and also connect up GND, otherwise the received data can look very strange.

After connecting the RS232 to the other device, it can be configured and is ready to send and received data.

root@kontron-mx8mm:/# stty -F /dev/ttymxc0 raw -echo -echoe -echok 19200
root@kontron-mx8mm:/# cat /dev/ttymxc0
Hello World!
Hello World!
Hello World!
Hello World!

Sending out data from the console, the echo command can be used and the output is forwarded to the serial device.

root@kontron-mx8mm:/# echo "Hello World!" > /dev/ttymxc0

The PC now also displays the the received text "Hello World!".

RS485 communication

This example assumes that the RS485 interface of the BL i.MX8MM (N801x S) is wired to a PC USB-to-RS485 adapter and that the lines A, B and GND are connected appropriately. Of course any other device with an RS485 interface is just as good.

After wiring the RS485, it can be configured and is ready to receive data.

root@kontron-mx8mm:/# stty -F /dev/ttymxc1 raw -echo -echoe -echok 9600
root@kontron-mx8mm:/# cat /dev/ttymxc1
Hello World!
Hello World!
Hello World!
Hello World!

Sending out data from the console, the echo command can be used and the output is forwarded to the serial device.

root@kontron-mx8mm:/# echo "Hello World!" > /dev/ttymxc1

The PC should now display the received text "Hello World!".

Using CAN-Bus

The CAN-Bus interface is present in the OS after boot, but it is not activated by default. Following is a table with the name of the CAN interface and for an example on how to configure and use it, see below.

Name Accessible via Connector
CAN can0 X12

Checking CAN availability

To be sure that the CAN device or interface is really present in the system, the command ifconfig with the -a parameter can be used to list all socket based communication devices. The can0 interface should be right at the top.

root@kontron-mx8mm:~# ifconfig -a
can0      Link encap:UNSPEC  HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
          NOARP  MTU:16  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:10
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

eth0      Link encap:Ethernet  HWaddr 82:73:E0:1D:85:45
....

eth1      Link encap:Ethernet  HWaddr 42:04:8D:DC:2E:DF
....

lo        Link encap:Local Loopback
....

Configure and activate the CAN interface

In order for the CAN interface to work, it has to be configured first and then activated to become available for use.

Use the following commands to ready the interface:

root@kontron-mx8mm:~# ifconfig can0 down
root@kontron-mx8mm:~# ip link set can0 type can bitrate 125000
root@kontron-mx8mm:~# ifconfig can0 up

The first command disables the interface, the second command configures the can0 interface as can with a bitrate of 125 kbits. The third command enables or re-enables the CAN interface with the new settings and the device is now ready for use.

Examples

To make sure the CAN interface is really available, entering the ifconfig command on its own will show all currently active network or socket based devices. In the following examples the programs candump and cansend are used to send and receive CAN messages.

Receiving data

To receive data from the CAN-Bus and print it to the console, we can use the candump command.

root@kontron-mx8mm:/# candump can0
interface = can0, family = 29, type = 3, proto = 1
<0x134> [4] de ad be ef
<0x134> [4] de ad be ef
<0x134> [4] de ad be ef
<0x134> [4] de ad be ef

The CAN-Bus master sent out 4 messages each containing 4 bytes of data. The id or CAN identifier of each message is 0x134 (hexadecimal) in this example.

Sending data

To send data via the CAN-Bus, we can use the cansend command.

root@kontron-mx8mm:/# cansend can0 -v -i 0x123 0xDE 0xAD 0xBE 0xEF
interface = can0, family = 29, type = 3, proto = 1
id: 291 dlc: 4
0xde 0xad 0xbe 0xef

The parameters -v means verbose output and with -i we can set our own message id. The default message id cansend uses is "1" if the "-i" parameter is not specified. The data or byte(s) which we want to send, have to be supplied individually in the format 0xNM, where NM has to be a hexadecimal number in the range of 0x00 to 0xFF which equals the decimal range of 0 to 255. In this example we send 4 bytes containing the data "deadbeef".