TS-8820-4100
Product Page | |
Documentation | |
---|---|
TS-4100 Schematic | |
TS-4100 Mechanical Drawing | |
TS-8820 Schematic | |
TS-8820 Mechanical Drawing | |
Software Support | |
TS-4100 FTP directory | |
TS-4100 source repository | |
Processor | |
NXP i.MX6UL 528 MHz or 696 MHz Arm® Cortex®-A7 | |
i.MX6UL Product Page | |
Dimensions (in enclosure) | |
6.35 inches (tall) by 7.714 inches (wide including DB9) by 1.14 inches (deep) |
Overview
The TS-8820-BOX is a rugged, feature-rich TS-SOCKET based baseboard and System-on-Module (SoM) combination for industrial applications. The TS-8820-BOX is powered by the TS-4100, TS-4700, TS-4710, TS-4720 or TS-4800 System-on-Module devices. The TS-8820-BOX enclosure exposes all of the available I/O on rugged screw terminals while protecting the SoM and other sensitive electronics. The TS-8820-BOX a tough, durable, flexible, powerful, and affordable industrial process control platform.
The TS-4100 is a TS-SOCKET System-on-Module (SoM) designed for low power applications. It is based around an NXP i.MX6UL 696 MHz CPU with 512 MB or 1GB DDR3 RAM. The TS-4100 can be ordered with soldered down WiFi which includes built in Bluetooth 4.0LE. There is also support for USB Gadget via a micro USB AB OTG connector and eMMC flash for a robust soldered down flash solution.
TS-4100
See the TS-4100 page for functionality regarding the CPU, FPGA, and OS.
NXP i.MX6ul 696 MHz Cortex-A7 (ARMv7) |
Getting Started
A Linux workstation is recommended and assumed for development using this documentation. For users in Windows or OSX, we recommend virtualizing Linux. Most of our platforms run Debian, which is recommended for ease of use if there is no personal distribution preference.
Virtualization
Suggested Linux Distributions
Development using a Windows or OSX system may be possible but is not supported. Development will include accessing drives formatted for Linux and often Linux-based tools.
First Linux Boot
The TS-8820-4100 accepts 10 V to 30 V DC connected directly to the terminal block inputs, as well as IEEE 802.3af PoE. See the Power Supply section for detailed information on powering the device.
Power input to the TS-4100 TS-SOCKET requires a single 5 V source from the baseboard (which may be regulated from other voltage ranges). Refer to the TS-SOCKET Connector section for information on power pins.
The TS-4100 can also be powered standalone from 5 V via the micro USB AB port labeled "P1" when in standalone and not attached to a baseboard. The "P1" connector is mechanically locked out on many of our baseboards to prevent powering the device from multiple sources. For more information on how to operate the TS-4100 in standalone mode see section on Standalone Mode.
Once power is applied to the system, there will be output on the debug console port. The connecting to a console section of the manual provides information on getting the serial console connected. The first output is from U-Boot and will resemble the following when booting from SD card:
U-Boot 2016.03-00367-gb3ce405827 (Jul 02 2019 - 16:40:10 -0700) CPU: Freescale i.MX6UL rev1.1 at 396 MHz Reset cause: POR Board: Technologic Systems TS-4100 FPGA: Rev 11 Silab: Rev 2 I2C: ready DRAM: 1 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 Baseboard ID: 0x8 Baseboard Rev: 0 Net: FEC0 [PRIME] Press Ctrl+C to abort autoboot in 1 second(s) starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 1 USB Device(s) found USB1: USB EHCI 1.00 scanning bus 1 for devices... 1 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found No storage devices, perhaps not 'usb start'ed..? Booting from the SD card ... ** File not found /boot/boot.scr ** ** File not found /boot/ts4100-fpga.vme ** 29205 bytes read in 146 ms (195.3 KiB/s) 8 detected 5244088 bytes read in 390 ms (12.8 MiB/s) Kernel image @ 0x80800000 [ 0x000000 - 0x5004b8 ] ## Flattened Device Tree blob at 83000000 Booting using the fdt blob at 0x83000000 Using Device Tree in place at 83000000, end 8300a214 Starting kernel ...
Note: | The "*** Warning - bad CRC, using default environment" message can be safely ignored when the unit is first booted. This means that no environment variables have been saved to disk, and U-Boot is falling back to the default. If "env save" is run, this will save the environment to disk, and this message will go away unless there are further issues. |
The default U-Boot boot process will check for a bootable USB drive, and then will check the "SD Boot" jumper state if it exists. If the "SD boot" jumper is set, it will boot to the Linux on the SD card, otherwise it will boot to the eMMC. Details about the bootup process, features, and other U-Boot information can be found in the U-Boot sections.
Power Supply
The TS-8820 can be powered via PoE or direct DC voltage input to the terminal block connectors. If PoE is not used, power must be supplied on terminal block P6.
DC via Terminal Blocks
Direct power input can be applied to the P6 terminal block. There are three terminals for power and three for a ground connection. Each of the three sets of terminals are electrically connected together internally in the TS-8820. Operational range of the TS-8820 is +10 VDC to +30 VDC on these inputs. Supply an external ground on terminal 10, 11, and/or 12. Supply +10 V to +30 V on terminal 7, 8, and/or 9.
802.3af PoE
The TS-8820 is IEEE 802.3af PoE compliant. This allows the whole unit to be powered directly from a PoE sourcing device.
When powered via PoE, +24 VDC is made available on the P6 terminal block power terminals. Ensure that the total power draw of the system does not exceed the limits defined by IEEE 802.3af and that power is not also supplied to the TS-8820 on these pins!
Connect to the Console
The TS-8820-4100 offers an RS-232 level console UART on the DB-9 connector. The console UART runs at 115200 baud, 8n1 (8 data bits, no parity, 1 stop bit), with no flow control.
By default, all system messages and a Linux login prompt are output on this interface. It is a "DTE" port, meaning it is equivalent to the same port on a PC/Desktop/Workstation. Due to this, a NULL MODEM cable is required to interface from a host PC to the TS-8820-4100. This port can be used for application purposes, for example to interface with a "DCE" serial device. However the login prompt and kernel information must be disabled. Additionally, note that it is not possible to disable the U-Boot output on this port; any connected devices must be able to handle this text output safely.
Console from Linux
There are many serial terminal applications for Linux, three common used applications are picocom
, screen
, and minicom
. These examples demonstrate all three applications and assume that the serial device is "/dev/ttyUSB0" which is common for USB adapters. Be sure to replace the serial device string with that of the device on your workstation.
picocom
is a very small and simple client.
sudo picocom -b 115200 /dev/ttyUSB0
screen
is a terminal multiplexer which happens to have serial support.
sudo screen /dev/ttyUSB0 115200
Or a very commonly used client is minicom
which is quite powerful but requires some setup:
sudo minicom -s
- Navigate to 'serial port setup'
- Type "a" and change location of serial device to "/dev/ttyUSB0" then hit "enter"
- If needed, modify the settings to match this and hit "esc" when done:
E - Bps/Par/Bits : 115200 8N1 F - Hardware Flow Control : No G - Software Flow Control : No
- Navigate to 'Save setup as dfl', hit "enter", and then "esc"
Console from Windows
Putty is a small simple client available for download here. Open up Device Manager to determine your console port. See the putty configuration image for more details.
- Connect the console serial terminal cable
- Connect the Ethernet cable if applicable.
- Monitor the device bootup using a terminal emulator connected to the serial console port to verify that the board is operating properly
See the TS-4100 page for more details on dealing with the functionality of the SoM.
U-Boot
This platform includes U-Boot as the bootloader to load and boot the full operating system. The i.MX6UL processor loads U-Boot from the eMMC flash at power-on. U-Boot allows booting images from the microSD, eMMC, NFS, or USB. U-Boot is a general purpose bootloader that is capable of booting into common Linux distributions, Android, QNX, or others.
On a normal boot, output from U-Boot will be similar to the following:
U-Boot 2016.03-00367-gb3ce405827 (Jul 02 2019 - 16:40:10 -0700) CPU: Freescale i.MX6UL rev1.1 at 396 MHz Reset cause: POR Board: Technologic Systems TS-4100 FPGA: Rev 11 Silab: Rev 2 I2C: ready DRAM: 1 GiB MMC: FSL_SDHC: 0, FSL_SDHC: 1 Baseboard ID: 0x8 Baseboard Rev: 0 Net: FEC0 [PRIME] Press Ctrl+C to abort autoboot in 1 second(s) starting USB... USB0: USB EHCI 1.00 scanning bus 0 for devices... 1 USB Device(s) found USB1: USB EHCI 1.00 scanning bus 1 for devices... 1 USB Device(s) found scanning usb for storage devices... 0 Storage Device(s) found No storage devices, perhaps not 'usb start'ed..? Booting from the SD card ... ** File not found /boot/boot.scr ** ** File not found /boot/ts4100-fpga.vme ** 29205 bytes read in 146 ms (195.3 KiB/s) 8 detected 5244088 bytes read in 390 ms (12.8 MiB/s) Kernel image @ 0x80800000 [ 0x000000 - 0x5004b8 ] ## Flattened Device Tree blob at 83000000 Booting using the fdt blob at 0x83000000 Using Device Tree in place at 83000000, end 8300a214 Starting kernel ...
The TS-8820 has an "SD Boot" jumper to control the boot source via hardware. It is also possible to modify the U-Boot environment variable "bootcmd" to set the whole device to boot to SD, eMMC, NFS, or USB by default.
Entering U-Boot Shell
Note: | U-Boot behaves differently when on Rev C or older compared to Rev D or newer of the TS-8820 PCB in regards to entering the U-Boot shell. Both behaviors are outlined below. |
The U-Boot shell is a powerful tool. It allows modification of the environment, as well as the ability to run commands directly.
Under most circumstances the U-Boot environment is set up to handle most boot situations, however it may be necessary to modify the environment. When using any of the following methods to enter the U-Boot shell, this will cause U-Boot to read a script file from an attached USB mass storage device before dropping to the U-Boot shell. This will happen regardless even if USB boot is disabled for normal boot.
TS-8820 Rev C and older:
When the TS-8820-4100 is booted, a prompt is provided by U-Boot to press ctrl+c
followed by a 1 second window. If ctrl+c
is found incoming on the serial terminal within this time window, or the push switch is held down (see below), then U-Boot will drop to its shell. This behavior can be modified by setting the U-Boot environment variable force_bootdelay
. Normally this variable does not exist in U-Boot environment, if it does, it will force the timeout for pressing ctrl+c
to be however many seconds the variable is set to. If it is set to 0, then the ctrl+c
prompt is skipped.
TS-8820 Rev D and newer:
By default, the TS-8820-4100 will automatically boot and not provide any prompt to cancel boot. If the U-Boot jumper is set, or the push switch is held down (see below), then U-Boot will drop to a shell prompt. Even if the push switch is disabled as outlined below, the U-Boot jumper will always force U-Boot to drop to its shell. If it is desired to have a prompt to emulate the behavior on older PCB revisions, it is possible to set the environment variable bootdelay
to be a value of 1, e.g.
env set bootdelay 1
env save
Note that in this state, either pressing ctrl+c
, setting the U-Boot jumper, or holding the push switch (unless it is disabled, see below), will cause the TS-8820-4100 to drop to a U-Boot shell.
TS-8820 all PCB revisions:
The baseboard offers a push switch which is broken out from pin 9 on CN1 of the TS-4100. This button can be held down before applying power, and at least 5 seconds after power is applied.
This allows for out of the box functionality and customized production via a USB drive. In order to provide increased security, the push switch entry to U-Boot can be disabled via the U-Boot environment variable rstuboot
. The following U-Boot commands can be used to disable the push switch check, thereby preventing it from being able to enter the U-Boot shell.
env set rstuboot 0
env save
Removing the rstuboot
environment variable, or setting it to a 1, will re-enable the ability for the push switch to interrupt U-Boot and drop to its shell.
Note: | Use caution when setting both "force_bootdelay" and "rstuboot". By setting a value of 0 to both of them on TS-8820 Rev C or older PCB, it is no longer possible to enter the U-Boot shell without booting the device on a compatible baseboard that has a "U-Boot" jumper! |
U-Boot Environment
The eMMC flash contains both the U-Boot executable binary and U-Boot environment. Our default build has 2 MiB of environment space which can be used for variables and boot scripts. The following commands are examples of how to manipulate the U-Boot environment:
# Print all environment variables
env print -a
# Sets the variable bootdelay to 5 seconds
env set bootdelay 5;
# Variables can also contain commands
env set hellocmd 'led red on; echo Hello world; led green on;'
# Execute commands saved in a variable
env run hellocmd;
# Commit environment changes to the SPI flash
# Otherwise changes are lost
env save
# Restore environment to default
env default -a
# Remove a variable
env delete emmcboot
U-Boot Commands
# The most important command is
help
# This can also be used to see more information on a specific command
help i2c
# This is a command added to U-Boot by TS to read the baseboard ID on our
# System on Module devices
bbdetect
echo ${baseboard} ${baseboardid}
# The echo will return something similar to:
# TS-8390 2
# Boots into the binary at $loadaddr. The loaded file needs to have
# the U-Boot header from mkimage. A uImage already contains this.
bootm
# Boots into the binary at $loadaddr, skips the initrd, specifies
# the FDT addrress so Linux knows where to find the device tree
bootm ${loadaddr} - ${fdtaddr}
# Boot a Linux zImage loaded at $loadaddr
bootz
# Boot in to a Linux zImage at $loadaddr, skip initrd, specifies
# the FDT address to Linux knows where to find the device tree
bootz ${loadaddr} - ${fdtaddr}
# Get a DHCP address
dhcp
# This sets ${ipaddr}, ${dnsip}, ${gatewayip}, ${netmask}
# and ${ip_dyn} which can be used to check if the dhcp was successful
# These commands are used for scripting:
false # do nothing, unsuccessfully
true # do nothing, successfully
# This command can set fuses in the processor
# Setting fuses can brick the unit, will void the warranty,
# and should not be done in most cases
fuse
# GPIO can be manipulated from U-Boot. Keep in mind that the IOMUX
# in U-Boot is only setup enough to boot the device, so not all pins will
# be set to GPIO mode out of the box. Boot to the full operating system
# for more GPIO support.
# GPIO are specified in bank and IO in this manual. U-Boot uses a flat numberspace,
# so for bank 2 DIO 25, this would be number (32*1)+25=89
# The formula thus being (32*(bank-1)+dio)=flattened_dio
# Note that on some products, bank 1 is the first bank
# Set 2_25 low
gpio clear 83
# Set 2_25 high
gpio set 83
# Read 2_25
gpio input 83
# Control LEDs
led red on
led green on
led all off
led red toggle
# This command is used to copy a file from most devices
# Load kernel from SD
load mmc 0:1 ${loadaddr} /boot/uImage
# Load Kernel from eMMC
load mmc 1:1 ${loadaddr} /boot/uImage
# Load kernel from USB
usb start
load usb 0:1 ${loadaddr} /boot/uImage
# Load kernel from SATA
sata init
load sata 0:1 ${loadaddr} /boot/uImage
# View the FDT from U-Boot
load mmc 0:1 ${fdtaddr} /boot/imx6q-ts4900.dtb
fdt addr ${fdtaddr}
fdt print
# It is possible to blindly jump to any memory location
# This is similar to bootm, but it does not require
# the use of the U-Boot header
load mmc 0:1 ${loadaddr} /boot/custombinary
go ${loadaddr}
# Browse fat, ext2, ext3, or ext4 filesystems:
ls mmc 0:1 /
# Access memory like devmem in Linux, read/write arbitrary memory
# using mw and md
# write
mw 0x10000000 0xc0ffee00 1
# read
md 0x10000000 1
# Test memory.
mtest
# Check for new SD card
mmc rescan
# Read SD card size
mmc dev 0
mmcinfo
# Read eMMC Size
mmc dev 1
mmcinfo
# The NFS command is like 'load', but used over the network
dhcp
env set serverip 192.168.0.11
nfs ${loadaddr} 192.168.0.11:/path/to/somefile
# Test ICMP
dhcp
ping 192.168.0.11
# Reboot
reset
# SPI access is through the SF command
# Be careful with sf commands since
# this is where U-Boot and the FPGA bitstream exist
# Improper use can render the board unbootable
sf probe
# Delay in seconds
sleep 10
# Load HUSH scripts that have been created with mkimage
load mmc 0:1 ${loadaddr} /boot/ubootscript
source ${loadaddr}
# Most commands have return values that can be used to test
# success, and HUSH scripting supports comparisons like
# test in Bash, but much more minimal
if load mmc 1:1 ${fdtaddr} /boot/uImage;
then echo Loaded Kernel
else
echo Could not find kernel
fi
# Commands can be timed with "time"
time sf probe
# Print U-Boot version/build information
version
Modify Linux Kernel cmdline
The Linux kernel cmdline can be customized by modifying the cmdline_append variable. If new arguments are added, the existing value should also be included with the new arguments.
env set cmdline_append rw rootwait console=ttymxc0,115200 quiet
env save
The kernel command line can also be modified from from within Linux by creating a U-Boot script. From the Linux shell prompt run the following commands to install the necessary tools and create the script:
apt-get update && apt-get install u-boot-tools -y
echo "env set cmdline_append rw rootwait console=ttymxc0,115200 quiet" > /boot/boot.source
mkimage -A arm -T script -C none -n 'tsimx6ul boot script' -d /boot/boot.source /boot/boot.scr
The boot.source includes the plain text commands to be run in U-Boot on startup. The mkimage tool adds a checksum and header to the output file which then can be loaded by U-Boot. The .scr file should not be edited directly.
By default, every boot to SD, eMMC, and NFS will look for the file "/boot/boot.scr" and attempt to load and run it if it exists. This allows for modification of the boot process dynamically every boot without having to enter the U-Boot shell and modify it.
Booting From NFS
U-Boot's NFS support can be used to load a kernel, device tree binary, and root filesystem. The default scripts include an example NFS boot script. Because of the way U-Boot tries to infer server data, the script we use will bypass this, making it more straightforward to use an NFS root that will not be heavily dependent on a particular network configuration.
# Set this to your NFS server IP
env set nfsip 192.168.0.1
# Set this to your NFS root path
env set nfsroot /path/to/nfs/rootfs/
env save
To boot to NFS root once the server details are set:
# Boot to NFS once
run nfsboot;
# To make the NFS boot the persistent default
env set bootcmd run nfsboot;
env save
Note: | 'bootcmd' is used to test for whether the system should stop at the U-Boot shell or continue, the above will make it difficult to get back to the U-Boot shell as it will always attempt to boot regardless of jumper status. |
Booting From USB
By default, U-Boot will attempt to read a U-Boot script from a USB drive on every bootup. This process copies /tsinit.scr
from the first partition of the USB drive into memory and jumps in to the script. If the drive or script do not exist, then this process is bypassed and U-Boot will continue its boot flow.
This process is attempted on every boot unless it is disabled. It can be disabled by modifying the U-Boot environment variable usbboot
. If usbboot
is set to 0 then this step will be bypassed on normal boot cycles. It is enabled by default to allow for a custom production process to be used.
If the U-Boot shell is entered by holding the push switch or using the U-Boot jumper (on baseboards with either a push switch or U-Boot jumper), this process will always run before dropping to the U-Boot shell regardless of the state of the usbboot
variable. If the U-Boot shell is entered by pressing ctrl+c
(on boaseboards without a U-Boot jumper or TS-4100 standalone), then this process is never run since autoboot is aborted and the shell is immediately entered. In this state, the USB boot process can always be manually started with the command run usbprod
.
For information on creating a USB drive to write existing images to either SD and/or eMMC, see the section on our custom production process for more details on the process.
To make a bootable USB drive that boots in to the same environment as SD or eMMC, create a single ext3 partition on a USB drive and unpack the rootfs tarball located here.
Additionally, a U-Boot script file, /tsinit.scr
, must be created and placed in the root folder of this partition. In order to do this, a script must be created and converted to the U-Boot .scr
format. This process requires a set of U-Boot specific tools. These tools are available on most every Linux distribution, the instructions below are for Debian, either on a host PC or on the device itself. See the package installation documentation for other respective distributions.
Install U-Boot tools in Debian
apt-get update && apt-get install u-boot-tools -y
Create the file "tsinit.source" in the root of the USB drive with the Linux filesystem:
# Prepare with:
# mkimage -A arm -T script -C none -n 'imx6ul usb' -d tsinit.source tsinit.scr
# DO NOT MANUALLY EDIT THE .scr FILE
if load usb 0:1 ${loadaddr} /boot/ts${model}-fpga.vme;
then fpga load 0 ${loadaddr} ${filesize};
fi;
if load usb 0:1 ${fdtaddr} /boot/imx6ul-ts${model}-${baseboardid}.dtb;
then echo "${baseboardid} detected;"
else echo "Booting default device tree";
load usb 0:1 ${fdtaddr} /boot/imx6ul-ts${model}.dtb;
fi;
load usb 0:1 ${loadaddr} /boot/zImage;
setenv bootargs root=/dev/sda1 rootwait rw ${cmdline_append} bbid=0x${baseboardid} bbrev=0x${baseboardrev};
run silowaitcharge;
bootz ${loadaddr} - ${fdtaddr};
fi;
Then in the same directory generate the tsinit.scr file:
mkimage -A arm -T script -C none -n 'imx6ul usb' -d tsinit.source tsinit.scr
Update U-Boot
WARNING: | Installing a custom U-Boot is not recommended and may cause the device to fail to boot. |
The TS-4100 uses slightly different U-Boot binaries for the 512 MB and 1 GB RAM variants. This is due to different DDR timing that needs to be set up at the start of U-Boot. When updating U-Boot, be sure to use the script that exists in U-Boot discussed below as it will use the correct file name and will reduce any potential issues
The latest U-Boot binary can be downloaded from the TS-4100 FTP site. Copy these files to /boot/ on the 1st partition of the SD card (or eMMC). The U-Boot binary can be updated by inserting that SD card in to the TS-4100, setting the jumpers to boot from SD, power up the unit, and enter the U-Boot shell. At the U-Boot prompt, the following command can be used:
run update-uboot
The above script will use the /boot/u-boot-${imx_type}.imx file from the SD card or eMMC, depending on the state of the SD Boot jumper.
U-Boot Development
We do provide our U-Boot sources, but we do not recommend rebuilding a custom U-Boot binary as it can leave the system in an unbootable state.
If proceeding with building a custom U-Boot, use the "tsimx_v2016.03_4.1.15_2.0.0_ga" branch from our github repo: https://github.com/embeddedTS/u-boot-imx this can be executed with the following command:
git clone https://github.com/embeddedTS/u-boot-imx.git -b tsimx_v2016.03_4.1.15_2.0.0_ga u-boot-ts4100
When compiling, we recommend using ONLY this cross-compiler, the use of any other compiler may cause issues or may leave the system in an unbootable state! Specifically, we have experienced RAM problems when using a more recent cross compiler to build this version of U-Boot. The tarball can be extracted with the following:
mkdir /opt/toolchains/ts4100/
tar -xf tsimx6ul-glibc-gnueabihf-4.9.4.tar.xz -C /opt/toolchains/ts4100/
Once the tarball has been properly extracted set up the following variables and run the build script:
export ARCH=arm
export CROSS_COMPILE=/path/to/folder/bin/arm-tsimx6ul-linux-gnueabihf-
After the environment variables have been set up as shown above the build is now ready to be executed:
cd /path/to/u-boot-imx
./build-imx6ul.sh ts4100
This will output binaries for 1 GB and 512 MB RAM variants in "/u-boot-imx/out/" that can be written to the device using the steps in Update U-Boot.
Note: | If the following error message is received: "error while loading shared libraries: libmpfr.so.4: cannot open shared object file:" create the following symbolic link in Debian:
sudo ln -s /usr/lib/x86_64-linux-gnu/libmpfr.so.6 /usr/lib/x86_64-linux-gnu/libmpfr.so.4
|
POST
The TS-4100 U-Boot includes a simple POST test. This is normally used in production to verify basic functionality rapidly before continuing to more thorough testing. By default, this is not enabled on every boot, but it can be added via U-Boot scripting if there is a need for additional confidence in the application. The POST test quickly verifies basic functionality of: USB, RTC (if present), Ethernet PHY, WiFi/BT module (if present), eMMC (see warning below), RAM, and the supervisory microcontroller.
The post test can be run with the following command in U-Boot:
post
WARNING: | The 'post' command has an optional "-d" argument; when this argument is passed it does a write and readback test of the eMMC and any other soldered down flash media on the TS-4100 or baseboards which is DESTRUCTIVE to the data on the disk! Note that it will not modify the boot sector contents of the eMMC which is needed by U-Boot. The eMMC chip is still tested for basic functionality without the argument passed, but no data is read or written from the disk itself. |
Debian
Debian Stretch(9)
Getting Started
The stock image uses a Debian Stretch distribution and Linux kernel version 4.9. The latest image can be downloaded below.
This image can then be written to a microSD card or the on-board eMMC flash in order to be booted on the TS-4100.
Debian Networking
Note: | The first physical port on the TS-4100 (or on Baseboards with a single port) is given the name "eth1", while the second port is "eth0". |
By default, Debian Stretch does not configure or bring up any interfaces.
Debian can automatically set up the networking based on the contents of "/etc/network/interfaces.d/" files. For example, to enable DHCP for "eth0" by default on startup:
echo "auto eth0
iface eth0 inet dhcp" > /etc/network/interfaces.d/eth0
To set up a static IP:
echo "auto eth0
iface eth0 inet static
address 192.168.0.50
netmask 255.255.255.0
gateway 192.168.0.1" > /etc/network/interfaces.d/eth0
echo "nameserver 1.1.1.1" > /etc/resolv.conf
To make this take effect immediately for either option:
service networking restart
To configure other interfaces, replace "eth0" with the other network device name. Some interfaces may use predictable interface names. For example, the traditional name for an ethernet port might be "eth1", but some devices may use "enp1s0" for PCIe, or "enx00D069C0FFEE" (the MAC address appended) for USB ethernet interfaces. Run 'ifconfig -a' or 'ip a' to get a complete list of interfaces, including the ones that are not configured.
Debian Wi-Fi Client
Note: | The latest image for this platform as of April 28th, 2022 has known issues with the Wi-Fi driver due to incompatibility with cfg80211 powersave modes.
If using Wi-Fi, it is strongly recommended to bring up the Wi-Fi interface, and then run This issue will be addressed in future images and has already been addressed in our kernel sources. We will continue to provide updates as we receive them from the Wi-Fi module manufacturer. |
Wireless interfaces are also managed with configuration files in "/etc/network/interfaces.d/". For example, to connect as a client to a WPA network with DHCP. Note some or all of this software may already be installed on the target SBC.
Install wpa_supplicant:
apt-get update && apt-get install wpasupplicant -y
Run:
wpa_passphrase youressid yourpassword
This command will output information similar to:
network={ ssid="youressid" #psk="yourpassword" psk=151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b }
Use the hashed PSK in the specific network interfaces file for added security. Create the file:
/etc/network/interfaces.d/wlan0
allow-hotplug wlan0
iface wlan0 inet dhcp
wpa-ssid youressid
wpa-psk 151790fab3bf3a1751a269618491b54984e192aa19319fc667397d45ec8dee5b
To have this take effect immediately:
service networking restart
For more information on configuring Wi-Fi, see Debian's guide here.
Debian Wi-Fi Access Point
Note: | The latest image for this platform as of April 28th, 2022 has known issues with the Wi-Fi driver due to incompatibility with cfg80211 powersave modes.
If using Wi-Fi, it is strongly recommended to bring up the Wi-Fi interface, and then run This issue will be addressed in future images and has already been addressed in our kernel sources. We will continue to provide updates as we receive them from the Wi-Fi module manufacturer. |
This section will discuss setting up the WiFi device as an access point that is bridged to an ethernet port. That is, clients can connect to the AP and will be connected to the ethernet network through this network bridge. The ethernet network must provide a DHCP server; this will be passed through the bridge to WiFi client devices as they connect.
It is also possible to run a DHCP client on the platform itself. In this case the hostapd.conf
file needs to be set up without bridging and a DHCP server needs to be configured. Refer to Debian's documentation for more details on DHCP server configuration.
The 'hostapd' utility is used to manage the access point of the device. This is usually installed by default, but can be installed with:
apt-get update && apt-get install hostapd -y
Note: | The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward. |
Modify the file "/etc/hostapd/hostapd.conf" to have the following lines:
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=wlan0
channel=7
driver=nl80211
logger_stdout=-1
logger_stdout_level=2
wpa=2
wpa_key_mgmt=WPA-PSK
Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
The access point can be started and tested by hand:
hostapd /etc/hostapd/hostapd.conf
Systemd auto-start with bridge to eth0
It is possible to configure the auto-start of 'hostapd' through systemd. The configuration outlined below will set up a bridge with "eth0", meaning the Wi-Fi connection is directly connected to the ethernet network. The ethernet network is required to have a DHCP server present and active on it to assign Wi-Fi clients an IP address. This setup will allow Wi-Fi clients access to the same network as the ethernet port, and the bridge interface will allow the platform itself to access the network.
Set up hostapd
First, modify the hostapd configuration to understand the bridge interface:
echo "bridge=br0" >> /etc/hostapd/hostapd.conf
Create the file "/etc/systemd/system/hostapd_user.service" with the following contents:
[Unit]
Description=Hostapd IEEE 802.11 AP
Wants=network.target
Before=network.target
Before=network.service
After=sys-subsystem-net-devices-wlan0.device
After=sys-subsystem-net-devices-br0.device
BindsTo=sys-subsystem-net-devices-wlan0.device
BindsTo=sys-subsystem-net-devices-br0.device
[Service]
Type=forking
PIDFile=/run/hostapd.pid
ExecStart=/usr/sbin/hostapd /etc/hostapd/hostapd.conf -P /run/hostapd.pid -B
[Install]
WantedBy=multi-user.target
Then enable this in systemd:
systemctl enable hostapd_user.service
systemctl enable systemd-networkd
Set up bridging
Create the following files with the listed contents.
"/etc/systemd/network/br0.netdev"
[NetDev]
Name=br0
Kind=bridge
"/etc/systemd/network/br0.network"
[Match]
Name=br0
[Network]
DHCP=yes
"/etc/systemd/network/bridge.network"
[Match]
Name=eth0
[Network]
Bridge=br0
Debian Wi-Fi Concurrent Client / Access Point
Note: | The latest image for this platform as of April 28th, 2022 has known issues with the Wi-Fi driver due to incompatibility with cfg80211 powersave modes.
If using Wi-Fi, it is strongly recommended to bring up the Wi-Fi interface, and then run This issue will be addressed in future images and has already been addressed in our kernel sources. We will continue to provide updates as we receive them from the Wi-Fi module manufacturer. |
The Wi-Fi device on this platform supports concurrent operation of client and access point (STA and AP). Please see the "Wi-Fi Client" section above first to connect the Wi-Fi module, in STA mode, to an external AP. This demo showcases the Wi-Fi module starting its own AP mode via hostapd
with a simple static IP address while also being concurrently connected to a separate AP.
The 'hostapd' utility is used to manage the access point of the device. This is usually installed by default, but can be installed with:
apt-get update && apt-get install hostapd -y
Note: | The install process may start an unconfigured 'hostapd' process. This process must be killed before moving forward. |
Modify the file /etc/hostapd/hostapd.conf
to have the following lines:
ssid=YourWiFiName
wpa_passphrase=Somepassphrase
interface=p2p0
auth_algs=3
channel=<channel>
driver=nl80211
logger_stdout=-1
logger_stdout_level=2
wpa=2
wpa_key_mgmt=WPA-PSK
Note: | The channel used for AP must match the channel the STA is using! Be sure to set 'channel=...' in the above file to a proper channel number. |
Note: | Refer to the kernel's hostapd documentation for more wireless configuration options. |
In order for the concurrent modes to work, a separate virtual wireless device must first be created. Note that hostapd.conf
above lists interface=p2p0
, a second interface with this name must be created:
iw wlan0 interface add p2p0 type managed
The access point can then be started and tested by hand:
hostapd /etc/hostapd/hostapd.conf &
An IP address can be set to p2p0
:
ifconfig p2p0 192.168.0.1
From this point, other Wi-Fi clients can connect to the SSID YourWiFiName
with the WPA2 key Somepassphrase
with a static IP in the range of 192.168.0.0/24
, and will be able to access the platform at 192.168.0.1
. More advanced configurations are also possible, including bridging, routing/NAT, or simply separate networks with the Wi-Fi module connecting to a network and hosting its own private network with DHCP.
Debian Application Development
Debian Stretch Cross Compiling
Debian Stretch provides cross compilers from the Debian apt repository archive for Debian Stretch. An install on a workstation can build for the same release on other architectures. A Linux desktop or laptop PC, virtual machine, or chroot will need to be used for this. Debian Stretch for a workstation can be downloaded from here.
From a Debian workstation (not the target), run these commands to set up the cross compiler:
# Run "lsb_release -a" and verify Debian 9.X is returned. These instructions are not
# expected to work on any other version or distribution.
su root
# Not needed for the immediate apt-get install, but used
# so we can install package:armhf for cross compiling
dpkg --add-architecture armhf
apt-get update
apt-get install curl build-essential crossbuild-essential-armhf -y
This will install a toolchain that can be used with the prefix "arm-linux-gnueabihf-". The standard GCC tools will start with that name, eg "arm-linux-gnueabihf-gcc".
The toolchain can now compile a simple hello world application. Create hello-world.c on the Debian workstation:
#include <stdio.h>
int main(){
printf("Hello World\n");
}
To compile this:
arm-linux-gnueabihf-gcc hello-world.c -o hello-world
file hello-world
This will return that the binary created is for ARM. Copy this to the target platform to run it there.
Debian Stretch supports multiarch which can install packages designed for other architectures. On workstations this is how 32-bit and 64-bit support is provided. This can also be used to install armhf packages on an x86 based workstation.
This cross compile environment can link to a shared library from the Debian root. The package would be installed in Debian on the workstation to provide headers and libraries. This is included in most "-dev" packages. When run on the arm target it will also need a copy of the library installed, but it does not need the -dev package.
apt-get install libcurl4-openssl-dev:armhf
# Download the simple.c example from curl:
wget https://raw.githubusercontent.com/bagder/curl/master/docs/examples/simple.c
# After installing the supporting library, curl will link as compiling on the unit.
arm-linux-gnueabihf-gcc simple.c -o simple -lcurl
Copy the binary to the target platform and run on the target. This can be accomplished with network protocols like NFS, SCP, FTP, etc.
If any created binaries do not rely on hardware support like GPIO or CAN, they can be run using 'qemu'.
# using the hello world example from before:
./hello-world
# Returns Exec format error
apt-get install qemu-user-static
./hello-world
Debian Installing New Software
Debian provides the apt-get system which allows management of pre-built applications. The apt tools require a network connection to the internet in order to automatically download and install new software. The update command will download a list of the current versions of pre-built packages.
apt-get update
A common example is installing Java runtime support for a system. Find the package name first with search, and then install it.
root@ts:~# apt-cache search openjdk default-jdk - Standard Java or Java compatible Development Kit default-jdk-doc - Standard Java or Java compatible Development Kit (documentation) default-jdk-headless - Standard Java or Java compatible Development Kit (headless) default-jre - Standard Java or Java compatible Runtime default-jre-headless - Standard Java or Java compatible Runtime (headless) jtreg - Regression Test Harness for the OpenJDK platform libreoffice - office productivity suite (metapackage) openjdk-8-dbg - Java runtime based on OpenJDK (debugging symbols) openjdk-8-demo - Java runtime based on OpenJDK (demos and examples) openjdk-8-doc - OpenJDK Development Kit (JDK) documentation openjdk-8-jdk - OpenJDK Development Kit (JDK) openjdk-8-jdk-headless - OpenJDK Development Kit (JDK) (headless) openjdk-8-jre - OpenJDK Java runtime, using Hotspot JIT openjdk-8-jre-headless - OpenJDK Java runtime, using Hotspot JIT (headless) openjdk-8-jre-zero - Alternative JVM for OpenJDK, using Zero/Shark openjdk-8-source - OpenJDK Development Kit (JDK) source files uwsgi-app-integration-plugins - plugins for integration of uWSGI and application uwsgi-plugin-jvm-openjdk-8 - Java plugin for uWSGI (OpenJDK 8) uwsgi-plugin-jwsgi-openjdk-8 - JWSGI plugin for uWSGI (OpenJDK 8) uwsgi-plugin-ring-openjdk-8 - Closure/Ring plugin for uWSGI (OpenJDK 8) uwsgi-plugin-servlet-openjdk-8 - JWSGI plugin for uWSGI (OpenJDK 8) java-package - Utility for creating Java Debian packages
In this case, the wanted package will likely be the "openjdk-8-jre" package. Names of packages can be found on Debian's wiki pages or the packages site.
With the package name apt-get install can be used to install the prebuilt packages.
apt-get install openjdk-8-jre
# More than one package can be installed at a time.
apt-get install openjdk-8-jre nano vim mplayer
For more information on using apt-get refer to Debian's documentation here.
Debian Setting up SSH
To install the SSH server, install the package with apt-get:
apt-get install openssh-server
Debian Stretch by default disallows logins directly from the user "root". Additionally, SSH will not allow remote connections without a password or valid SSH key pair. This means in order to SSH to the device, a user account must first be created, and a password set:
useradd --create-home --shell /bin/bash newuser
passwd newuser
After this setup it is now possible to connect to the device as user "newuser" from a remote PC supporting SSH. On Linux/OS X this is the "ssh" command, or from Windows using a client such as PuTTY.
Debian Starting Automatically
A systemd service can be created to start up headless applications. Create a file in /etc/systemd/system/yourapp.service
[Unit]
Description=Run an application on startup
[Service]
Type=simple
ExecStart=/usr/local/bin/your_app_or_script
[Install]
WantedBy=multi-user.target
If networking is a dependency add "After=network.target" in the Unit section. Once you have this file in place add it to startup with:
# Start the app on startup, but will not start it now
systemctl enable yourapp.service
# Start the app now, but doesn't change auto startup
systemctl start yourapp.service
Note: | See the systemd documentation for in depth documentation on services. |
Buildroot
The full-featured Debian image may be too cumbersome for some applications. Applications that require faster bootup time or a smaller root filesystem will benefit greatly from using a lighter distribution like Buildroot. Using Buildroot for generating images makes it easy to keep software up to date, both userspace and kernel. Additionally, the use of Buildroot allows for building full images completely from source, with semi-reproducable builds, and full software license reports.
To assist customers heading down this path, we maintain our own Buildroot br2-external tree. This tree includes upstream Buildroot as a submodule, which eases updating between Buildroot releases. See the Buildroot manual for more information on Buildroot and br2-external trees.
In order to provide an easy transition from a larger Linux distribution to Buildroot, we provide and maintain two levels of configurations:
- The base configuration for each device brings in hardware support to get the unit booted, but offers minimal software support and relies mostly on tools provided by BusyBox.
- An "extra packages" defconfig that can be merged in with any of the base configurations in order to provide many additional packages to create an environment that is more consistent with larger Linux distributions.
The larger Buildroot configuration averages about 10 seconds of boot time, much of which is spent on networking. The base configurations can reduce this time significantly.
Our Buildroot br2-external currently uses the linux-5.10.y
branch of our Linux LTS kernel repository for the majority of its supported platforms.
Note: | Note that our base configurations include that device's utilities package where possible. Normally, these utilities (e.g. tshwctl , tsmicroctl , etc.) list the git hash of the build source in the help output. However, due to the Buildroot process, the git hash in these utilities reflects the git hash of Buildroot-ts, NOT of the utilities repository. There is no way to work around this without building the utilities outside of Buildroot.
|
Buildroot - Installing
When building Buildroot from source, the output files can be used to create a bootable microSD card and a bootable eMMC for the TS-4100. The output files are also compatible with our USB Image Replicator.
The default configuration was designed to be as close to our stock Debian distribution. This includes our ts4100-utils like tsmicroctl, our TS-SILO monitor daemon, drivers, firmware, and software for the Wi-Fi and Bluetooth module, and support for the ZPU in-FPGA microcontroller.
Buildroot - Building
Buildroot is intended to be completely cross-compiled from a host Linux workstation. This process creates a cross-compiler which is then used to build all target applications, kernel, etc., and then output a bootable image / tarball. The following instructions will create a bootable image / tarball for the target system:
Clone the repository:
git clone --recurse-submodules https://github.com/embeddedTS/buildroot-ts.git
cd buildroot-ts/
Configure the build:
# The following command uses a Buildroot script to merge two config files.
# The extra_packages_defconfig includes more usual packages to match our stock images
./buildroot/support/kconfig/merge_config.sh technologic/configs/extra_packages_defconfig technologic/configs/ts4100_defconfig
# A smaller base image can be made with bare hardware support using:
# make ts4100_defconfig
At this point, the default configuration can be modified if desired:
make menuconfig
And finally, start the build process:
make
The Buildroot process can take a large amount of time to build depending on available system resources. Note that if any changes occur in the config file, it is recommended to clean the build tree and start the process over. Buildroot ccache is not enabled by default, but can be to help speed up repeated builds. See the Buildroot manual for more information about ccache and Buildroot.
Once it is finished building, Buildroot will output a filesystem tarball to buildroot/output/images/rootfs.tar.xz
. This file can be used with the Installing Buildroot instructions to get this tarball booted on the target device.
Buildroot - Cross Compiling
In order to generate a cross-compiler from Buildroot, first configure the target build as outlined in the first steps of the build instructions. Once configured, a separate make
command can be issued to generate a tarball package of the cross-compiler. This can be unpacked to any location on the host Linux workstation's filesystem and then used to cross-compile additional applications for the target. The build, setup, and use of the cross-compiler can be done with the following steps:
# Be sure the target is configured first!
# The following command will output the cross-compiler package as well as build the target image completely if not built already
make sdk
# Unpack the tarball to new directory in the users home directory
# Note that the tarball name may be slightly different depending on how the toolchain is configured in Buildroot
mkdir ~/buildroot-toolchain
tar xf buildroot/output/images/arm-buildroot-linux-gnueabihf_sdk-buildroot.tar.gz -C ~/buildroot-toolchain/
# Update the path information for the toolchain (must be done when the tarball is unpacked, or if the root folder of the toolchain is moved!)
# Note that, as above, the path for the compiler may be slightly different depending on how the toolchain is configured in Buildroot
~/buildroot-toolchain/arm-buildroot-linux-gnueabihf_sdk-buildroot/relocate-sdk.sh
# Create a simple Hello World application source
cat << EOF > hello.c
#include <stdio.h>
void main(void) { printf("Hello!\n"); }
EOF
# Build a binary from the Hello World source that can be run on the target device
~/buildroot-toolchain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin/arm-linux-gcc hello.c -o hello
# This cross compiler can be added to the user's PATH variable for easy access
export PATH=$PATH:~/buildroot-toolchain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin
arm-linux-gcc hello.c -o hello
The hello
binary can then be copied to the target device and executed on it.
Note that the make sdk
command can be run at any time to generate the toolchain tarball. Even after Buildroot has generated the output image.
Buildroot is extremely flexible in its generation and use of a cross-compiler. See the Buildroot manual for more information on advanced use of the Buildroot generated toolchain as well as using Buildroot's generated cross-compiler as an external compiler for Buildroot.
Buildroot - Configuring Network
Buildroot implements the ip
, ifconfig
, route
, etc., commands to manipulate the settings of interfaces. The first Ethernet interface is set up to come up automatically with our default configuration. The interfaces can also be manually set up:
# Bring up the CPU network interface
ifconfig eth0 up
# Set an IP address (assumes 255.255.255.0 subnet mask)
ifconfig eth0 192.168.0.50
# Set a specific subnet
ifconfig eth0 192.168.0.50 netmask 255.255.0.0
# Configure a default route. This is the server that provides an internet connection.
route add default gw 192.168.0.1
# Edit /etc/resolv.conf for the local DNS server
echo "nameserver 192.168.0.1" > /etc/resolv.conf
Most commonly, networks will offer DHCP which can be set up with one command:
# To setup the default CPU Ethernet port
udhcpc -i eth0
# All Ethernet ports can be made active and request DHCP addresses with:
udhcpc
To have network settings take effect on startup in Buildroot, edit /etc/network/interfaces
:
# interface file auto-generated by Buildroot
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
pre-up /etc/network/nfs_check
wait-delay 15
Note that the default network startup may timeout on some networks, e.g. network protocols such as STP can delay packet movement. This can be resolved in Buildroot by adding network configuration options to fail after a number of attempts (rather than a timeout) or retry for a DHCP lease indefinitely. For example, adding one of the following lines under the iface eth0 inet dhcp
section:
udhcpc_opts -t 0
to infinitely retryudhcpc_opts -t 5
to fail after five attempts.
See the man page for interfaces(5) for further information on the syntax of the interfaces
file and all of the options that can be passed.
For more information on network configuration in general, Debian provides a great resource here that can be readily applied to Buildroot in most cases.
Buildroot - Installing New Software
Buildroot does not include a package manager by default (though it is possible to enable one). This means installing software directly on the platform can be cumbersome and is not the intended path when using Buildroot. It is recommended to modify the Buildroot configuration to include additional packages. See the Building Buildroot section for information on modifying the configuration to build additional packages.
If a desired package is not available in Buildroot, there are a number of options available moving forward. It is possible to add packages to the build process, though this does require some knowledge of Buildroot internals. Another option is to use the cross compiler that is output by Buildroot in order to compile packages on a host system and then copy them over to the target. It is also possible to install a toolchain directly on the device, and compile applications natively. The last option is the least recommended as it greatly increases the final image size and adds unnecessary complexity.
Buildroot - Setting Up SSH
The default configuration has Dropbear set up. Dropbear is a lightweight SSH server.
Make sure the device is configured on the network and set a password for the remote user. SSH will not allow remote connections without a password set. The default configuration does not set a password for the root user, nor are any other users configured.
passwd root
After this setup it is now possible to connect from a remote PC supporting SSH. On Linux/OS X this is the ssh
command, or from Windows using a client such as PuTTY.
Buildroot - Starting Automatically
Buildroot defaults to using the BusyBox init system, and all of our provided configurations use this as well. The following custom startup script uses this format. For information on other init systems that Buildroot can use, as well as creating startup scripts for these, see the Buildroot manual.
The most straightforward way to add an application to startup is to create a startup script. This example startup script that will toggle the red LED on during startup, and off during shutdown. In this case the script is named customstartup
which can be changed as needed.
Create the file /etc/init.d/S99customstartup
with the following contents. Be sure to set the script as executable!
#! /bin/sh
# /etc/init.d/customstartup
case "$1" in
start)
echo 1 > /sys/class/leds/red-led/brightness
## If you are launching a daemon or other long running processes
## this should be started with
# nohup /usr/local/bin/yourdaemon &
;;
stop)
# if you have anything that needs to run on shutdown
echo 0 > /sys/class/leds/red-led/brightness
;;
*)
echo "Usage: customstartup start|stop" >&2
exit 3
;;
esac
exit 0
Note: | The $PATH variable is not set up by default in init scripts so this will either need to be done manually or the full path to your application must be included. |
Buildroot provides numerous mechanisms to create this file in the target filesystem at build time. See the Buildroot manual for more information on this.
This script will be automatically called at startup and shutdown thanks to the file location and naming. However, it can also be manually started or stopped:
/etc/init.d/S99customstartup start
/etc/init.d/S99customstartup stop
Backup / Restore
While all of our products ship with images pre-loaded in to any supplied media, there are many situations where new images may need to be written. For example, to restore a device to its factory settings or apply a customized image/filesytem for application deployment. Additionally, specific units may be used for development and that unit's disk images need to be replicated to other units to be deployed in the field.
We offer a number of different ways to accomplish both capturing images to be written to other units, and the actual writing process itself. See the sections below for details on our USB Image Replicator tool to capture and/or write images, as well as details on manual processes to capture and write images on each of this device's media.
Image Replicator
This platform supports our Image Replicator tool. The Image Replicator tool is intended for use by developers as a means to write bootable images or filesystems on to a device's media (SD / eMMC / SATA / etc.) as part of their production or preparation process. In addition to writing media, the Image Replicator tool is capable of capturing images from a device's media and preparing them to be written to other devices.
The Image Replicator tool is a USB disk image that can be booted on a target device to capture or write its media directly without the need for a host workstation. The USB disk image is based on Buildroot and contains a set of scripts which handle the capture and write process. The process and its scripts are flexible and can be used as-is or adapted in to larger production processes to format and load data on to devices. The single USB drive can be used to capture images from a device, and then can be inserted in to other devices to write those same images on to other devices. The capture process is not necessary if it is not needed. Images for the target device can be copied to the USB drive, booted on compatible units, and have the target images written to that unit's media.
Image Capture Process
The image capture process performs the following steps. For more detailed information, see the Image Capture section below.
- If no valid images exist on the disk, image capture starts.
- For each valid media present on the unit, a bit for bit copy of the source is made.
- This image is mounted, sanitized (to remove unneeded files and allow safe copying of the image to other units), and saved as either a disk image or a tarball depending on the partition layout of the source disk.
- All images and tarballs are compressed, with both the output files having their MD5 hash saved as well as all of the files contained in the root partition having their MD5 hashes saved to a file for later verification.
The captured images and tarballs are named such that the USB Image Replicator disk can be immediately used to boot another unit and have it perform the Image Write process to write that unit's media with the captured images.
Note: | When using this process, the USB drive used for the Image Replicator must be sized large enough to handle multiple compressed images as well as the uncompressed copy of the media image actively being worked with. If the image capture process runs out of space, the process will indicate a failure. |
Image Write Process
The image write process performs the following steps. For more details information see the Image Write section below.
- For each valid media present on the unit, find the first valid source image file for it.
- If a source image exists for a media that is not present on the unit, then the process indicates a failure.
- If the source image is a tarball, format the target disk with an appropriate filesystem, and unpack it to the target disk, verifying all files against the MD5 hash file list after they are written.
- If the source image is a disk image, write that to the target disk. If an MD5 file for the disk image exists, read back the written disk and compare it to the hash.
Creating a USB Image Replicator Disk
Image Replicator USB disk images can be found below:
Disk image: tsimx6ul-usb-image-replicator.dd.xz
Tarball: tsimx6ul-usb-image-replicator-rootfs.tar.xz
Two types of USB Image Replicator images are available for this platform, a tarball and an actual disk image. They both have the same contents and are intended to provide different methods to write the Image Replicator tool to a USB disk.
- Disk Image (.dd.xz)
- The disk image is easier to write from different workstation OSs, will auto-expand to the full disk length on its first boot, and is intended to be used for image capture (and later image writing) due to its small size and auto-expansion process. We recommend this route for users who may not have access to a Linux workstation or need to capture images from a golden unit first.
- Tarball Image (.tar.xz)
- The tarball image is easiest to write from a Linux workstation, but requires creating a partition table on the USB disk (if one does not already exist), formatting the filesystem, and unpacking the tarball. It can readily be used for for both image capture and writing, but is the easiest route when image capture is not needed due to the auto-expansion process.
Note: | It is recommended to use USB drives with solid-state media for this process. Slower USB drives, especially those with spinning media, may take too long to enumerate and the bootloader will not boot the Image Replicator disk. Additionally, the use of low quality, damaged, and/or worn out USB drives may cause unexpected errors that appear unrelated to the USB drive itself. If there are issues using the Image Replicator, we recommend first trying a new, fresh, high-quality USB drive from a trusted named brand. |
Disk Image
This process uses a small disk image that can be written to a USB device. This disk image uses an ext3 filesystem which expands on its first boot to the full length of the disk before beginning the image capture process. This disk is recommended for users who may not have access to a Linux workstation or who need to capture images from a golden unit.
It is possible to use the disk image for just image writing, however, in order to ensure full disk space is available it is recommended to write the disk image to a USB drive, boot it on a unit, let the image capture process complete, insert the USB drive in to a workstation, and then remove the captured image files before copying in the desired image files for the target unit from the workstation.
Writing Disk Image From a Linux Workstation
The disk image can be written via the command line with the dd
command (replace /dev/sdX
with the correct USB device node):
xzcat <platform>-usb-image-replicator.dd.xz | dd of=/dev/sdX bs=1M conv=fsync
Graphical tools also exist for this purpose, for example balenaEtcher[1] offers this functionality.
Writing Disk Image From a Windows Workstation
A number of tools exist for writing an image to a USB drive, including (but not limited to) balenaEtcher[1] and Win32DiskImager[2]
Writing Disk Image From a MacOS Workstation
We recommend using a tool such as balenaEtcher[1] to write disk images.
Tarball
This process is easiest on a Linux workstation, but can be performs on other operating systems as well so long as they can support a compatible filesystem, the xz
compression algorithm, as well as the tarball archive format. Note that in many cases, one of our computing platforms running our stock Linux image can be used if a Linux workstation is not available. After writing the tarball to a USB disk, the full length of the USB disk would be available to copy source images to in order to write them to other units.
The image replicator and scripts require a minimum of 50 MB; this plus the size of any target disk images or tarballs to be used dictates the minimum USB disk size required. The USB drive should have only a single partition, which is formatted ext2[1] / 3 / 4[2] or FAT32/vfat[3] Note that other filesystems are not compatible with U-Boot and therefore cannot be used.
Writing Tarball From a Linux Workstation
# This assumes USB drive is /dev/sdc:
sudo mkfs.ext3 /dev/sdc1
sudo mkdir /mnt/usb/
sudo mount /dev/sdc1 /mnt/usb/
sudo tar --numeric-owner -xf /path/to/<platform>-usb-image-replicator-rootfs.tar.xz -C /mnt/usb/
sudo umount /mnt/usb/
Writing Tarball From a Windows Workstation
It is recommended to use a third party tool, as native Windows archive tools have been observed to not work correctly. Tools such as 7-Zip[4] or PeaZip[5] are known working. It may also be possible to use Windows Subsystem for Linux following the Linux Workstation instructions above, but this has not been tested.
Note that some Windows tools may attempt to use the whole disk, rather than create a partition table. A partition table with a single partition is required for U-Boot support.
With a formatted USB disk, the archive can be unpacked to the root folder of the USB disk. Be sure to not unpack the tarball contents in to a new folder on the drive as this will not be bootable.
- ↑ The ext2 filesystem has a max file size limit as low at 16 GiB. This may cause issues for Image Capture.
- ↑ Use of ext4 may require additional options. U-Boot on some platforms does not support the 64-bit addressing added as the default behavior in recent revisions of
mkfs.ext4
. If using e2fsprogs 1.43 or newer, the options-O ^64bit,^metadata_csum
may need to be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed, nor are they needed for ext2 / 3. - ↑ The FAT32 (supported by vfat in Linux) filesystem has a max file size limit of 4 GiB. This may cause issues for Image Capture.
- ↑ embeddedTS is not affiliated with this tool. 7-Zip 21.07 tested in Windows 10 on 20220222
- ↑ embeddedTS is not affiliated with this tool. PeaZip 7.2.0 tested in Windows 10 on 20220222
Running the Image Replicator Tool
Once a USB drive is formatted with the Image Replicator tool (see Creating a USB Image Replicator Disk for the correct files and process), boot to this USB drive (note that the Image Replicator already sets up the correct U-Boot boot scripts to boot to the USB drive, see the aforementioned section for details on how to make U-Boot call the scripts on the USB drive). This will start either image capture if no disk images/tarballs are present on the USB drive, or image write if there are disk images/tarballs present on the USB drive.
The Image Replicator tool, while in progress, will flash the green LED once per second while the red LED remains solidly lit. Upon completion, the red LED turns off and the green LED will slowly blink to indicate success, while a blinking red LED with the green LED off indicates a failure.
On each boot, startup scripts will check if the single partition of the USB drive can be expanded and do so if possible. If this process fails, then any further operations will not be run and the LEDs will blink to indicate a failure.
Image Capture
If no valid images to write exist on the booted USB Image Replicator drive, the image capture process starts automatically.
Note that while in progress, the USB Image Replicator drive is mounted read-write. It is not advised to remove power or disconnect the USB Image Replicator drive until the whole process has completed.
To help diagnose failures, files in /tmp/logs/
contain output from each capture process.
For each media present on the unit (SD / eMMC / SATA / etc.), the image capture process will do the following:
- Copy the entire media image to an appropriately named file on the USB Image Replicator drive, e.g.
sdimage.dd
. No data is written to the source media and it is never mounted. The source disk can follow the stock partition layout, or implement a customized one. - Perform an fsck on the Linux rootfs partition in the image file. Note that, if deviating from the standard partition layout, it may be necessary to modify the scripts handling the capture process.
- Mount the Linux rootfs partition from the image file and sanitize the filesystem. The sanitization process removes temporary files (e.g.
/log/
files), unique files (e.g. ssh private key files, machine ID files), adds a file to indicate that it is a custom image with the date as its contents, etc. The full list of operations can be found in this script. It may be necessary to modify this file for unique situations. - If the media's partition layout uses only a single partition, the filesystem is packed in to a tarball on the USB Image Replicator drive which is appropriately named and compressed, e.g.
sdimage.tar.xz
. The image file is then unmounted and removed from the USB Image Replicator drive. - If the media's partition layout uses multiple partitions, the image file is then unmounted, an md5sum of the image file taken, it is compressed and appropriately named on the USB Image Replicator drive, e.g.
emmcimage.dd.xz
, and then an md5sum of the compressed image is taken.
Note that when using this process, the USB Image Replicator drive that is used must be sized large enough to handle multiple compressed images as well as the uncompressed copy of the media image actively being worked with. If the image capture process runs out of space, the process will indicate a failure via the LEDs.
The images files captured are saved to the root folder of the USB Image Replicator drive. Upon completion, it is safe to remove power or unplug the USB drive.
For more details on the image capture process, see this script.
Image Write
This process is used to write existing images to media on a target unit. If appropriately named disk images or tarballs (see table below) are present in the root folder of the USB Image Replicator drive when booted, then the startup scripts will start the image writing process. The latest disk images we provide for our platforms can be downloaded from our FTP site, see the backup and restore section for links to these files.
Note that the USB Image Replicator drive remains read-only through the entire process but target devices may be mounted or actively written. It is not advised to remove power or disconnect the USB Image Replicator drive until the whole process has completed.
To help diagnose failures, files in /tmp/logs/
contain output from each writing process.
The Image Replicator script expects disk images or tarballs to have specific names to match the target media. The script will attempt to match tarball and then disk image names (in the order they are listed in the table below) for each target media, using the first file that is found to write to the target media. Note that symlinks can be used on the USB Image Replicator disk if formatted with a filesystem that supports symlinks. This can be used, for example, to write the same tarball to both SD and eMMC from only a single copy of the source tarball.
Upon completion, it is safe to remove power or unplug the USB drive.
For more details on the image write process, see this script.
The following table is the list of valid file names and how they are processed:
Target media | Accepted filenames | Description |
---|
SD Card |
|
Tar of the filesystem. This will repartition the SD card to a single partition and extract this tarball to the filesystem. If present, a file named /md5sums.txt in the tarball will have its contents checked against the whole filesystem after the tarball is extracted. This md5sums.txt file is optional and can be omitted, but it must not be blank if present. This file is present in our official images and is created during image capture with the Image Replicator tool.
|
---|---|---|
|
Disk image of the media. This will be written to the SD card block device directly. If present on the USB Image Replicator drive, a file named /sdimage.dd.md5 will be used to verify the data written to the SD card against this checksum. This file is provided with our official images and is created during image capture with the Image Replicator tool.
|
eMMC |
|
Tar of the filesystem. This will repartition the eMMC to a single partition and extract this tarball to the filesystem. If present, a file named /md5sums.txt in the tarball will have its contents checked against the whole filesystem after the tarball is extracted. This md5sums.txt file is optional and can be omitted, but it must not be blank if present. This file is present in our official images and is created during image capture with the Image Replicator tool.
|
---|---|---|
|
Disk image of the media. This will be written to the eMMC block device directly. If present on the USB Image Replicator drive, a file named /emmcimage.dd.md5 will be used to verify the data written to the SD card against this checksum. This file is provided with our official images and is created during image capture with the Image Replicator tool.
|
U-Boot |
|
U-Boot binary blob. This will be written to the bootloader area of eMMC. If the file /u-boot.imx.md5 is present on the USB drive, this will be used to verify the data written to disk.
|
---|
Building the Image Replicator from Source
The Image Replicator tool uses Buildroot to create the bootable USB disk image and tarball. See the project repository on github for information on compatibility and instructions on building: https://github.com/embeddedTS/buildroot-ts
Creating A Production Image
Note: | Our Image Replicator tool can be used to automate this process. |
It is usually desired to create a golden image to use for unit production after development is complete. This process can vary greatly from application to application but there are a few steps that are going to be most often wanted. These include cleaning up temporary files, removing files that should be unique and re-generated on the first boot (SSH keys, machine-id files, etc.), setting up the hostname, and so on. We have created a script that will automate most of this process and provides hooks for additional scripts to be called as well. The script is simply passed the device node of the development disk or an existing .dd file. From this, it will create a new .dd file based on the partition scheme with all modifications made to the new image. The image source is left completely untouched and is read only. The script also assumes that the last partition on the disk is the bootable linux partition. If this is not the case or there are multiple partitions that are used in the end application, the script will need to be modified in order to accommodate this fact.
Note: | The script uses output from various commands. The output format of linux utilities can vary greatly from distribution to distribution, or even within versions of the distribution. It is strongly recommended to verify the final processed image contains everything necessary for the application and that all processes completed without issue. |
The simplest use of the script is:
./prep_customer_image /dev/sdX <output base name>
Note that "/dev/sdX" will need to be changed accordingly. Be sure to pass the whole disk and not just a partition.
The "<output base name>" is used as the base for all files output. For example, if "TechnologicSystems-latest" was used, then the compressed tarball output would be named "TechnologicSystems-latest.tar.bz2" (or it may end with ".tar.xz" depending on the compression used by the script). If no base name is provided, then the current date is used.
Additionally, there are two hooks available in the 'prep_customer_image' script, "prep" and "post". The top of the file has two variables, `PREP_SCRIPTS=""` and `POST_SCRIPTS=""`. Adding in a space separated list of script names to those variables will cause them to be called in order. For example, setting `PREP_SCRIPTS="add_application change_hostname"` will cause the 'prep_customer_image' script to run through its initial steps, then call './add_application', then call './change_hostname', and then will continue with the rest of the script steps.
Every script for "prep" and "post" is called with a single argument, the name of the image file. This specifically will be "<output base name>.dd". At the time of calling the prep scripts, the folder "./mount_point/" will have the last partition of the image file mounted as read/write. It is not wise to modify the image file directly since it is already mounted. All of the post scripts are called after the last partition of the image file is unmounted. This can be useful for creating additional file outputs, extracting specific partition images, etc., from the image itself. We have used these hooks in the past to remove special files and create additional images for our DoubleStore based devices.
It is also possible to run this script directly on the device when booted. This can be used to take an image of eMMC for example, when booted from the SD card. We always recommend doing initial development on SD, creating an image from that on a host PC, and then transferring it to the eMMC. This process makes development and image creation faster. If using the 'prep_customer_image' script from a booted device, be sure there is enough free space as the script creates a disk image of the target disk and then copies that in to a tarball, compressing everything as the final step.
The "prep_customer_image" script can be found in the TS-4100 utilities github.
microSD Card
Note: | Our Image Replicator tool can be used to automate this process. |
Click to download the latest tarball. |
These instructions assume an SD card with one partition. Most SD cards ship this way by default, but if there are modified partitions, a utility such as 'gparted' or 'fdisk' may be needed to remove the existing partition table and recreate it with a single partition.
Note: | That the partition table must be "MBR" or "msdos", as the "GPT" partition table format is NOT supported by U-Boot. |
Using other OSs
At this time, we're unable to provide assistance with writing SD cards for our products from non-Linux based operating systems. We acknowledge however, that there are methods to write images and files from a variety of difference operating systems. If a native installation of Linux is unavailable, we recommend using a Virtual Machine. See the Getting Started section for links to common virtualization software and Linux installation.
Using a Linux workstation
An SD card can be written to allow it to be bootable. Download the above file and write this from a Linux workstation using the information below. A USB SD adapter can be used to access the card; or if the workstation supports direct connection of SD cards, that can be used instead. Once inserted in to the workstation, it is necessary to discover which /dev/ device corresponds with the inserted SD card before the image can be written.
Option 1: using 'lsblk'
Newer distributions include a utility called 'lsblk' which allows simple identification of the intended card.
Note: | This command may need to be run as the root user: |
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdY 8:0 0 400G 0 disk
├─sdY1 8:1 0 398G 0 part /
├─sdY2 8:2 0 1K 0 part
└─sdY5 8:5 0 2G 0 part [SWAP]
sr0 11:0 1 1024M 0 rom
sdX 8:32 1 3.9G 0 disk
├─sdX1 8:33 1 7.9M 0 part
├─sdX2 8:34 1 2M 0 part
├─sdX3 8:35 1 2M 0 part
└─sdX4 8:36 1 3.8G 0 part
In this case the, SD card is 4GB, so sdX is the target device and already contains 4 partitions. Note that sdX is not a real device, it could be sda, sdb, mmcblk0, etc. embeddedTS is not responsible for any damages cause by using the improper device node for imaging an SD card. The instructions below to write to the device will destroy the partition table and any existing data!
Option 2: Using 'dmesg'
After plugging in the device, the 'dmesg' command can be used to list recent kernel events. When inserting a USB adapter, the last few lines of 'dmesg' output will be similar to the following (note that this command may need to be run as the root user):
$ dmesg
...
scsi 54:0:0:0: Direct-Access Generic Storage Device 0.00 PQ: 0 ANSI: 2
sd 54:0:0:0: Attached scsi generic sg2 type 0
sd 54:0:0:0: [sdX] 3862528 512-byte logical blocks: (3.97 GB/3.84 GiB)
...
In this case, sdX is shown as a 3.97GB card with a single partition. Note that sdX is not a real device, it could be sda, sdb, mmcblk0, etc. embeddedTS is not responsible for any damages cause by using the improper device node for imaging an SD card. The instructions below to write to the device will destroy the partition table and any existing data!
Running these commands will write the SD card to our default latest image.
# Verify nothing else has the disk mounted with 'mount'
# If partitions are mounted automatically, they can be unmounted with
sudo umount /dev/sdX1
sudo mkfs.ext3 /dev/sdX1
sudo mkdir /mnt/sd
sudo mount /dev/sdX1 /mnt/sd/
wget https://files.embeddedTS.com/ts-socket-macrocontrollers/ts-4100-linux/distributions/debian/ts4100-armhf-stretch-latest.tar.xz
sudo tar -xJf ts4100-armhf-stretch-latest.tar.xz -C /mnt/sd
sudo umount /mnt/sd
sync
Note: | The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3. |
After the image is written, the files can all be verified on disk against the original files created in the tarball. Reinsert the disk to verify any block cache is gone, then run the following:
mount /dev/sdX1 /mnt/sd
cd /mnt/sd/
sudo md5sum --quiet -c md5sums.txt
umount /mnt/sd
sync
The 'md5sum' command will report any differences between files and their checksums. Any differences are an indication of failure to write data or a damaged disk.
eMMC
Booted from SD
Note: | Our Image Replicator tool can be used to automate this process. |
These instructions assume the TS-4100 is booted from SD card all the way to Linux. They also assume that the eMMC is unmodified, with a single partition. If the partition table has been modified, a utility such as 'gparted' or 'fdisk' may be needed to remove the existing partition table and recreate it with a single partition. Note that the partition table must be "MBR" or "msdos", the "GPT" partition table format is not supported by U-Boot.
# Verify nothing else has the partition mounted
umount /dev/mmcblk1p1
mkfs.ext3 /dev/mmcblk1p1
mount /dev/mmcblk1p1 /mnt/emmc
wget http://ftp.embeddedTS.com/ftp/ts-socket-macrocontrollers/ts-4100-linux/distributions/debian/ts4100-armhf-stretch-latest.tar.xz
tar -xf ts4100-armhf-stretch-latest.tar.xz -C /mnt/emmc
umount /mnt/emmc
sync
Note: | The ext4 filesystem can be used instead of ext3, but it may require additional options. U-Boot does not support the 64bit addressing added as the default behavior in recent revisions of mkfs.ext4. If using e2fsprogs 1.43 or newer, the options "-O ^64bit,^metadata_csum" must be used with ext4 for proper compatibility. Older versions of e2fsprogs do not need these options passed nor are they needed for ext3. |
Once written, the files on disk can be verified to ensure they are the same as the source files in the archive. To do so, run the following commands:
mount /dev/mmcblk1p1 /mnt/emmc
cd /mnt/emmc/
md5sum --quiet -c md5sums.txt
cd -
umount /mnt/emmc
sync
The 'md5sum' command will report any differences between files and their checksums. Any differences are an indication of failure to write data or a damaged disk.
Compile the Kernel
Linux 4.9.y (stock)
Compiling the kernel requires an armhf toolchain. We recommend development under Debian Stretch which includes an armhf compiler in the repositories. See the Debian Stretch cross compilation section for instructions on installing a proper cross compiler.
# Install dependencies for kernel build
# The following command is for Ubuntu / Debian workstations. If using a different
# distribution, please consult distribution docs for the proper commands to install
# new packages/tools/libraries/etc.
apt-get install libncurses5-dev bc
# Clone the kernel repository
git clone https://github.com/embeddedTS/linux-lts
# To do a shallow clone of just the latest snapshot of the linux-4.9.y branch, which results in a smaller download size and size on disk, the following command can be used:
# git clone --depth 1 https://github.com/embeddedTS/linux-lts -b linux-4.9.y
cd linux-4.9.y
# Set necessary environment variables for building
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export LOADADDR=0x80800000
# The following defconfig is the same kernel configuration the unit ships with
make tsimx6ul_defconfig
## Make any changes in "make menuconfig" or driver modifications, then compile
make && make zImage && make modules
To install the kernel and modules to an SD card, attach it to the PC and assuming the the SD card shows up as "/dev/sdX", where "X" is the letter drive corresponding to the SD card.
export DEV=/dev/sdX1
sudo mount "$DEV" /mnt/sd
sudo cp arch/arm/boot/zImage /mnt/sd/boot/zImage
sudo cp arch/arm/boot/dts/imx6ul*ts*.dtb /mnt/sd/boot/
INSTALL_MOD_PATH="/mnt/sd" sudo -E make modules_install
sudo -E make headers_install INSTALL_HDR_PATH="/mnt/sd/usr"
sudo umount /mnt/sd/
sync
Note: | Shutting down and coming back or operating from another shell instance will require re-exporting the environment variables. |
Linux 5.10.y
Note: | At this time we do not have an updated userspace more recent than our Debian Stretch distribution. The Debian Stretch disk image can be used as a base and is compatible with the 5.10 kernel. If a newer userspace is needed, we recommend our Buildroot repository for building a complete system image which includes the 5.10 kernel. |
A compatible armhf
cross compiler is needed for building the 5.10 kernel. We recommend using the cross compiler available in Debian distributions (the linked instructions are for Debian Stretch but will work on more recent Debian distributions as well). It is also possible to use our Buildroot repository to build a compatible cross compiler.
Download and Configure
These steps assume a host Linux workstation with an appropriate cross compiler. While on most platforms the kernel can be downloaded, built, and installed all on the device, we recommend against this due to the amount of time, memory, and disk space that can be needed for a build.
Prerequisites
In addition to a cross compiler, a number of host tools are required.
# Install dependencies for kernel build
# The following command is for Ubuntu / Debian workstations. If using a different
# distribution, please consult distribution docs for the proper commands to install
# new packages/tools/libraries/etc.
apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
Note: | The above prerequisite libraries and tools may not be the complete list, depending on the workstation's distribution and age. It may be necessary to install additional packages to support kernel compilation. |
Download kernel repo on a host Linux workstation:
git clone -b linux-5.10.y https://github.com/embeddedTS/linux-lts
# Alternatively, a shallow clone can instead be performed to save space on disk. This makes the source smaller and faster to clone, but can make development and updating from remote more complex.
# git clone --depth 1 -b linux-5.10.y https://github.com/embeddedTS/linux-lts
cd linux-lts/
Configure environment variables needed for building. This specifies the architecture, the cross compiler that is being used, and to set up building the kernel modules for the WILC3000 Wi-Fi/BLE module:
export CROSS_COMPILE=arm-linux-gnueabihf- # This may be different if using a different compiler!
export ARCH=arm
export WILC=y
The WILC3000 Wi-Fi/BLE drivers are maintained and built externally out of the kernel tree. Clone this tree inside of the linux-lts/
directory (this is built later):
git clone -b linux4microchip-2021.10-1 https://github.com/embeddedTS/wilc3000-external-module/
Next, set the default configuration for this platform. Note that a minimal defconfig and a full-feature defconfig are available. The minimal defconfig contains options for supporting the device and a few common peripherals and technologies. While the full defconfig includes much more support for things like USB devices, a more broad range of netfilter/iptables filter module support, etc.
make tsimx6ul_defconfig
# The minimal defconfig can alternately be used with:
# make tsimx6ul_minimal_defconfig
Build and Install
The following will build the kernel and modules, and install the kernel, modules, and headers to a folder and create a tarball from that. This tarball can be unpacked to bootable media, e.g. microSD, eMMC, USB, etc., to update an existing bootable disk.
The script below is most easily saved as a text file and run from the command line as a script. Most terminal emulators will accept the whole script copy/pasted in to the terminal. But it is also possible to copy paste each line of text in to a terminal. In any case, the following is an example of how to compile the kernel. The script or commands used can be modified as needed to suit a specific build pipeline.
The script assumes the following environment variables are set before it is run. See the above sections for what these variables should be set to for this specific platform.
ARCH
- Used to indicate the target CPU architecture.
CROSS_COMPILE
- Used to point to an appropriate cross toolchain for the target platform.
LOADADDR
[Optional]- Used on some platforms to tell U-Boot where to load the file.
WILC
[Optional]- Set to "y" to build and install the WILC3000 Wi-Fi/BLE external modules.
#!/bin/bash -e
# Always build zImage, most common. If LOADADDR is set, then uImage is also built
TARGETS="zImage"
if [ -n "${LOADADDR}" ]; then TARGETS+=" uImage"; fi
# Build the actual kernel, binary files, and loadable modules.
# Use as many CPUs to do this as possible.
make -j"$(nproc)" && make ${TARGETS} && make modules
# Create a temporary directory to install the kernel to in order to use that as a base directory for a tarball.
# Also creates a temporary file that is used as the tarball name.
TEMPDIR=$(mktemp -d)
TEMPFILE=$(mktemp)
mkdir "${TEMPDIR}/boot/"
# Adds "arch/arm/boot/" path prefix to each TARGET
cp $(for i in ${TARGETS}; do echo arch/arm/boot/$i; done) "${TEMPDIR}"/boot/
# Copy the full .config file to the target, this is optional and can be removed
cp .config "${TEMPDIR}"/boot/config
# Copy all of the generated FDT binary files to the target
find arch/arm/boot/dts -name "*ts*.dtb" -exec cp {} "${TEMPDIR}/boot" \;
# Install kernel modules to the target
INSTALL_MOD_PATH="${TEMPDIR}" make modules_install
# Install kernel headers to the target, this is optional in most cases and can be removed to save space on the target
make headers_install INSTALL_HDR_PATH="${TEMPDIR}"
# If WILC is set to "y", then build the external module for the WILC300 Wi-Fi/BLE device.
# Note that this expects the source to be available as a subfolder in the kernel. See the above sections
# for details on getting the driver source if it is used on this specific platform.
if [ "${WILC}" == "y" ]; then
CONFIG_WILC_SPI=m INSTALL_MOD_PATH="${TEMPDIR}" make M=wilc3000-external-module modules modules_install
fi
# Use fakeroot to properly set permissions on the target folder as well as create a tarball from this.
fakeroot sh -c "chmod 755 ${TEMPDIR};
chown -R root:root ${TEMPDIR};
tar czf ${TEMPFILE}.tar.gz -C ${TEMPDIR} .";
# Create a final output tarball and cleanup all of the temporary files and folder.
cp ${TEMPFILE}.tar.gz embeddedTS-linux-lts-"$(date +"%Y%m%d")"-"$(git describe --abbrev=8 --dirty --always)".tar.gz
rm -rf "${TEMPDIR}" "${TEMPFILE}"
At this point, the tarball can be unpacked to a bootable media for the device. This can be done from a booted device, or by mounting removable media from a host Linux workstation. For example, if the root folder of the target filesystem to be updated is mounted to /mnt/
, the following can be used to unpack the above tarball:
# Ensure the target filesystem is mounted to /mnt first!
# Extract kernel tarball to target filesystem,
tar xhf embeddedTS-linux-lts-*.tar.gz -C /mnt
Note: | The h argument to tar is necessary on recent distributions that use paths with symlinks. Not using it can potentially render the whole filesystem no longer bootable.
|
This will correctly unpack the kernel, modules, and headers to the target filesystem which can then be booted as normal.
Linux 6.6.y
Note: | At this time we do not have an updated userspace more recent than our Debian Stretch distribution. The Debian Stretch disk image can be used as a base and is compatible with the 5.10 kernel. If a newer userspace is needed, we recommend our Buildroot repository for building a complete system image which includes the 6.6 kernel. |
A compatible armhf
cross compiler is needed for building the 6.6 kernel. We recommend using the cross compiler available in Debian distributions (the linked instructions are for Debian Stretch but will work on more recent Debian distributions as well). It is also possible to use our Buildroot repository to build a compatible cross compiler.
Download and Configure
These steps assume a host Linux workstation with an appropriate cross compiler. While on most platforms the kernel can be downloaded, built, and installed all on the device, we recommend against this due to the amount of time, memory, and disk space that can be needed for a build.
Prerequisites
In addition to a cross compiler, a number of host tools are required.
# Install dependencies for kernel build
# The following command is for Ubuntu / Debian workstations. If using a different
# distribution, please consult distribution docs for the proper commands to install
# new packages/tools/libraries/etc.
apt-get install git fakeroot build-essential ncurses-dev xz-utils libssl-dev bc flex libelf-dev bison
Note: | The above prerequisite libraries and tools may not be the complete list, depending on the workstation's distribution and age. It may be necessary to install additional packages to support kernel compilation. |
Download kernel repo on a host Linux workstation:
git clone -b linux-6.6.y https://github.com/embeddedTS/linux-lts
# Alternatively, a shallow clone can instead be performed to save space on disk. This makes the source smaller and faster to clone, but can make development and updating from remote more complex.
# git clone --depth 1 -b linux-6.6.y https://github.com/embeddedTS/linux-lts
cd linux-lts/
Configure environment variables needed for building. This specifies the architecture, the cross compiler that is being used, and to set up building the kernel modules for the WILC3000 Wi-Fi/BLE module:
export CROSS_COMPILE=arm-linux-gnueabihf- # This may be different if using a different compiler!
export ARCH=arm
export WILC=y
The WILC3000 Wi-Fi/BLE drivers are maintained and built externally out of the kernel tree. Clone this tree inside of the linux-lts/
directory (this is built later):
git clone -b linux4microchip-2024.04 https://github.com/embeddedTS/wilc3000-external-module/
Next, set the default configuration for this platform. Note that a minimal defconfig and a full-feature defconfig are available. The minimal defconfig contains options for supporting the device and a few common peripherals and technologies. While the full defconfig includes much more support for things like USB devices, a more broad range of netfilter/iptables filter module support, etc.
make tsimx6ul_defconfig
# The minimal defconfig can alternately be used with:
# make tsimx6ul_minimal_defconfig
Build and Install
The following will build the kernel and modules, and install the kernel, modules, and headers to a folder and create a tarball from that. This tarball can be unpacked to bootable media, e.g. microSD, eMMC, USB, etc., to update an existing bootable disk.
The script below is most easily saved as a text file and run from the command line as a script. Most terminal emulators will accept the whole script copy/pasted in to the terminal. But it is also possible to copy paste each line of text in to a terminal. In any case, the following is an example of how to compile the kernel. The script or commands used can be modified as needed to suit a specific build pipeline.
The script assumes the following environment variables are set before it is run. See the above sections for what these variables should be set to for this specific platform.
ARCH
- Used to indicate the target CPU architecture.
CROSS_COMPILE
- Used to point to an appropriate cross toolchain for the target platform.
LOADADDR
[Optional]- Used on some platforms to tell U-Boot where to load the file.
WILC
[Optional]- Set to "y" to build and install the WILC3000 Wi-Fi/BLE external modules.
#!/bin/bash -e
# Always build zImage, most common. If LOADADDR is set, then uImage is also built
TARGETS="zImage"
if [ -n "${LOADADDR}" ]; then TARGETS+=" uImage"; fi
# Build the actual kernel, binary files, and loadable modules.
# Use as many CPUs to do this as possible.
make -j"$(nproc)" && make ${TARGETS} && make modules
# Create a temporary directory to install the kernel to in order to use that as a base directory for a tarball.
# Also creates a temporary file that is used as the tarball name.
TEMPDIR=$(mktemp -d)
TEMPFILE=$(mktemp)
mkdir "${TEMPDIR}/boot/"
# Adds "arch/arm/boot/" path prefix to each TARGET
cp $(for i in ${TARGETS}; do echo arch/arm/boot/$i; done) "${TEMPDIR}"/boot/
# Copy the full .config file to the target, this is optional and can be removed
cp .config "${TEMPDIR}"/boot/config
# Copy all of the generated FDT binary files to the target
find arch/arm/boot/dts -name "*ts*.dtb" -exec cp {} "${TEMPDIR}/boot" \;
# Install kernel modules to the target
INSTALL_MOD_PATH="${TEMPDIR}" make modules_install
# Install kernel headers to the target, this is optional in most cases and can be removed to save space on the target
make headers_install INSTALL_HDR_PATH="${TEMPDIR}"
# If WILC is set to "y", then build the external module for the WILC300 Wi-Fi/BLE device.
# Note that this expects the source to be available as a subfolder in the kernel. See the above sections
# for details on getting the driver source if it is used on this specific platform.
if [ "${WILC}" == "y" ]; then
CONFIG_WILC_SPI=m INSTALL_MOD_PATH="${TEMPDIR}" make M=wilc3000-external-module modules modules_install
fi
# Use fakeroot to properly set permissions on the target folder as well as create a tarball from this.
fakeroot sh -c "chmod 755 ${TEMPDIR};
chown -R root:root ${TEMPDIR};
tar czf ${TEMPFILE}.tar.gz -C ${TEMPDIR} .";
# Create a final output tarball and cleanup all of the temporary files and folder.
cp ${TEMPFILE}.tar.gz embeddedTS-linux-lts-"$(date +"%Y%m%d")"-"$(git describe --abbrev=8 --dirty --always)".tar.gz
rm -rf "${TEMPDIR}" "${TEMPFILE}"
At this point, the tarball can be unpacked to a bootable media for the device. This can be done from a booted device, or by mounting removable media from a host Linux workstation. For example, if the root folder of the target filesystem to be updated is mounted to /mnt/
, the following can be used to unpack the above tarball:
# Ensure the target filesystem is mounted to /mnt first!
# Extract kernel tarball to target filesystem,
tar xhf embeddedTS-linux-lts-*.tar.gz -C /mnt
Note: | The h argument to tar is necessary on recent distributions that use paths with symlinks. Not using it can potentially render the whole filesystem no longer bootable.
|
This will correctly unpack the kernel, modules, and headers to the target filesystem which can then be booted as normal.
TS-8820-4100 MUXBUS Interface
The TS-4100 uses the MUXBUS protocol to read and write the TS-8820 FPGA registers. The TS-4100 FPGA does not natively support the MUXBUS protocol in any way, however all of the relevant electrical connections are accessible to the TS-4100 FPGA as GPIO pins. In order to facilitate the communication, the TS-4100 ZPU is loaded with a program that is designed to accept data from the CPU and perform MUXBUS bus cycles by directly manipulating the FPGA GPIO pins.
Loading the MUXBUS Application
The utility 'tszpuctl' is used to compile applications, load them in to the ZPU, perform ZPU reset, dump ZPU RAM, and get basic information about the ZPU itself. The sources for 'tszpuctl' as well as the "zpu_muxbus" application are available from the ts4100-utils github repository.
The ZPU can be loaded with the MUXBUS application with the following commands:
tszpuctl -l /usr/local/bin/zpu/zpu_muxbus.bin
Note that the ZPU must be re-loaded with this application each time the unit is booted up. The program is loaded directly in to ZPU RAM and executed from there. The sources for zpu_muxbus.bin can be found in the TS-4100 utilities repository.
Using the ts8820ctl Application
With the ZPU loaded, it is now ready to accept commands to read and write TS-8820 FPGA registers. Many of the TS-8820 features listed below show an example of using "ts8820ctl" to interact with I/O or other peripherals. The 'ts8820ctl' application is included in the stock TS-4100 image and requires the ZPU be loaded with the "zpu_muxbus" application first. If the ZPU is not loaded, 'ts8820ctl' will return with an error indicating that it was unable to communicate with the ZPU.
Custom Applications
The 'ts8820ctl' application is meant as a demo application. While it can be used on its own it may be necessary to integrate its features in to a larger application. This is the reason that 'ts8820ctl' is broken down in to multiple layers.
The top level "src/ts8820ctl.c" file in the ts4100-utils github repository is the command line interface. From there it makes a number of calls to functions provided by "src/ts8820.c". These functions do the heavy lifting of formatting data and making calls to the ZPU via a custom FIFO interface. The functions in "ts8820.c" can be called from other applications to directly manipulate the TS-8820 peripherals.
Features
ADC Channels
Note: | Support for this feature requires the use of the TS-4100 ZPU to handle MUXBUS transactions to the TS-8820. See this section for setup information. |
The TS-8820 offers 16 channels of 16-bit, simultaneous acquisition, single ended, bi-polar ADC inputs. These ADC inputs are provided by two separate 8 channel ADC devices. Each ADC controller supports a selectable voltage (via GPIO from the SoM, see below) ranges of -5 V to +5 V as well as -10 V to +10 V. This means that each set of 8 channels can be set to different ranges. Each set of 8 channels are sampled simultaneously inside the ADC device.
All 16 ADC inputs are located on the P3, P4, and P5 terminal blocks. While each ADC has a pair of inputs, they are single ended ADC channels; all negative input terminals connect to the TS-8820 common ground.
Additionally, the ADC devices support a number of oversampling options, also controlled via GPIO from the SoM. Enabling oversampling has the effect of adding a digital filter function after the ADC. Increasing the oversampling ratio will decrease the effective sampling rate of the ADC but will increase the signal to noise ratio of each channel. The oversampling rate is shared between both ADC devices, that is, the rate can not be independently set per-device.
DIO numbers are expressed in <chip>_<pin> notation for use with TS-4100 GPIO.
Setting the ADC voltage range:
DIO | Val | Range |
---|---|---|
3_22 | 1 | -10 V to +10 V |
3_22 | 0 | -5 V to +5 V |
DIO | Val | Range |
---|---|---|
3_23 | 1 | -10 V to +10 V |
3_23 | 0 | -5 V to +5 V |
Setting the oversampling rate:
3_26 | 3_25 | 3_24 | OS Rate |
---|---|---|---|
0 | 0 | 0 | N/A |
0 | 0 | 1 | 2 |
0 | 1 | 0 | 4 |
0 | 1 | 1 | 8 |
1 | 0 | 0 | 16 |
1 | 0 | 1 | 32 |
1 | 1 | 0 | 64 |
1 | 1 | 1 | Invalid |
Note: | SoM GPIO pins will usually start as inputs with pull up resistors. Therefore the default range will likely be -10 V to +10 V with an invalid oversampling rate. It is advised to set up these pins before acquiring ADC samples. |
Current Loops (4-20 mA measurement)
All 16 ADC channels independently support 4-20 mA current loop measurements. This is achieved by setting a pin jumper for the respective channel on the current loop enable pin header. Setting a jumper will electrically enable a 220 Ω 0.5% resistor from the ADC channel to ground allowing for a constant current measurement.
Thermistor
The TS-8820 supports up to 8 thermistors on channels 1 though 8. Support for a thermistor is enabled via software, the ADC pullup bit of TS-8820 FPGA register 0x2. Setting bit 8 enables a pull up on ADC channels 1 and 2, setting bit 9 enables a pull up on ADC channels 3 and 4, and setting bit 10 enables a pull up on channels 5 through 8. When enabled, each channel will get a separate 6.04 kΩ resistor to +12.5 V allowing the use of a thermistor probe.
ADC Usage
The 'ts8820ctl' application can be used to quickly sample the ADCs. This will send simultaneous sampling commands to each of the two ADC devices which will then sample all 16 channels in total the amount of times specified. See the "ts8820ctl.c" and "ts8820.c" files for examples on how this operation takes place.
Due to the datapath required for MUXBUS transactions on the TS-8820-4100, the highest achievable sustained sampling rate is 2000 / <number of channels> Hz
[1]. That is, a single channel can be sampled continuously at 2000 Hz[1], and up to all 16 channels can be read continuously at 125 Hz[1]. The data throughput is limited by the I2C bus to the TS-4100 FPGA and the MUXBUS bridge in the ZPU. This throughput is separate from oversampling rates and it is recommended to use oversampling at these lower rates to get a higher signal-to-noise ratio of the resulting channel. It is also possible to sample at much higher rates in bursts, however the ADC state machine will only be guaranteed to acquire a number of samples equal to the total FIFO space, 8192 samples, and sampling will cease once the FIFO is full.
For example, to sample all of the channels 5 times, with a -10 to +10 V range, and an oversampling rate of 64x, the following command would be used:
ts8820ctl --sample=5 --range 1 --os 6
Collected 80 samples total.
Ch 1 Ch 2 Ch 3 Ch 4 Ch 5 Ch 6 Ch 7 Ch 8 Ch 9 Ch10 Ch11 Ch12 Ch13 Ch14 Ch15 Ch16
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
-7626 2195 2193 2199 2192 2195 2195 2192 2189 2189 2193 2190 2189 2192 2191 2191
-7626 2194 2192 2198 2191 2194 2194 2191 2188 2189 2192 2189 2188 2191 2189 2190
-7626 2193 2191 2197 2190 2193 2193 2190 2187 2188 2191 2188 2186 2190 2189 2189
-7626 2189 2188 2193 2186 2189 2190 2186 2183 2184 2187 2184 2183 2186 2185 2185
-7626 2189 2187 2192 2186 2188 2189 2186 2183 2183 2187 2184 2182 2185 2184 2185
Above, channel 1 has a -7.62 V voltage source attached to it, all other channels are left unconnected. It is recommended to always specify range and oversampling rate when running an ADC acquisition cycle.
Another example of sampling channel 1, 100k times, with a rate of 300 Hz, an input range of -5 to +5 V, to a temporary RAM file:
TMPFILE=$(mktemp)
ts8820ctl -a 100000 -r 300 -m 0x0001 -o 0 > "${TMPFILE}"
For programmers concerned with maximizing sampling bandwidth, it is helpful to understand the design of the TS-8820 ADC system. There are two ADC chips. ADC channels 1-8 on the TS-8820 are on chip 1, and channels 9-16 are on chip 2. The TS-8820 FPGA provides a buffer of 4K samples per chip. The 16-bit channel mask passed to either ts8820ctl
(or the API functions if integrating the ADC functionality in to a custom application) is only a high level software mask. Each 8-bit half of the 16-bit channel mask is OR'ed together and then the resulting 8-bit mask specifying which channels are sampled is applied to both chips. In order to maximize bandwidth, an application needs to minimize the number of channels activated in the 8 bit channel mask. As a result, high speed applications should be designed to use mirroring channels on each chip. Consider the following function calls, each of which attempt to burst 5,000 samples of 8 channels at 350 Hz[1]:
// This one works:
ts8820_adc_acq(350, 5000, 0x0f0f);
// This one suffers an overflow:
ts8820_adc_acq(350, 5000, 0xf00f);
// This one suffers an overflow:
ts8820_adc_acq(350, 5000, 0x00ff);
Baseboard ID
All of our off the shelf baseboards contain a hard-wired 8-input multiplexer to indicate the baseboard model. This is not required to implement in custom baseboards, but it can be useful to identify the board model in software. The baseboard model is determined in the bootloader and the proper device tree is selected for the respective baseboard. For example, the TS-8551-4100 would use the "imx6ul-ts4100-16.dtb" device tree file. In U-Boot the device tree IDs are specified in hex, so 0x16 (U-Boot defaults to using base 16 for number representations) will match baseboard ID 22. If a board does not have a specific device tree, it will fall back to the default device tree which is "imx6ul-ts4100.dtb".
4 DIO pins are used to obtain the baseboard model ID. The red LED (CN2_06), green LED (CN2_08), BUS_DIR (CN1_98), and BD_ID_DATA (CN1_83) are used for this purpose. All of these IO pins can be used normally outside of acquiring the ID number.
The 6 least significant input pins (Y0 - Y5) are used to define the baseboard model. The upper two inputs (Y6 and Y7) define board revision.
For custom baseboards we have reserved the address 42 which will never be used by our standard products.
ID | Baseboard |
---|---|
0 | TS-8200 |
1 | Reserved, do not use |
2 | TS-TPC-8390 |
4 | TS-8500 |
5 | TS-8400 |
6 | TS-8160 |
7 | TS-8100 |
8 | TS-8820-BOX |
9 | TS-8150 |
10 | TS-TPC-8900 |
11 | TS-8290 |
13 | TS-8700 |
14 | TS-8280 |
15 | TS-8380 |
16 | TS-AN20 |
17 | TS-TPC-8920 |
19 | TS-8550 |
20 | TS-TPC-8950 |
22 | TS-8551 |
42 | Reserved for customer use, never used by us |
63 | TS-8200 |
Bluetooth
The Wi-Fi option for this platform also includes a Bluetooth 5.0 LE module. Support for Bluetooth is provided by the BlueZ project. BlueZ has support for many different profiles for HID, A2DP, and many more. Refer to the BlueZ documentation for more information. Please see our BLE Examples page for information on installing the latest BlueZ release, getting started, and using demo applications.
Both Wi-Fi and Bluetooth can be active at the same time on this platform. Note however, that either the Wi-Fi interface needs to be not brought up if Wi-Fi is unused, or it needs to actively connect to an access point or act as an access point. The Bluetooth module can be activated with the following commands:
For Bluez versions found on Debian Stretch and below:
# Enable Bluetooth, and load the firmware
echo BT_POWER_UP > /dev/wilc_bt
sleep 1
echo BT_DOWNLOAD_FW > /dev/wilc_bt
sleep 1
# Attach the BLE device to the system, increase the baud, and enable flow control
hciattach /dev/ttymxc2 any 115200 noflow
sleep 1
hcitool cmd 0x3F 0x0053 00 10 0E 00 01
stty -F /dev/ttymxc2 921600 crtscts
# Note that no other HCI commands should be used! In older versions of BlueZ, HCI commands exist alongside bluetoothd, however HCI commands can interfere with the bluetoothd stack.
For newer versions of BlueZ found on Debian Buster or newer, or newer versions of BlueZ built from source:
echo BT_POWER_UP > /dev/wilc_bt
sleep 1
echo BT_DOWNLOAD_FW > /dev/wilc_bt
sleep 1
btattach -N -B /dev/ttymxc2 -S 115200 &
sleep 1
bluetoothctl power on
sleep 1
hcitool cmd 0x3F 0x0053 00 10 0E 00 01
kill %1 # This terminates the above btattach command
sleep 1
btattach -B /dev/ttymxc2 -S 921600 &
At this point, the device is running at 921600 baud with flow control, and is fully set up ready to be controlled by various components of BlueZ tools. For example, to do a scan of nearby devices:
bluetoothctl
power on
scan on
This will return a list of devices such as:
root@ts-imx6ul:~# bluetoothctl Agent registered [CHG] Controller F8:F0:05:XX:XX:XX Pairable: yes [bluetooth]# power on Changing power on succeeded [CHG] Controller F8:F0:05:XX:XX:XX Powered: yes [bluetooth]# scan on Discovery started [CHG] Controller F8:F0:05:XX:XX:XX Discovering: yes [NEW] Device 51:DD:C0:XX:XX:XX Device_Name [NEW] Device 2A:20:E2:XX:XX:XX Device_Name [CHG] Device 51:DD:C0:XX:XX:XX RSSI: -93 [CHG] Device 51:DD:C0:XX:XX:XX RSSI: -82 [NEW] Device E2:08:B5:XX:XX:XX Device_Name [CHG] Device 51:DD:C0:XX:XX:XX RSSI: -93 [CHG] Device 2A:20:E2:XX:XX:XX RSSI: -94 [NEW] Device 68:62:92:XX:XX:XX Device_Name [NEW] Device 68:79:12:XX:XX:XX Device_Name [bluetooth]# quit
Please note that the Bluetooth module requires the modem control lines CTS and RTS as flow control when running at higher baud rates. It is possible to run the module at the initial 115200 baud if the flow control lines are unwanted.
The module supports some other commands as well:
# Allow the BT chip to enter sleep mode
echo BT_FW_CHIP_ALLOW_SLEEP > /dev/wilc_bt
# Power down the BT radio when not in use
echo BT_POWER_DOWN > /dev/wilc_bt
CAN
Note: | The TS-8820-4100 has a single isolated CAN port. This is the can0 device.
|
The i.MX6UL CPU has two FlexCAN ports that use the linux SocketCAN implementation. The ports can be set up and used with the following commands:
ip link set can0 up type can bitrate 1000000
ip link set can1 up type can bitrate 1000000
At this point the ports can be used with standard SocketCAN libraries. The default Debian distribution ships with "can-utils" installed by default in order to test the ports or as a simple packet send/receive tool. The 'candump' utility can be used to dump all data packets from the CAN network, while the 'cansend' utility will send out packets.
# To print all incoming CAN packets
candump can0
# To send out a CAN packet
cansend can1 7Df#03010c
The above example packet is designed to work with the Ozen Elektronik myOByDic 1610 ECU simulator to read the RPM speed. In this case, the ECU simulator would return data from candump with:
<0x7e8> [8] 04 41 0c 60 40 00 00 00 <0x7e9> [8] 04 41 0c 60 40 00 00 00
In the output above, columns 6 and 7 are the current RPM value. This shows a simple way to prove out the communication before moving to another language.
The following example sends the same packet and parses the same response in C:
#include <stdio.h>
#include <pthread.h>
#include <net/if.h>
#include <string.h>
#include <unistd.h>
#include <net/if.h>
#include <sys/ioctl.h>
#include <assert.h>
#include <linux/can.h>
#include <linux/can/raw.h>
int main(void)
{
int s;
int nbytes;
struct sockaddr_can addr;
struct can_frame frame;
struct ifreq ifr;
struct iovec iov;
struct msghdr msg;
char ctrlmsg[CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(sizeof(__u32))];
char *ifname = "can0";
if((s = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
perror("Error while opening socket");
return -1;
}
strcpy(ifr.ifr_name, ifname);
ioctl(s, SIOCGIFINDEX, &ifr);
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
if(bind(s, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
perror("socket");
return -2;
}
/* For the ozen myOByDic 1610 this requests the RPM guage */
frame.can_id = 0x7df;
frame.can_dlc = 3;
frame.data[0] = 3;
frame.data[1] = 1;
frame.data[2] = 0x0c;
nbytes = write(s, &frame, sizeof(struct can_frame));
if(nbytes < 0) {
perror("write");
return -3;
}
iov.iov_base = &frame;
msg.msg_name = &addr;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = &ctrlmsg;
iov.iov_len = sizeof(frame);
msg.msg_namelen = sizeof(struct sockaddr_can);
msg.msg_controllen = sizeof(ctrlmsg);
msg.msg_flags = 0;
do {
nbytes = recvmsg(s, &msg, 0);
if (nbytes < 0) {
perror("read");
return -4;
}
if (nbytes < (int)sizeof(struct can_frame)) {
fprintf(stderr, "read: incomplete CAN frame\n");
}
} while(nbytes == 0);
if(frame.data[0] == 0x4)
printf("RPM at %d of 255\n", frame.data[3]);
return 0;
}
See the Kernel's CAN documentation here. Other languages have bindings to access CAN such as Python, Java using JNI.
In production use of CAN we also recommend setting a restart-ms for each active CAN port.
ip link set can0 type can restart-ms 100
This allows the CAN bus to automatically recover in the event of a bus-off condition.
CPU
This device uses the i.MX6UL CPU, running at 696 MHz, based upon a Cortex-A7 core and targeting low power consumption.
Refer to NXP's documentation for more detailed information on the i.MX6UL.
CPU Frequency Scaling
The i.MX6UL CPU has a number of power management features to scale the CPU speed. The maximum speed of the i.MX6UL is 696 MHz; other frequencies possible are 528 MHz, 396 MHz, and 198 MHz. By default, the "ondemand" frequency governor is used. This allows the CPU to run at its lowest speed and increase it when there is computation demand. Other governors are available, see the kernel documentation for a list of these governors and their operation.
The current CPU frequency as well as the governor used are modified by a set of files within the folder "/sys/bus/cpu/devices/cpu0/cpufreq". Some key files are outlined below:
/sys/bus/cpu/devices/cpu0/cpufreq/cpuinfo_cur_freq - Lists the current frequency /sys/bus/cpu/devices/cpu0/cpufreq/scaling_governor - Lists/sets the current frequency governor /sys/bus/cpu/devices/cpu0/cpufreq/scaling_setspeed - When govenor is "userspace", set current frequency /sys/bus/cpu/devices/cpu0/cpufreq/scaling_available_frequencies - List all available frequencies /sys/bus/cpu/devices/cpu0/cpufreq/scaling_available_governors - List all available governors
In order to manually specify a frequency, the frequency governor must be set to userspace. For example, to force the lowest CPU frequency all the time:
echo "userspace" > /sys/bus/cpu/devices/cpu0/cpufreq/scaling_governor
echo "198000" > /sys/bus/cpu/devices/cpu0/cpufreq/scaling_setspeed
Temperature Monitoring
Note: | Older images do not support temperature sensing discussed below. Support for this feature can be added by moving to the newest image. |
The i.MX6UL CPU has an internal TEMPMON peripheral that is supported by Linux's Thermal Zone management. This on-die sensor is meant to measure of the thermal state of the CPU for throttling control. This can be read via the Linux kernel's sysfs (/sys) interface. The following command returns the temperature in millicelsius:
cat /sys/class/thermal/thermal_zone0/temp
DAC Channels
Note: | Support for this feature requires the use of the TS-4100 ZPU to handle MUXBUS transactions to the TS-8820. See this section for setup information. |
The TS-8820 has 4 channels of 0 to +10 V DAC outputs. Each DAC channel has a positive and negative terminal connection. The negative side of the terminals are connected to the common ground of the TS-8820 and are non-isolated. The DAC terminals are on the P3 and P9 terminal blocks.
The DAC channels each have 12 bits of resolution that correspond to 0 to +10 V output. The upper bit (bit 15) of each register is a control bit that is used to synchronize the output of all 4 DAC channels. This means that all four registers can be updated without modifying the actual DAC output. Setting the control bit of any DAC channel register will case an update of the DAC output of all four channels. If the DAC register has not been modified, the update will still be sent but the actual output will remain the same. Reading this control bit will indicate if the synchronization is complete. Writing the DAC registers while the control bit is still asserted, indicating busy, will result in undefined behavior. The update process from setting the control bit to its completion takes approximately 3 microseconds.
When 0 is written to the control bit, the DAC values are updated internally in the FPGA but not transferred to the DAC. Thus any set of channels can be updated simultaneously by only writing a one on the final write.
The DAC channels can be controlled through 'ts8820ctl'. Note that the "--setdac" option to 'ts8820ctl' will always set the control bit of the selected register. See "ts8820ctl.c" and "ts8820.c" for an example of how this process works.
The following command would set DAC output 1 to 0.5 V:
ts8820ctl --setdac=1 --mvolts=500
Digital Inputs
Note: | Support for this feature requires the use of the TS-4100 ZPU to handle MUXBUS transactions to the TS-8820. See this section for setup information. |
The TS-8820 offers 14 digital input pins. There are 8 isolated inputs that are 30 V tolerant. The 6 non-isolated inputs are 40 V tolerant.
The inputs can be polled directly through the ts8820ctl application. See ts8820ctl.c and ts8820.c for examples of how this reads from the TS-8820 registers.
With the ts8820ctl application, all 14 inputs can be read with a single command. A 14-bit value is returned in hex in a format that can be parsed easily by scripting languages. For example, the following output indicates that IN1 and IN3 are active:
ts8820ctl --getdio
dio=0x5
When an input is activated its associated LED indicator is enabled to provide visual feedback.
Isolated Inputs
Digital inputs IN1 though IN8 are isolated, each having their own positive and negative terminal. In order to activate an input, a potential of at least 1.4 VDC and not more than 30 VDC must be generated across these terminals. Isolated input terminals are located on P1 and P7 terminal blocks.
Buffered Inputs
Digital inputs IN9 through IN14 are non-isolated, buffered, active low inputs. Each pin has a nominal threshold of 2.5 VDC, a 3.24 Kohm pull-up to 5 VDC, and are 40 VDC tolerant. Non-isolated inputs are located on the P2 terminal block.
Pulse Counter
Each of the 14 digital inputs has an associated 16-bit pulse counter. The counters are reset at power on, and continue counting through their entire 16 bit range before rolling over. There is no mechanism to clear the counters arbitrarily.
Each counter is incremented once per transition of the associated IN channel, on the asserted edge of the signal. IN1-IN8 counters increase when a positive voltage is applied while IN9-IN14 counters increment when the pin is grounded. The pulse counters do not increment when the signal is returning to its deasserted state.
Note: | The counter logic does not include any debounce; care should be taken when using the pulse counter for a mechanical contact closure to ensure an accurate count. |
The current count for any given channel can be acquired with:
ts8820ctl --counter <in>
ts8820ctl --counter 10
# Returns the output of
counter10=4
Digital Outputs
Note: | Support for this feature requires the use of the TS-4100 ZPU to handle MUXBUS transactions to the TS-8820. See this section for setup information. |
The TS-8820 offers 6 digital outputs. OUT1 through OUT4 are isolated and act as a solid state relay capable of switching up to 40 VDC at 1 A continuous draw. OUT5 and OUT6 are non-isolated, able to sink up to 1 A continuous current, and are 40 VDC tolerant.
The outputs can be controlled directly through the 'ts8820ctl' application. See "ts8820ctl.c" and "ts8820.c" for examples of how this writes to the TS-8820 registers.
With the 'ts8820ctl' application, all 6 outputs are manipulated in a single command. That is, a 6-bit value is passed as an argument, and that value is directly set to the outputs. For example, to set OUT5:
ts8820ctl --setdio=0x10
When an output is activated its associated LED indicator is enabled to provide visual feedback.
Isolated Outputs
Digital outputs OUT1 through OUT4 are isolated, each having their own positive and negative terminal. Each isolated output acts as a solid state relay allowing current to flow through the contacts only when it is activated. The isolated outputs are able to switch up to 40 VDC at 1 A continuous current draw. Isolated output terminals are made available on the P7 terminal block.
Non-Isolated Outputs
Digital outputs OUT5 and OUT6 are non-isolated, they rely on the main TS-8820 ground and only have a single contact. Each non-isolated output is a low side switch capable of sinking current when activated. The non-isolated outputs are capable of sinking 1 A continuous current with 40 V input voltage. Non-isolated input terminals appear on the P2 terminal block.
PWM
The TS-8820 has 6 PWM outputs. PWM channels 1 to 6 feed digital outputs 1 to 6 respectively when the PWM override bit is set for a given output.
For all 8 PWM channels, the PWM frequency is approximately (12207/(2^prescaler)) Hz, where the prescaler value is 3 bits wide. That is, a prescaler value of 0 through 7. The PWM duty cycle has 12 bits of resolution. If bit 12 of a PWM register is set, then the PWM output for that channel will be 100% high. Otherwise, the duty cycle setting is divided by 4096 to give the effective duty cycle.
When using ts8820ctl
, the duty can be passed on a scale from 0-1000 which directly corresponds to 0-100%.
To give OUT5 a ~3 kHz 50% duty cycle PWM output using ts8820ctl
, the following arguments would be used:
# --prescaler= sets the PWM frequency via a prescaler value to (12207/(2^VALUE))Hz.
# --duty= sets the PWM duty cycle percentage from a decimal scale of 0-1000
# --pwm= PWM channel to enable and modify (1-6)
ts8820ctl --pwm=5 --duty=500 --prescaler=2
eMMC
The i.MX6UL SD card controller supports the eMMC specification, the TS-4100 includes a soldered down eMMC IC to provide on-board flash media.
Our default software image contains 3 partitions:
Device | Contents |
---|---|
/dev/mmcblk1 | eMMC block device |
/dev/mmcblk1boot0 | eMMC boot partition |
/dev/mmcblk1boot1 | eMMC boot partition |
/dev/mmcblk1p1 | Full Debian linux partition |
This platform includes an eMMC device, a soldered down MMC flash device. Our off the shelf builds are 4 GB, but up to 64 GB are available for customized builds. The eMMC flash appears to Linux as an MMC card at /dev/mmcblk1
. Our default programming of the eMMC is the same as the SD card image for standard partitions, but includes additional boot partitions that are used by U-Boot and are not affected by the eMMC partition table.
The eMMC module has a similar concern by default to SD cards in that they should not be powered down during a write/erase cycle. However, this eMMC module includes support for setting a fuse for a "Write Reliability" mode, and a "pseudo-SLC (pSLC)" mode. With both of these enabled all writes will be atomic to 512 B and each flash cell will be treated as a single layer rather than a multi-layer cell. If a sector is being written during a power loss, a block is guaranteed to have either the old or new data. Even in cases where the wrong data is present on the next boot, fsck is often able to deal with the older data being present in a 512 B block. The downsides to setting these modes are that it will reduce the overall write speed and halve the available space on the eMMC. Please note that even with these settings, embeddedTS strongly recommends designing the end application to eliminate any situations where a power-loss event can occur while any disk is mounted as read/write. The TS-SILO option for the TS-4100 can help to eliminate the dangerous situation.
The mmc-utils
package is used to enable these modes. The command is pre-installed on the latest image. Additionally we have created a script to safely enable the write reliability and pSLC modes. Since the U-Boot binary and environment reside on the eMMC, care must be taken to save the current state of the boot partitions, enable the modes, restore the boot partitions, and re-enable proper booting options. This script can be used in combination with the production mechanism scripting to complete these steps as part of an end application production process.
WARNING: | Enabling these modes causes all data on the disk to become invalid and must be rewritten. Do not attempt to run the mmc commands from the script individually, all steps in the script must occur as they are or the unit may be unable to boot. If there are any failures of the script, care must be taken to resolve any issues while the unit is still booted or it may fail to boot in the future.
|
WARNING: | The script is only compatible with Rev. B or newer PCBs. Running the script on any previous PCB revision WILL result in the unit being unable to boot! There is no safe way to enable these modes on previous PCB revisions. |
Note: | Enabling these modes is a one-way operation, it is not possible to undo them once they are made. Because of this, setting these eMMC modes will invalidate embeddedTS' return/replacement warranty on the unit. See the warranty section for more information on this. |
The emmc_reliability
script can be found in the TS-4100 utilities github repository.
The script must be run when boot from any media other than eMMC, such as SD, NFS, or USB. No partition of the eMMC disk can be mounted when these commands are run. Doing so may result in corruption or inability for the unit to boot. Once the pSLC mode is enabled, all data on the disk will become invalid. This means the partition table will need to be re-created, the filesystems formatted, and all filesystem contents re-written to disk. This is why we recommend using this script in conjunction with the production mechanism scripting. The emmc_reliability
script can be run first, then the rest of the production script can create and format the partitions as well as write data to disk.
The script requires a single argument, the device node of the eMMC disk, and will output verbosely to stderr. Any specific errors will also be printed out on stderr.
Example usage:
./emmc_reliability /dev/mmcblk1
Upon successful run, the script will return 0. Any errors will return a positive code. See the script for detailed error code information.
Ethernet
This platform includes two Ethernet devices using the dual in-CPU MACs and external PHYs. The MAC addresses are assigned from the Technologic System's OUI of 00:D0:69:xx:xx:xx, and the two MAC addresses assigned will always be sequential. These MAC addresses are burned into the CPU's fuses during production.
U-Boot supports only the ethernet port on CN1_01-11 (odd numbered pins); once booted to Linux, this is eth1
. The CN2_16-24 (even numbered pins) provide eth0
in Linux.
The TS-8820 brings out a single 10/100 Ethernet port. This is recognized as eth1
in Linux. Due to the way that the Ethernet PHYs are set up, both devices will always be present on the TS-4100, even though only one is available on the TS-8820-4100.
FEC PTP Support
The i.MX6UL CPU Ethernet supports 1588 PTP (PTPv1 & PTPv2).
PTP is supported in Linux via the linuxptp project. This allows synchronizing the system clock to within ±1 us.
Note that Linux kernel version 4.9 or greater is required for PTP support with the i.MX6UL CPU. An example of setting up an ethernet interface with PTP and adjusting the clock based on that is below.
apt-get install linuxptp -y
# For PTP on eth0
phc2sys -s /dev/ptp0 -w &
ptp4l -2 -H -i eth0 -m -p /dev/ptp0 &
# For PTP on eth1
phc2sys -s /dev/ptp1 -w &
ptp4l -2 -H -i eth1 -m -p /dev/ptp1 &
If the clocks are significantly off this may take time for the clocks to converge.
FPGA
FPGA Registers
The TS-4100 FPGA provides additional DIO (that are connected to a Crossbar MUX), some miscellaneous system peripherals, and the 32-bit ZPU microcontroller. The FPGA is a Lattice MachXO2.
See the GPIO section for information on accessing the FPGA DIO.
The FPGA registers are accessed via an I2C bus. The FPGA emulates an I2C EEPROM, allowing for a simple and standard communication protocol to the FPGA. The FPGA is available at I2C addresses 0x28-0x2F. Accessing individual registers requires a chip address write, a 16-bit register address write, then 8-bit data values. A read or write stream can occur; every every byte read or written the internal register pointer moves to the next sequential register. This allows for reading or writing multiple registers without having to re-issue the chip and register address sequence.
We provide a simple access mechanism to the FPGA using the tshwctl
utility. This utility can read or write arbitrary registers, return some information about the FPGA, as well as configure the Crossbar MUX. Sources for tshwctl
and other utilities specific to the TS-4100 can be found in the TS-4100 utilities github repository.
The register map is broken in to a few different sections:
Section | Address | Bits | Description |
---|---|---|---|
GPIOn | 0x0000-0x007F | 7:3 | Reserved (Write 0) |
2 | GPIOn Input Data | ||
1 | GPIOn Output Data | ||
0 | GPIOn Output Enable | ||
CROSSBARn | 0x0080-0x00FF | 7 | CROSSBARn GPIO mode |
6:0 | CROSSBARn Value | ||
BANKn | 0x0100-0x010F | 7:0 | GPIOn Bank Input |
0x0110-0x011F | 7:0 | GPIOn Bank Output Data | |
0x0120-0x012F | 7:0 | GPIOn Bank Output Enable | |
Misc | 0x0130 | 7:0 | Model Number MSB (0x41) |
0x0131 | 7:0 | Model Number LSB (0x00) | |
0x0132 | 7:0 | FPGA Rev | |
0x0133-0x1FFF | 7:0 | Reserved | |
ZPU | 0x1FFF-0x2FFF | 7:0 | ZPU RAM access |
GPIOn
Registers 0x00-0x7F provide DIO control. The GPIO can be manipulated via the sysfs GPIO interface, information on this can be found in the GPIO section which is the recommended way to manipulate these pins. Each register in this section manipulates a different DIO pin. See the "FPGA I/O" table below for the register offset for this section. For example, to set "DIO_1" to a low output, the value 0x1 would be written to FPGA register 0x26 (the I/O number of "DIO_1").
Note: | The sysfs GPIO interface is recommended because it guarantees a clean state transition. When setting a GPIOn register, modifying multiple bits simultaneously creates a race condition between the output and output enable bits. This may result in a short glitch on the pin as it transitions. The sysfs GPIO driver will only manipulate a single bit at a time resulting in a clean and guaranteed transition. |
CROSSBARn
Registers 0x80-0xFF provide control for the Crossbar MUX. Like GPIOn above, each register represents a single DIO pin which are listed in the "FPGA I/O" table below. In order to change the MUX setting of any individual pin, its corresponding register is written to. For example, to set "UARTA_TXD" to output the data from "UART2_TXD", write the value of 0x5 (the I/O number of "UART2_TXD") to register (0x80+0x21) = 0xA1 (the I/O number of "UARTA_TXD" plus the CROSSBARn section starting register). The 'tshwctl' utility provides an easy abstraction for this process. See the Crossbar MUX section for more information on this process as well as a breakdown of Crossbar assignments.
BANKn
Registers 0x100-0x12F provide banked DIO access. The banked DIO allows for manipulating multiple pins simultaneously. Each bank register has 8 bits that represent 8 DIO pins. There are 48 bank registers total, 16 for GPIO input, 16 for GPIO output, and 16 for GPIO output enable. The bank and bit position of any given DIO listed in the "FPGA I/O" table below can be calculated by dividing the I/O number by 8 to get the bank number and then taking the modulus of that same calculation to get the bit position. The BANKn registers are not intended for normal use and exist to allow the ZPU to readily manipulate GPIO pins.
Misc
Registers 0x130-0x132 provide the model number and FPGA software revision. Registers 0x133-0x1FFF are reserved.
ZPU
Registers 0x2000-0x3FFF are RAM intended for use by the ZPU. Normally unused unless the ZPU is loaded and run, these registers can be used for volatile storage if wanted.
I/O Number | Signal name | Direction |
---|---|---|
0x01 | SPARE_1 | I/O |
0x02 | SPARE_2 | I/O |
0x03 | SPARE_3 | I/O |
0x04 | SPARE_4 | I/O |
0x05 | UART2_TXD | Input |
0x06 | UART2_CTS# | Input |
0x07 | UART3_TXD | Input |
0x08 | UART6_TXD | Input |
0x09 | UART2_RXD | Output |
0x0A | UART2_RTS# | Output |
0x0B | UART3_RXD | Output |
0x0C | UART6_RXD | Output |
0x0D | WIFI_RXD | Input |
0x0E | WIFI_RTS | Input |
0x0F | WIFI_IRQ# | Input |
0x10 | WIFI_TXD | Output |
0x11 | WIFI_CTS | Output |
0x12 | ZPU_BREAK | Input |
0x13 | ZPU_RESET | Output |
0x14 | EN_WIFI_PWR | Output |
0x15 | WIFI_RESET# | Output |
0x16 | EN_USB_HOST_5V | Output |
0x17 | EN_LCD_3V3 | Output |
0x18 | ETH_PHY_RESET# | Output |
0x19 | OFF_BD_RESET# | Output |
0x1B | GREEN_LED# | Output |
0x1C | RED_LED# | Output |
0x1D | UARTA_RXD | I/O |
0x1E | UARTB_RXD | I/O |
0x1F | UARTC_RXD | I/O |
0x20 | UARTD_RXD | I/O |
0x21 | UARTA_TXD | I/O |
0x22 | UARTB_TXD | I/O |
0x23 | UARTC_TXD | I/O |
0x24 | UARTD_TXD | I/O |
0x25 | DIO_0 | I/O |
0x26 | DIO_1 | I/O |
0x27 | DIO_2 | I/O |
0x28 | DIO_3[1] | I/O |
0x29 | DIO_4 | I/O |
0x2A | DIO_5 | I/O |
0x2B | DIO_6 | I/O |
0x2C | DIO_7 | I/O |
0x2D | DIO_8 | I/O |
0x2E | DIO_9 | I/O |
0x31 | DIO_12 | I/O |
0x32 | DIO_13 | I/O |
0x33 | DIO_14 | I/O |
0x34 | DIO_15 | I/O |
0x35 | DIO_16 | I/O |
0x36 | DIO_17 | I/O |
0x37 | DIO_18 | I/O |
0x38 | DIO_19 | I/O |
0x39 | DIO_20 | I/O |
0x3A | DIO_21 | I/O |
0x3B | DIO_22 | I/O |
0x3C | DIO_23 | I/O |
0x3D | DIO_24 | I/O |
0x3E | DIO_25 | I/O |
0x3F | DIO_26 | I/O |
0x40 | DIO_27 | I/O |
0x41 | DIO_28 | I/O |
0x42 | DIO_29 | I/O |
0x43 | DIO_30 | I/O |
0x44 | DIO_31 | I/O |
0x45 | DIO_32 | I/O |
0x46 | DIO_33 | I/O |
0x47 | DIO_34 | I/O |
0x48 | DIO_35 | I/O |
0x49 | DIO_36 | I/O |
0x4A | DIO_37 | I/O |
0x4B | DIO_38 | I/O |
0x4C | DIO_39 | I/O |
0x4E | DIO_41 | I/O |
0x4F | DIO_42 | I/O |
0x50 | DIO_43 | I/O |
0x51 | DIO_44 | I/O |
0x52 | DIO_45 | I/O |
0x53 | DIO_46 | I/O |
DIO_3 Clock Override
DIO_3 has special modes that override the normal output and places a clock frequency on it. This is required for compatibility with certain TS-8XXX baseboards with MUXBUS functionality. See the ZPU section for more information on MUXBUS and TS-8XXX baseboards. The override consists of two registers, and only the Output Data bits in each register.
0x57:0x58 OD bit | DIO_3 output |
---|---|
b00 | DIO_3 |
b01 | 14.3 MHz clock |
b10 | 12.5 MHz clock |
b11 | 12.5 MHz clock |
- ↑ For compatibility with various TS-8XXX baseboards, this pin has a special mode that allows it to output a clock. See I/O register 0x57 and 0x58.
Crossbar
The TS-4100 implements a limited crossbar MUX. This allows functional reassignment of pins to serve other purposes. For example, it is possible to connect different UARTs to different locations which can be used to repurpose otherwise unused UART ports. Additionally it can be used to connect a passthrough from a CPU GPIO to a pin that is only otherwise available from the FPGA.
Due to space constraints of the FPGA, there is a limitation of how pins can be assigned. The "Crossbar Assignable" column of the FPGA I/O table below lists the type of input assignment a pin will accept. The table also lists the default assignment of every pin.
- All FPGA I/O pins listed in the table can have their input assigned as "GPIO". Note that even with an input assignment of "GPIO", some pins are still limited to being an input or output only GPIO. Pins assigned to an input of "GPIO" are controlled by the standard GPIO interface and numbered according to the FPGA GPIO table. Also note that if an invalid assignment is given to a pin, it will default back to the "GPIO" assignment.
- An input of "GPIO" means that the logical input to the switching block comes directly from its associated pin. For example, the "UART2_TXD" signal is set to "GPIO" as its input. This means that the input to this switchable signal comes from the pin, which is connected to the CPU UART2_TXD signal. The "WIFI_TXD" signal has its input set to "UART2_TXD", with the "WIFI_TXD" physical pin connecting directly to the UART input of the Wi-Fi/BT module. This full path connects the CPU UART output, to the FPGA pin, to the "UART2_TXD" switching block, to the "WIFI_TXD" output pin, to the UART RX on the Wi-Fi/BT module.
- No matter which FPGA I/O is assigned, the output signal must have its data direction set to out and the input signal must have its data direction set to in. Without these set properly the physical pins themselves will be unable to properly MUX signals.
- The FPGA I/O pins compatible with an "Any" input assignment can be assigned any other pin in the table as an input.
- The FPGA I/O pins compatible with "Input only" assignment can only be assigned "GPIO" as an input. They can, however, be used as inputs in to other pins that are able to accept it as an input. Attempting to set this pin to any other input assignment will result it in automatically reverting to "GPIO".
- The FPGA I/O pins compatible with "UART only" assignments can only be assigned I/O numbers 0x01 through 0x08 inclusive. Attempting to assign any other input will automatically set the pin to "GPIO".
I/O Number | Signal name | Crossbar Assignable | Default Input Assignment |
---|---|---|---|
0x01 | SPARE_1 | Any | GPIO |
0x02 | SPARE_2 | Any | GPIO[1] |
0x03 | SPARE_3 | Any | GPIO[2] |
0x04 | SPARE_4 | Any | WIFI_IRQ# |
0x05 | UART2_TXD | Input only | GPIO |
0x06 | UART2_CTS# | Input only | GPIO |
0x07 | UART3_TXD | Input only | GPIO |
0x08 | UART6_TXD | Input only | GPIO |
0x09 | UART2_RXD | Any | WIFI_RXD |
0x0A | UART2_RTS# | Any | WIFI_RTS# |
0x0B | UART3_RXD | Any | UARTA_RXD |
0x0C | UART6_RXD | Any | UARTB_RXD |
0x0D | WIFI_RXD | Input only | GPIO |
0x0E | WIFI_RTS# | Input only | GPIO |
0x0F | WIFI_IRQ# | Input only | GPIO |
0x10 | WIFI_TXD | UART only | UART2_TXD |
0x11 | WIFI_CTS# | UART only | UART2_CTS# |
0x12 | ZPU_BREAK | Input only | GPIO |
0x13 | ZPU_RESET | Input only | GPIO |
0x14 | EN_WIFI_PWR | Input only | SPARE_2 |
0x15 | WIFI_RESET# | Input only | SPARE_3 |
0x16 | EN_USB_HOST_5V | Input only | GPIO |
0x17 | EN_LCD_3V3 | Input only | GPIO |
0x18 | ETH_PHY_RESET# | Input only | GPIO |
0x19 | OFF_BD_RESET# | Input only | GPIO |
0x1B | GREEN_LED# | Input only | GPIO |
0x1C | RED_LED# | Input only | GPIO |
0x1D | UARTA_RXD | UART only | GPIO |
0x1E | UARTB_RXD | UART only | GPIO |
0x1F | UARTC_RXD | UART only | GPIO |
0x20 | UARTD_RXD | UART only | GPIO |
0x21 | UARTA_TXD | UART only | UART3_TXD |
0x22 | UARTB_TXD | UART only | UART6_TXD |
0x23 | UARTC_TXD | UART only | GPIO |
0x24 | UARTD_TXD | UART only | GPIO |
0x25 | DIO_0 | UART only | GPIO |
0x26 | DIO_1 | UART only | GPIO |
0x27 | DIO_2 | UART only | GPIO |
0x28 | DIO_3 | UART only | GPIO |
0x29 | DIO_4 | UART only | GPIO |
0x2A | DIO_5 | UART only | GPIO |
0x2B | DIO_6 | UART only | GPIO |
0x2C | DIO_7 | UART only | GPIO |
0x2D | DIO_8 | UART only | GPIO |
0x2E | DIO_9 | UART only | GPIO |
0x31 | DIO_12 | UART only | GPIO |
0x32 | DIO_13 | UART only | GPIO |
0x33 | DIO_14 | UART only | GPIO |
0x34 | DIO_15 | UART only | GPIO |
0x35 | DIO_16 | UART only | GPIO |
0x36 | DIO_17 | UART only | GPIO |
0x37 | DIO_18 | UART only | GPIO |
0x38 | DIO_19 | UART only | GPIO |
0x39 | DIO_20 | UART only | GPIO |
0x3A | DIO_21 | UART only | GPIO |
0x3B | DIO_22 | UART only | GPIO |
0x3C | DIO_23 | UART only | GPIO |
0x3D | DIO_24 | UART only | GPIO |
0x3E | DIO_25 | UART only | GPIO |
0x3F | DIO_26 | UART only | GPIO |
0x40 | DIO_27 | UART only | GPIO |
0x41 | DIO_28 | UART only | GPIO |
0x42 | DIO_29 | UART only | GPIO |
0x43 | DIO_30 | UART only | GPIO |
0x44 | DIO_31 | UART only | GPIO |
0x45 | DIO_32 | UART only | GPIO |
0x46 | DIO_33 | UART only | GPIO |
0x47 | DIO_34 | UART only | GPIO |
0x48 | DIO_35 | UART only | GPIO |
0x49 | DIO_36 | UART only | GPIO |
0x4A | DIO_37 | UART only | GPIO |
0x4B | DIO_38 | UART only | GPIO |
0x4C | DIO_39 | UART only | GPIO |
0x4E | DIO_41 | UART only | GPIO |
0x4F | DIO_42 | UART only | GPIO |
0x50 | DIO_43 | UART only | GPIO |
0x51 | DIO_44 | UART only | GPIO |
0x52 | DIO_45 | UART only | GPIO |
0x53 | DIO_46 | UART only | GPIO |
0x80 | GPIO[3] | N/A | N/A |
Modify Crossbar Assignments
All of the crossbar assignments are managed through the FPGA syscon registers, in the bank of registers labeled as "CROSSBARn". However, this can more easily be managed through the 'tshwctl' utility. The 'tshwctl' utility provides a pair of flags that make it quick to assign an input to an FPGA I/O. For example, normally UART 2 is set up to connect to the on-board Bluetooth module. However, if a model of TS-4100 does not have this module present, or it is not needed in a particular application, it can be assigned to another unused set of UART pins on the TS-SOCKET interface, like UARTC:
tshwctl --out 0x9 --in 0x1f # Set UART2_RXD's input assignment to be UARTC_RXD. The UART2_RXD signal in the FPGA is connected directly to UART2_RXD on the CPU.
tshwctl --out 0x23 --in 0x5 # Set UARTC_TXD's input assignment to be UART2_TXD. The UART2_TXD signal in the FPGA is connected directly to UART2_TXD on the CPU.
tshwctl --out 0x10 --in 0x80 # Set WIFI_TXD's input assignment to GPIO. This prevents UART2_TXD data from appearing on this pin when unwanted.
tshwctl --out 0x11 --in 0x80 # Set WIFI_CTS's input assignment to GPIO. This prevents UART2_RTS data from appearing on this pin when unwanted.
Note: | Using 'tshwctl' to set crossbar assignments also sets the the GPIO direction. The I/O number passed as --out is set to a low output, and the I/O number passed as --in is set to an input. |
The latest sources for 'tshwctl' and other utilities can be found in the TS-4100 utilities github repository.
FPGA: TS-8820
The TS-8820 is powered by a Lattice XP2 FPGA with 5000 LUTs. Many of the features of the TS-8820 are driven by logic in this FPGA.
The SoM communicates with the TS-8820 FPGA using the MUXBUS, a simple address/data bus defined by Technologic Systems. Application developers do not need to understand the hardware layers involved to read/write the TS-8820 register map. See the demo application source, ts8820ctl.c, for more information on the software interface for the TS-8820.
For applications that require custom logic or interfaces please contact us regarding FPGA customization.
FPGA Registers
The 'ts8820ctl' application is able to perform arbitrary reads or writes to any of the TS-8820 FPGA registers. The flags "--read", "--write", and "--address" (where address is the 8-bit address listed in the table below) are used to perform this action.
Most of the access to the I/O is abstracted by 'ts8820ctl' and "ts8820.c", but it is also possible to access them directly through MUXBUS registers if applicable.
Offset | Bits | Description |
---|---|---|
0x0 | 15:0 | Model ID: Reads 0x8820 |
0x2 | 15:11 | Reserved |
10 | Pull-up 5-8 enable | |
9 | Pull-up 3-4 enable | |
8 | Pull-up 1-2 enable | |
7 | H-bridge 2 enable (contacts go high-Z otherwise) | |
6 | H-bridge 1 enable (contacts go high-Z otherwise) | |
5 | H-bridge 2 direction | |
4 | H-bridge 1 direction | |
3:0 | FPGA Revision | |
0x4 | 15:14 | Reserved |
13:0 | Digital inputs 14:1 | |
0x6 | 15:10 | Reserved |
9:0 | SRAM Page register | |
0x8 | 15:12 | Reserved |
11:6 | Override Digital Outputs 6:1 with PWM | |
5:0 | Digital Output Values 6:1 | |
0xa | 15:0 | Reserved |
0xc | 15:0 | Reserved |
0xe | 15:0 | Reserved |
0x10 | 15:13 | PWM #1 Prescaler |
12:0 | PWM #1 Duty Cycle | |
0x12 | 15:13 | PWM #2 Prescalar |
12:0 | PWM #2 Duty Cycle | |
0x14 | 15:13 | PWM #3 Prescaler |
12:0 | PWM #3 Duty Cycle | |
0x16 | 15:13 | PWM #4 Prescaler |
12:0 | PWM #4 Duty Cycle | |
0x18 | 15:13 | PWM #5 Prescaler |
12:0 | PWM #5 Duty Cycle | |
0x1a | 15:13 | PWM #6 Prescaler |
12:0 | PWM #6 Duty Cycle | |
0x1c | 15:13 | PWM #7 Prescaler (H Bridge 1) |
12:0 | PWM #7 Duty Cycle (H Bridge 1) | |
0x1e | 15:13 | PWM #8 Prescaler (H Bridge 2) |
12:0 | PWM #8 Duty Cycle (H Bridge 2) | |
0x20 | 15:0 | Pulse Counter #1 (RO) |
0x22 | 15:0 | Pulse Counter #2 (RO) |
0x24 | 15:0 | Pulse Counter #3 (RO) |
0x26 | 15:0 | Pulse Counter #4 (RO) |
0x28 | 15:0 | Pulse Counter #5 (RO) |
0x2a | 15:0 | Pulse Counter #6 (RO) |
0x2c | 15:0 | Pulse Counter #7 (RO) |
0x2e | 15:0 | Pulse Counter #8 (RO) |
0x30 | 15:0 | Pulse Counter #9 (RO) |
0x32 | 15:0 | Pulse Counter #10 (RO) |
0x34 | 15:0 | Pulse Counter #11 (RO) |
0x36 | 15:0 | Pulse Counter #12 (RO) |
0x38 | 15:0 | Pulse Counter #13 (RO) |
0x3a | 15:0 | Pulse Counter #14 (RO) |
0x3c | 15:0 | Reserved |
0x3e | 15:0 | Reserved |
0x80 | 15:0 | ADC Core ID (reads 0xadc1) |
0x82 | 15:8 | ADC Channel Mask (0 = do not save channel data) |
7:6 | Highest number chip to use (0-3, if 01 then sample chip 0 and chip 1) | |
5 | 1 = Force standby | |
4 | 1 = Use standby between samples to save power | |
3 | 1 = Smart DMA IRQ mode | |
2 | 1 = Enable IRQ | |
1 | 1 = Collect samples, 0 = stop | |
0 | 1 = Reset ADC chips and all FIFOs | |
0x84 | 15 | 1 = There has been a FIFO overflow since last reset |
14:0 | Number of samples available to be read | |
0x86 | 15:0 | Sample Data (RO) |
0x88 | 15:0 | Sampling period LSB (RW) |
0x8a | 15:0 | Sampling period MSB (RW) |
0x8c | 15:0 | IRQ Threshold (RW) |
0x8e | 15:0 | Reserved |
0x90 | 15:0 | Reserved |
0x92 | 15:0 | Reserved |
0x94 | 15:0 | Reserved |
0x96 | 15:0 | Reserved |
0x98 | 15:0 | Reserved |
0x9a | 15:0 | Reserved |
0x9c | 15:0 | Reserved |
0x9e | 15:0 | Reserved |
0xa0 | 15:0 | DAC 1 Control Register |
0xa2 | 15:0 | DAC 2 Control Register |
0xa4 | 15:0 | DAC 3 Control Register |
0xa6 | 15:0 | DAC 4 Control Register |
GPIO
The i.MX6UL CPU and FPGA GPIO are exposed using a kernel character device. This interface provides a set of files and directories for interacting with GPIO which can be used from any language that interact with special files in linux using ioctl() or similar. For our platforms, we pre-install the "libgpiod" library and binaries. Documentation on these tools can be found here. This section only covers using these userspace tools and does not provide guidance on using the libgpiod library in end applications. Please see the libgpiod documentation for this purpose.
A user with suitable permissions to read and write /dev/gpiochip*
files can immediately interact with GPIO pins. For example, to read the push switch on the TS-8551-4100 which is connected to FPGA DIO_9:
gpioget 5 46
Multiple pins in the same chip can be read simultaneously by passing multiple pin numbers separated by spaces.
To write to a pin, the gpioset
command is used. For example, to set LCD_D02:
gpioset 2 7=0
Multiple pins in the same chip can be set simultaneously by passing multiple <pin>=<value>
pairs separated by spaces.
If a call to gpioset
or gpioget
fails with the message Device or resource busy
that means that specific GPIO is claimed by another device. The command cat /sys/kernel/debug/gpio
can be used to get a list of all of the system GPIO and what has claimed them.
The gpiomon
tool can be used to monitor pins for changes.
CPU GPIO Table
The GPIO table below is for all usable GPIO pins from the CPU of the TS-4100. The chip and pin numbers are listed for use with the GPIO control outlined above. Some pins can have additional functions outside of GPIO. Not every possible function is listed but we have tried to list the most useful functions. The default kernel assigned function is surrounded by parenthesis. See the CPU documentation for a full list of functions that can be assigned to GPIO pins. Note that changing any of the functions requires kernel device-tree modifications to reassign the CPU's IOMUX for any given pin.
Chip | Pin | Functions | Location |
---|---|---|---|
0 | 0 | (USB1 OTG ID) / GPIO | CN2_074 |
0 | 1 | (GPIO) / ADC input | CN2_012 |
0 | 8 | (PWM0) / ADC input / GPIO | CN1_057 |
0 | 9 | (PWM1) / ADC input / GPIO | CN2_091 |
0 | 10 | (Ethernet PHY power en.) / GPIO | CN2_046 |
0 | 11 | (I2S Master Clock) / GPIO | CN2_054 |
0 | 12 | (I2S TX Sync) / GPIO | CN2_038 |
0 | 13 | (I2S TX Bit Clock) / GPIO | CN2_036 |
0 | 14 | (I2S RX Data) / GPIO | CN2_042 |
0 | 15 | (I2S TX Data) / GPIO | CN2_040 |
0 | 16 | (Console UART TXD) / GPIO | CN2_093 / Microcontroller |
0 | 17 | (Console UART RXD) / GPIO | CN2_095 / Microcontroller |
0 | 18 | (GPIO) | FPGA Crossbar SPARE_1 |
0 | 19 | (GPIO) | FPGA Crossbar SPARE_2 |
0 | 20 | (UART1 TXD) / GPIO | CN2_082 |
0 | 21 | (UART1 RXD) / GPIO | CN2_084 |
0 | 22 | (CAN1 TX) / GPIO | CN1_071 |
0 | 23 | (CAN1 RX) / GPIO | CN1_069 |
0 | 24 | (UART2 TXD) / GPIO | FPGA Crossbar UART2_TXD |
0 | 25 | (UART2 RXD) / GPIO | FPGA Crossbar UART2_RXD |
0 | 26 | (UART2 CTS) / GPIO | FPGA Crossbar UART2_CTS |
0 | 27 | (UART2 RTS) / GPIO | FPGA Crossbar UART2_RTS |
0 | 28 | (UART3 TXD) / GPIO | FPGA Crossbar UART3_TXD |
0 | 29 | (UART3 RXD) / GPIO | FPGA Crossbar UART3_RXD |
0 | 30 | (UART4 TXD) / GPIO | CN2_090 |
0 | 31 | (UART4 RXD) / GPIO | CN2_092 |
2 | 0 | (GPIO) / LCD CLK | CN1_049 |
2 | 1 | (GPIO) / LCD DE | CN1_055 |
2 | 2 | (GPIO) / LCD HSYNC | CN1_051 |
2 | 3 | (GPIO) / LCD VSYNC | CN1_053 |
2 | 7 | (GPIO) / LCD D02 | CN1_028 |
2 | 8 | (GPIO) / LCD D03 | CN1_030 |
2 | 9 | (GPIO) / LCD D04 | CN1_032 |
2 | 10 | (GPIO) / LCD D05 | CN1_034 |
2 | 11 | (GPIO) / LCD D06 | CN1_038 |
2 | 12 | (GPIO) / LCD D07 | CN1_040 |
2 | 13 | (CAN0 TX) / GPIO | CN2_097 |
2 | 14 | (CAN0 RX) / GPIO | CN2_099 |
2 | 15 | (GPIO) / LCD D10 | CN1_023 |
2 | 16 | (GPIO) / LCD D11 | CN1_025 |
2 | 17 | (GPIO) / LCD D12 | CN1_027 |
2 | 18 | (GPIO) / LCD D13 | CN1_031 |
2 | 19 | (GPIO) / LCD D14 | CN1_033 |
2 | 20 | (GPIO) / LCD D15 | CN1_035 |
2 | 21 | (UART6 TXD) / GPIO | FPGA Crossbar UART6_TXD |
2 | 22 | (UART6 RXD) / GPIO | FPGA Crossbar UART6_RXD |
2 | 23 | (PWM4) / GPIO / LCD D18 | CN1_041 |
2 | 24 | (PWM5) / GPIO / LCD D19 | CN1_043 |
2 | 25 | (GPIO) / LCD D20 | CN1_045 |
2 | 26 | (GPIO) / LCD D21 | CN1_042 |
2 | 27 | (GPIO) / LCD D22 | CN1_044 |
2 | 28 | (GPIO) / LCD D23 | CN1_046 |
3 | 10 | (SPI2 Offboard CS#) / GPIO | CN2_065 / HD1_13 |
3 | 11 | (GPIO) | FPGA_RESET# |
3 | 12 | (SPI2 FPGA CS#) / GPIO | FPGA |
3 | 13 | (SPI2 CLK) / GPIO | CN2_071 / HD1_15 / FPGA |
3 | 14 | (SPI2 MOSI) / GPIO | CN2_067 / HD1_11 / FPGA |
3 | 15 | (SPI2 MISO) / GPIO | CN2_069 / HD1_9 / FPGA |
3 | 16 | (GPIO) | FPGA Crossbar SPARE_3 |
3 | 17 | (GPIO) / Camera MCLK | CN2_034 |
3 | 18 | (GPIO) / Camera PIXCLK | CN2_032 |
3 | 19 | (GPIO) / Camera VSYNC | CN2_072 |
3 | 20 | (GPIO) / Camera HSYNC | CN2_070 |
3 | 21 | (GPIO) / Camera D0 | CN2_052 |
3 | 22 | (GPIO) / Camera D1 | CN2_056 |
3 | 23 | (GPIO) / Camera D2 | CN2_058 |
3 | 24 | (GPIO) / Camera D3 | CN2_060 |
3 | 25 | (GPIO) / Camera D4 | CN2_062 |
3 | 26 | (GPIO) / Camera D5 | CN2_064 |
3 | 27 | (GPIO) / Camera D6 | CN2_066 |
3 | 28 | (GPIO) / Camera D7 | CN2_068 |
4 | 0 | POWER_FAIL[1] | N/A |
4 | 1 | ZPU IRQ | FPGA |
4 | 8 | (Wi-Fi IRQ) / GPIO | FPGA Crossbar SPARE_4 |
- ↑ Asserted when external power input falls below valid input range.
FPGA GPIO Table
The GPIO table below is for all usable GPIO pins from the FPGA of the TS-4100. The chip and pin numbers are listed for use with the GPIO control outlined above. The FPGA pins have an internal Crossbar MUX that can be used to re-assign pin functions. When the pin is set to have a crossbar input of "GPIO" then the FPGA GPIO can be controlled as standard GPIO. Note that some FPGA pins can only be inputs while others can only be outputs. See the FPGA register and crossbar sections for more information on this.
- ↑ GPIO pins are formatted in "<chip>_<pin>" notation.
H Bridge
Note: | Support for this feature requires the use of the TS-4100 ZPU to handle MUXBUS transactions to the TS-8820. See this section for setup information. |
The TS-8820 is able to support dual H Bridge drivers via an ST L6205 DMOS Dual Full Bridge driver. Through the TS-8820, each H Bridge can be independently controlled in all states of operation -- forward, reverse, coast (free-wheel), and brake -- with either a PWM signal or a constant drive voltage. PWM can be used to ramp up or down an attached load as well as to maintain it at a constant specified rate.
The H Bridge power source is from the main power supply. Please ensure that the input is able to supply enough power to the load in order to not disrupt the rest of the system operations.
The two H Bridges are exposed on the P6 terminal block, pins 1 through 4. The first output pair is marked "1A" and "1B," with the second pair being "2A" and "2B."
Below are some examples of controlling the H Bridges from the command line:
# Set H Bridge 1 to forward direction at 75% duty cycle
ts8820ctl --hbridge1 --fwd 750
# Set H Bridge 2 to reverse direction at 100% duty cycle
ts8820ctl --hbridge2 --rev 1000
# Brake H Bridge 1 (turns off PWM and grounds both sides of the H Bridge)
ts8820ctl --hbridge1 --brake
# Let H Bridge 2 coast to a stop, aka free-wheel
ts8820ctl --hbridge2 --coast
Additionally, the "--prescaler" flag can be passed to adjust the driving frequency:
# 381 Hz @ 50% duty cycle in the forward direction
ts8820ctl --hbridge1 --fwd 500 --prescaler 5
The prescaler value is 0-7, the output frequency can be calculated with (12207/(2^prescaler)). A lookup table has been provided below.
Prescaler | Freq. |
---|---|
0[1] | 12207 Hz |
1 | 6103 Hz |
2 | 3052 Hz |
3 | 1526 Hz |
4 | 763 Hz |
5 | 381 Hz |
6 | 191 Hz |
7 | 95 Hz |
- ↑ Default if prescaler is unspecified.
I2C
The i.MX6UL supports standard I2C at 100khz, or using fast mode for 400khz operation. The CPU has 2 I2C buses used on the TS-4100.
I2C 1 is internal to the TS-4100 and only connects to the on-board supervisory microcontroller.
Address | Device |
---|---|
0x4A | Supervisory Microcontroller |
The second I2C bus is brought out on CN2_28 (SCL) and CN2_30 (SDA). This bus is shared with the on-board FPGA and runs at 400 kHz by default.
Address | Device |
---|---|
0x28-0x2F | FPGA |
Note: | It is also possible to request the kernel to use arbitrary GPIO pins as an I2C interface. See an example here. |
The kernel makes the I2C busses available at /dev/i2c-#. The "i2c-tools" (i2cdetect, i2cget, i2cset) package can be used to interact with the bus. Or a specific application can be created.
Isolated CAN Port
The TS-8820 provides an isolated CAN port on the P10 terminal block. The CAN interface itself is from the SoM with the TS-8820 facilitating the isolated physical interface.
Optionally, a 124 ohm termination resistor can be electrically added by setting the Term. CAN jumper.
More information about controlling the CAN interface can be found in the CAN section.
Isolated RS-232
The TS-8820 provides a single isolated RS-232 port on the P10 terminal block. The UART interface itself is from the SoM with the TS-8820 facilitating the isolated RS-232 physical interface.
By default, this UART port is connected to the ttymxc1 device on the TS-4100.
Isolated RS-485
The TS-8820 provides a single isolated RS-485 port on the P10 terminal block. The UART interface itself is from the SoM with the TS-8820 facilitating the isolated RS-485 physical interface.
Optionally, a 124 ohm termination resistor can be electrically added by setting the Term. 485 jumper.
By default, this port is connected to the ttymxc3 on the TS-4100.
The TS-4100 uses an automatic TXEN for half-duplex RS-485 handled by a CPU GPIO pin. However in order for this to function, it is necessary to modify the TS-4100 FPGA crossbar mux to route this CPU GPIO pin to the TXEN pin on the TS-8820. The following command needs to be run each time the unit is powered on in order for RS-485 to properly function:
tshwctl --out 0x31 --in 0x1
This connects the CPU GPIO pin directly to the RS-485 TXEN pin on the TS-8820 via internal switches in the TS-4100 FPGA.
Jumpers
The TS-8820 has two sets of jumpers, one located near the System-on-Module (inside the enclosure), and another near the system power, red, and green LEDs. These jumpers control a number of aspects of the platform's behavior. The jumpers are labeled on the silkscreen rather than numbered:
Label | Description |
---|---|
Force SD Boot | When jumper is set, boot kernel and Debian from the SD card. Otherwise boot kernel and Debian from eMMC. |
U_Boot | When jumper is set, U-Boot attempts to boot from USB before dropping to a U-Boot shell. Otherwise boot straight to Debian. |
No Chrg | When jumper is set, disable charging of the TS-SILO Supercapacitors. Beneficial for early development and testing. |
Term. CAN | When jumper is set, adds a 124 ohm termination resistor across the isolated CAN H and L pins. |
Term. 485 | When jumper is set, adds a 124 ohm termination resistor across the isolated TS-485 + and - pins. |
LEDs
The LEDs available to the TS-4100 are dependent on the baseboard that is used. However, all of our compatible baseboards will at a minimum provide a green and a red LED that is used for status as well as can be controlled by end applications. Note that when used standalone, the TS-4100 does not provide controllable status LEDs.
The kernel provides access to control the LEDs using the sysfs interface:
# Set Red led on
echo 1 > /sys/class/leds/red-led/brightness
# Set Red led off
echo 0 > /sys/class/leds/red-led/brightness
# Set Green led on
echo 1 > /sys/class/leds/green-led/brightness
# Set Green led off
echo 0 > /sys/class/leds/green-led/brightness
The kernel provides various triggers that can be useful for debugging purposes. The trigger
file for a given LED is in its named sub-directory, e.g.
echo "heartbeat" > /sys/class/leds/red-led/trigger
Trigger value | LED toggles on |
---|---|
none | Default, no action, manually controlled by brightness file
|
rc-feedback | IR Reciever trigger [1] |
can0-tx | CAN0 transmit activity |
can0-rx | CAN0 receive activity |
can0-rxtx | CAN0 activity |
can1-tx | CAN1 transmit activity |
can1-rx | CAN1 receive activity |
can1-rxtx | CAN1 activity |
mmc0 | microSD activity |
mmc1 | eMMC activity |
timer | 2hz blink |
oneshot | Blinks after delay. [2] |
heartbeat | Similar to timer, but varies the period based on system load |
backlight | Toggles on FB_BLANK |
gpio | Toggle based on a specified gpio. [3] |
cpu0 | Blink on CPU core 0 activity |
default-on | Only turns on by default. Only useful for device tree. |
transient | Specify on/off with time to turn off. [4] |
- ↑ There is no IR directly on the TS-4100, this would be from a USB peripheral.
- ↑ See the Kernel documentation for more details on "oneshot" operation.
- ↑ When this trigger is set, a "gpio" file appears in the same directory which can be used to specify what GPIO to follow when it blinks
- ↑ See the Kernel documentation for more details on "transient" operation.
Reading the contents of the trigger
will list all compatible triggers as well as the current trigger set. The currently set trigger is indicated by surrounding brackets, e.g. none [timer] cpu ...
Status LED Behavior
The following applies to the stock TS-4100 bootup process, from U-Boot to fully booted. Note that when used standalone, the TS-4100 does not provide these status LEDs.
Green | Red | Meaning |
---|---|---|
Solid On | Off | System is booted and running. |
Off | Solid On | The TS-4100 is in U-Boot. If the LEDs remain in this state for longer than a few seconds, U-Boot may be unable to find a proper boot device, or booting of the kernel failed. The green LED will flash briefly at power-on. |
Off | Off | The device is not able to boot. Typically, either too low of an input voltage is provided or the unit has been otherwise damaged. If a stable voltage is being provided as per the power input specifications and the input power is able to meet the device's power consumption requirements, an RMA may be needed to have the unit diagnosed by our repair team. |
TS-4100 LED
The TS-4100 SoM has a single LED on the module itself. This is directly controlled by the supervisory microcontroller and is used to indicate its status.
At power-on of the microcontroller, when USB serial is connected or 5 VDC input to the module is valid, the green LED on the TS-4100 will flash once.
When the TS-SILO supercapacitors are charging, the green LED on the TS-4100 will be solidly lit. As the capacitors near their full charge value then LED will turn off. As the microcontroller tops up the charge to keep them at or as close to 100% as possible, this LED will turn on and off while charging is enabled and input power remains valid.
TS-8820 LEDs
The TS-8820 has 27 LEDs used to indicate the electrical status of the inputs and outputs on the device. LEDs are labelled as "LED#" on the PCB silkscreen.
The majority of the LEDs are not able to be directly controlled, they turn on or off as a reaction to the status of the I/O they are connected to. For example, when DIG_OUT1 is set, LED17 will turn on. The "System" LEDs are the exception to this and are controlled via the SoM LED interface.
LED | FUNCTION | --- | LED | FUNCTION |
---|---|---|---|---|
1 | System RED_LED | 2 | Doesn't exist. | |
3 | System Power | 4 | System GREEN_LED | |
5 | RELAY_1 | 6 | RELAY_2 | |
7 | RELAY_3 | 8 | RELAY_4 | |
9 | DIG_IN1 | 10 | DIG_IN2 | |
11 | DIG_IN3 | 12 | DIG_IN4 | |
13 | DIG_IN5 | 14 | DIG_IN6 | |
15 | DIG_IN7 | 16 | DIG_IN8 | |
17 | DIG_OUT1 | 18 | DIG_OUT2 | |
19 | DIG_OUT3 | 20 | DIG_OUT4 | |
21 | DIG_IN9 | 22 | DIG_IN10 | |
23 | DIG_IN11 | 24 | DIG_IN12 | |
25 | DIG_IN13 | 26 | DIG_IN14 | |
27 | DIG_OUT5 | 28 | DIG_OUT6 |
microSD Card Interface
The i.MX6UL SDHCI driver supports microSD (0-2 GB), microSDHC (2-32 GB), and microSDXC(32-2048 GB). The cards available on our website on average support up to 16MB/s read, and 22MB/s write using this interface. Sandisk Extreme cards with UHS support have shown 58MB/s Read and 59MB/s write. The Linux driver provides access to this socket at /dev/mmcblk0 as a standard Linux block device.
See the i.MX6UL reference manual for more information on this controller.
We have performed compatibility testing on the Sandisk microSD cards we provide, and we do not suggest switching brands/models without performing qualification testing. Though SD cards in theory will all follow the standard and just work, in practice cards vary significantly and can fail in subtle ways. We do not recommend ATP or Transcend microSD cards specifically due to known corruption issues that can occur after many GB of written data.
Our testing has shown that on average microSD cards will last between 6-12 TB of written data before showing a single bit of corruption. This is enough for most applications to write for years and not see any issues, but for more reliable consider the eMMC which is expected to last over 100 TB of writes. Higher end SD cards can also extend this, but industrial grade SD cards typically carry a cost much higher than the eMMC.
SD cards in general should not be powered down during a write/erase cycle, doing so will eventually lead to disk corruption. It is not always possible for 'fsck' to recover from the types of failures that will be seen with SD power loss. The system should be designed to avoid power loss to SD cards, or the eMMC module should be used for storage instead which can be configured to be resilient to power loss.
Relays
The TS-8820 provides 4 mechanical SPDT relays. Each relay has a common connection, a normally open (NO), and normally closed (NC) contact. All 4 sets of contacts are located on the P8 terminal block.
Each relay has contacts rated for 277 VAC / 30 VDC @ 5 A (NO contacts) and 3 A (NC contacts). The use of these relays in the TS-8820 are rated for 30 VAC / 30 VDC @ 5 A (NO) and 3 A (NC).
These 4 relays are manipulated by GPIO from the SoM, not the TS-8820 itself. The relays are controlled by the following GPIO pins:
Relay | GPIO Chip | GPIO Pin |
---|---|---|
1 | 5 | 45 |
2 | 5 | 44 |
3 | 5 | 43 |
4 | 5 | 41 |
See the GPIO section for information on how to manipulate the DIO pins for the relays.
RTC
On this platform, the NXP SNVS Low Power Realtime Clock (RTC) module inside of the i.MX6UL CPU is used at the hardware clock. This is presented as /dev/rtc0
from the Linux kernel and is accessed using the standard hwclock command. In order to keep time, there must be a constant 3.3 V provided on CN1_36 to keep the RTC active.
For proper operation of the RTC, a CR2450 coin cell must be set in the battery holder on the TS-8820. This will allow the TS-4100 SNVS RTC to maintain time when the system is powered off.
Supervisory Microcontroller
The TS-4100 includes an on-board supervisory microcontroller. It is an 8051 based device that has a number of operational responsibilities. It creates a USB serial UART for the debug UART, manages power-up and reset sequencing which includes deep sleep mode, manages charging the TS-SILO Supercapacitors, is the system WDT, and has a number of ADC inputs of various system voltages.
Information about the microcontroller as well as output from its internal ADCs can be retrieved with the command:
tsmicroctl -i
Since the microcontroller handles power-up and reset, it includes a low power "sleep" mode that removes power from the CPU and all peripherals for a predefined period of time. Note that as soon as the sleep command is issued, the microcontroller will more power from all peripherals. Care must be taken to ensure there is no damage to peripherals or datalosses occurring during this sudden power-off event. It is recommended to run this command as the last step after a proper Linux shutdown sequence.
Sleep mode can be entered with the command:
tsmicroctl --sleep <time in seconds>
After the internal timer expires, the microcontroller will run the power-up sequence and boot the whole system back up normally.
On platforms that support TS-SILO supercapacitor backup, tsmicroctl
can be used to control that charging from userspace. The microcontroller itself has been carefully tuned to charge the supercapacitors at a safe rate, these parameters are not adjustable. However charging can be enabled and disabled from the command line:
# Enable charging
tsmicroctl --tssiloon
# Disable charging
tsmicroctl --tssilooff
TS-SILO Supercapacitors
This device can optionally support our TS-SILO technology. This consists of a charge and feedback monitor in the supervisory microcontroller on the TS-4100, a dedicated charging circuit on the TS-4100, and a pair of 2.7 V, 25 F supercapacitors in series on a TS-4100 baseboard. This full application provides up to 60 seconds of back up power if external power is removed from the device. Additionally, a notification of power failure is asserted on a CPU GPIO pin when external power has fallen below a valid input level. Monitoring this signal can be used to initiate a proper reboot and ensure that all data is flushed from cache to disk, and all disks are unmounted properly.
Using a reboot is important as issuing a shutdown command will put the kernel in a halted state with no way to cycle it back on so long as the supercapacitors are providing backup power. A reboot will get the system back to the U-Boot shell which by default will monitor the Power Fail input and will only continue to boot to the operating system if input power is valid.
The supercapacitor charge and discharge are monitored by the microcontroller on the TS-4100. A charge cycle is initiated automatically at startup by U-Boot, and can be disabled via a jumper setting on the baseboard. Once a charge cycle is started, the microcontroller will fully charge the supercapacitors and keep them topped off until charging is explicitly disabled. U-Boot can also be configured to load the kernel and FDT, but delay starting them until the supercapacitors are at a specified charge level. This can allow for a guaranteed available amount of reserve power in the case of external power being disconnected once the kernel starts booting.
Manual enabling and disabling of charging can be handled in U-Boot or Linux userspace:
# Enable the supercapacitor charging cycle in U-Boot or Linux userspace
tsmicroctl -e
# Disable the supercapacitor charging cycle in U-Boot or Linux userspace
tsmicroctl -d
# Get current charge level information in U-Boot or Linux userspace
tsmicroctl -i
U-Boot Settings
When the No Charge
jumper is removed from the baseboard, U-Boot will automatically start charging the supercapacitors at startup. It is also possible to to configure U-Boot to delay booting Linux until the capacitors are at a certain charge level. This is automatically manged with the environment variable chrg_pct
. If the baseboard supports TS-SILO and the No Charge
jumper is not set, then U-Boot will begin charging, load the kernel and FDT, and then delay executing them until the supercapacitors are charged to a level equal to or greater than the value of chrg_pct
. Additionally, if the environment variable chrg_verb
is set to 1
, then U-Boot will print out the current charge level once every second. If the No Charge
jumper is set, then U-Boot will not enable charging automatically.
Note that once charging is started, the supercapacitors will continue to be charged and managed by the microcontroller. In other words, once chrg_pct
is reached and U-Boot boots the kernel, the supercapacitors will still continue to charge to 100% and remain topped off unless explicitly disabled.
Our monitor script, "/usr/local/bin/tssilomon", will issue a reboot if the external power is removed and the supercapacitor charge drops below a set threshold. This threshold can be tuned to lower values to allow the system to continue to operate during short power loss events where the system is briefly supported by the supercapacitors. When tuning this value, we strongly recommend testing in final application to ensure enough power is available for a complete shutdown cycle in the case of a longer power loss event.
Since a reboot is issued by the script if power is lost, when U-Boot starts up again it will wait for a valid power input before attempting to load any data from media to reduce power loss during media access. Once external power is restored, U-Boot will continue booting as it would normally. If the supercapacitors charge falls below the valid input threshold before power is restored, the TS-4100 microcontroller will cut power to the CPU and peripherals which will be resumed when external power is restored.
We recommend a chrg_pct
value of 60
. 60% is enough of a charge level in most applications to be able to boot up fully, have our background monitor script detect that external power has been removed, and shut down the system with about 10 seconds of remaining power to handle any potential variances. We strongly recommend testing in a final application to ensure a safe process. Note that the supercapacitors may be at 0% for a large period of time while charging. The 0% charge level is any charge level that is unable to sustain the device if power is removed at that point in time.
An example of this process:
# From the U-Boot shell
env set chrg_pct 60
env set chrg_verb 1
env save
# Now, boot unit without stopping at U-Boot prompt
U-Boot 2016.03-00372-g92371f4445 (Jul 16 2019 - 12:01:04 -0700)
CPU: Freescale i.MX6UL rev1.1 at 396 MHz
...
Booting from the SD card ...
...
Waiting until SuperCaps are charged to 60%
0%
...
55%
57%
59%
60%
...
Starting kernel ...
Note: | The maximum achievable charge of the supercapacitors is dependent on input voltage of the 5 VDC power input. It may not be possible for a specific application to see 100% supercapacitor charge. Setting chrg_pct to a value higher than is achievable will cause an infinite wait state.
|
Note: | When on Supercapacitor power (external power removed), the RS-232 serial console stops being functional due to a loss of input power to the RS-232 transceiver. The CPU is still executing during this time, despite the loss of serial console. |
UARTs
The FPGA includes a crossbar to select where UARTs are routed so these can be changed. Below are the default mappings.
Port Name | Device | TX | RX | TXEN |
---|---|---|---|---|
UART0 | ttymxc0 | CN2_93 | CN2_95 | N/A |
UART1 | ttymxc1 | CN2_82 | CN2_84 | N/A |
UART2 | ttymxc2 | Onboard Bluetooth RX | Onboard Bluetooth TX | N/A |
UART3 | ttymxc3 | CN2_78 | CN2_80 | N/A |
UART4 | ttymxc4 | CN2_90 | CN2_92 | N/A |
UART6 | ttymxc6 | CN2_86 | CN2_88 | N/A |
TS-8820 Mappings
The host UARTs are mapped to the following ports on the TS-8820:
UART | Type | TX/+ | RX/- |
---|---|---|---|
ttymxc0 | RS-232 | DB9, pin 3 | DB9, pin 2 |
ttymxc1 | RS-232 | P10, pin 7 | P10, pin 8 |
ttymxc2 | TTL | NA | NA |
ttymxc3 | RS-485 | P10, pin 5 | P10, pin 6 |
ttymxc6 | RS-232 | DB9, pin 7 | DB9, pin 8 |
NC[1] | RS-485 | DB9, pin 1 | DB9, pin 6 |
- ↑ This port is normally not connected to any CPU UARTs due to the pinout. It is possible with the Crossbar MUX to re-assign UART3 to this physical port. Additionally, SPARE_1 must be assigned as a Crossbar input to DIO_14 as DIO_14 is connected to this UART's TXEN pin.
USB
USB Host
The TS-4100 provides a standard USB 2.0 host supporting 480Mb/s. Typically this is interfaced with by using standard Linux drivers, but low level USB communication is possible using libusb.
The TS-8820 brings out two USB type A host ports on the side of the device.
Watchdog
The kernel provides an interface to the watchdog driver at /dev/watchdog. Refer to the kernel documentation for more information:
WIFI
This board uses an ATWILC3000-MR110CA IEEE 802.11 b/g/n Link Controller Module With Integrated Bluetooth® 4.0. Linux provides support for this module using the wilc3000 driver.
Summary features:
- IEEE 802.11 b/g/n RF/PHY/MAC SOC
- IEEE 802.11 b/g/n (1x1) for up to 72 Mbps PHY rate
- Single spatial stream in 2.4GHz ISM band
- Integrated PA and T/R Switch Integrated Chip Antenna
- Superior Sensitivity and Range via advanced PHY signal processing
- Advanced Equalization and Channel Estimation
- Advanced Carrier and Timing Synchronization
- Wi-Fi Direct and Soft-AP support
- Supports IEEE 802.11 WEP, WPA, and WPA2 Security
- Supports China WAPI security
- Operating temperature range of -40°C to +85°C
ZPU
The on-board FPGA contains a ZPU core.
The ZPU is a 32-bit stack based CPU with a full gcc compiler available for it. Our specific implementation gives it a single length of contiguous FPGA BlockRAM for code and data storage. The ZPU can be used to offload processing tasks, perform real-time operations, or facilitate communication between the ZPU and external peripherals. The ZPU is controlled completely from userspace using the tszpuctl
utility. This utility can load binaries, compile and load from source code, control reset of the ZPU, dump the entire memory space, or connect stdin and stdout from the terminal to the ZPU.
The ZPU has a total of 8192 bytes of RAM for shared code, data, and stack space. After exiting from reset, it begins execution from the lowest address with the stack starting from the highest address of RAM. The entire RAM address space is accessible through the FPGA interface. This is how applications are loaded in to the ZPU. It is also used for the communication FIFO and can be used as a way to quickly extract the entire contents of the ZPU for debugging or other purposes.
ZPU FIFO
A RAM based communication channel can be created to facilitate data transmission between the running ZPU and the main CPU. This channel is agnostic of the connection between the FPGA and the CPU. So long as the CPU can read and write any arbitrary address in the ZPU memory space, this channel is available. It is a bidirectional communication channel for arbitrary data between the ZPU and CPU.
The FIFO is implemented in software. There is an API for code running on the ZPU as well as a separate API for userspace software running on the CPU.
The ZPU reserves 256 bytes for TX and 16 bytes for RX at runtime in a structure. The base of this structure is placed at a known memory location. The CPU can then read from this memory location which contains the size of each FIFO, the head and tail of each FIFO, and other options for the FIFO.
When the ZPU needs to send data to the CPU it writes the bytes to the next free TXFIFO entries, updates the TXFIFO head pointer, and then raises the IRQ to the CPU. In order to assert an IRQ, the ZPU writes an address to the IRQ register. The IRQ remains asserted until the CPU reads from the address written to the IRQ register, or the ZPU is reset. For this reason, the FIFO implementation writes the address of the current TXFIFO head to the IRQ register. Once the CPU reads from the head address, the IRQ will deassert. The CPU sees the interrupt, reads from the current tail through the head of the TXFIFO, and then updates the new tail address when completed. There is an option for "flow control" which will prevent the ZPU from writing additional data to the TXFIFO if it is full.
When the CPU needs to send data to the ZPU, it writes data directly in to the ZPU RXFIFO and then changes the head. The ZPU is required to poll for changes in the head position in its RXFIFO. Once it sees a difference, it reads a byte from the RXFIFO and then changes the tail position.
ZPU Demo
We have included a demo ZPU application that simply shows how the ZPU can interact directly with FPGA I/O, as well as an example of the ZPU FIFO implementation. The ZPU can be loaded and started with one command, and the FIFO can be connected to with another:
tszpuctl --load /usr/local/bin/zpu/zpu_demo.bin
tszpuctl --connect
The tszpuctl --connect
connects the ZPU FIFO directly to the terminal's stdin and stdout. The zpu_demo.bin
application will toggle the red and green LEDs with every character typed, as well as echo every character back. When enter/return is pressed, the ZPU will display the number of timer ticks since the last character the ZPU received. The standard ctrl+c
escape sequence is used to exit from tszpuctl
.
Building ZPU Applications
We have binary compilers available for x86_64 for building on a Linux workstation and armhf for building on the TS-4100 directly. The toolchains are `gcc` based.
We also provide a number of simple source files to ease in development of ZPU applications. These include mechanisms for controlling MUXBUS (for example, with the TS-8820-4100 MUXBUS interface), creating a communication channel between the CPU and ZPU using a FIFO, simple string handling for plaintext communication over the FIFO, and static offsets for accessing various FPGA resources from ZPU execution context. All of these can be found in the zpu/
folder, alongside the demo application and the MUXBUS application for TS-8820-4100, in the TS-4100 utilities git repository.
We are happy to help with custom ZPU application development, please contact us with any questions on how your application may benefit from using the ZPU.
Source code for tzpuctl
as well as our ZPU applications and APIs are available in the TS-4100 utilities repository.
Specifications
Power Specification
The TS-8820 accepts both DC input power as well as 802.3af POE input power.
Input | Min. Voltage | Max. Voltage |
---|---|---|
DC input power | 10 VDC | 30 VDC |
802.3af POE input power | N/A[1] | N/A[1] |
Power Consumption
TS-8820-4100 Consumption
Input (V) | Test | Avg. (W) | Peak (W) |
---|---|---|---|
24 VDC | CPU idle, Ethernet down | 2.545 W | 2.830 W |
24 VDC | CPU fully loaded [1], Ethernet down | 2.800 W | 2.975 W |
24 VDC | CPU idle, Ethernet port up and active [2] | 3.240 W | 3.335 W |
24 VDC | CPU fully loaded [1], Ethernet port up and active [2] | 3.410 W | 3.455 W |
PoE | CPU idle, Ethernet down | 2.950 W[3] | N/A[4] |
PoE | CPU fully loaded [1], Ethernet down | 3.200 W[3] | N/A[4] |
PoE | CPU idle, Ethernet port up and active [2] | 3.675 W[3] | N/A[4] |
PoE | CPU fully loaded [1], Ethernet port up and active [2] | 3.895 W[3] | N/A[4] |
- ↑ 1.0 1.1 1.2 1.3 This is accomplished by running
openssl speed
which generally consumes 100% CPU time - ↑ 2.0 2.1 2.2 2.3 Using
iperf
to create bidirectional activity which adds minor CPU load - ↑ 3.0 3.1 3.2 3.3 Power measured via PSE equipment with slow measurement update rate, average calculated from number of values recorded over a few minutes.
- ↑ 4.0 4.1 4.2 4.3 Power measured via PSE equipment which does not have min/avg/max reporting.
TS-4100 Consumption
The core of any TS-4100 application, either pared with a baseboard or standalone, is the TS-4100 itself. As a SoM, the TS-4100 contains the bulk of the voltage regulation, CPU, RAM, non-volatile storage, Ethernet PHYs, etc. This is where the bulk of the power is consumed in most applications.
The TS-4100's i.MX6UL CPU is very flexible with power. It can change the running frequency as needed to consume less power or to allow for more processing power.
The following tables list rough numbers measured on a TS-4100 for reference. These numbers were measured using a TS-8551-4100 which has a test point to measure power draw of the TS-4100 directly. Bear in mind that this will include some of the powered devices on the TS-8551 such as RTC, FRAM, RS-232 transceivers, etc., but is after any power input losses.
Please see Power Consumption Caveats for details on how to get these power numbers. Additionally, see Lowest Running Power for an example of the lowest power modes of the whole device.
Test | Avg. (W) | Peak (W) |
---|---|---|
CPU idle, Ethernet down | 0.665 W | 0.890 W |
CPU fully loaded [1], Ethernet down | 0.910 W | 1.030 W |
CPU idle, single Ethernet port up and active [2] | 1.315 W | 1.390 W |
CPU fully loaded [1], single Ethernet port up and active [2] | 1.500 W | 1.550 W |
Power Consumption Caveats
In order to achieve the numbers documented above, there are some operational caveats that must be noted.
- Due to the design of the Ethernet MAC/PHY of the i.MX6UL CPU and the software patterns of U-Boot and the Linux kernel, the PHYs are booted to Linux in a high power state. This occurs even though Linux leaves the interfaces unconfigured and down. This is because U-Boot brings up the MAC and PHY devices to configure them, but leaves them on. Lower power can be achieved by bringing the interfaces up and then back down if the interfaces are not in use; the kernel puts the PHYs in a low-power state when the interfaces are brought down. This does not apply if both Ethernet interfaces are used. This can be done with:
ifconfig eth0 up
ifconfig eth1 up
ifconfig eth0 down
ifconfig eth1 down
- The WILC WiFi device achieves the lowest power if either the kernel module (
wilc_spi
) is not loaded, or if thewlan0
interface is brought up but left unconfigured. If WiFi/BLE is not needed for an application, it is best to prevent thewilc_spi
module from being loaded. If only BLE is needed in an application, thewlan0
interface should be left down. If WiFi is used in an application, then the driver will automatically handle power levels during operation of the interface.
Lowest Running Power
The lowest power consumption is achieved by having the Ethernet interfaces in low power mode, the WiFi device module unloaded or wlan0
up but unconfigured (see Power Consumption Caveats above for notes on both of these), and the CPU speed locked to its lowest rate (see CPU Frequency Scaling). This can all be achieved with the following commands:
ifconfig eth0 up
ifconfig eth1 up
ifconfig eth0 down
ifconfig eth1 down
ifconfig wlan0 up
echo "userspace" > /sys/bus/cpu/devices/cpu0/cpufreq/scaling_governor
echo "198000" > /sys/bus/cpu/devices/cpu0/cpufreq/scaling_setspeed
Test | Min. (W) | Avg. (W) | Peak (W) |
---|---|---|---|
Network interfaces and CPU frequency as above | 0.640 W (with CPU idle) | 0.665 W (with CPU idle) | 0.815 W (with CPU fully loaded) |
I/O Specifications
Analog I/O
I/O | Typical Range | Absolute Range | Input Impedance |
---|---|---|---|
ADC (-5 V to +5 V) | -5 V to +5 V | -16.5 V to +16.5 V | 1 Mohm |
ADC (-10 V to +10 V) | -10 V to +10 V | -16.5 V to +16.5 V | 1 Mohm |
ADC (4-20 mA) | 4 mA to 20 mA | 0 mA to 23 mA | 220 ohm |
I/O | Voltage Ref. | Series Resistance |
---|---|---|
ADC (Thermistor) | 12.5 VDC @ 300 mA | 6040 ohms to +12.5 VDC |
I/O | Typical Range | Slew Rate | Drive Strength |
---|---|---|---|
DAC | 0 V to +10 V | 13 V/μs | 4 mA per output |
Digital I/O
Note: | All I/O specifications below are derated for high temperature environments. In applications with lower ambient temperatures, it may be possible to switch higher power loads. |
I/O | Typical Range | Absolute Range | Logic Low Max. Input | Logic High Min. Input | Drive Strength |
---|---|---|---|---|---|
Isolated Inputs | 0 V to +28 V | -0.5 V to +30 V | +1.33 VDC | +1.35 VDC | N/A |
Buffered Inputs | 0 V to +40 V | -0.5 V to +43 V | +2.5 VDC | +3.0 VDC | N/A |
Isolated Outputs | 0 V to +40 V | -0.5 V to +43 V | N/A | N/A | 0.5 W cont. 1 W max. each output |
Buffered Outputs | 0 V to +40 V | -0.5 V to +43 V | N/A | N/A | 1 W cont. 2 W max. each output |
I/O | Typical Range | Absolute Range | Logic Low Max. Input | Logic High Min. Input | Drive Strength |
---|---|---|---|---|---|
H Bridge | N/A[1] | N/A[1] | N/A | N/A | 2.8 A RMS each channel |
- ↑ 1.0 1.1 H Bridge power is sourced from the main power supply. Ensure the power supply is capable of handling the H Bridge load.
Power Output
The TS-8820 terminal block connectors do not directly provide power output of any kind. The exception to this is if using PoE power input then 24 VDC is provided to the P6 power input pins. Note that the max total power draw for PoE must not be exceeded if using this to power external devices.
See I/O Specifications for more information on the various high-power outputs.
Temperature Specifications
TS-8820-4100 Temperature Specifications
See TS-4100 temperature specifications below for more details about the i.MX6UL CPU.
The TS-8820-4100 is robust enough to remain passively cooled even while in high-temperature environments. The all metal enclosure protects the TS-4100 from the environment but still allows heat transfer from the TS-4100. Below, find a graph of a 24 hour temperature test.
Test parameters:
- TS-8820 Rev C PCB, TS-4100 SRW9I Rev C PCB
- TS-8820-4100 fully contained in enclosure, end caps applied, with vinyl sticker on top
- TS-8820-4100 inside temperature controlled chamber, ambient set to 60 °C
- Input power is 24 VDC
- 1 W load added to buffered outputs, 0.5 W load added to isolated outputs
- All 4 relay coils engaged
- Single thread alternating between full CPU load and idle CPU load for 1 hour each
- Separate single thread running
memtester
application continuously - TS-8820 ADCs sampled at max continuous rate
After roughly 24 hours of testing in the 60 °C environment, we found that the junction temperature stays near 100 °C under load (103 °C peak), dropping down to around 97 °C during periods of idle. This correlates with data from NXP indicating that there is minimal difference between junction temperatures at idle compared to full load. At this temperature, the CPU is rated between ~50 k hours and >140 k hours depending on CPU speeds (lower speeds are better).
TS-4100 Temperature Specifications
The TS-4100 uses the automotive grade i.MX6UL CPU across all part numbers ensuring consistent behavior across the TS-4100 line. The TS-4100 is designed using industrial components that will support -40 °C to +85 °C operation, however the CPU is rated to a max silicon junction temperature rather than an ambient temperature.
Model | Junction Temp. Min. | Junction Temp. Max. |
---|---|---|
TS-4100 (all models) | -40 °C | +125 °C |
The trip points for thermal throttling are exposed vis /sys/
# Passive
cat /sys/devices/virtual/thermal/thermal_zone0/trip_point_0_temp
# Critical
cat /sys/devices/virtual/thermal/thermal_zone0/trip_point_1_temp
The current CPU silicon temperature can be read with:
cat /sys/devices/virtual/thermal/thermal_zone0/temp
The thermal driver, by default, takes no action if the CPU junction temperature exceeds the passive trip point. However, if the CPU junction exceeds the critical temperature, then the system will halt before the junction temperature exceeds the absolute max specified by the CPU:
[ 1619.447637] thermal thermal_zone0: critical temperature reached(120 C),shutting down [ OK ] Stopped target Graphical Interface. [ OK ] Closed Load/Save RF Kill Switch Status /dev/rfkill Watch. [ OK ] Stopped target Multi-User System. Stopping TS-SILO SuperCap Monitor Daemon... Stopping OpenBSD Secure Shell server... [ OK ] Stopped target Login Prompts. Stopping Getty on tty1... Stopping Login Service... Stopping Serial Getty on ttymxc0... ...
External Interfaces
Terminal Blocks
|
|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
|
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
Ethernet Connector
The TS-8820 can connect to any 10/100 Ethernet LAN. The Ethernet connector includes LEDs indicating link and activity. The link LED will be illuminated when the TS-8820 is powered on and connected to a network. This connector also allows the TS-8820 to be powered by PoE.
USB Host
The USB is available on two ports as a USB 2.0 host.
|
DB9 Connector
|
Current Loop Jumpers
Situated in the middle of the terminal blocks are two 2x8 jumper headers that are numbered on the right side of the headers. Starting from 16 at the top, down to 1 at the bottom; setting a jumper on a particular number enables a 220 ohm, 0.5 % resistor that turns the respective ADC channel in to a current loop sensor. For example, setting a jumper on the pins marked as "15" will enable 4-20 mA current input measurement on ADC channel 15.
TS-SOCKET
Connection between the TS-4100 and TS-8820 is provided by our high-density TS-SOCKET interface standard. This standard specifies certain pin functions for both our SoM modules and baseboards to allow for as much cross-compatibility as possible.
The final TS-8820-4100 stack means that the end developer does not need to be concerned with the TS-SOCKET pinout. However, more information about the TS-4100 interface can be found in the TS-4100 manual.
Revisions and Changes
TS-8820 PCB Revisions
Revision | Changes |
---|---|
A |
|
B |
|
C |
|
D |
|
TS-4100 PCB Revisions
Revision | Changes |
---|---|
A |
|
B |
|
C |
|
TS-4100 U-Boot Changelog
Revision | Changes |
---|---|
July 2, 2019 | Initial pre-production release |
December 18, 2020 |
|
September 8th, 2021 |
|
November 5th, 2021 |
|
TS-4100 FPGA Changelog
Revision | Changes |
---|---|
0x0A | Initial pre-production release |
0x0B |
|
Software Images
Debian Changelog
Revision | Changes |
---|---|
ts4100-armhf-stretch-20190702.tar.xz | Initial pre-production release. |
ts4100-armhf-stretch-20191122.tar.xz |
|
ts4100-armhf-stretch-20210111.tar.xz |
|
ts4100-armhf-stretch-20210817.tar.xz |
|
ts4100-armhf-stretch-20211013.tar.xz |
|
ts4100-armhf-stretch-20240820.tar.xz |
|
ts4100-debian-bookworm-headless-20240904.tar.xz md5 |
|
Product Notes
FCC Advisory
This equipment generates, uses, and can radiate radio frequency energy and if not installed and used properly (that is, in strict accordance with the manufacturer's instructions), may cause interference to radio and television reception. It has been type tested and found to comply with the limits for a Class A digital device in accordance with the specifications in Part 15 of FCC Rules, which are designed to provide reasonable protection against such interference when operated in a commercial environment. Operation of this equipment in a residential area is likely to cause interference, in which case the owner will be required to correct the interference at his own expense.
If this equipment does cause interference, which can be determined by turning the unit on and off, the user is encouraged to try the following measures to correct the interference:
Reorient the receiving antenna. Relocate the unit with respect to the receiver. Plug the unit into a different outlet so that the unit and receiver are on different branch circuits. Ensure that mounting screws and connector attachment screws are tightly secured. Ensure that good quality, shielded, and grounded cables are used for all data communications. If necessary, the user should consult the dealer or an experienced radio/television technician for additional suggestions. The following booklets prepared by the Federal Communications Commission (FCC) may also prove helpful:
How to Identify and Resolve Radio-TV Interference Problems (Stock No. 004-000-000345-4) Interface Handbook (Stock No. 004-000-004505-7) These booklets may be purchased from the Superintendent of Documents, U.S. Government Printing Office, Washington, DC 20402.
Limited Warranty
See our Terms and Conditions for more details.
WARNING: | Writing ANY of the CPU's One-Time Programmable registers will immediately void ALL of our return policies and replacement warranties. This includes but is not limited to: the 45-day full money back evaluation period; any returns outside of the 45-day evaluation period; warranty returns within the 1 year warranty period that would require SBC replacement. Our 1 year limited warranty still applies, however it is at our discretion to decide if the SBC can be repaired, no warranty replacements will be provided if the OTP registers have been written. |