text:
|Product Page
|Product Images
|Mechanical Drawing
|FTP Path
|Freescale i.MX286
|454MHz ARMv5TE ARM926EJ-S
|CPU Datasheet
1 Overview
The TS-7670 Rev. A was released February 2014. This is a small embedded board with a Freescale i.MX286 454Mhz ARM9 CPU with 128-256MB DDR2.
2 Getting Started
A Linux PC is recommended for development, and will be assumed for this documentation. For users in Windows or OSX we recommend virtualizing a Linux PC. Most of our platforms run Debian and if there is no personal distribution preference this is what we recommend for ease of use.
Suggested Linux Distributions
It may be possible to develop using a Windows or OSX system, but this is not supported. Development will include accessing drives formatted for Linux and often Linux based tools.
2.1 Booting up the board
|Be sure to take appropriate Electrostatic Discharge (ESD) precautions. Disconnect the power source before moving, cabling, or performing any set up procedures. Inappropriate handling may cause damage to the board.
The TS-7670 has an input voltage range of 8v to 28v DC through the main power connector which offers screw terminals for secure wiring. The TS-7670 will require approximately 1.1W at idle. An ideal power supply for the TS-7670 will allow up to 5W to allow peripherals to be powered as well.
Once you have applied power you should look for console output. The first output is from the bootrom:
HTLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLC >> TS-BOOTROM - built Sep 4 2013 14:49:24 >> Copyright (c) 2013, Technologic Systems LLCLLLLLLLFLCLLJUncompressing Linux... done, booting the kernel. Booted in 3.89s Initramfs Web Interface: http://ts7670-4f3029.local #
The i.MX28 internal bootrom prints out the strings of letters to indicate various stages of its internal process. The TS-BOOTROM build date reflects when then imx-bootlets were built. When building a custom kernel from source this date will be changed and may not always reflect the kernel build date.
2.2 Get a Console
2.2.1 Option 1: Telnet
If your system is configured with zeroconf support (Avahi, Bonjour, etc) you can simply connect with:
telnet ts7670-<last 6 characters of the MAC address>.local # You will need to use your TS-7670 MAC address, but # for example if you mac is 00:d0:69:01:02:03 telnet ts7670-010203.local
When the board first powers up it has two network interfaces. The first interface eth0 is configured to use IPv4LL, and eth0 is configured to use DHCP. The board broadcasts using multicast DNS advertising the _telnet._tcp service. You can use this to query all of the available TS-7670s on the network.
From Linux you can use the avahi commands to query for all telnet devices with:
avahi-browse _telnet._tcp
Which would return:
+ eth0 IPv4 TS-7670 console [4f47a5] Telnet Remote Terminal local + eth0 IPv4 TS-7670 console [4f471a] Telnet Remote Terminal local
This will show you the mac address you can use to resolve the board. In this case you can connect to either ts7670-4f47a5.local or ts7670-4f471a.local
From Windows you can use Bonjour Print Services to get the dns-sd command. OSX also comes preinstalled with the same command. Once this is installed you can run:
dns-sd -B _telnet._tcp
Which will return:
Browsing for _telnet._tcp Timestamp A/R Flags if Domain Service Type Instance Name 10:27:57.078 Add 3 2 local. _telnet._tcp. TS-7670 console [4f47a5] 10:27:57.423 Add 3 2 local. _telnet._tcp. TS-7670 console [4f471a]
This will show you the mac address you can use to resolve the board. In this case you can connect to either ts7670-4f47a5.local or ts7670-4f471a.local
2.2.2 Option 2: Serial Console
The TS-7670 includes a USB device port, this uses an 8051 based microcontroller to create a serial device on a host PC. The serial console is provided through this port at 115200 baud, 8n1, with no flow control.
Console from Linux
There are many serial terminal applications for Linux, but 3 common implementations would be picocom, screen, and minicom. These examples assume that your COM device is /dev/ttyUSB0 (common for USB adapters), but replace them with the COM device on your workstation.
Linux has a few applications capable of connecting to the board over serial. You can use any of these clients that may be installed or available in your workstation's package manager:
Picocom is a very small and simple client.
picocom -b 115200 /dev/ttyUSB0
Screen is a terminal multiplexer which happens to have serial support.
screen /dev/ttyUSB0 115200
Or a very commonly used client is minicom which is quite powerful:
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.
2.3 Initramfs
When the board first boots up you should have a console such as:
HTLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFLC >> TS-BOOTROM - built Sep 4 2013 14:49:24 >> Copyright (c) 2013, Technologic Systems LLCLLLLLLLFLCLLJUncompressing Linux... done, booting the kernel. Booted in 3.89s Initramfs Web Interface: http://ts7600-4f3029.local #
|Your version dates may be different depending on ship date and the image used.
This is a minimalistic initial ram filesystem that includes our specific utilities for the board, and is then used to bootstrap the Linux root. The initramfs is built into the kernel image so it cannot be modified without rebuilding the kernel, but it does include 8 bits for common configuration option we call soft jumpers.
For most development you will want to boot to the Debian filesystem which can be reached by typing "exit" through the serial or telnet console, or by removing the file /ts/fastboot while in Debian to make the board automatically boot to Debian.
|Removing the "fastboot" file will cause the SBC to boot with a Debian default network configuration, skipping the automatic configuration done by the initramfs. Please see the network section and configure the SBC for your network before removing the "/ts/fastboot" file.
2.3.1 Scripting in the initramfs
220.127.116.11 From on-board media (SD/NAND/eMMC)
A bash script at /ts/init can be created in order to run any custom scripting needed from the initramfs. This does not use the same $PATH as Debian, so all commands should have the full path to any applications called from this environment. The init file does not exist by default and must be created in order to be utilized. The initramfs looks for this file to be at the full path "/mnt/root/ts/init". The initramfs will automatically mount the Debian partition of the booted media and attempt to execute this file if it exists. This process happens near the end of the initramfs initialization, but before Debian is started; it is run in the foreground. Standard output and error are to the serial/telnet console, standard input is /dev/null for the script.
An example of the script would look like the following.
#!/bin/sh /path/to/your/application &
126.96.36.199 From USB storage device (USB update mechanism)
For implementing a custom production process or applying updates in the field, this SBC is capable of detecting a USB device and running a script contained on it. The behavior of this process can be tuned, see the config information section below. The script must be named "tsinit", must be executable, and must be in the root directory of the first partition of the USB device. $PATH is passed to the tsinit script, it is what the initramfs environment $PATH is; if additional $PATHs are required they can be added in the tsinit script. It is recommended that the partition be formatted with ext2 or ext3. The process to execute this script happens near the end of the initramfs initialization, after the above /ts/init script, but before debian is started; it is run in the foreground. If a USB device exists, the first partition is mounted, and if the script file exists it is executed. The initramfs will by default mount the partition to "/mnt/usbdev/". Standard output and error are to the serial/telnet console, standard input is /dev/null.
An example of the script would look like the following.
#!/bin/sh /path/to/your/application &
2.3.2 /mnt/root/ts/initramfs-xinit
Graphical applications should use /ts/initramfs-xinit. The xinit file is used to start up a window manager and any applications. The default initramfs-xinit starts a webbrowser viewing localhost:
#!/bin/sh # Causes .Xauthority and other temp files to be written to /root/ rather than default / export HOME=/root/ # Disables icewm toolbars export ICEWM_PRIVCFG=/mnt/root/root/.icewm/ # minimalistic window manager icewm-lite & # this loop verifies the window manager has successfully started while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK do sleep 0.1 done # This launches the fullscreen browser. If the xinit script ever closes, x11 will close. This is why the last # command is the target application which is started with "exec" so it will replace the xinit process id. exec /usr/bin/fullscreen-webkit http://localhost
2.3.3 /mnt/root/ts/config
This config file can be used to alter many details of the initramfs boot procedure.
## This file is included by the early init system to set various bootup settings. ## if $jp7 is enabled none of these settings will be used. ## Used to control whether the FPGA is reloaded through software. ## 1 to enable reloading (default) ## 0 to disable reloading #CFG_FPGARELOAD="0" ## By default dns-sd is started which advertises the ts<model>-<last 6 of mac> ## telnet and http services using zeroconf. ## 1 to enable dns-sd (default) ## 0 to disable dns-sd #CFG_DNSSD_EN="0" ## This is used to discover hosts and advertise this host over multicast DNS. ## 1 to enable mdns (default) ## 0 to disable mdns #CFG_MDNS_EN="0" ## ifplugd is started in the initramfs to start udhcpc, and receive an ipv4ll ## address. ## 1 to enable ifplugd (default) ## 0 to disable ifplugd #CFG_IFPLUGD_EN="0" ## By default telnet is started on port 2323. ## 1 to enable telnet (default) ## 0 to disable telnet #CFG_TELNET_EN="0" ## The busybox webserver is used to display a diagnostic web interface that can ## be used for development tasks such as rewriting the SD or uploading new ## software ## 1 to enable (default) ## 0 to disable #CFG_HTTPD_EN="0" ## This eanbles a reset switch on DIO 29 (TS-7700), or DIO 9 on all of the ## boards. Pull low to reset the board immediately. ## 1 to enable the reset sw (default) ## 0 to disable #CFG_RESETSW_EN="0" ## The main debug console in the initramfs can be turned off. Since the console ## has no password protection, disabling it will prevent any access to it if ## the /ts/fastboot file is present, or is JP1 is on. ## 1 to enable the debug serial console (default) ## 0 to disable the debug serial console #CFG_CONSOLE_EN="0" ## The console is forwarded through xuartctl which makes the cpu console available ## over telnet or serial console. ## 1 to enable network console (default) ## 0 to disable network console #CFG_NETCONS_EN="0" ## By default Alsa will put the SGTL5000 chip into standby after 5 seconds of ## inactivity. This is desirable in that it results in lower power consumption, ## but it can result in an audible popping noise. This setting prevents ## standby so the pop is never heard. ## 1 to disable standby ## 0 to enable standby (default) #CFG_SGTLNOSTBY="1" ## xuartctl is used to access the FPGA uarts. By default it is configured to ## be IRQ driven which is optimized for best latency, but at the cost of ## additional CPU time. You can reduce this by specifying a polling rate. ## The xuartctl process also binds to all network interfaces which can provide a ## simple network API to access serial ports remotely. You can restrict this to ## the local network with the bind option. ## Configure XUART polling 100hz ## Default is IRQ driven CFG_XUARGS="--irq=100hz" ## Configure xuartctl to bind on localhost ## Default binds on all interfaces #CFG_XUARGS="--bind 127.0.0.1 --irq=100hz" ## For a full list of arguments, see the xuartctl documentation here: ## http://wiki.embeddedarm.com/wiki/Xuartctl#Usage ## By default the system will probe for up to 10s on USB for a mass storage device ## and mount the first partition. If there is an executable /tsinit script in the ## root this will be executed. This is intended for production or updates. ## 2 to enable USB init always (adds 10s or $CFG_USBTIME to startup) ## 1 to enable USB init when jp1=0 (default) ## 0 to disable USB init always #CFG_USBINIT="0" ## The USB init script by default blocks for 10s to detect a thumb drive that ## contains the tsinit script. Most flash media based drives can be detected ## in 3s or less. Some spinning media drives can take 10s, or potentially longer. ## This options is the number of seconds to wait before giving up on the ## mass storage device. #CFG_USBTIME="3" ### TS-8700 ## Using the TS-8700 baseboard the board will by default initialze all of the ## ethernet ports as individual vlan ports, eg eth0.1, eth0.2, eth0,3, and eth0.4 ## The alterantive option sets Port A to eth0.1, and Ports B-D to eth0.2, or ## you can configure all ethernet ports as a single eth0 port. ## See http://wiki.embeddedarm.com/wiki/TS-8700 for more information ## 2 disables any vlan and passes through all interfaces to eth0 ## 1 enables "WLAN" mode setting "A" as eth0.1, and all others as eth0.2 ## 0 enables "VLAN" mode for 4 individual ports (default) #CFG_4ETH="1" ###TS-7670/TS-7400_V2 ## DoubleStore as the root Debian filesystem is an option on the ## TS-7670/TS-7400_V2 that must be configured here. This is only possible if ## the TS-7670/TS-7400_V2 is first booted from NAND, SDBoot jumper removed. ## The TS-7670 can use a 1 or 2 card DoubleStore dataset, while the TS-7400_V2 ## can use only single card. If this option is enabled, and no DoubleStore ## cards are present, the initramfs will fall back to mounting NAND as the root ## filesystem. ## 1 to use DoubleStore as rootfs when booted from NAND (default) ## 0 to always disable DoubleStore as the rootfs #CFG_DBLSTOR_ROOT="0" ### TS-4712 / TS-4720 ## These boards include an onboard switch with 2 external ports. By default ## the switch will detect if it is on a known baseboard that supports the second ## ethernet switch port, and set up VLAN rules to define eth0.1 and eth0.2. The ## other option is to configure the switch to pass through the packets to eth0 ## regarless of port. ## 2 Disable VLAN and pass through to eth0 ## 1 Enable VLAN on all baseboards ## 0 Enable VLAN on supported baseboards (Default) #CFG_2ETH="1"
3 Debian Configuration
For development, it is recommended to work directly in Debian on the SD card. Debian provides many more packages and a much more familiar environment for users already versed in Debian. Through Debian it is possible to configure the network, use the 'apt-get' suite to manage packages, and perform other configuration tasks. Out of the box the Debian distribution does not have any default username/password set. The account "root" is set up with no password configured. It is possible to log in via the serial console without a password but many services such as ssh will require a password set or will not allow root login at all. It is advised to set a root password and create a user account when the unit is first booted.
It is also possible to cross compile applications. Using a Debian host system will allow for installing a cross compiler to build applications. The advantage of using a Debian host system comes from compiling against libraries. Debian cross platform support allows one to install the necessary development libraries on the host, building the application on the host, and simply installing the runtime libraries on the target device. The library versions will be the same and completely compatible with each other. See the respective Debian cross compiling section for more information.
3.1 Configuring the Network
From almost any Linux system you can use "ip" or the ifconfig/route commands to initially set up the network. To configure the network interface manually you can use the same set of commands in the initramfs or Debian.
# Bring up the CPU network interface ifconfig eth0 up # Or if you're on a baseboard with a second ethernet port, you can use that as: ifconfig eth1 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 your route. This is the server that provides your internet connection. route add default gw 192.168.0.1 # Edit /etc/resolv.conf for your 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:
Configure DHCP in Debian:
# To setup the default CPU ethernet port dhclient eth0 # Or if you're on a baseboard with a second ethernet port, you can use that as: dhclient eth1 # You can configure all ethernet ports for a dhcp response with dhclient
Configure DHCP in the initrd:
udhcpc -i eth0 # Or if you're on a baseboard with a second ethernet port, you can use that as: udhcpc -i eth1
To make your network settings take effect on startup in Debian, edit /etc/network/interfaces:
# Used by ifup(8) and ifdown(8). See the interfaces(5) manpage or # /usr/share/doc/ifupdown/examples for more information. # We always want the loopback interface. # auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 192.168.0.50 netmask 255.255.255.0 gateway 192.168.0.1 auto eth1 iface eth1 inet dhcp
|During Debian's startup it will assign the interfaces eth0 and eth1 to the detected mac addresses in /etc/udev/rules.d/70-persistent-net.rules. If the system is imaged while this file exists it will assign the new interfaces as eth1 and eth2. This file is generated automatically on startup, and should be removed before your first software image is created. The initrd network configuration does not use this file.
In this example eth0 is a static configuration and eth1 receives its configuration from the DHCP server. For more information on network configuration in Debian see their documentation here.
3.1.1 WIFI Client
This board optionally supports 802.11 through the WIFI-N-USB-2 module using the ath9k_htc driver.
Scan for a network
ifconfig wlan0 up # Scan for available networks iwlist wlan0 scan
In this case I'm connecting to "default" which is an open network:
Cell 03 - Address: c0:ff:ee:c0:ff:ee Mode:Managed ESSID:"default" Channel:2 Encryption key:off Bit Rates:9 Mb/s
To connect to this open network:
iwconfig wlan0 essid "default"
You can use the iwconfig command to determine if you have authenticated to an access point. Before connecting it will show something similar to this:
# iwconfig wlan0 wlan0 IEEE 802.11bgn ESSID:"default" Mode:Managed Frequency:2.417 GHz Access Point: c0:ff:ee:c0:ff:ee Bit Rate=1 Mb/s Tx-Power=20 dBm Retry long limit:7 RTS thr:off Fragment thr:off Encryption key:off Power Management:off Link Quality=70/70 Signal level=-34 dBm Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0 Tx excessive retries:0 Invalid misc:0 Missed beacon:0
If you are connecting using WEP, you will need to define a network key:
iwconfig wlan0 essid "default" key "yourpassword"
If you are connecting to WPA you will need to use wpa_passphrase and wpa_supplicant:
wpa_passphrase the_essid the_password > /etc/wpa_supplicant.conf
Now that you have the configuration file, you will need to start the wpa_supplicant daemon:
wpa_supplicant -Dwext -iwlan0 -c/etc/wpa_supplicant.conf -B
Now you are connected to the network, but this would be close to the equivalent of connecting a network cable. To connect to the internet or talk to your internal network you will need to configure the interface. See the #Configuring the Network for more information, but commonly you can just run:
dhclient wlan0
|Some older images did not include the "crda" and "iw" packages required to make a wireless connection. If you cannot get an ip address you may want to connect over ethernet and install these packages with "apt-get install crda iw -y".
3.1.2 Host a WIFI Access Point
The software image includes a build of compat-drivers from 3.8 so a large amount of wireless devices are supported. Some devices support AP/Master mode which can be used to host an access point. The WIFI-N-USB-2 module we provide also supports this mode.
First install hostapd to manage the access point:
apt-get update && apt-get install hostapd -y
Edit /etc/hostapd/hostapd.conf to include:
interface=wlan0 driver=nl80211 ssid=YourAPName channel=1
|Refer to the kernel's hostapd documentation for more wireless configuration options.
To start the access point launch hostapd:
hostapd /etc/hostapd/hostapd.conf &
This will create a valid wireless access point, however many devices will not be able to connect without either a static connection, or a DHCP server. Refer to Debian's documentation for more details on DHCP configuration.
3.1.3 Cellular Data Network
The TS-7670 includes support for the Multitech MTSMC-G2 or MTSMC-H5 which can connect to the internet using pppd. The UART can be set up as follows:
ln -s /dev/ttySP3 /dev/ttymultidc
The pppd application must be installed and any required modules loaded:
apt-get update && apt-get install -y ppp
This example is configured for T-Mobile in the US:
/dev/ttymultidc noauth 115200 debug usepeerdns persist defaultroute connect "/usr/sbin/chat -v -f /etc/ppp/chatscripts/tmobile" disconnect "/usr/sbin/chat -v -f /etc/ppp/chatscripts/tmobile-disconnect"
TIMEOUT 10 ABORT 'BUSY' ABORT 'NO ANSWER' ABORT 'ERROR' "" "\p\p\p\p\p\p\p\p\p\p\p\p+++\p\p\p\p\p\p\p\p\p\p\p\p" "" "ATH0" "OK" 'AT+CGDCONT=1,"IP","wap.voicestream.com"' ABORT 'NO CARRIER' OK 'ATD*99***1#' CONNECT
Using a different carrier you will likely only need to replace wap.voicestream.com with the access point for your carrier.
To start pppd:
pppd call tmobile # Or for more logging information: # pppd nodetach call tmobile
This will create a ppp0 interface that can now be used as a standard network interface, and should set up a default route to the internet. For other carriers, typically you will only need a different access point listed in the AT+CGDCONT call, but further adjustments may be necessary.
|We have observed that the MTSMC-H5 connected to some networks has issues at or below 115200 baud. The issues observed are connection timeouts with the network itself. The connection between the modem and host device remain rock solid. While many applications are tolerant to the connection being reset, we have found some network downloads will abort without being able to recover. Running the unit at a faster baud rate, 230400 or higher, has been observed to eliminate this issue entirely. This does mean, however, that every time the device is started up, the modem must be issued an AT+IPR command (as noted below) at 115200 baud, then pppd started with the matched and higher baud rate in the peer script as shown above.
Faster Data Rates
While the MTSMC-G2 (GPRS) is limited to 115200 baud, the MTSMC-H5 (HDSPA) can communicate over serial up to 921600 allowing actual transfer rates around 80-90KB/s.
To set a custom baudrate in Linux, the method depends on the CPU and kernel support. More recent UART peripherals have a higher clock and a smarter driver, and can therefore use custom baud rates inherently. However, some systems require the use of 'setserial' using the spd_cust flag and some manual settings. When the spd_cust baud rate is set, Linux will re-purpose 38400 baud to use the set custom baud rate.
First, test the unit to see if it is possible to open up the UART with a higher baud rate:
picocom -b 921600 /dev/ttymultidc
If the higher baud is unsupported, picocom will return a failure similar to the following:
FATAL: failed to add device /dev/ttymultidc: Invalid baud rate
If the above error is received, then the method below using setserial must be used.
Otherwise, the port can be closed, re-opened at 115200 baud to communicate with the modem, and then the following command can be used to tell the cell modem to enter a higher baud rate:
Now the port can be closed everything will function at the higher baud rate. Be sure to update the providers file. Using the example T-Mobile configuration, edit /etc/ppp/peers/tmobile and change 115200 to 38400. Starting pppd will now allow communication around 80-90KB/s (depending on your local cell tower's availability).
Larger divisors will also work, but this should cover the common range. Using the setserial command you can specify the divisor. For example, to reach 115200 with the alternative baud base:
setserial /dev/ttymultidc spd_cust baud_base 921600 divisor 8
Next you will need to tell the modem to communicate at the faster baud rates. You can use a client like picocom or minicom to connect directly to the modem to send it commands.
picocom -b 38400 /dev/ttymultidc
Even though we are talking at 115200, 38400 must be specified since we are using a custom baud_base. You can test communication with the modem again by typing "AT", pressing enter, and receiving "OK". To reconfigure the modem to the faster 921600 baud rate you can send it this command:
This will respond with OK, but now you will need to quit out of picocom (ctrl a,x) and reconfigure the baud base to use divisor 1:
setserial /dev/ttymultidc spd_cust baud_base 921600 divisor 1
The only change now needed is in your providers file. Using the example T-Mobile configuration , edit /etc/ppp/peers/tmobile and change 115200 to 38400. Starting pppd will now allow communication around 80-90KB/s (depending on your local cell tower's availability).
If you are not able to obtain a ppp connection there are a few values you can check:
Troubleshooting: Cell Signal
Make sure ppp is not running, and execute these commands to check the signal strength.
stty raw -echo speed 115200 -F /dev/ttymultidc cat /dev/ttymultidc & echo -e "AT+CSQ\r\n" > /dev/ttymultidc killall cat
The return value should be something like "+CSQ: 9,2", or with no connection, +CSQ: 99,99. The second argument is the signal strengh which follows this table:
|-113 dBm or less
|-111 dBm
|2 to 30
|-109 to -53dBm
|-51dBm or greater
|not known or detectable
If you return 99, make sure the antenna is connected and that you are in an area with good signal from your provider. Even without a valid SIM card you can have a good connection. If you are in another country, you may need to adjust the band for those supported by your carrier. The default value is appropriate for most US based carriers. Refer to the +WMBS command in your AT command guide for more options.
Troubleshooting: SIM card
If you have a good signal strength but are not obtaining a connection you can verify that the modem is able to read the subscriber number. This proves your SIM card is valid.
stty raw -echo speed 115200 -F /dev/ttymultidc cat /dev/ttymultidc & echo -e "AT+CNUM\r\n" > /dev/ttymultidc killall cat
With a valid SIM this will return something like:
If the SIM not detected you will only read ERROR. Make sure in this case that the card is inserted in the right direction so the pads on the card line up with the socket.
Troubleshooting: Other Options
If neither of the above steps get you connected you may want to contact your service provider for more information about where your connection attempts are failing.
3.2 Installing New Software
Debian provides the apt-get system which manages pre-built applications. Before packages can be installed, the list of package versions and locations needs to be updated. This assumes the device has a valid network connection to the internet.
Debian Wheezy has been moved to archive status, this requires an update of /etc/apt/sources.list to contain only the following lines:
deb http://archive.debian.org/debian wheezy main non-free deb-src http://archive.debian.org/debian wheezy main non-free
apt-get update
For example, lets say you wanted to install openjdk for Java support. You can use the apt-cache command to search the local cache of Debian's packages.
<user>@<hostname>:~# apt-cache search openjdk icedtea-6-jre-cacao - Alternative JVM for OpenJDK, using Cacao icedtea6-plugin - web browser plugin based on OpenJDK and IcedTea to execute Java applets openjdk-6-dbg - Java runtime based on OpenJDK (debugging symbols) openjdk-6-demo - Java runtime based on OpenJDK (demos and examples) openjdk-6-doc - OpenJDK Development Kit (JDK) documentation openjdk-6-jdk - OpenJDK Development Kit (JDK) openjdk-6-jre-headless - OpenJDK Java runtime, using Hotspot Zero (headless) openjdk-6-jre-lib - OpenJDK Java runtime (architecture independent libraries) openjdk-6-jre-zero - Alternative JVM for OpenJDK, using Zero/Shark openjdk-6-jre - OpenJDK Java runtime, using Hotspot Zero openjdk-6-source - OpenJDK Development Kit (JDK) source files openoffice.org - office productivity suite freemind - Java Program for creating and viewing Mindmaps default-jdk-doc - Standard Java or Java compatible Development Kit (documentation) default-jdk - Standard Java or Java compatible Development Kit default-jre-headless - Standard Java or Java compatible Runtime (headless) default-jre - Standard Java or Java compatible Runtime
In this case you will likely want openjdk-6-jre to provide a runtime environment, and possibly openjdk-6-jdk to provide a development environment. You can often find the names of packages from Debian's wiki or from just searching on google as well.
Once you have the package name you can use apt-get to install the package and any dependencies. This assumes you have a network connection to the internet.
apt-get install openjdk-6-jre # You can also chain packages to be installed apt-get install openjdk-6-jre nano vim mplayer
For more information on using apt-get refer to Debian's documentation here.
3.3 Setting up SSH
On our boards we include the Debian package for openssh-server, but we remove the automatically generated keys for security reasons. To regenerate these keys:
dpkg-reconfigure openssh-server
Make sure your board is configured properly on the network, and set a password for your remote user. SSH will not allow remote connections without a password or a shared key.
passwd root
You should now be able to connect from a remote Linux or OSX system using "ssh" or from Windows using a client such as putty.
Note: If your intended application does not have a DNS source on the target network, it can save login time to add "UseDNS no" in /etc/ssh/sshd_config.
3.4 Starting Automatically
From Debian the most straightforward way to add your application to startup is to create a startup script. This is an example simple startup script that will toggle the red led on during startup, and off during shutdown. In this case I'll name the file customstartup, but you can replace this with your application name as well.
Edit the file /etc/init.d/customstartup to contain this:
#! /bin/sh # /etc/init.d/customstartup case "$1" in start) /path/to/your/application ## 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 /path/to/your/shutdown/scripts ;; *) echo "Usage: customstartup start|stop" >&2 exit 3 ;; esac exit 0
|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.
To make this run during startup and shutdown:
update-rc.d customstartup defaults
To manually start and stop the script:
/etc/init.d/customstartup start /etc/init.d/customstartup stop
While this is useful for headless applications, if you are using X11 you should modify "/usr/bin/default-x-session":
#!/bin/sh export HOME=/root/ export ICEWM_PRIVCFG=/mnt/root/root/.icewm/ icewm-lite & while ! xprop -root | grep -q _NET_SUPPORTING_WM_CHECK do sleep 0.1 done exec /usr/bin/fullscreen-webkit http://127.0.0.1
Replace fullscreen-webkit with your own graphical application.
4 Backup / Restore
If you are using a Windows workstation there is no support for writing directly to block devices. However, as long as one of your booting methods still can boot a kernel and the initrd you can rewrite everything by using a usb drive. This is also a good way to blast many stock boards when moving your product into production. You can find more information about this method with an example script here.
|Note that the MBR installed by default on this board contains a 446 byte bootloader program that loads the initial power-on kernel and initrd from the first and second partitions. Replacing it with an MBR found on a PC would not work as a PC MBR contains an x86 code bootup program.
4.1 MicroSD Card
|Click to download the latest 4GB SD card image.
Using another Linux workstation
If you do not have an SD card that can boot to the initramfs, you can download the latest SD card image and rewrite this from a Linux workstation. A USB MicroSD adapter can be used to access the card. First, you must find out which /dev/ device corresponds with your USB reader/writer.
Step 1 Option 1 (lsblk)
Newer distributions include a utility called "lsblk" which allows simple identification of the intended card:
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. Note that on your system, sdX will not be a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card.
Step 1 Option 2 (dmesg)
After plugging in the device, you can use dmesg to list
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, sdXc is shown as a 3.97GB card. Note that on your system, sdX will not be a real device, it could be sda, sdb, mmcblk0, etc. Technologic Systems is not responsible for any damages cause by using the improper device node for imaging an SD card.
Step 2
Once you have the target /dev/ device you can use "dd" to backup/restore the card. To restore the board to stock, or rewrite to the latest SD image:
wget ftp://ftp.embeddedarm.com/ts-arm-sbc/ts-7670-linux/binaries/ts-images/ts7670_7400v2-latest.dd.bz2 # Specify your block device instead of /dev/sdX # Note that this is a whole disk image, so use /dev/sdX instead of # using /dev/sdX1 bzcat ts7670_7400v2-latest.dd.bz2 | dd conv=fsync bs=4M of=/dev/sdX
To take a backup of your entire SD card, you can switch the input file and the output file:
# Specify your block device instead of /dev/sdX dd if=/dev/sdX conv=fsync bs=4M | bzip2 > backup.dd.bz2
4.2 NAND Flash
|The TS-7670 only has NAND on PCB Rev. B and older. For TS-7670 Rev. C and newer, see the eMMC section. For PCB revision information, see the PCB Revisions section.
The NAND is divided in to three devices, mtd0, mtd1, and mtd2. mtd0 contains the raw bootstream (kernel and initramfs in one binary), mtd1 contains what would normally be the /ts folder on the SD card, and mtd2 contains the linux root filesystem (mtd1 and mtd2 use UBI and UBIFS and can be subdivided down further with mechanisms in UBIFS, see UBI and UBIFS for more information). Since UBI/UBIFS does have a fairly linear mount time for device size, mtd1 is made fairly small, 8MB. This allows for increased startup speed when booting from NAND so that configuration, FPGA softload, or other scripts may be run as soon as possible after power is applied.
4.2.1 Kernel
When the kernel is built and installed to the SD card from a host PC, the script also copies the newly built bootstream file to the linux partition, to /lib/modules/imx28_ivt_linux.sb. The bootstream is a Freescale boot mechanism that contains the bootloader and kernel all in one binary. When booted from an SD card, the bootstream at /lib/modules/imx28_ivt_linux.sb can be flashed to mtd0 with
This will take a few moments and then will return with no messages if everything was successful.
The following command can be used to update the kernel on NAND from the imx28_ivt_linux.sb file from USB:
The file is expected to be located at /mnt/usbdev/imx28_ivt_linux.sb, the command is intended for use with our USB update mechanism. The file can be copied from the Debian partition of a bootable SD card, /lib/modules/imx28_ivt_linux.sb; or directly from a kernel build, /<kernel_tree>/imx-bootlets-src-10.12.01/imx28_ivt_linux.sb.
See the section on our USB update mechanism for more information about utilizing this process.
4.2.2 Filesystem
Making a UBIFS Debian image from existing filesystem is the best way to make a custom image for production devices. Technologic Systems strongly recommends doing all development on an SD card; later, create a UBIFS image from that Debian filesystem. Copying the large amount of small files on the Debian filesystem directly to or from the NAND device is very time consuming.
In order to create a UBIFS image from a host PC mtd-utils will need to be installed, please see your distribution's documentation for instructions on installation
#/mnt/source_fs_root is the mounted Debian filesystem on an SD; /mnt/usb is a USB drive to store the image for later use mkfs.ubifs -m4096 -e516096 -c3861 -r /mnt/source_fs_root/ nandimg.ubifs
Note that the UBI rootfs partition on NAND is 1900MiB, Make sure that the UBIFS image is smaller than this. UBI does implement compression on-disk, so the total size of a folder tree may not reflect the actual filesystem size when made in to a UBIFS image. For example, our default SD Debian root filesystem is around 1.2GB, however when made in to a UBIFS image with the above command, it is compressed to roughly 550MB and remains this size on disk.
The latest UBIFS image can be found on our FTP site.
This NAND UBIFS image can be used in conjunction with tools in our initramfs to flash the NAND device.
Copy nandimg.ubifs to the root Debian folder (partition 2) of a pre-imaged bootable SD card. The SD card can either be a freshly imaged SD card, or be one that was used for current development, provided that there is enough space to fit the UBIFS image. Boot from the SD card to the initramfs, when presented a command prompt, run the following command:
Output from the command will look like the following:
The following command can be used to flash the UBIFS image to NAND:
The UBIFS image file is expected to be located at /mnt/usbdev/nandimg.ubifs, the command is intended for use with our USB update mechanism.
|The `filesystem_from_*` commands will completely format any existing data that is on the NAND linux root partition
Using filesystem_from_usb when booted from NAND
While there is no issue in executing filesystem_from_usb when booted from SD (provided there are no flash partitions mounted), further preparation is required in order to successfully boot from eMMC/NAND, and use the USB update functionality to update the flash. A USB device is required to have the the Debian distribution on the first partition and a specific set of steps in the "tsinit" script - this ensures that all flash partitions are safely unmounted and the necessary tools are available. See the initramfs USB scripting section for more information on setting up the "tsinit" script.
Using a linux host PC, format a USB drive with the first partition (min. 2GB) formatted ext2/3. Download the distribution tarball and extract it to first partition of the USB drive.
Next, set up the "tsinit" file with the following script outline:
#!/bin/sh #We only need unmount /mnt/root and use USB if booted from NAND/eMMC if [ "$bootmode" == "0x1" ]; then killall mdnsd >/dev/null #Required to cleanly umount /etc sleep 1 if [ -e /dev/mtd0 ]; then umount /mnt/root/ts fi umount /etc umount /mnt/root mount -obind /mnt/usbdev /mnt/root mount -obind /mnt/root/etc /etc/ fi echo "" source /ts.subr tshwctl --greenledon --redledon echo "Flashing kernel" kernel_from_usb >/dev/null 2>&1 if [ "$?" != "0" ]; then echo "Failed flashing kernel" tshwctl --greenledoff while true; do tshwctl --redledon; sleep .5; tshwctl --redledoff; sleep .5 ; done & return 1 fi echo "Flashing filesystem" eval `filesystem_from_usb` if [ "$prog_ok" != "1" ] ; then echo "Failed flashing filesystem" tshwctl --greenledoff while true; do tshwctl --redledon; sleep .5; tshwctl --redledoff; sleep .5 ; done & return 1 fi #We only need unmount /mnt/root and use USB if booted from NAND if [ "$bootmode" == "0x1" ]; then umount /etc umount /mnt/root fi echo "Done" while true; do tshwctl --greenledon; sleep .5; tshwctl --greenledoff; sleep .5 ; done &
Be sure to copy nandimg.ubifs and imx28_ivt_linux.sb to the root directory of the first partition of the USB drive as well!
Note, if you wish to integrate this in to your own custom USB update script, the critical sections for setting up this process are surrounded by the if blocks that check for NAND being the bootdev.
The above script will keep both LEDs on and solid while the process is happening, and will blink the green or red LED upon success or fail of the imaging process. Upon completion a power cycle or reboot is required if booted from NAND to run the update.
There are a number of different configurations and setups available when using UBI and UBIFS, see UBI and UBIFS for more information about the capabilities of the subsystem.
4.3 eMMC
|The TS-7670 only has eMMC on PCB Rev. C and newer. For TS-7670 Rev. B and older, see the NAND Flash section. For PCB revision information, see the PCB Revisions section.
The eMMC device is set up like a standard SD card when presented to the system, however it does have a few differences. eMMC offers "enhanced mode" which makes the usually MLC device behave like an SLC device. This setting does decrease the effective device size, however the benefit of reliability greatly makes up for it. Another option that eMMC offers is "write reliability." This setting changes the internal behavior of the eMMC, meaning that if a power-off occurs during a write, the guaranteed loss is limited to the currently written 512 byte sector. Aside from those two settings, the device will appear as a standard SD card, with the same partition setup as our standard SD card size, save for the maximum size of the linux partition, the second partition. The first partition contains the raw bootstream (kernel and initramfs in one binary blob); the second partition houses the Debian linux filesystem.
4.3.1 Kernel
Due to the way the freescale bootlets work, the easiest way to get a kernel on the eMMC device is to use a direct `dd` image of a bootable SD card. In order to create a `dd` image, use the following command on a bootable SD card:
dd if=/dev/sdX1 of=kernelpart.dd
Replace /dev/sdX1 with the first partition of a bootable SD card. The file "kernelpart.dd" can then be copied to the first partition of a USB drive and used in conjunction with kernel_from_usb below. This step is not necessary if using kernel_from_sd.
If a bootable SD card is in slot 0, the following command can be used when booted from either said SD card, or eMMC:
In using a USB device to update the kernel of the eMMC, the process is slightly different. The following script expects the file /mnt/usbdev/kernelpart.dd The kernelpart.dd file is created by using the `dd` command as stated above.
Both scripts above will take a few moments and will return with an exit of 0, and print "prog_ok=1" upon success. This command will also destroy and re-create the partition table. As long as the factory partition scheme is used, this command is safe to run without having to update the eMMC filesystem as well.
See the section on our USB update mechanism for more information about utilizing this process.
4.3.2 Filesystem
The process to update the filesystem on eMMC simply uses a tarball of the desired linux filesystem. Technologic Systems strongly recommends to do all development on an SD card and later create a tarball from that Debian filesystem. This allows for easy creation of a tarball from the existing master SD card to be used in production processes.
The tarball can be created from an existing filesystem. A command like the following should be all that is needed.
tar cvf rootfs.tar -C /mnt/source_fs_root/ .
This command will create rootfs.tar in the current directory from the filesystem tree root located at /mnt/source_fs_root/ Many implementations of `tar` will not have issues with creating the output file in the same directory as input. However it is recommended to keep the output file in a different directory than the source, just in case.
This tarball can be used in conjunction with scripts in our initramfs to flash the eMMC device.
Copy rootfs.tar to the root Debian folder (partition 2) of a bootable SD card. Be sure there is enough space available. Our standard image has enough free space to allow this. Boot from the SD card to the initramfs, and use the following command:
Alternatively, the rootfs.tar can be copied to the root directory of the first partition of a USB drive:
In this case, the script expects the file /mnt/usbdev/rootfs.tar to exist.
Output from the commands will look like the following:
|The `filesystem_from_*` commands will completely format any existing data that is on the eMMC linux root partition
Using *_from_usb when booted from eMMC
Since part of this process will modify an active partition table in the eMMC, this script is required for updating either the kernel or the filesystem when booted from eMMC.
While there is no issue in executing filesystem_from_usb when booted from SD (provided there are no flash partitions mounted), further preparation is required in order to successfully boot from eMMC/NAND, and use the USB update functionality to update the flash. A USB device is required to have the the Debian distribution on the first partition and a specific set of steps in the "tsinit" script - this ensures that all flash partitions are safely unmounted and the necessary tools are available. See the initramfs USB scripting section for more information on setting up the "tsinit" script.
Using a linux host PC, format a USB drive with the first partition (min. 2GB) formatted ext2/3. Download the distribution tarball and extract it to first partition of the USB drive.
Next, set up the "tsinit" file with the following script outline:
#!/bin/sh #We only need unmount /mnt/root and use USB if booted from NAND/eMMC if [ "$bootmode" == "0x1" ]; then killall mdnsd >/dev/null #Required to cleanly umount /etc sleep 1 if [ -e /dev/mtd0 ]; then umount /mnt/root/ts fi umount /etc umount /mnt/root mount -obind /mnt/usbdev /mnt/root mount -obind /mnt/root/etc /etc/ fi echo "" source /ts.subr tshwctl --greenledon --redledon echo "Flashing kernel" kernel_from_usb >/dev/null 2>&1 if [ "$?" != "0" ]; then echo "Failed flashing kernel" tshwctl --greenledoff while true; do tshwctl --redledon; sleep .5; tshwctl --redledoff; sleep .5 ; done & return 1 fi echo "Flashing filesystem" eval `filesystem_from_usb` if [ "$prog_ok" != "1" ] ; then echo "Failed flashing filesystem" tshwctl --greenledoff while true; do tshwctl --redledon; sleep .5; tshwctl --redledoff; sleep .5 ; done & return 1 fi #We only need unmount /mnt/root and use USB if booted from NAND if [ "$bootmode" == "0x1" ]; then umount /etc umount /mnt/root fi echo "Done" while true; do tshwctl --greenledon; sleep .5; tshwctl --greenledoff; sleep .5 ; done &
Be sure to copy kernelpart.dd and rootfs.tar to the root directory of the first partition of the USB drive as well!
Note, if you wish to integrate this in to your own custom USB update script, the critical sections for setting up this process are surrounded by the if blocks that check the bootdev. These sections will unmount the root filesystem and then mount the USB drive as the new root filesystem. This allows the contents of the eMMC device to be completely re-written with tools available in Debian without having the eMMC device mounted.
The above script will keep both LEDs on and solid while the process is happening, and will blink the green or red LED upon success or fail of the imaging process. Upon completion a power cycle or reboot is required if booted from NAND to run the update.
5 Software Development
Most of our examples are going to be in C, but Debian will include support for many more programming languages. Including (but not limited to) C++, PERL, PHP, SH, Java, BASIC, TCL, and Python. Most of the functionality from our software examples can be done from using system calls to run our userspace utilities. For higher performance, you will need to either use C/C++ or find functionally equivalent ways to perform the same actions as our examples. Our userspace applications are all designed to go through a TCP interface. By looking at the source for these applications, you can learn our protocol for communicating with the hardware interfaces in any language.
The most common method of development is directly on the SBC. Since debian has space available on the SD card, we include the build-essentials package which comes with everything you need to do C/C++ development on the board.
Vim is a very common editor to use in Linux. While it isn't the most intuitive at a first glance, you can run 'vimtutor' to get a ~30 minute instruction on how to use this editor. Once you get past the initial learning curve it can make you very productive. You can find the vim documentation here.
Emacs is another very common editor. Similar to vim, it is difficult to learn but rewarding in productivity. You can find documentation on emacs here.
Nano while not as commonly used for development is the easiest. It doesn't have as many features to assist in code development, but is much simpler to begin using right away. If you've used 'edit' on Windows/DOS, this will be very familiar. You can find nano documentation here.
We only recommend the gnu compiler collection. There are many other commercial compilers which can also be used, but will not be supported by us. You can install gcc on most boards in Debian by simply running 'apt-get update && apt-get install build-essential'. This will include everything needed for standard development in c/c++.
You can find the gcc documentation here. You can find a simple hello world tutorial for c++ with gcc here.
Build tools
When developing your application typing out the compiler commands with all of your arguments would take forever. The most common way to handle these build systems is using a make file. This lets you define your project sources, libraries, linking, and desired targets. You can read more about makefiles here.
If you are building an application intended to be more portable than on this one system, you can also look into the automake tools which are intended to help make that easier. You can find an introduction to the autotools here.
Cmake is another alternative which generates a makefile. This is generally simpler than using automake, but is not as mature as the automake tools. You can find a tutorial here.
Linux has a few tools which are very helpful for debugging code. The first of which is gdb (part of the gnu compiler collection). This lets you run your code with breakpoints, get backgraces, step forward or backward, and pick apart memory while your application executes. You can find documentation on gdb here.
Strace will allow you to watch how your application interacts with the running kernel which can be useful for diagnostics. You can find the manual page here.
Ltrace will do the same thing with any generic library. You can find the manual page here.
5.1 Cross Compiling
While it is recommend to develop entirely on the SBC itself, it is also possible to develop from an x86 compatible Linux system using a cross compiler. For this SBC use the cross compiler located here. The resulting binary will be for ARM.
[user@localhost]$ /path/to/arm-fsl-linux-gnueabi/bin/arm-linux-gcc hello.c -o hello [user@localhost]$ file hello hello: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
This is one of the simplest examples. For working with a larger project a Makefile will typically be used. More information about Makefiles is available here. Another common requirement is linking to third party libraries provided by Debian on the SBC. There is no exact set of steps for every project when cross compiling, but the process will be very much the same. Provide the cross compiler with access to the necessary headers, libraries, and source files, and install the binary on the target. The following example will link to sqlite from Debian.
Install the sqlite library and header on the SBC:
apt-get update && apt-get install -y libsqlite3-0 libsqlite-dev
This will fetch the binaries from the internet and install them on the SBC. The installed files can then be listed with dpkg:
dpkg -L libsqlite3-0 libsqlite3-dev
The needed files from this output will be the .h and .so files, they will need to be copied to the project directory on the cross-compling host.
See the example with libsqlite3 below. This is not intended to provide any functionality, but just call functions provided by sqlite.
#include <stdio.h> #include <stdlib.h> #include "sqlite3.h" int main(int argc, char **argv) { sqlite3 *db; char *zErrMsg = 0; int rc; printf("opening test.db\n"); rc = sqlite3_open("test.db", &db); if(rc){ fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); sqlite3_close(db); exit(1); } if(rc!=SQLITE_OK){ fprintf(stderr, "SQL error: %s\n", zErrMsg); } printf("closing test.db\n"); sqlite3_close(db); return 0; }
To build this with the external libraries the makefile below can be used. This will have to be adjusted for the proper toolchain path. In this example, the headers are located in external/include and the library in external/lib.
CC=/opt/arm-2008q3/bin/arm-none-linux-gnueabi-gcc CFLAGS=-c -Wall all: sqlitetest sqlitetest: sqlitetest.o $(CC) sqlitetest.o external/lib/libsqlite3.so.0 -o sqlitetest sqlitetest.o: sqlitetest.c $(CC) $(CFLAGS) sqlitetest.c -Iexternal/include/ clean: rm -rf *o sqlitetest.o sqlitetest
The resulting binary can be copied to the target and executed. There are many ways to transfer the compiled binaries to the board. Using a network filesystem such as sshfs or NFS will be the simplest to use if needed frequently during development, but will require a setup. See the host linux distribution's manual for more details. The simplest network method is using ssh/sftp. If running Windows, winscp can be used, or just scp in linux. Make sure a password is set for a user account, root or otherwise, in order to properly ssh or scp files to the target. From winscp, enter the ip address of the SBC, the root username, and the password; this will create an explorer window that can use drag-and-drop of files to copy them to the target.
For scp in linux, run:
#replace with the binary name and the SBC IP address scp sqlitetest firstname.lastname@example.com:/root/
After transferring the file to the board, execute it:
ts:~# ./sqlitetest opening test.db closing test.db
5.2 Compile the Kernel
For adding new support to the kernel, or recompiling with more specific options you will need to have an x86 compatible Linux host available that can handle the cross compiling. Compiling the kernel on the board is not supported or recommended. Before building the kernel you will need to install a few support libraries on your workstation:
yum install ncurses-devel ncurses yum groupinstall "Development Tools" "Development Libraries"
sudo apt-get install build-essential libncurses5-dev libncursesw5-dev git
If you are on a 64-bit system, then 32-bit libraries will be required for the toolchain, for newer Debian and Ubuntu distrubutions with Multiarch support, use the command:
sudo dpkg --add-architecture i386 sudo apt-get update sudo apt-get install libc6-dev:i386 zlib1g-dev:i386
On older distributions:
sudo apt-get install ia32-libs
For other distributions, please refer to their documentation to find equivalent tools.
Download sources and configure
git clone https://github.com/embeddedarm/linux-22.214.171.124-imx28.git cd linux-22.214.171.124-imx28/ # This sets up the default configuration that we ship with make ts7400_defconfig ln -sf initramfs.cpio-ts7400 initramfs.cpio
Once you have the configuration ready you can make your changes to the kernel. Commonly a reason for recompiling is to add support that was not built into the standard image's kernel. You can get a menu to browse available options by running:
make menuconfig
You can use the "/" key to search for specific terms through the kernel.
Build the kernel
Once you have it configured you can begin building the kernel. This usually takes about 5-10 minutes.
make -j4 && make zImage
Build bootstream
The i.MX28 utilizes what Freescale calls a "bootstream," this is a series of "bootlets" that are all put together in a binary blob. The default bootstream sets up RAM, power, and contains the kernel to be run. Every time a kernel is rebuilt, a new bootstream must be compiled containing the new kernel image. The following script is used to take the newly built kernel and output a bootstream for the SD card:
This will create imx-bootlets-src-10.12.01/imx28_ivt_linux.sb The .sb file is the standard image used for the SD card and NAND.
Building External Wireless Modules
In order to support the wide range of USB wifi modules that Technologic Systems has offered over the years, the compat-wireless project is used to build all compatible modules. A simple command is used to build them:
Install the bootstream (kernel/initramfs) and Modules
Next you need to install the kernel and modules to the SD card. Freescale uses a specialized booting mechanism for their processor, so to simplify installation we provide two scripts to handle installation of the kernel+bootstream, kernel modules, headers, and compat-wireless modules.
For example, if your workstation's SD card is /dev/mmcblk0:
./install_bootstream imx-bootlets-src-10.12.01/imx28_ivt_linux.sb mmcblk0 p1 ./install_hdr_mod mmcblk0p2
If your workstation's SD card is /dev/sdc:
./install_bootstream imx-bootlets-src-10.12.01/imx28_ivt_linux.sb sdc 1 ./install_hdr_mod sdc2
| On newer linux distributions, the output of 'fdisk' has changed. If the unit fails to boot after a compile, take a look at the output of the './install_bootstream ... ' command. If the line
./install_bootstream: line 122: [: !=: unary operator expected
is printed, then you need to apply the patch to fix this. Use the following command to apply the patch:
patch -p1 < install_bootstream-newer-fdisk.patch
6 Features
6.1 ADC (Measure VIN)
The on-board supervisory microcontroller has the ability to monitor the current VIN voltage. Sample code to read this information is provided by Technologic Systems, see get_vin.c. This code can be used as-is, or integrated in to another application. The get_vin program will output the VIN volts in mV. Due to rounding errors, the output accuracy can vary through the VIN range, however it remains within 4% from the full voltage range.
6.2 Battery Backed RTC and Temperature Sensor
This board includes a temperature compensating RTC which maintains ±5 ppm between 0C to +85C. This is accessed in software using tshwctl. By default, tshwctl will run "tshwctl --getrtc" on startup which will pull system time from the RTC, and set the system time. During the Technologic Systems production process the RTC will be programmed with an accurate time.
If time ever needs to be set you can run:
tshwctl --setrtc
This will take the system time and write it to the RTC. The battery in the RTC will last approximately 10 years for most applications, but the RTC allows you to see when the battery reaches low or critical voltages:
# tshwctl --rtcinfo rtc_present=1 rtctemp_millicelsius=36000 rtcinfo_oscillator_ok=1 rtcinfo_batt_low=0 rtcinfo_batt_crit=0 rtcinfo_firstpoweroff=0000000000 rtcinfo_lastpoweron=0000000000
rtcinfo_oscillator_ok is true when the RTC is operational and time is being kept
rtcinfo_batt_low is true when the battery is less than 2.805v (85% of 3.3v)
rtcinfo_batt_crit is true when the battery is less than 2.475v (75% of 3.3v)
|While the RTC will remain operational with a battery voltage down to 1.8v, the lithium battery used has a very steep discharge curve. Once the battery reaches critical level it should be replaced.
rtcinfo_first/lastpoweroff/on are two registers that denote the first time the RTC started using battery power, and the last time power was restored and the RTC stopped using battery power for timekeeping. The output of these registers is in the format MMDDhhmmss. Once `tshwctl --rtcinfo` is called, these registers are cleared and able to be set again. This is a great tool to check if a power off has occurred and how long it lasted.
The TS-7670 i.MX286 CPU has two FlexCAN ports that use the linux SocketCAN implementation. The ports can be set up and used with the following commands:
modprobe flexcan ifconfig can0 up ifconfig can1 up
In order to set the baud rate of either CAN interface, the interface must first be brought down with:
ifconfig canX down
Where "X" is interface 0 or 1. At this point, the desired baud rate can be directly entered in to the file "/sys/devices/platform/FlexCAN.X/bitrate", where X is the desired interface. For example, to set a baud rate of 750kHz on both interfaces:
echo 750000 > /sys/devices/platform/FlexCAN.0/bitrate echo 750000 > /sys/devices/platform/FlexCAN.1/bitrate
At this point the ports can be used with standard SocketCAN libraries. In debian we provide cansend and candump to test the ports or as a simple packet send/recv tool. In order to test the two ports together, tie CAN_H of both CAN ports together, and do the same for CAN_L. Then use the following commands:
candump can0 & cansend can1 can1 7DF#03010C #This command will return can0 7DF [3] 03 01 0C
|It has been observed that the flexCAN driver present in the 2.6.35 kernel has some issues. If your application is running in to these issues, please see the discussion thread here: https://community.nxp.com/thread/272930 Apply the mentioned patch and compile the kernel. The patch is also included in our kernel git repo. Be sure after the patch is applied to set the kernel config options CONFIG_CAN_DEV, CONFIG_CAN_CALC_BITTIMING, and CONFIG_CAN_FLEXCAN. They can be modules or built-in.
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 using C-types, Java using JNI.
This board features the i.MX286 454MHz ARM9 from Freescale. For more information about the processor and it's included peripherals, refer to the CPU manual.
This board uses CPU DIO, typically there are 4 functions associated with each physical pin (I2C, PWM, SPI, DIO, etc). See the CPU manual for the complete listing and for information on how to control these DIO.
Note that most of the pins start in their "Function" mode and must be set to DIO mode to be able to be used as DIO. Be aware that doing this on a running system may have adverse effects if there are kernel drivers trying to use specific pins in their peripheral mode(s).
DIO numbers are referenced in bank_pin notation in the table below. This makes associating pins with DIO registers much simpler when looking at the manual. The example code below is also based around using the bank and pin notation.
|Push Switch
- ↑ Input only, state of push switch. Note, default behavior will reset the board if the switch is pressed, see External Reset for how to disable this.
- ↑ 2.0 2.1 Not peripheral controlled
- ↑ Input only, RS232 logic
- ↑ Output only, RS232 logic
- ↑ 5.0 5.1 Input only, 5v tolerant
Example code for DIO manipulation:
#include <assert.h> #include <fcntl.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #define DIO_Z 2 volatile unsigned int *pinctl = NULL; /******************************************************************************* * setdiopin: accepts a DIO register and value to place in that DIO pin. * Values can be 0 (low), 1 (high), or 2 (z - high impedance). *******************************************************************************/ void setdiopin(int bank, int pin, int val) { if(val == 2) { pinctl[((0xB00) + (0x10 * bank) + 0x8)/4] = (0x1 << pin); } else { pinctl[((0x700) + (0x10 * bank) + (0x8 / (val+1)))/4] = (0x1 << pin); pinctl[((0xB00) + (0x10 * bank) + 0x4)/4] = (0x1 << pin); } } /******************************************************************************* * getdiopin: accepts a DIO pin number and returns its value. *******************************************************************************/ int getdiopin(int bank, int pin) { return (((pinctl[((0x900) + (0x10 * bank))/4]) >> pin) & 0x1); } /******************************************************************************* * Main: accept input from the command line and act accordingly. *******************************************************************************/ int main(int argc, char **argv) { int devmem = 0; int pin, bank, reg = 0, muxpin; int val; int returnedValue; // Check for invalid command line arguments if ((argc > 4) | (argc < 3)) { printf("Usage: %s bank pin [0|1|2]>\n", argv[0]); return 1; } // We only want to get val if there are more than 3 command line arguments if (argc == 3) { bank = strtoul(argv[1], NULL, 0); pin = strtoul(argv[2], NULL, 0); val = 0; } else { bank = strtoul(argv[1], NULL, 0); pin = strtoul(argv[2], NULL, 0); val = strtoul(argv[3], NULL, 0); } assert(bank >= 0 && bank < 5); assert(pin >= 0 && pin < 32); assert(val >=0 && val < 3); devmem = open("/dev/mem", O_RDWR|O_SYNC); pinctl = mmap(0, getpagesize(), PROT_READ|PROT_WRITE, MAP_SHARED, devmem, 0x80018000); /* We determine what muxsel reg we need, and set the right pin to DIO*/ if(pin > 15) { reg = 1; muxpin = pin - 16; } else muxpin = pin; pinctl[((0x100) + (0x20 * bank) + (0x10 * reg) + 0x4)/4] = (0x3 << (muxpin * 2)); // Parse through the command line arguments, check for valid inputs, and exec if (argc == 3) { returnedValue = getdiopin(bank, pin); printf("dio_%d_%d=%d\n", bank, pin, returnedValue); } else if(argc == 4) { setdiopin(bank, pin, val); } return 0; }
tsctl can also be used to manipulate the DIO of the TS-7670, a tarball of libtsctl can be found here. See the tsctl page for more information.
6.6 DoubleStore
|Click to download the latest 4GB DoubleStore SD card image.
This series supports DoubleStore which can be used to significantly increase the reliability of SD cards. This allows one SD image to be written to two cards allowing redundancy among both SD cards. See our white paper for more information on the concept. Development can take place with a single MicroSD card, but for using DoubleStore 2 MicroSD cards are used.
|Due to the design of the SBC and its use of the Freescale bootstream, the device cannot directly boot from a DoubleStore dataset. The device must first boot from on-board media (SPI, NAND, eMMC), and the initramfs will then find the DoubleStore dataset and mount it to the Debian directory. From there, the unit can boot to Debian on the DoubleStore dataset, either manually with the 'exit' command, or by setting up the initramfs to boot straight to Debian. See the Initramfs section for more details on setting up the initramfs to accomplish this.
The default SD image is 3GB which is designed to fit in a dual-card Doublestore configuration. When dual card doublestore is used it stores the same image on both cards and also includes metadata and checksums for the entire image.
You can use the dblstorctl utility to work with DoubleStore on your Linux workstation. The simplest way to get doublestore set up is to first take a backup of your SD image, and then use dblstorctl on a workstation to convert it:
export INPUTIMAGE="yourimagebackup.dd" eval $(stat -c "imgsize=%s" $INPUTIMAGE) dblstorctl --primary ${INPUTIMAGE}.dblstor --fallback /dev/null --init --writeimg "$INPUTIMAGE" --size=${imgsize}B
This will output yourimagebackup.dd.dblstor which can be written directly to both SD cards:
dd if=yourimagebackup.dd.dblstor bs=4M conv=fsync of=/dev/sdb # replace sdb with your SD card device
Note that the stock DoubleStore image linked at the top of this section can be used in place of 'yourimagebackup.dd' to write our stock image to a two card DoubleStore set.
The board will boot the same using the DoubleStore MicroSD cards, but dblstorctl includes additional information:
# dblstorctl --stats nbdpid=338 nbd_readreqs=1508 nbd_read_blks=95490 nbd_writereqs=0 nbd_write_blks=0 nbd_seek_past_eof_errs=0 sdcard_resets=4 read_seeks=1261 write_seeks=0 size=0x641800 humanized_size=3.35GB fb_offset=-6559744 primary_tainted=0 primary_failed=0 fallback_tainted=0 fallback_failed=0 resilver_pct_done=0 lifetime_write_blks=59038888 humanized_lifetime_write_blks=30.22GB errors=0 unrecoverable_errors=0 conflicts=0 fallback_configuration="separate disk"
fallback_configuration should read "seperate disk" when booting doublestore correctly. For diagnostics, the tainted and failed settings are the most relevant:
primary_tainted=0 primary_failed=0 fallback_tainted=0 fallback_failed=0
When a card is tainted, the LED near the card will begin to blink. This indicates Doublestore has seen the card perform an unexpected behavior that DoubleStore was able to correct.
6.7 External Reset
The TS-7670 has a multi-purpose tactile button at a right angle to the PCB. This button can be used as a mechanism to issue a hardware reset to the SBC or as a way to wake up the device from its sleep modes (see Sleep for more information). The stock image for both SD and NAND enable the button to be a reset switch. This functionality can be disabled with:
tshwctl --resetswitchoff
And can be re-enabled with:
tshwctl --resetswitchon
6.8 GPS Receiver
There is an optional GPS receiver that can be soldered down to the TS-7670. This appears on ttySP4 and defaults to 9600 baud, 8n1, no flow control. The GPS receiver outputs standard NMEA statements and can either be parsed by an application reading the serial port or be run through a daemon like gpsd that can be parsed and interacted with a number of ways.
The optional GPS receiver can be powered on or off via DIO 1_1 (see the DIO section for more information). Writing 0 to this DIO will enable power to the GPS device. Writing 1 to this DIO will disable the GPS device. This is useful for applications where power consumption is sensitive.
|If the GPS receive is to be used alongside of putting the TS-7670 in to standby, it is necessary to turn off power to the GPS module before entering standby, and to re-apply power upon waking up. This is not necessary when putting the unit to sleep as wake up from sleep is equivalent to a full power cycle.
The i.MX28 CPU I2C pins are not exposed to any external interfaces on this SBC. Because of this, bitbanging is strongly recommended for any attached peripherals that would utilize I2C.
Technologic Systems recommends using direct bitbanging of I2C pins from userspace to drive an I2C interface. See the DIO section for further information on manipulating DIO pins.
Another option is to implement i2c-gpio in linux. This allows for an I2C physical interface on GPIO pins, but uses the kernel I2C software interface to read and write data on the I2C bus. See linux kernel documentation and i2c-dev for more information on this.
6.10 Jumpers
The TS-7670 has a set of jumpers located between the microSD sockets and the J7 connector. These jumpers control a number of aspects of the TS-7670's behavior. The jumpers are labeled on the silkscreen rather than numbered:
|SD Boot
|When jumper is set, boot kernel and Debian from the SD card. Otherwise boot kernel and Debian from on-board flash.
|When jumper is set, adds a 120 ohm termination resistor across CAN0 data lines.
6.11 LEDs
On all of our SBCs we include 2 indicator LEDs which are under software control. You can manipulate these using "tshwctl --greenledon --redledon" or "tshwctl --greenledoff --redledoff". The LEDs have 4 behaviors from default software.
|Green Behavior
|Red behavior
|Solid On
|System is booted and running
|Solid On
|On for approximately 15s, then off
|Once the system has booted the kernel and executed the startup script, it will check for a USB device and then determine if it is a mass storage device. This is used for updates/blasting through USB. Once it determines this is not a mass storage device the red LED will turn back off.
|On for 10s, off for 100ms, and repeating
|Turns on after Green turns off for 300ms, and then turns off for 10s
|The watchdog is continuously resetting the board. This happens when the system cannot find a valid boot device, or the watchdog is otherwise not being fed. This is normally fed by tshwctl once a valid boot media has started. See the #Watchdog section for more details.
|The SBC is not able to boot. Typically either the board is not being supplied with enough voltage, or the SBC has been otherwise damaged. If a stable voltage is being provided and the supply is capable of providing at least 1A to the SBC, an RMA is suggested.
|Blinking about 5ms on, about 10ms off.
|Blinking about 5ms on, about 10ms off.
|The board is receiving too little power, or something is drawing too much current from the macrocontroller's power rails.
In addition to the red and green LEDs, there is a yellow and a blue LED usable as custom indicators. As stated above, the green and red LEDs have a default power on behavior, however after that our default software does not change them and they can be manipulated by customer applications. The yellow LED is completely untouched by our software, while the blue LED will flicker on power-on as controlled by the on-board microcontroller. The Blue LED is not driven by the microcontroller or CPU for any other reason by default. The blue LED can be driven from both the CPU DIO and the microcontroller in an OR fashion. See the DIO section for information on turning on and off the blue and yellow LEDs.
6.12 MicroSD Card Interface
The i.MX28 SD card controller is used for both SD cards present on the board which supports the SD and SDHC specifications. This controller has been tested with Sandisk Extreme SD cards which allow read speeds up to 20.5MB/s, and write speeds up to 21.5MB/s.
Our default software image contains 2 partitions:
|SD Card block device
|Kernel and initramfs
|Full Debian linux partition
The NAND on the i.MX286 is a 2GiB part attached directly to the CPU. The kernel handles the NAND through its MTD drivers.
Instead of a traditional flash filesystem (JFFS2 for example) the i.MX286 implements UBI and UBIFS.
6.13.1 UBI and UBIFS
UBI is the Unsorted Block Images layer, and is an erase block management layer. UBI serves two purposes, tracking NAND bad blocks and providing wear leveling. While it is possible to run a traditional flash filesystem on top of UBI, it is not recommended. UBIFS was written with UBI in mind and is able to take full advantage of what UBI provides. UBIFS has multiple advantages over JFFS2, UBIFS supports write caching, UBIFS performs better on larger NAND devices, mounts faster, allows for quicker access to large files, improved write speeds, and indexes stored in flash not in system memory.
6.13.2 Using UBI and UBIFS
UBI is implemented directly on top of linux's MTD subsystem, the first thing necessary is to format the device for UBI to use.
ubiformat /dev/mtd1 #This will prepare /dev/mtd1 to accept UBI and is mindful of UBIs erase counters
After this, the device must be attached to UBI
ubiattach -m 1
This will attach the device to the UBI subsystem. Doing this will create a /dev/ubi0 device node that represents the entire UBI device. A UBI attach does take longer on larger MTD devices.
Once this is done, at least one volume must be made. There are two types of volumes, static and dynamic. A dynamic volume is liken to a standard filesystem, it creates and uses a UBIFS filesystem. A static volume is meant to be run right on top of UBI, and does not use UBIFS. It is meant for smaller volumes with blobs of configuration data, and is protected with CRC32s. While it is possible, it is not wise to use UBIFS on top of a static volume, it will result in a much slower device since since both UBI and UBIFS will be implementing CRC32s.
The RTC has an included 128-byte battery-backed NVRAM which can be accessed using tshwctl. Its contents will remain with the main power off, so long as the RTC battery is installed and withing a valid voltage range.
tshwctl --nvram
This will return a format such as:
nvram0=0xf7f8a73e nvram1=0x2fef5ae0 nvram2=0x48ca4278 ... nvram31=0x70544510
This breaks up the NVRAM into 32 32-bit registers which can be accessed in bash. As this uses the name=value output, "eval" can be used for simple parsing:
eval `tshwctl --nvram` echo $nvram2
From the above value, this would return 0x48ca4278. To set values, the respective environment variable name can be set:
nvram0=0x42 tshwctl --nvram
Note that the command 'tshwctl --nvram' will output the current contents of NVRAM before setting any new values. At this point, running 'tshwctl --nvram' once more will print the updated contents for verification. This can be used for reading a 32-bit quantity and updating it with a single command.
6.15 Sleep
The addition of a microcontroller on board this SBC allows it to play a supervisory role over the CPU. Two sleep modes are available, each with the ability to wake up after a set amount of time, or after a push of the tactile push switch on the edge of the PCB.
6.15.1 Sleep
This low power sleep mode will remove power from all of the rails, turning off the CPU and every other peripheral save for the microcontroller. This mode offers extreme power savings, only requiring around 9mW of power, with the ability to wake up after an arbitrary timeout (up to 1847297s, which is 21d 9h 8m 17s) with a 1s resolution. Note that as soon as the command to sleep is issued, the device will sleep as soon as possible. This has the ability to cause filesystem corruption if proper precautions are not taken before the SBC is put to sleep. In order to enter this mode, issue the following command:
tshwctl --sleep --timewkup <time in seconds> --resetswitchwkup
Note that both --timewkup and --resetswitchwkup are optional arguments, you can pass none, one, or both. If no arguments are passed then the SBC will remain in sleep mode forever, until power is removed completely and re-applied. This can be useful instead of halting in linux as sleeping would consume far less power than simply halting the CPU. Waking up from this mode will take roughly 4-5s from when the timer expires or when the reset button is pressed. This is normal bootup time for the CPU.
6.15.2 Standby
This sleep mode does consume more power, roughly 250mW, however the CPU is put in a standby mode with the RAM contents and CPU cache preserved. When the CPU wakes up from this mode it will continue execution from where it left off. This wakeup process takes roughly 250ms from when the sleep timer expires or the reset button is pushed. Like the sleep mode above, the timer on standby can be an arbitrary number (up to 1847297s, which is 21d 9h 8m 17s) with a 1s resolution. Unlike the above sleep mode, it is safe to enter standby at almost any time without concern for data loss. The only unsafe time is during a write to the SD card that has completed in linux, but the SD card controller is still attempting to flush the write to disk. In all of Technologic Systems' testing, we have not observed any corruption caused by entering or exiting the standby mode. The standby mode can be entered with the following command:
tshwctl --standby --timewkup <time in seconds> --resetswitchwkup
Note that both --timewkup and --resetswitchwkup are optional arguments, you can pass none, one, or both. If no arguments are passed then the SBC will remain in standby mode forever, until power is removed completely and re-applied. In the case of the standby mode however, it does not make sense to leave it in this mode indefinitely. After this mode is exited, the function of the reset switch is restored to its previous state, see External Reset for more information.
This SBC utilizes all of the i.MX28 CPU SPI ports for the SD cards, therefore there is no externally available SPI peripheral from the CPU. Because of this, bitbanging is strongly recommended for any attached peripherals that would utilize SPI.
Technologic Systems recommends using direct bitbanging of SPI pins from userspace to drive an SPI interface. See the DIO section for further information on manipulating DIO pins.
Another option is to implement spi-gpio in linux. This allows for a SPI physical interface on GPIO pins, but uses the kernel SPI software interface to read and write data on the SPI bus. See linux kernel documentation, spi-gpio, and spidev for more information on this.
6.17 Temperature Sensor
This SBC includes temperature sensors located on the CPU and RTC. Both of these can be read using tshwctl:
tshwctl --rtcinfo tshwctl --cputemp
These commands will return the temperature of the RTC or internal CPU die temperature. Note that the --rtcinfo option will also return other information, See the Battery Backed RTC and Temperature Sensor section for more information.
6.18 UARTs
The TS-7670 uses 5 CPU UARTs, two brought out at RS-232 logic levels on two RJ45 jacks, one MODBUS/RS-485 port on an RJ45 jack, one TTL level UART brought out on HD2 (5v tolerant RX, 3.3v TX), and one UART directly connected to an optional GPS receiver.
The default software image for the TS-7670 has the i.MX286 UART driver as a module, it must be loaded with the following command before the UARTs can be used:
modprobe mxs_auart
This will then spawn the ttySP* devices in the /dev/ folder
- ↑ 1.0 1.1 1.2 1.3 J4 is labeled "B" on the enclosure
- ↑ 2.0 2.1 2.2 2.3 J5 is labeled "A" on the enclosure
- ↑ 3.0 3.1 Not peripheral controlled, must be driven/read as DIO
- ↑ 4.0 4.1 J6 is labeled "MODBUS" on the enclosure
- ↑ 5V tolerant
6.18.1 RS-232 Enable
The RS-232 transceiver can be enabled and disabled as needed. Disabling will lower the power consumption of the unit.
tshwctl --232on tshwctl --232off
The RS-485 port on the TS-7670 is half-duplex with an automatic TXEN that is realized with a simple hardware circuit, and the M0 microcontroller on-board. To enable this feature, the M0 Microcontroller must be told what bit rate the system will be operating at. To do this, run the command
tshwctl --485speed=<bitrate>
This ensures that TXEN is set for the first bit time and turns off TXEN after the last bit is sent. This operation is completely transparent to the OS and the end user.
184.108.40.206 MODBUS Power
The J6 connector is set up for a standard 2W-MODBUS pinout that provides power. The voltage output is VIN minus a diode drop. The power can be enabled with the following command:
tshwctl --modbuspoweron #Will return modbuspoweron=1
The power on sequence will first apply 3 V, verify there is no short on the bus, and then apply the full voltage. If the command returns 'modbuspoweron=0' then that means there is a detected short on the other side of the bus due to mis-wiring or incorrect connection on the other side. The power can be turned off with:
tshwctl --modbuspoweroff
See the DIO section For more information on which DIO pins are being manipulated in order to safely enable power. The source for tshwctl will also provide this information in detail.
The USB host port is a standard USB 2.0 at 480Mbps. The Linux kernel provides most of the USB support, and some devices may require a kernel recompile. For creating custom USB support, libusb may be the easiest route.
USB 5V Power can be disabled or re-enabled using DIO 69, marked EN_USB_5V on the schematic. See the syscon for more information on using this bit.
See the WIFI-N-USB manual for information on our WIFI support.
6.20 Watchdog
By default there is a /dev/watchdog with the tshwctl daemon running at the highest possible priority to feed the watchdog. This is a pipe that is created in userspace, so for many applications this may provide enough functionality for the watchdog by verifying that userspace is still executing applications. If you would like to have the watchdog functionality more tightly integrated with your application you can specify various feed options.
The watchdog is implemented in the microcontroller that is on this SBC alongside the CPU. This means that a completely separate device is responsible for the sanity of the CPU. The WDT has 100ms resolution, and can be fed for a length of time up to 6553.5s, which is 1h 49m 13s 500ms. Writing a 0, 1, 2, or 3 to the WDT has a special meaning that corresponds with our traditional WDT feed scheme:
|feed watchdog for .3s
|feed watchdog for 2.7s
|feed watchdog for 10.8s
|disable watchdog
The watchdog is armed by default for 10s for the operating system to take over, after which the startup scripts autofeed the watchdog with:
echo a2 > /dev/watchdog
The /dev/watchdog fifo accepts 3 types of commands:
|f<3 digits>
|One time feed for a specified amount of time which uses the 3 digit number / 10. For example, "f456" would feed for 45.6 seconds.
|"0", "1", "2", "3"
|One time feed with the value in the above table.
|a<num 0-3>
|This value autofeeds with the value in the above table.
Most applications should use the f<3 digits> option to more tightly integrate this to their application. For example:
#include <stdio.h> #include <fcntl.h> #include <unistd.h> void do_some_work(int data) { /* The contract for sleep(int n) is that it will sleep for at least n * seconds, but not less. If other kernel threads or processes require * more time sleep can take longer, but when your process has a high * priority this is usually measured in millseconds */ sleep(5); } int read_some_io() { /* If this function (or do_some_work) misbehave and stall thee watchdog * will not be fed in the main loop and cause a reboot. You can test * this by uncommenting the next line to force an infinite loop */ // while (1) {} return 42; } int main(int argc, char **argv) { int wdfd; /* In languages other than C/C++ this is still essentially the same, but * make sure you are opening the watchdog file synchronously so the writes * happen immediately. Many languages will buffer writes together to make * them more efficient, but the watchdog needs the writes to be timed * precisely */ wdfd = open("/dev/watchdog", O_SYNC|O_RDWR); while (1) { int data; /* This loop is expected to take about 5-6 seconds, but to allow some * headroom for other applications, I will feed the watchdog for 10s. */ write(wdfd, "f100", 4); data = read_some_io(); do_some_work(data); } }
7 External Interfaces
7.1 Power input CN5
The TS-7670 accepts 8-28 VDC on CN5. Polarity of this connector can be seen below.
7.2 HD1 Pin Header
All pins labelled DIO are coming directly off of the CPU and are rated for 3.3V, and can sink or source 8mA.
- ↑ 5V tolerant input
7.3 HD2 Pin Header
Note that there are two different variations of the HD2 header based on PCB revision. PCB rev. A and B had one style, rev. C and D removed this header, and rev. E added a different connector with the same reference designation.
7.3.1 Rev. A/B
This header is not normally populated and driving some of the signals on these pins can cause conflicts.
7.3.2 Rev. E
This header is not normally populated and driving some of the signals on these pins can cause conflicts.
- ↑ Switched 3.3 V regulator, controlled via supervisory microcontroller; enabled under normal operation.
- ↑ 2.0 2.1 System internal bus, use with caution to prevent address conflicts
8 Peripherals
The TS-7670 is compatible with the TS-BAT12 battery backup. This member of the TS-SILO series grants all downstream devices the knowledge of current inbound power status. The downstream devices receive instant notification of main power loss (switching to battery) and as much as an hour's notice (given minimal power usage) before battery cutoff. Below is some sample code that enables scripted reading of the input power. See the TS-BAT12 documentation for more information. This source can be found on the Technologic Systems FTP here.
// TS-7670 BAT12 Monitor // Written by Michael D. Peters // C. 2016 Technologic Systems, Inc. // Read ADC at I2C address 0x78, parse bytes 3 (adc high byte) // and 2 (adc low byte), divide by magic 24.7 and presto input // voltage. // Output VIN=<input voltage> so a script can parse and use. #include <stdio.h> #include <stdint.h> #include <fcntl.h> #include <stdlib.h> #include <strings.h> #include <linux/i2c-dev.h> #define CONVERSION_DIVISOR 24.7 #define DATASET_SIZE 28 const char copyright[] = "Copyright (c) Technologic Systems - " __DATE__ ; /// Divide raw by conversion value. /// \arg rawValue The ADC value to convert to volts. float vConvert(int rawValue){ float theConversion; theConversion = (float)rawValue / CONVERSION_DIVISOR; return theConversion; } /// Gets ADC value from i2c. /// \arg twifd file descriptor for i2c. int getVinAdc(int twifd) { uint8_t data[DATASET_SIZE]; bzero(data, DATASET_SIZE); int adcValue = 0; read(twifd, data, DATASET_SIZE); // most of this data is reserved // but the microcontroller will // only dump all or none. adcValue = data[3]<<8|data[2]; // Byte 3 is MSB, byte 2 is LSB. return adcValue; } /// Opens I2C to 0x78. Returns file descrptor if OK else quits. int i2cInit() { int fd = -1; fd = open("/dev/i2c-0", O_RDWR); if(fd != -1) { if (ioctl(fd, I2C_SLAVE_FORCE, 0x78) < 0) { return -2; } } return fd; } /// Main Entry Point. // program quits with -1 on file io error, -2 on i2c error. int main(void) { int raw, fd; float voltage; fd = i2cInit(); if(fd == -1 || fd == -2) { printf("VIN=%d\n", fd); return fd; // quit on error. } raw = getVinAdc(fd); voltage = vConvert(raw); printf("VIN=%f\n", voltage); return 0; }
9 Revisions and Changes
9.1 Microcontroller Changelog
9.2 PCB Revisions
9.3 Software Images
|Image File
|Known Issues
"UBI device number 0, total 40 LEBs (20643840 bytes, 19.7 MiB), available 1 LEBs (51609)" "mount: mounting /mnt/root/etc on /etc/ failed: No such file or directory" "umount: can't umount /etc: Invalid argument" "UBI device number 1, total 4015 LEBs (2072125440 bytes, 1.9 GiB), available 110 LEBs)"
9.4 Product Change Notices
9.4.1 New eMMC Revisions
|Due to reasons beyond our control, the eMMC devices used on this product are no longer available. This new parts include an updated revision marker in a register read by the kernel. A kernel modification is required for it to properly use the new parts.
|Necessary kernel change
|Kernel updates complete
With the changed eMMC device, a static version indication register was changed as well. The existing kernel software checks for specific revisions. Because of this, existing images and kernel builds before the patch was applied will refuse to finish setting up the eMMC device, making it appear absent from the system
Any kernel builds of commit 74c87c2a1d83893cccb23ad1d1c406ec6cafb2d3 or newer will resolve any issues. An older kernel with the newer eMMC chip will have output in the kernel logs similar to: "mmc: unrecognised EXT_CSD structure version XXX"
Necessary Action:
All new shipping units will have the proper kernel installed on both eMMC and any microSD cards ordered with the unit as well. Any custom software or production modifications that leave the existing kernel intact will not require any further changes.
If the end production process or software modifies the kernel binary, then the kernel binary and modules that are written to the boot media must be of kernel commit 74c87c2a1d83893cccb23ad1d1c406ec6cafb2d3 or newer. This will require a kernel rebuild and reinstall on the master image used. Information on compiling the kernel can be found here.
10 Product Notes
10.1 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.
10.2 Limited Warranty
Technologic Systems warrants this product to be free of defects in material and workmanship for a period of one year from date of purchase. During this warranty period Technologic Systems will repair or replace the defective unit in accordance with the following process:
A copy of the original invoice must be included when returning the defective unit to Technologic Systems, Inc. This limited warranty does not cover damages resulting from lightning or other power surges, misuse, abuse, abnormal conditions of operation, or attempts to alter or modify the function of the product.
This warranty is limited to the repair or replacement of the defective unit. In no event shall Technologic Systems be liable or responsible for any loss or damages, including but not limited to any lost profits, incidental or consequential damages, loss of business, or anticipatory profits arising from the use or inability to use this product.
Repairs made after the expiration of the warranty period are subject to a repair charge and the cost of return shipping. Please, contact Technologic Systems to arrange for any repair service and to obtain repair charge information.
|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.