Welcome to NetModule OEM Linux Distribution’s documentation!¶
For more than 15 years NetModule has proven itself as a reliable OEM partner with thousands of installed devices for customers all over the world!
NetModule OEM platforms come with the feature-rich NetModule Router Software or a standard Yocto Linux for customer-specific applications.
Contents:
Contributing¶
Release Notes¶
OEM Linux 1.6.2 / 6-Feb-2023¶
Added features
kernel maintenance: update to v5.10.166
Fixed Bugs
#359191 OEM Linux: Release Pipeline wrongly fails with “Tag already exists” #359204 OEM Linux: Release Pipeline corrupts srcrev entries in recipes #359226 U-Boot Repository Redundancy: some recipes were referencing wrong internal repo #359227 Release Pipeline is failing while syncing legacy repos #359229 OEM Linux: Release Pipeline did not send a slack notification after repo sync stage failed #359376 wwan-config is crashing with LARA-L6 when a default APN is configured #359419 Aurix Update Failure: not reproducible
OEM Linux 1.6.1 / 23-Jan-2023¶
Added features
- OEM Linux: Modem Lara-L6 Support
kernel: enable lara-l6 detection
modemmanager: ublox lara-l6 support
- OEM Linux: neo-m9 support
neo-m9: nmubxlib update
neo-m9: gnss-mgr update
kernel maintenance: update to v5.10.164 and v4.14.303
Known Issues
#359376 wwan-config is crashing with LARA-L6 when a default APN is configured
OEM Linux 1.6.0 / 28-Nov-2022¶
Added features
OEM Linux: eUICC support
Added support for NG800, board v3.2 and new machine based on this board (hw26-vcupro)
kernel maintenance: kernel: update to v5.10.149 and v4.14.295
Fixed Bugs
[81329] kernel: can: backported mainline implementation for 64 bits messages objects to replace custom NetModule implementation which had a bug
OEM Linux 1.5.2 / 30-Jun-2022¶
Added¶
Nothing
Changed¶
[80015] yocto: Remove all dependencies to MACHINE variable when building the kernel, allowing better reusability of the kernel for different hardware sharing the same kernel
[80088] yocto: using a shared sstate mirror
[80137] wwan-config: Small code readability improvements
[80391] linux: Updated with latest security patches to 5.10.126
[79481] HW17: integrated in our OEM Linux yocto environment
[80072] OEM Linux: get rid of release revisions include file (set in recipes)
[79425] yocto: Updated community layers with latest security patches
[79996] linux: Updated with latest security patches to 5.10.120 and 4.14.282
[79987] yocto: Reorganization of the kernel recipes to split different versions of the kernel
Fixed¶
[80178] wwan-config: Fixed rare cases where the modem stayed poweroff forever
[80331] yocto: Fixed deployment of netmodule-fitimage when building entirely from sstate
Known Issues¶
[77282] hw23: dhcp bootarg is not supported
Supported devices¶
NG800¶
Telematic Control Unit
Interfaces: BroadR, CAN, Ethernet, Wi-Fi, LTE, GNSS, BT
Interna interface for user modules: Ethernet, USB, SPI, I2C, GPIO
CPU: TI am335x, 1000MHz
BSP: hw26
NB800¶
Customer-specific OEM Router
Interfaces: LTE, Wi-Fi, Bluetooth and BLE
CPU: TI am335x, 600MHz
BSP: nrhw16, nrhw24
NB1601¶
Ruggedized OEM Router
Interfaces: LTE, WiFi, GNSS and 4x Ethernet
CPU: TI am335x, 600MHz
BSP: nrhw20
NB1800¶
BSP: nrhw18
Setup your Board¶
Image Installation¶
Over the Network¶
Note: This procedure will remove all contents on the eMMC. Make sure to backup your data!
Setup a HTTP server¶
Install python3
sudo apt install python3
Set your ip to 192.168.1.254 (If you use a network-manager set your static ip there! This command will not work in this case.)
sudo ifconfig <Your ethernet device e.g. eth0> 192.168.1.254
Make a new folder and enter it
sudo mkdir /srv/http
cd /srv/http
Start the http-server
sudo python3 -m http.server --bind 192.168.1.254 80
Setup a TFTP server¶
Install the following packages
sudo apt-get install xinetd tftpd tftp
Edit or make a file in:
/etc/xinetd.d/tftp
with the following content:
service tftp
{
protocol = udp
port = 69
socket_type = dgram
wait = yes
user = nobody
server = /usr/sbin/in.tftpd
server_args = -s /srv/tftp
disable = no
}
Create a tftp folder
mkdir -p /srv/tftp
Restart the xinetd service
sudo service xinetd restart
Instructions¶
Put the WIC file (e.g. image-am335x-nmhw21.wic) file on the http-server (/srv/http).
Put the Minimal Linux fitImage (e.g. fitImage-am335x-nmhw21.bin) on the tftp-server (/srv/tftp).
Verify the /srv folder:
/srv
|-- http
| |-- image-am335x-nmhw21.wic
|-- tftp
. |-- fitImage-netmodule-linux-image-minimal-am335x-nmhw21
Power up the board and press ‘s’ on the serial terminal to stop in u-boot.
Validate that you are in u-boot console by typing
# env print serverip
serverip=192.168.1.254
Load kernel binary into ram
# tftp $ramdisk_addr_r fitImage-netmodule-linux-image-minimal-am335x-nmhw21
restrict positioning of initrd ramdisk image
# setenv initrd_high 0x84000000
Set boot args
# setenv bootargs root=/dev/ram0 console=ttyS2,115200 ti_cpsw.rx_packet_max=1526
Boot from ramdisk. Linux will boot to login prompt within < 30s
# bootm $ramdisk_addr_r
Login as root (empty password).
Disable kernel messages in Linux system
echo 1 > /proc/sys/kernel/printk
Burn the .wic file to the eMMC: (this takes about 5 min)
curl http://192.168.1.254/image-am335x-nmhw21.wic | dd of=/dev/mmcblk1 bs=10M && sync
Reboot your system.
reboot
From USB Stick¶
Prepare USB Stick¶
Format a USB-pendrive to have a with fat with a maximum partition size of 4.0GB for the first partition.
Use gnome-disks
or gparted` for this.
The output of parted -l should look like this:
Model: Kingston DataTraveler 3.0 (scsi)
Disk /dev/sdb: ...GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags:
Number Start End Size Type File system Flags
1 1049kB 4001MB 4000MB primary fat32 lba
Put the image-am335x-nmhw21.wic file on a USB-pendrive.
Put the files image-minimal-am335x-nmhw21.cpio.gz.u-boot, fitImage-am335x-nmhw21.bin on the USB-pendrive.
Your USB-pendrive should no look like this:
USB-root
|-- image-am335x-nmhw21.wic
|-- image-minimal-am335x-nmhw21.cpio.gz.u-boot
|-- fitImage-am335x-nmhw21.bin
Flash from USB Stick¶
Plug the USB-pendrive into the nmhw21.
Power up the board and press ‘s’ on the serial terminal to stop in u-boot.
Boot the ramdisk (copy-paste into u-boot terminal):
usb reset; fatload usb 0:1 $kernel_addr_r fitImage-am335x-nmhw21.bin; fatload usb 0:1 $ramdisk_addr_r image-minimal-am335x-nmhw21.cpio.gz.u-boot; setenv bootargs root=/dev/ram0 console=ttyS2,115200 ti_cpsw.rx_packet_max=1526; bootm $kernel_addr_r $ramdisk_addr_r
When the the system has booted, log in with user root.
Mount the USB-pendrive
mount /dev/sda1 /mnt
Burn the .wic file to the eMMC: (this takes about 5 min)
dd if=/mnt/image-am335x-nmhw21.wic of=/dev/mmcblk1 bs=10M && sync
Reboot your system
reboot
From SD Card¶
Build Your Image¶
NetModule provides its own meta layer for customized image generation.
Project Setup¶
Netmodule Meta Layer¶
Meta Layer |
Description |
Repository |
---|---|---|
meta-netmodule-distro |
|
|
meta-netmodule-bsp |
|
|
meta-netmodule-wlan |
|
Additional Layers and Bitbake¶
Following additional resources are required:
Setup workspace¶
Start new build project with cloning all required git repositories:
Clone the nm-oem-linux repository
Move into the cloned repository and run
git submodule init
thengit submodule update
Your workspace should now look similar as in the snippet below:
.
├── bitbake
├── build
├── env
├── meta-netmodule-bsp
├── meta-netmodule-distro
├── meta-netmodule-wlan
├── meta-openembedded
├── meta-updater
├── openembedded-core
└── README.md
Configure project¶
Start to source environment: . ./env/distro/ostree-image
select your hardware in the prompt. You will be moved to the build
directory.
Build NetModule reference images¶
NetModule provides several reference images depends on use case:
Image |
Description |
---|---|
netmodule-linux-image |
Standard reference image. Contains required applications, drivers and tools to use interfaces, network connectivities and sensors. |
netmodule-linux-image-dev |
Based on |
netmodule-linux-image-minimal |
Minimal ramdisk based image for simple bring up or can be used for emmc operations like device flashing or data recovery. |
Images recipes location¶
Images recipes are located in layer meta-netmodule-distro
:
meta-netmodule-distro/recipes-core/images/
├── includes
│ ├── firmware.inc
│ └── image-preprocessing.inc
├── initramfs-ostree-image.bbappend
├── netmodule-linux-image.bb
├── netmodule-linux-image-dev.bb
├── netmodule-linux-image-mdev.bb
├── netmodule-linux-image-minimal.bb
├── netmodule-linux-image-oem.bb
└── nmcontainer-python3.bb
Images build instructions¶
Start image build after sourcing environment with:
bitbake netmodule-linux-image
Images deploy location¶
- Built images are located in deploy directory.::
<project root>/build/tmp/deploy/images/<hw type e.g. am335x-nmhw21>/
Getting Started: NetModule Linux¶
NetModule AG provides an open source Linux Distribution based on Yoctoproject’s Reference distro “Poky”.
If you are new into yoctoproject you might want to read this: Getting Started: The Yocto Project Overview
NetModule Addons¶
- Board Support Packages
Layer meta-netmodule-bsp: Recipes to provide hardware support
- NetModule Distro
Layer meta-netmodule-distro: NetModule HW specific package selection
- Integration of OSTree
Layer meta-updater
Image Types¶
- netmodule-linux-release
OSTree support
clean build, ready to deploy
- netmodule-linux-dev
OSTree support
Several tools a developer would find useful already integrated.
- netmodule-linux-minimal
Minimal Kernel and Image size
RAM Disk Support
OSTree¶
OSTree is a system for versioning updates of Linux-based operating systems. It can be considered as “git for operating system binaries”.
Description¶
Difference between a “normal” OS and an “atomic” OS¶
On a normal OS, the updates are handled by a package-manager. If an update is executed, the package-manager updates each package to the newest version available at the current time. This results in an unique set of packages after every update.
When you do an update on an atomic OS, you update the OS as a whole, giving you a specific set of packages every time.
Filesystem structure¶
An operating system deployed with ostree is always consistent with the “ostree commit”. To make sure this is the case, the os has to be immutable. Ostree does this by creating a read-only bind-mount of the /usr folder.
OSTree uses UsrMov, this means that the folders “bin”, “lib” and “sbin” are moved from the root to the /usr directory. On the root those folders are replaced with links to the new location under /usr. This is done, because it reduces the need of read-only bind-mounts to the single /usr directory.
The root of an ostree-deployment is located in:
/sysroot/ostree/deploy/<os-name>/deploy/<commit hash>
System Partitioning¶
Because ostree mounts the /usr folder as read-only, we have two options to add additional software:
Create a new partition on the eMMC and mount it on lets say /data. | If done like this, new software can now be added to this data-folder.
Create an overlay over the /usr directory. If done like this, the /usr folder behaves like a normal read-write folder. This can be done with the command
ostree admin unlock --hotfix
Note: The changes done like this are reverted after another ostree update. Note: This is generally not recommended for production systems.
Boot Sequence¶
u-boot loads a uEnv.txt file which contains:
variable |
contents |
---|---|
kernel_image |
path to the kernel image |
ramdisk_image |
path to the ramdisk image |
bootargs |
the bootargs containing the path to the ostree-root. |
kernel_image2 |
path to the fallback kernel image |
ramdisk_image2 |
path to the fallback ramdisk image |
bootargs2 |
the bootargs containing the path to the fallback ostree-root. |
u-boot loads the kernel and ramdisk given by uEnv.txt
the ramdisk contains a script (/sbin/init) which prepares the rootfs.
the script runs
pivot_root
to switch from the ramdisk to the newly generated rootfs.the script calls the /sbin/init of the new rootfs.
Update system with ostree via USB¶
Put the “ostree_repo” folder on a USB-pendrive (ext4 formated).
Plug the USB-pendrive into the nmhw21.
On the nmhw21 terminal type:
bash # full path of repository e.g. /mnt/ostree_repo
OSTREE_REPO_PATH= # name the repository e.g. update_repo or just repo
OSTREE_REPO_NAME=
ostree remote add OSTREE_REPO_NAME file://OSTREE_REPO_PATH --no-gpg-verify
ostree --repo=$OSTREE_REPO_PATH summary -u OSTREE_REFS_REPO=
ostree remote refs $OSTREE_REPO_NAME
ostree pull $OSTREE_REFS_REPO
ostree admin deploy $OSTREE_REFS_REPO
verify pending update¶
ostree admin status | grep pending
reboot to apply update¶
reboot
Update system with ostree via network¶
Connect to the network.
nmcli c mod ethernet ipv4.method auto
nmcli c up ethernet
Add the repositories.
ostree remote add nmrepo-stable https://nmrepo.netmodule.com/chbe/stable/ --no-gpg-verify
ostree remote add nmrepo-unstable https://nmrepo.netmodule.com/chbe/unstable/ --no-gpg-verify
Download the image.
There are multiple architectures and images available. The naming convention is:
{YOCTO_VERSION}-{MACHINE}-{IMAGE_TYPE}
e.g. dunfell-am335x-nmhw21-vcu
Do only one of the following commands.
# Do this to get the newest stable image.
ostree pull nmrepo-stable dunfell-am335x-nmhw21-vcu
# Do this to get the newest unstable / nightly image.
ostree pull nmrepo-unstable dunfell-am335x-nmhw21-vcu
On the nmhw21 terminal type:
Do only one of the following commands.
# Do this to deploy the newest stable image.
ostree admin deploy nmrepo-stable:dunfell-am335x-nmhw21-vcu
# Do this to deploy the newest unstable / nightly image.
ostree admin deploy nmrepo-unstable:dunfell-am335x-nmhw21-vcu
Artifacts for nmhw21¶
wic-file¶
Address in blocks of 512B |
Content |
---|---|
0x0000 |
MBR (Partition Table) |
0x0100 (128kB) |
MLO |
0x0300 (384kB) |
u-boot.img |
0x2000 (4096kB) |
root-partition |
Artifacts overview¶
wic-file¶
The wic file is a flashable image file. When upgrading a system with a wic-file, the contents of the wic-file are mirrored to the mass storage device.
Kickstart/wks-file¶
The wks-file defines where the contents are placed in the wic-file. In our yocto build-system the file is located in meta-netmodule-bsp/wic/*.wks.
More Information: Yocto Project Reference Manual
am335x Startup¶

am335x-startup
HW |
*list |
---|---|
nmhw21 |
MMC1, MMC0, UART0, USB0 |
nmhw21 (jumper on X200) |
UART0, XIP, MMC0, NAND |
*See also:* AM335x Technical Reference Manual -> Chapter 26 - Initialization (S. 5014)
Automatic Partitioning¶
When you flashed a “.wic”-file your system will only have one partition
with almost no space. To make the filesystem usable, we provide an
auto-partitioning tool called nmhw-auto-part
.
Recommended settings¶
Run the script in interactive mode.
nmhw-auto-part -i
Press enter without entering values on all the steps.
Usage¶
nmhw-auto-part.sh [OPTION] 'devicename' 'size' 'mode' 'size'
Arguments¶
- ‘devicename’
device to use: e.g. /dev/sdb /dev/mmcblk1
- ‘size’
size of the first partition in MB (set 0 to keep current size)
- ‘mode’
‘data’ or ‘overlay’; type of partition to append
- ‘size’
size of the appended partition in MB (set to 0 to fill)
Options¶
-i interactive mode
-h help
You can either pass the four arguments ‘devicename’, ‘size’, ‘mode’ and ‘size’ or one option.
How to undo the partitioning¶
Delete Partition information
rm -r /etc/nmhw-auto-part
reboot
parted /dev/mmcblk1 rm 2
Rerun the autopartition script.
Note: The first partition will keep its size.
Files in /etc¶
/etc/nmhw-auto-part/overlay
This is an empty file. It indicates to the init script that it needs to mount an overlay.
/etc/nmhw-auto-part/data-partition
This file contains the path of the device, which serves as the data partition. It indicates to the init script that it needs to mount the data partition.
Bluetooth¶
For full documentation visit bluez.org.
Commands¶
Start and Discover nearby devices¶
root@am335x-vcu:~# bluetoothctl
[NEW] Controller 0C:B2:B7:11:61:9B am335x-vcu [default]
[NEW] Device 40:4E:36:55:DE:CE niconico
[bluetooth]# power on
Changing power on succeeded
[CHG] Controller 0C:B2:B7:11:61:9B Powered: yes
[bluetooth]# agent on
Agent registered
[bluetooth]# default-agent
Default agent request successful
[bluetooth]# discoverable on
[CHG] Controller 0C:B2:B7:11:61:9B Class: 0x200000
Changing discoverable on succeeded
[CHG] Controller 0C:B2:B7:11:61:9B Discoverable: yes
[bluetooth]# scan on
Discovery started
[CHG] Controller 0C:B2:B7:11:61:9B Discovering: yes
[NEW] Device 56:D2:37:FA:DC:8B 56-D2-37-FA-DC-8B
[NEW] Device 74:8D:3C:66:C9:7D 74-8D-3C-66-C9-7D
[NEW] Device 5A:D3:22:54:BD:6C 5A-D3-22-54-BD-6C
[NEW] Device CC:5B:4F:F4:8A:2B fenix 3 HR
[CHG] Device 74:8D:3C:66:C9:7D RSSI: -80
[NEW] Device 6F:90:CD:32:DE:1B 6F-90-CD-32-DE-1B
[NEW] Device 46:FB:E1:BC:5F:C8 46-FB-E1-BC-5F-C8
[CHG] Device 6F:90:CD:32:DE:1B RSSI: -103
[CHG] Device 6F:90:CD:32:DE:1B RSSI: -85
[CHG] Device 5A:D3:22:54:BD:6C RSSI: -75
[CHG] Device 74:8D:3C:66:C9:7D RSSI: -82
[CHG] Device 40:4E:36:55:DE:CE RSSI: -52
[CHG] Device 5A:D3:22:54:BD:6C RSSI: -66
[bluetooth]# scan off
[CHG] Device E0:E5:CF:96:FA:09 RSSI is nil
[CHG] Device 40:4E:36:55:DE:CE RSSI is nil
[CHG] Device 46:FB:E1:BC:5F:C8 RSSI is nil
[CHG] Controller 0C:B2:B7:11:61:9B Discovering: no
Discovery stopped
CAN¶
CAN Interfaces¶
Linux provides CAN driver for physical available CAN controller and for virtual created CAN adapter so called vcan.
Physical CAN Interface¶
Physical can interfaces depends on hardware and driver support. To check if physical can interfaces are available do:
ifconfig -a | grep can
Output should be similar to following:
can0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
can1 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
To initialize an interface, do the following:
ip link set can0 type can bitrate 125000
ip link set up can0
It is then possible to send and receive data with:
cansend can0 1FFFFFFF#112233445D556677
candump can0
Virtual CAN Interface - vcan¶
To bring up virtual can interface the kernel module vcan is required. Load vcan module:
modprobe vcan
And controls whether the module is loaded successfully:
lsmod | grep vcan
Output should be similar to following:
vcan 16384 0
Now a virtual can interface vcan0 can be created:
ip link add dev vcan0 type vcan
ip link set vcan0 mtu 16
ip link set up vcan0
To bring up CAN FD interface mtu size must increased to 72:
ip link add dev vcan0 type vcan
ip link set vcan0 mtu 72
ip link set up vcan0
And again control new created virtual can interface:
ifconfig vcan0
Output should be similar to following:
vcan0 Link encap:UNSPEC HWaddr 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00
UP RUNNING NOARP MTU:16 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:1000
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
From this point the virtual can interface vcan0 can be used e.g. for SocketCAN.
SocketCAN¶
SocketCAN is used to tunnel CAN data over TCP/IP (e.g. ethernet). For linux based system, Cannelloni and socketcand are examples for user space tool which use SocketCAN.
Bind virtual can adapter vcan0 to any counterpart:
cannelloni -I vcan0 -R <remote ip> -r <remote port> -l <local port>
For non blocking console append a &
in the command above.
Cannelloni Example¶

In this example you see Machine 1 with a physical CAN-Interface (can0) and Machine 2 with a virtual CAN-Interface (vcan0). With cannelloni its now possible to link the two CAN-Interfaces together via the TCP/IP stack (UDP and SCTP). This makes it possible to read and write the physical CAN from Machine 2 as if it were directly connected to Machine 2. This is useful if you want to process the CAN-data on an external Machine.
Example use of SocketCAN between two machines.
Config |
MACHINE 1 |
MACHINE 2 |
---|---|---|
IP |
192.168.0.2 |
192.168.0.3 |
Local cannelloni port |
2000 |
2000 |
MACHINE 1
cannelloni -I can0 -R 192.168.0.3 -r 2000 -l 2000
MACHINE 2
cannelloni -I vcan0 -R 192.168.0.2 -r 2000 -l 2000
Now you can test the functionallity with the following commands.
MACHINE 1
candump can0
MACHINE 2
cansend vcan0 1FFFFFFF#112233445D556677
You should now see the data on can0.
External Physical CAN Interface¶
Ensure that any can participant is on can bus. For communication verification a can PC interface is recommendend. Check also that physical bus is proper terminated with 120 Ohm impedance.
can-utils¶
can-utils provides severals tools to e.g. interact and monitor general can interfaces.
To send can frames to vcan0 command cansend can be used:
cansend <device> <can_frame>
# example
cansend vcan0 5A2#11.2233.445D556677.66
To dump can frames on a can interface use command candump:
candump <device>
# example
candump vcan0
Resources¶
Cannelloni: https://github.com/mguentner/cannelloni
Chrony¶
Chrony is a versatile implementation of the Network Time Protocol (NTP). It can synchronise the system clock with NTP servers, reference clocks (e.g. GPS receiver), and manual input using wristwatch and keyboard. It can also operate as an NTPv4 (RFC 5905) server and peer to provide a time service to other computers in the network.
Ensure that no other time daemon is running like ntp or ntimed to avoid conflicts.
Usage¶
Two programs are included in chrony, chronyd is a daemon that can be started at boot time and chronyc is a command-line interface program which can be used to monitor chronyd’s performance and to change various operating parameters while it is running.
If chrony is already configured, time sources can be watched with:
chronyc sources
Chrony Configuration File¶
Chrony daemon configuration file is located in directory /etc/chrony.conf
NTP Servers¶
NTP time servers can be defined in configuration files. It is recommended to select time servers which are physicaly close to the device. A pool of time servers can be found at the NTP Pool Project.
Example configuration:
server 0.pool.ntp.org iburst
server 1.pool.ntp.org iburst
server 2.pool.ntp.org iburst
GNSS¶
Chrony is able to use GNSS signal and their delivered time. If GPSD is used as GNSS daemon, then chrony can access GPSD shared memory to get time data.
Example configuration with GPSD shared memory access:
refclock SHM 0 poll 1 refid GPS offset 0.0 delay 2 filter 16
RTC¶
Chrony can handle hardware real time clock (rtc), measure time drift and correct it automatically. Define rtc device in configuration file by adding device path.
rtcdevice /dev/rtc
More configuration option¶
Chrony is a powerfull tool and provides much more functionality than described here. For further information see Chrony Documentation
Package Management using DNF¶
For full documentation visit dnf.readthedocs.io <https://dnf.readthedocs.io/en/latest/index.html>`_.
Setup¶
Add the netmodule package repository
mkdir /etc/yum.repos.d
touch /etc/yum.repos.d/oe-packages.repo
Add following lines to
/etc/yum.repos.d/oe-packages.repo
[oe-packages]
baseurl=https://nmrepo.netmodule.com/chbe/rpm/
gpgcheck=False
Commands¶
dnf search <pkg-name>
- Search packagednf install <pkg-name>
- Install packagednf remove <pkg-name>
- Remove package
OSTree compatibility¶
To use dnf with ostree you have to do the following steps:
mount an overlay-fs You might use the auto-partition-script with the recommended settings.
Add symbolic link to /lib/rpm
ln -s /usr/lib/rpm /var/lib/rpm
Hint: If this fails, remove the /var/lib/rpm
directory and rerun this step.
Ethernet¶
Overview¶
NetModule OEM Linux Distribution comes with built-in support for a number of Ethernet devices. This includes support for hardware solutions as simple as single port standard Ethernet PHY and very complex hardware architecture involving cascading Ethernet switches with external PHYs.
Supported scenarios¶
Basic setup¶
Single network for internal (umnet0) and external (eth0, broadr0 and broadr1) interfaces.
Supported hardware¶
NMHW21¶
TI Common Platform Ethernet Switch (CPSW)
NXP SJA1105TEL Five- Ports AVB & TSN Automotive Ethernet Switch
NXP TJA1100 100BASE-T1 PHY for Automotive Ethernet
SMSC LAN8710/LAN8720 PHY
+-------------------------------+
| TI AM335X |
| ARM Cortex A8 |
| |
+---------------+---------------+
|
+---+---+
| sw0p2 |
+-----------+-------+-----------+
| [cpu] |
| |
| TI CPSW Switch driver |
| |
| internal <eth1 > |
+--+-------+----------+-------+-+
| sw0p0 | | sw0p1 |
+---+---+ +---+---+
|
+---+---+
| sw1p4 |
+----------------+-------+---------------------+
| cpu |
| |
| NXP SJA1105TEL switchdev driver |
| |
| umnet0 broadr0 broadr1 eth0 |
+-------+----+-------+----+-------+----+-------+
| sw1p0 | | sw1p1 | | sw1p2 | | sw1p3 |
+---+---+ +---+---+ +---+---+ +---+---+
| | | |
| | | |
| | | |
+---+----+ +---+---+ +---+---+ +---+---+
| User | | phy6 | | phy7 | | phy1 |
| Module | +---+---+ +---+---+ +---+---+
| | | | |
| | +------------------+ +-----------------+
| | | NXP TJA110X | | SMSC LAN87X |
| | | driver | | driver |
+--------+ +------------------+ +-----------------+
NXP SJA1105TEL switchdev driver¶
Note
Changes between kernel 4.19 and kernel 5.10:
Interfaces have been renamed:
eth0 => internal (no need to configure it, it just needs to be up)
lan0 => eth0
eth0* (removed)
The “physical” interfaces (eth0, broadr0, broadr1, etc) can be configured directly
VLAN tagging is handled by the driver and there is no need to care about it
bridging can be configured directly through NetworkManager
Warning
Putting two interfaces of the switch in the same subnet will lead to networking problems. There should anyway be no reason for such a setup except for testing.
The SJA1105TEL switchdev driver functionality: - Ports are available in user space as netdevs (e.g. broadr1, eth0) - Hardware statistics and standard information about devices (ethtool) - Rx/Tx and error statistics (ifconfig) - Hardware offloading (bridge fdb) - VLAN tagging/bridging support (brctl, bridge vlan)
The SJA1105TEL switchdev driver limitations: - No VLAN double tagging
Hardware offloading¶
The idea is to offload the L2 data forwarding (switching) path from the kernel to the switch device by mirroring bridge FDB entries down to the device. An FDB entry is the {port, MAC, VLAN} tuple forwarding destination.
Static bridge FDB entries are installed, for example, using bridge command:
$ bridge fdb add ADDR dev DEV [vlan VID] [self]
The SJA1105TEL switch device has 1024 entries in the L2 address lookup table. Parts of the table can be statically configured, e.g.:
$ bridge fdb add 00:1b:21:2f:fa:1f dev eth0
Some of the entries are dynamically learned during operation. Show all valid FDB entries:
$ bridge fdb show
Loaded entries never time-out and cannot be replaced by learned entries. They have to be removed manually, e.g.:
$ bridge fdb del 00:1b:21:2f:fa:1f dev eth0
Bridging¶
Two or more interfaces of the switch can be bridged together. This means that devices on these two interfaces will be able to communicate as if they were directly connected, without, the CPU having to route the packets.
Warning
stp must never been enabled when bridging two ports of the switch, therefore, two ports should also never be put in the same subnet and loops must be avoided manually.
If a loop is created or if stp is enabled, the switch will not behave as expected and other interfaces which may not be involved in the bridge can also stop working properly.
E.g. Bridging eth0 and broadr0:
nmcli con add type bridge ifname br0 con-name br0 bridge.stp no
nmcli con add type bridge-slave ifname eth0 master br0
nmcli con add type bridge-slave ifname broadr0 master br0
nmcli con up br0
By default, NetworkManager enables DHCP on the created bridge. If the two interface must just be bridged without interaction with linux, ipv4 and ipv6 can be disabled.
nmcli con add type bridge ifname br0 con-name br0 bridge.stp no
nmcli con modify br0 ipv4.method disable ipv6.method disabled
nmcli con add type bridge-slave ifname eth0 master br0
nmcli con add type bridge-slave ifname broadr0 master br0
nmcli con up br0
NXP TJA110X PHY driver¶
Note
Changes between kernel 4.19 and kernel 5.10:
Configuration is now done through ethtool instead of sysfs
Checking link status of a TJA1100 PHY.
E.g. broadr0, cable connected:
ethtool broadr0 | grep -i "link detected"
Link detected: yes
E.g. broadr1, cable disconnected:
ethtool broadr1 | grep -i "link detected"
Link detected: no
Both TJA110X PHYs are configured as slaves by default.
E.g. check master/slave configuration of broadr0, default configuration:
ethtool broadr0 | grep -i "master-slave"
master-slave cfg: forced slave
E.g. set broadr1 as master (a counterpart has to be set as slave):
ethtool -s broadr1 master-slave forced-master
ethtool broadr1 | grep -i "master-slave"
master-slave cfg: forced master
The TJA1100 PHY driver can give SNR class of a connection.
E.g. check connection quality of broadr0 to a counterpart over short good quality cable:
ethtool broadr0 | grep -i sqi
SQI: 7/7
E.g. check connection quality of broadr1 to a counterpart over long poor quality cable:
ethtool broadr1 | grep -i sqi
SQI: 1/7
User space tools and configuration¶
Check available interfaces:
$ ip link show
List IP addresses:
$ ip address show
List routes:
$ ip route show
Deactivate a link layer device:
$ ip link set dev devicename down
Activate a device:
$ ip link set dev devicename up
Print current settings of the specified device
$ ethtool devname
Print statistics of the specified device
$ ethtool -S devname
References¶
Updating firmware¶
The NetModule Linux system provides a tool to upgrade the firmware of the different modules in the system.
The firmware packages are not available in the reference image but the latest supported firmware versions are part of each software release.
Firmware Location¶
The firmwares officialy supported by NetModule are available at https://nmrepo.netmodule.com/chbe/fwupdate/
Preparation¶
Before upgrading a module, it is recommended to check if it has been properly configured and started. All modules have matching service which is fetching the relevant informations from this module. See module specific examples below to see how to check the service for each type of module.
When the modules are properly configured, the output shows one of the two following lines:
Active: active (running)
Active: active (exited)
Once the device is started, the firmware version can be read under the following path: /run/<module type>/<module>.config
See module specific examples below.
Usage¶
The update tool can fetch the new firmware from the local device or via http from a remote server.
Local firmware¶
To upgrade using a local firmware, the firmware must be copied to the target first. The following command can then be executed:
nmhw-fwupdate <module> <firmware.tar.gz>
Where <module> is the module name as reported in the “.config” filename under /run/<module type>/<module>.config and <firmware> is the relative or full path to the firmware archive. See module specific examples below.
Remote firmware (HTTP)¶
If the firmware is available on an HTTP server (reachable from the target), the following command can be used:
nmhw-fwupdate <module> <http link>
Where <module> is the module name as reported in the “.config” filename under /run/<module type>/<module>.config and <http link> is the link to the firmware on the HTTP server. See module specific examples below.
Bootloaders¶
Warning
Upgrading a bootloader is a critical step and incompatibilities between a bootloader and the linux version in use may break the system. The upgrade should NOT be done without detailed instructions.
Supported systems¶
HW21 (u-boot)
HW26 (u-boot)
HW23 (imx-boot)
Example¶
# Check service status
systemctl status bootloader-config
# Check bootloader type and version
cat /run/bootloader/bootloader0.config
# Update from local firmware
nmhw-fwupdate bootloader0 nmhw21-u-boot-1.2.2.tar.gz
WWAN¶
Warning
Downgrading a WWAN modem will likely lead to a broken modem
Supported modules¶
u-blox TOBY-L210
Example¶
# Check service status
systemctl status wwan-config@wwan0
# Check wwan0 type and version
cat /run/wwan/wwan0.config
# Update from local firmware
nmhw-fwupdate wwan0 ublox-toby-l210_17.00-A01.01.tar.gz
# Update from remote firmware
nmhw-fwupdate wwan0 https://nmrepo.netmodule.com/chbe/fwupdate/ublox-toby-l210_17.00-A01.01.tar.gz
GNSS¶
Supported modules¶
u-blox NEO-M8L
Example¶
# Check service status
systemctl status gnss-mgr
# Check gnss0 type and version
cat /run/gnss/gnss0.config
# Update from local firmware
nmhw-fwupdate gnss0 UBX_M8_301_ADR_431_NEO_M8L.tar.gz
# Update from remote firmware
nmhw-fwupdate gnss0 https://nmrepo.netmodule.com/chbe/fwupdate/UBX_M8_301_ADR_431_NEO_M8L.tar.gz
Creating Bootloader Update Package¶
Preparation¶
Make sure you have the following binaries available:
The bootloader images:
for am335x devices:
spl-u-boot-am335x-<hwType>.img
u-boot-am335-<hwType>.img
for imx8 devices:
imx-boot
the flasher and helper binaries, which you can extract from a previously gotten bootloader update package otherwise call your NetModule Contact
for am335x devices:
flasher-netbird
check_uboot_header.sh
for imx8 devices:
flasher-net64
Create the Package¶
The update package is a simple gzipped tarball of the following content:
for am335x devices:
e.g. for a HW24 . ├── checksums ├── check_uboot_header.sh ├── flasher-netbird ├── info ├── spl-u-boot-am335x-nmhw24.img └── u-boot-am335x-nmhw24.img
for imx8 devices:
. ├── checksums ├── flasher-net64 ├── img │ └── imx-boot └── info
Follow the steps below and use the binaries as described before and you will get your own update package:
create a directory, e.g.
fw-pkg
copy the bootloader and flasher binaries into this directory
NOTE: For imx8 devices the bootloader binary goes into a sub-directory named
img
create the checkum file
checksums
with the following syntax:for am335x devices:
<md5-sum> <spl-image-name> <md5-sum> <u-boot-image-name>
for imx8 devices:
<md5-sum> img/<bootloader-image-name>
create an information file
info
with the following content, whereas thecompatible
string uses the HW numbers as defined as follows:until HW20:
nrhw<HW-Nbr>
example for HW20:
nrhw20
after HW20 to HW24:
nmhw<HW-Nbr>
example for HW24:
nmhw24
after HW24:
hw<HW-Nbr>
example for HW26:
hw26
version: <version> type: bootloader family: bootloader compatible: <hw-compatible-string>
for a HW24 with version 1.3.0 you will have this version file:
version: 1.3.0 type: bootloader family: bootloader compatible: nmhw24
create the package of the entire content
pack the content using tar:
tar czf <package-name>.tar.gz -C fw-pkg .
example for HW24 and version 1.3.0:
tar czf hw24-bootloader-1.3.0.tar.gz -C fw-pkg .
GNSS¶
The Global Navigation Satellite System can be accessed using different tools: gpsd provides a useful toolset and the gnss-mgr provides configuration possibilities.
gpsd¶
gpsd is used as the interface between the GNSS receiver and other location aware applications. Multiple applications can access the GNSS receiver via TCP connections on port 2947 at the same time, solving the problem of multiple applications requiring access to the same tty interface. gpsd includes several tools to interface to the GNSS receiver, like cpgs, gpsctl, gpscat and ubxtool.
Connecting ubxtool¶
The ubxtool might not establish a stable connection to the modem (interruptions, connection issues, …) depending on how the modem is connected internally. The following command helps to get a stable connection with ubxtool:
ser2net -C "2947:raw:0:/dev/gnss0: 115200 8DATABITS NONE 1STOPBIT NOBREAK"
NEO-M8L¶
The NEO-M8L module is a GNSS receiver by u-blox with the following key features:
Automotive Grade
GPS / QZSS, GLONASS, Galileo and BeiDou
Dead Reckoning using built in IMU
NEO-M9V¶
The NEO-M9V module is the replacement of the NEO-M8 and provided similar features.
gnss-mgr¶
gnss-mgr
provides GNSS receiver configuration possibilities and replaces the obsolete gnss-config
, gnss-save-on-shutdown
and neom8tool
.
This tool operates directly on the serial interface before gpsd is staring up and comes with different functionalities like:
- initialization (runs on each boot-up)
configuring the communciation bitrate of the receiver if necessary
configuring the used NMEA protocol version if necessary
clearing latest receiver state (save on shutdown)
save on shutdown (SoS) features like persisting/clearing/verifying receiver state to/from internal storage
configuring the receiver using a configuration file (in ini file format, see below)
- control functions
persist the actual configuration into non-volatile storage
cold-start the receiver
resetting the receiver’s configuration to default
The gnss-mgr is set up as systemd service (gnss-mgr.service
).
On each boot-up the gnss-mgr
checks and if necessary configures the bitrate and the NMEA protocol version. The gnss-mgr
configures the recevier with volatile parameters, i.e. the configuration is not persisted and when the power is cut, the receiver looses your configuration (the receiver then re-applies its internally stored setup at the next power-up). Additionally after successfully starting up the gnss services, some basic information about the GNSS receiver can be found at /run/gnss/gnss0.conf
.
root@am335x-nmhw21:~# cat /run/gnss/gnss0.config
Vendor: ublox
Model: NEO-M8L-0
Firmware: ADR 4.21 (Deprecated)
ubx-Protocol: 19.20
Supported Satellite Systems: GPS;GLO;GAL;BDS
Supported Augmentation Services: SBAS;IMES;QZSS
SW Version: EXT CORE 3.01 (1ec93f)
HW Version: 00080000
Capabilities¶
The command gnss-mgr --help
shows the entire capabilities of the gnss-mgr
:
root@am335x-nmhw21:~# gnss-mgr --help
usage: gnss-mgr [-h] [-V] [-v] [-q] device {init,sos,config,control} ...
Manages GNSS modem
positional arguments:
device local serial device to which GNSS modem is connected
(e.g. /dev/gnss0)
optional arguments:
-h, --help show this help message and exit
-V, --version show program's version number and exit
-v, --verbose be verbose, show debug output
-q, --quiet be quiet, only show warnings and errors
command:
{init,sos,config,control}
select command
init sets up GNSS modem
sos save on shutdown operations
config configures GNSS modem
control performs GNSS modem control function
Each command (init, sos, config and control) provides a sub-help:
root@am335x-nmhw21:~# gnss-mgr /dev/gnss0 init --help
usage: gnss-mgr device init [-h] [-f RUNFILE]
optional arguments:
-h, --help show this help message and exit
-f RUNFILE, --file RUNFILE
path to run file
----------------------------
root@am335x-nmhw21:~# gnss-mgr /dev/gnss0 sos --help
usage: gnss-mgr device sos [-h] {save,clear}
positional arguments:
{save,clear} selects sos operation to perform
optional arguments:
-h, --help show this help message and exit
----------------------------
root@am335x-nmhw21:~# gnss-mgr /dev/gnss0 config --help
usage: gnss-mgr device config [-h] [-f CONFIGFILE]
optional arguments:
-h, --help show this help message and exit
-f CONFIGFILE, --file CONFIGFILE
path to config file
----------------------------
root@am335x-nmhw21:~# gnss-mgr /dev/gnss0 control --help
usage: gnss-mgr device control [-h] {cold-start,persist,factory-reset}
positional arguments:
{cold-start,persist,factory-reset}
selects action to perform
optional arguments:
-h, --help show this help message and exit
Configuring the GNSS Receiver¶
The gnss-mgr
configures the GNSS receiver by using configuration files in ini format. Writing the configuration is managed by feeding the appropriate file to the gnss-mgr.
Warning
A misconfigured GNSS with Dead Reckoning (DR) generates worse results as a GNSS receiver only!
Note
When running the GNSS receiver at 9600 baud some UBX packets might be lost which results in overall worse GNSS performance. Therefore it is strongly recommended to let the receiver operate with 115200 baudto. Additionally it is recommended to configure the GNSS receiver persistent (see example Persistent configuration of the GNSS receiver below.
Configuration files¶
Use the configuration file /etc/gnss/gnss0.conf
as template to properly configure the GNSS receiver.
Warning
The IMU angles (yaw, pitch, roll) are different between NEO-M9 and M8
The following example of gnss0 config file shows the configuration capabilities of the gnss-mgr
. The comments show how to setup each parameter:
root@am335x-nmhw21:~# cat /etc/gnss/gnss0.conf
#
# This file is part of gnss-mgr service
# To make changes, edit the values in this file and reload
# gnss-mgr service.
#
# Any empty value will use the default or persistent configuration
# of the receiver.
[default]
# Indicates the version of this config file, it should not be modified.
# If unsure of its value, sample config file can always be found in
# /usr/etc/gnss/
#
# Change history
# version 3: Added field navigation.dead-reckoning
# version 4: Added "time" section
version=4
# Select measurement and navigation output rate
# Allowed values : 1 - 10 [Hz]
update-rate=
#update-rate=1
#
# Navigation settings
#
[navigation]
# Enables or disables dead reckoning
# Supported values:
# enable, disable
dead-reckoning=
#dead-reckoning=disable
# Selects dynamic mode
# Supported values:
# stationary, vehicle
mode=
#mode=vehicle
#
# Selects GNSS systems
# Allowed values:
# GPS;GLONASS;SBAS
# GPS;Galileo;Beidou;SBAS
systems=
#systems=GPS;GLONASS;SBAS
#systems=GPS;Galileo;Beidou;SBAS
#
# Installation settings
# For details on this section, see the relevant documentation
#
[installation]
#
# IMU orientation in degrees [°]
#
# ! Be careful, the IMU orientation may be different between
# NEO-M8 and NEO-M9
#
# ! Also configuring these angles will disable auto-alignment
#
# yaw: value in degrees (0 to 360)
# pitch: value in degrees (-90 to 90)
# roll: value in degrees (-180 to 180)
yaw=
pitch=
roll=
# Lever arm lengths in meters [m]
# Format x;y;z
# Example:
# vrp2antenna=1.0;1.5;0.3
vrp2antenna=
vrp2imu=
#
# Configurations related to time
# For details on this section, see the relevant documentation
#
[time]
#
# Enables or disables the time pulse (PPS) line
# If it is not set, the default or already configured
# state of the receiver will be used.
#
# NB: This feature may not be available on all systems
# Handling of the PPS line must also be done.
#
timepulse=
#timepulse=enable
#timepulse=disable
#
# Sets the frequency [Hz] of the time pulse (PPS) line
#
# If not set the default or already configured value is used
#
timepulse-frequency=
#timepulse-frequency=1
#timepulse-frequency=20
Lever Arm Lengths¶
The following figure shows an installation example and how to configure the receiver’s lever arm lengths.
Installation and positioning¶
- LeverConfiguration with values
vrp2antenna=1.6;0;1.7
vrp2imu=2.1;0.6;0.8
Timepulse configuration¶
The timepulse can be enable or disabled and configured in the [time] section. This feature sends a pulse every 1/X seconds. Note that the PPS line must be handled outside of gnss-mgr: depending on the system, it may be:
not connected
connected directly to the CPU and in this case handled by the “time” software
connected to an external component
Examples¶
Configuring the GNSS receiver:
gnss-mgr /dev/gnss0 config -f /etc/gnss/gnss0.conf
Persisting the configuration of the GNSS receiver:
gnss-mgr /dev/gnss0 control persist
Resetting the receiver’s configuration to default:
gnss-mgr /dev/gnss0 control factory-reset
Troubleshooting¶
If the receiver is no longer accessible, the issue most seen is that baud rates of serial interface (ttyS3) and receiver are not matching.
Save on Shutdown¶
The u-blox GNSS receivers can be instructed to save their current state to the internal non-volatile memory and restore it after a power cycle.
Note that the receiver state and the receiver configuration must be distinguished: Saving the state before the system is shut-down can help your GNSS receiver to get a faster fix after booting. Save on shutdown does however not save any configuration done by the user. The receiver configuration needs to be saved manually to the receiver’s internal non-volatile memory (only once), see Example Persiting the configuration of the GNSS receiver.
The gnss-mgr
service instructs the GNSS receiver to save its state whenever your linux system receives a shutdown or reboot instruction.
Upon reboot the same service logs if the GNSS receiver state has been successfully restored.
Examples¶
Storing the state to the GNSS receiver’s internal storage:
gnss-mgr /dev/gnss0 sos save
Clearing the state in the GNSS receiver’s internal storage:
gnss-mgr /dev/gnss0 sos clear
Firmware update (specific to u-blox NEO-M8L)¶
The firmware of the module u-blox NEO-M8L can be upgraded as explained in Updating firmware.:
Testing¶
To test the GNSS function connect an active GNSS antenna to X3300 “GNSS”.
Run “cgps” tool
Your output should look like this. Typically it takes 3..20 seconds for a fix.
┌───────────────────────────────────────────┐┌─────────────────────────────────┐
│ Time: 2018-07-05T06:49:00.000Z ││PRN: Elev: Azim: SNR: Used: │
│ Latitude: 47.31890666 N ││ 6 18 082 28 Y │
│ Longitude: 7.97375949 E ││ 17 15 039 30 Y │
│ Altitude: 1641.076 ft ││ 19 35 052 27 Y │
│ Speed: 0.14 mph ││ 32 32 305 16 Y │
│ Heading: 0.0 deg (true) ││ 66 27 311 23 Y │
│ Climb: 0.00 ft/min ││ 74 43 076 28 Y │
│ Status: 3D FIX (3 secs) ││ 84 46 063 21 Y │
│ Longitude Err: +/- 33 ft ││ │
│ Latitude Err: +/- 111 ft ││ │
│ Altitude Err: +/- 200 ft ││ │
│ Course Err: n/a ││ │
│ Speed Err: +/- 152 mph ││ │
│ Time offset: 7176.328 ││ │
│ Grid Square: JN37xh ││ │
└───────────────────────────────────────────┘└─────────────────────────────────┘
Access gps interface¶
If direct interface access is required, the gps device is
available under /dev/gnss0
.
Be aware that gnss0
is just a symlink to the real device managed by udev.
If you need to know the real device, follow the symlink with:
Example output:
root@am335x-nmhw21:~# ls -l /dev/gnss0
lrwxrwxrwx 1 root root 5 Jul 2 07:06 /dev/gnss0 -> ttyS3
IMU¶
ST provides LSM6DSx driver which provides two different ways of reading out IMU data.
Note
Changes betweeen kernel 4.19 and 5.10:
The gyroscope and accelerometer have switched numbering:
gyroscope is now at /sys/bus/iio/devices/iio:device0
accelerometer is now at /sys/bus/iio/devices/iio:device1
There is only one scale value for all axes instead of one per axis
Polling mode¶
Polling mode is the simplest IMU driver configuration, where data is read out on request. This mode does not support hardware timestamping.
Accelerometer¶
Get raw value of z-axis
cat /sys/bus/iio/devices/iio\:device1/in_accel_z_raw
Get scale value
cat /sys/bus/iio/devices/iio\:device1/in_accel_scale
Multiply the two to get the acceleration in m/s2. For z-axis this should be around 9.81m/s2.
Example:
cat /sys/bus/iio/devices/iio\:device1/in_accel_z_raw
# 16499
cat /sys/bus/iio/devices/iio\:device1/in_accel_scale
# 0.000598
# --> 9.8664
Buffered mode¶
Buffered mode enables full driver functionality, but requires hardware interrupts to be processed by the driver, which consumes more CPU load. This mode supports hardware timestamping.
Configuration¶
Buffered mode requires configuration. Following is a typical configuration to receive all the data IMU provides, including hardware timestamps:
Accelerometer¶
# Disable buffered mode
echo 0 > /sys/bus/iio/devices/iio\:device1/buffer/enable
# Subscribe to data elements
echo 1 > /sys/bus/iio/devices/iio\:device1/scan_elements/in_accel_x_en
echo 1 > /sys/bus/iio/devices/iio\:device1/scan_elements/in_accel_y_en
echo 1 > /sys/bus/iio/devices/iio\:device1/scan_elements/in_accel_z_en
echo 1 > /sys/bus/iio/devices/iio\:device1/scan_elements/in_timestamp_en
# Set sampling frequency
echo 13 > /sys/bus/iio/devices/iio\:device1/sampling_frequency
# Set buffer length
echo 2 > /sys/bus/iio/devices/iio\:device1/buffer/length
# Enable buffered mode
echo 1 > /sys/bus/iio/devices/iio\:device1/buffer/enable
Gyro¶
# Disable buffered mode
echo 0 > /sys/bus/iio/devices/iio\:device0/buffer/enable
# Subscribe to data elements
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_anglvel_x_en
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_anglvel_y_en
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_anglvel_z_en
echo 1 > /sys/bus/iio/devices/iio\:device0/scan_elements/in_timestamp_en
# Set sampling frequency
echo 13 > /sys/bus/iio/devices/iio\:device0/sampling_frequency
# Set buffer length
echo 2 > /sys/bus/iio/devices/iio\:device0/buffer/length
# Enable buffered mode
echo 1 > /sys/bus/iio/devices/iio\:device0/buffer/enable
Data¶
Reading out IMU data in buffered mode is done in a different way comparing to polling mode. In polling mode data is provided via driver SysFS nodes, while in buffered mode data is read out via dedicated char devices.
Accelerometer¶
hexdump /dev/accel0
Gyro¶
hexdump /dev/gyro0
Reconfiguration¶
Buffered mode does not allow reconfiguration on the fly. However, it is allowed to temporarily disable buffered mode while IMU char device is opened, which gives a possibility to reconfigure IMU driver. For example, if some application is used to read the data from accelerometer (see example above), it is possible to change its sampling frequency without closing the application:
echo 0 > /sys/bus/iio/devices/iio:device1/buffer/enable
echo 13 > /sys/bus/iio/devices/iio:device1/sampling_frequency
echo 1 > /sys/bus/iio/devices/iio:device1/buffer/enable
LEDs¶
NMHW21 provides four LEDs that can be controlled by user application or via command line.
The LEDs are described as follows:
Indicator onboard (ind)
Status onboard (status)
Indicator user-interface (ind ui)
Status user-interface (status ui)
Standard LED behavior¶
On startup (during bootloader/system-boot) the LEDs follow a specific pattern. During the startup the LEDs on the user-interface and the onboard LEDs are synced.
start of the bootloader (hard coded into u-boot)
start of kernel (defined in the device tree)
Hard reset¶
On a hard reset the onboard status LED starts orange.
Mainboard Indicator¶
Green
$ echo 1 > /sys/class/leds/ind\:green/brightness
$ echo 0 > /sys/class/leds/ind\:red/brightness
Orange
$ echo 1 > /sys/class/leds/ind\:green/brightness
$ echo 1 > /sys/class/leds/ind\:red/brightness
Red
$ echo 0 > /sys/class/leds/ind\:green/brightness
$ echo 1 > /sys/class/leds/ind\:red/brightness
Off
$ echo 0 > /sys/class/leds/ind\:green/brightness
$ echo 0 > /sys/class/leds/ind\:red/brightness
Mainboard Status¶
Green
$ echo 1 > /sys/class/leds/status\:green/brightness
$ echo 0 > /sys/class/leds/status\:red/brightness
Orange
$ echo 1 > /sys/class/leds/status\:green/brightness
$ echo 1 > /sys/class/leds/status\:red/brightness
Red
$ echo 0 > /sys/class/leds/status\:green/brightness
$ echo 1 > /sys/class/leds/status\:red/brightness
Off
$ echo 0 > /sys/class/leds/status\:green/brightness
$ echo 0 > /sys/class/leds/status\:red/brightness
User Interface Indicator¶
Green
$ echo 1 > /sys/class/leds/ui\:ind\:green/brightness
$ echo 0 > /sys/class/leds/ui\:ind\:red/brightness
Orange
$ echo 1 > /sys/class/leds/ui\:ind\:green/brightness
$ echo 1 > /sys/class/leds/ui\:ind\:red/brightness
Red
# echo 0 > /sys/class/leds/ui\:ind\:green/brightness
$ echo 1 > /sys/class/leds/ui\:ind\:red/brightness
Off
# echo 0 > /sys/class/leds/ui\:ind\:green/brightness
$ echo 0 > /sys/class/leds/ui\:ind\:red/brightness
User Interface Status¶
Green
$ echo 1 > /sys/class/leds/ui\:status\:green/brightness
$ echo 0 > /sys/class/leds/ui\:status\:red/brightness
Orange
$ echo 1 > /sys/class/leds/ui\:status\:green/brightness
$ echo 1 > /sys/class/leds/ui\:status\:red/brightness
Red
$ echo 0 > /sys/class/leds/ui\:status\:green/brightness
$ echo 1 > /sys/class/leds/ui\:status\:red/brightness
Off
$ echo 0 > /sys/class/leds/ui\:status\:green/brightness
$ echo 0 > /sys/class/leds/ui\:status\:red/brightness
Linux System Logging¶
Our distribution supports user space and kernel log messages and uses journald as system logger. Its configuration file provides a lot of parameters and can be found under /etc/systemd/journald.conf
and in the drop-in folders journald.conf.d
(for the full detailed information, please check journald.conf(5). This section describes the most important parameters and information regarding logging.
Accessing Log Files¶
- To read out journals the command line tool journalctrl is provided:
journalctl
- To follow latest log messages pass argument -f:
journalctl -f
- Show filtered by units:
journalctl -u <your-unit.service>
More information in journalctrl man page
Storage of the Logs¶
There are two modes about how logs can be stored: - volatile = logs are stored to RAM - persistent = logs are stored to flash
NOTE: The flash memory has limited write cycles which needs to be taken into account for the devices lifetime.
IMPORTANT: To not stress unnecessary the flash memory, our distribution logs as default the messages into RAM = volatile.
The logging system can be tailored to the need of the application. Full system logging makes analyzing an issue simpler and purposeful but it may cost valuable disk space and perfomance as well.
The follow subsection explains the most important configuration settings.
Configuration Parameters¶
Be aware about configuration files in the drop-in folders as described in the man pages.
You can take the config file /etc/systemd/journald.conf
as template and change or tailor the parameters for the application’s need. Nevertheless, the following parameters are the most important to understand:
Storage=
Can be either “volatile”, “persistent”, “auto” or “none”:
volatile (default) - The logs will be stored in memory below /run/log/journal - After a reboot the logs will be gone - The storage parameters with the “Runtime” prefix apply here
persistent - The logs will be stored on the disk below /var/log/journal - After a reboot the logs will still be there - The storage parameters with the “System” prefix apply here
auto - If the folder
/var/log/journal
exists, the behavior is the same as with “persistent” otherwise it behaves like “volatile”none - No logs will be saved. Only forwarding will be done (if enabled).
SystemMaxUse= / RuntimeMaxUse=
Control how much disk / memory space the journal may use up at most. Specify values in bytes or use K, M, G, T, P, E as units. Default values: SystemMaxUse=64M, RuntimeMaxUse=16M
SystemKeepFree= / RuntimeKeepFree=
Control how much disk / memory space the journal may keeps free. Specify values in bytes or use K, M, G, T, P, E as units. Systemd-journald will respect both limits (KeepFree/MaxUse) and use the smaller of the two values. Default values: SystemKeepFree=350M, RuntimeKeepFree=not set
SyncIntervalSec=
The timeout before synchronizing journal files to disk. This setting takes time values which may be suffixed with the units “m” for minutes. Default value = 5min
ForwardToSyslog=
Use “yes” or “no”. Enables forwarding to the old syslog (/var/log/messages). If this is enabled, there will still be messages written to the disk regardless of the “Storage=” parameter. Default = no
ForwardToConsole=
Use “yes” or “no”. Useful for debugging purposes Default = no
How to change the settings¶
If you want to change the default settings like for example persisting the log files, the following steps need to be done…
Without having drop-in folders:
Change the storage parameter in the config file
/etc/systemd/journald.conf
toStorage=persistent
Reboot your device (
reboot
) or restart the logger system (systemctl restart systemd-journald
)
Having drop-in folders:
Create a drop-in folder like
/etc/systemd/journald.conf.d/
Add your configuration changes to a file within that folder, e.g.
/etc/systemd/journald.conf.d/01-journald.conf
Reboot your device (
reboot
) or restart the logger system (systemctl restart systemd-journald
)
NOTE: Don’t forget to clean the logs when you are switching from persistent to volatile storage. More details see section Maintaining the Logs below.
Maintaining the Logs¶
In embedded devices the disk usage might be essential. The logger system provides several tools to maintain the logs.
Disk Usage¶
To check the amount of disk space the logs are taking, just run this command:
root@am335x-nmhw21:~# journalctl --disk-usage
Archived and active journals take up 18.0M in the file system.
Cleaning¶
There are several methods provided to clean the logs.
Cleaning your logs to a specific size run journalctl --vacuum-size=
. This removes the oldest archived journal files until the disk space they use falls below the specified size (specified with the usual “K”, “M”, “G” and “T” suffixes):
root@am335x-nmhw21:~# journalctl --vacuum-size=4M
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-00000000000014c8-0005ae5e2a594f10.journal (2.0M).
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-0000000000001af7-0005ae5ecf0899e3.journal (2.0M).
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-00000000000020d0-0005ae5f68b8138f.journal (2.0M).
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-00000000000026c9-0005ae600002f7a6.journal (2.0M).
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-0000000000002cc1-0005ae60973a5468.journal (2.0M).
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-00000000000032b9-0005ae612e720fcf.journal (2.0M).
Vacuuming done, freed 12.0M of archived journals from /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc.
Cleaning your logs using a specific time run journalctl --vacuum-time=
. This removes all archived journal files contain no data older than the specified timespan (specified with the usual “s”, “m”, “h”, “days”, “months”, “weeks” and “years” suffixes):
root@am335x-nmhw21:~# journalctl --vacuum-time=1s
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-00000000000038b1-0005ae61c5b11a9d.journal (2.0M).
Deleted archived journal /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc/system@335f2d7f78764e27ba522dc69770346f-0000000000003ef0-0005ae6259e61874.journal (2.0M).
Vacuuming done, freed 4.0M of archived journals from /run/log/journal/c8b8c280f0bc43aba10c21e3574e81fc.
NOTE: When switched from persistent to volatile and after cleaning, it might also be possible to remove the persistent logs by calling rm -rf /var/log/journal/*
.
(e)MMC¶
Health Status¶
You can read your eMMC health status by using the mmc
command and reading
the EXT_CSD (extended card specific data) section. The life time estimation
can be read for SLC and MLC areas as well as pre EOL status.
~# mmc extcsd read /dev/mmcblk1 | grep LIFE
eMMC Life Time Estimation A [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_A]: 0x01
eMMC Life Time Estimation B [EXT_CSD_DEVICE_LIFE_TIME_EST_TYP_B]: 0x01
~# mmc extcsd read /dev/mmcblk1 | grep EOL
eMMC Pre EOL information [EXT_CSD_PRE_EOL_INFO]: 0x01
The life time values are provided in 10% steps:
0x01 = 0-10% device life time used
0x02 = 10-20% device life time used
…
whereas life time estimation type A is for SLC eraseblocks and type B is for MLC eraseblocks.
The EOL information is an overall status for reserved blocks, given as follows:
0x00 = Not defined
0x01 = Normal: consumed less than 80% of the reserved blocks
0x02 = Warning: consumed 80% of the reserved blocks
0x03 = Urgent: consumed 90% of the reserved blocks
Write Reliability¶
Similar to the eMMC health status, you can check and set the write reliablity
using the mmc
command. The information reside also the EXT_CSD (extended
card specific data) section. There are two parameters which are needed for the
write reliability:
WR_REL_PARAM
the LSB 1 defines if
WR_REL_SET
is writableLSB = 1: writable
LSB = 0: read-only
WR_REL_SET
shows the setup of reliable writing for each partition, whereas partition 1 starts at the LSB 1
WR_REL_SET = ext_csd[EXT_CSD_WR_REL_SET] | (1<<partition);
Check Write Reliability Setup¶
Check the write reliability setup by reading EXT_CSD from your device and filtering the two parameters:
~# mmc extcsd read /dev/mmcblk0 | grep WR_REL_PARAM
Write reliability parameter register [WR_REL_PARAM]: 0x05
~# mmc extcsd read /dev/mmcblk0 | grep WR_REL_SET
Write reliability setting register [WR_REL_SET]: 0x1f
Value Explanation:
WR_REL_PARAM = 0x05
The LSB in
WR_REL_PARAM
is set, which means thatWR_REL_SET
is writable. I.e. read-only would have shownWR_REL_PARAM: 0x04
WR_REL_SET = 0x1f
The LSB in
WR_REL_SET
is set, which means that reliable write is enable for partition 1. I.e. disabled would have shownWR_REL_SET = 0x1e
Enable Write Reliability¶
Enabling reliable writing can be done with the mmc command
write_reliability set
as seen in the help:
~# mmc --help
...
mmc write_reliability set <-y|-n|-c> <partition> <device>
Enable write reliability per partition for the <device>.
Dry-run only unless -y or -c is passed.
Use -c if more partitioning settings are still to come.
NOTE! This is a one-time programmable (unreversible) change.
...
whereas a dry run can be made by providing the parameter -n.
Note
Setting write reliability can only be done once (unreversible)!
Storage Information¶
The information described in the upper sections are as well collected by a
small application called storage-info. This application reports the values
in a human readable format to the file /run/storage/storage0.config
:
~# cat /run/storage/storage0.config
Chip Name: DG4008
HW Revision: 0x0
Revision: 0x8
FW Version: 39102417
Serial Number: 0x65b0470c
Reliable Writable: 1
Reliable Write Config: 0x1f
Pre-EOL Information: 1 = Normal
Lifetime used (SLC): 10%
Lifetime used (MLC): 10%
Disk space free: 492.7MB
Footnotes
NetModule Linux Networking¶
Power Management¶
Overview¶
NetModule OEM Linux Distribution provides two standard high-level power management strategies:
system-wide power management,
working-state power management.
System-wide power management strategy is using global low-power states to reduce system activity. In these states, referred as sleep states, user space code cannot be executed. Depending on sleep state supported by the platform, different levels of energy saving can be achieved. To get back to the working state, the system expects to receive a special signal from one of the designated devices.
Working-state power management strategy corresponds to adjusting the power states of individual hardware components.
Supported hardware¶
DA9063 System PMIC
Supported sleep states¶
- Standby
This state provides a relatively straightforward transition back to the working state. In this state the system core logic retains power and no operating state is lost. It offers moderate, real energy savings.
- PMIC’s Power Down Mode
Platforms with DA9063 System PMIC can support more sophisticated energy saving options by disabling the system power domain. The system power domain is enabled on a signal received from a preconfigured wake-up device.
Supported wake-up scenarios¶
RTC based alarm
IMU based events: single-tap, double-tap
ONKEY event
KL15 event
Smart Battery¶
NetModule OEM Linux Distribution can run on devices supplied by a smart battery. To get current status of the battery our distribution provides a battery test tool.
User space tools and configuration¶
Enter standby state:
$ echo standby > /sys/power/state
Wake up from standby after 10 seconds:
rtcwake -d /dev/rtc0 -m standby -s 10
or without rtcwake in your image:
echo +10 > /sys/class/rtc/rtc0/wakealarm && echo standby > /sys/power/state
Enter PMIC’s power down mode:
$ poweroff
Start system after ~1 min when in PMIC’s power down mode:
echo +60 > /sys/class/rtc/rtc0/wakealarm && poweroff
Using a battery test:
$ batterytest -h
battery tool
Examples:
batterytest -v get voltage
batterytest -a get current
batterytest -t do battery test
Main modes of operation:
-h, --help print this help
-A, --all print all battery information
-v, --voltage get battery voltage
-a, --current get battery current
-c, --capacity get remaining capacity
-r, --reg raw mode, register access
-t, --test run battery test
Remote GPIO driver¶
Configuration¶
By default, driver will create 32 GPIO’s (named RGPIO0-RGPIO31), and will set server IP and port as 192.168.1.42:6666.
It is possible, however, to configure Remote GPIO driver via device tree:
remote-gpios {
compatible = "remote-gpios";
ip = "192.168.1.64";
port = /bits/ 16 <6666>;
remote-gpio@0 {
label = "umgpo0";
};
remote-gpio@1 {
label = "umgpo1";
};
remote-gpio@2 {
label = "umgpo2";
};
remote-gpio@3 {
label = "umgpo3";
};
remote-gpio@4 {
label = "umpu0";
};
remote-gpio@5 {
label = "umpu1";
};
remote-gpio@6 {
label = "umpu2";
};
remote-gpio@7 {
label = "umpu3";
};
};
The ip-address and port can be changed via SysFS under /sys/class/remote-gpio/remote-gpio/config/
. The service “um-service-config.service” will configure the port to either “6666” or “7020” depending on the user-module firmware revision.
Protocol¶
The Protocol uses TCP. It consists of commands and events, where command is something that is received by user module (server), and event is a state notification to the client. There can be multiple events or commands in one TCP-Package.
Command: set GPIO output
O<id><state>
Where:
id is two digit pin hex number
state is 0 for low, 1 for high
Examples:
Set GPIO 13 low
O0D0
Set GPIO 8 high
O081
Event: GPIO input state
I<id><state>
Where:
id is two digit pin hex number
state is 0 for low, 1 for high
Examples:
GPIO input 2 set to low
I020
GPIO input 11 set to high
I0B1
GPIO output 1 and 2 are set to high
O011O021
Usage¶
Since linux 4.8 the GPIO sysfs interface is deprecated. User space should use the character device instead. Current de-facto standard of using new GPIO system is libgpiod library and its tools:
gpiodetect
gpioinfo
gpioget
gpioset
gpiofind
gpiomon
System State Framework (SSF)¶
Introduction¶
This document describes an extensible design for tracking and publishing the system state for NG800 and OEM products derived from NG800.
The system state is a string variable that reflects the run-level of the overall system (off, booting, starting, up, shutdown-pending, shutting-down, powering-down). This value is published to user applications via the sysfs (file system).
At the core of the design a state machine tracks the system state and processes multiple inputs such as the ignition signal. Before shutting down Linux because of a de-asserted ignition signal, the state machine grants user-space application time to properly shut down. User applications can prolong the shutdown timer if they need more time to terminate. If the timer elapses, the state machine instructs the kernel to shut down.
File System Entries¶
All the entries are available under the directory /sys/kernel/broker:
ignition
status of the ignition signal
1 = asserted
0 = de-asserted
system-state
state of the system
starting –> operating system, applications, etc are starting up
up –> system start-up finished, i.e. fully booted, up and running
shutdown-pending –> system was told to shut down by giving applications time to terminate, see also shutdown-delay
shutting-down –> shut down in progress
system-state-target
interface to “command” the SSF, i.e. the following parts can be written in it:
up –> –> triggers the SSF for being up (transition from starting to up)
reboot –> triggers an immediate reboot
powerdown –> triggers an immediate power-off
shutdown-delay [seconds]
set or read the default shutdown-delay
this value is initialized in the device-tree
extend-shutdown-delay [seconds]
delay the shutdown to have more time to terminate applications
remaining-shutdown-delay [seconds]
countdown with the remaining time until the device shuts down
start-reason
information about the reason for the start-up
power –> ignition and power are both attached to the device
reboot –> device is rebooting (reboot command, ignition signal or RTC alarm during shut down process)
watchdog –> device is reset by watchdog (see watchdog feature below)
wakeup;ignition –> the device was ignited at a power down (power supply still attached)
wakeup;rtc-alarm –> the device woke up by an RTC alarm (power supply still attached)
ping-request
used for the watchdog feature to test a correct operation of the kernel modules
writing a test string triggers the kernel modules (response shown in ping-response)
ping-response
used for the watchdog feature to test a correct operation of the kernel modules
reading the response triggered by writing into ping-request
voltage-in
used by the battery-protection module.
It shows the current input voltage in mV.
For testing purposes we can write an voltage to it to simulate a specific input voltage.
SSF Components¶
The SSF consists of two kernel modules and a user space application:
SSF broker (kernel module)
exposes all important SSF topics as sysfs files
distributes SSF notifications to registerd components
SSF sysstate (kernel module)
exposes the current core system state in the sysfs file
SSF manager (user space application)
writes the state to filesys system-state file such as
up as soon as the system is completely booted
powerdown as soon as a powerdown is progressing
reboot as soon as a reboot is progressing
handles the watchdog including the ping check (ping-request and ping-response)
Note
The SSF manager is provided with our OEM Linux Release. If a custom handling of the SSF is needed it can be configured with its command line options, see section SSF Manager below.
Device Tree Entries¶
At the moment there are only two relevant options to set in the device-tree. The rest of the device tree entries should be left as is or the device may not function properly.
default-shutdown-delay-s
the default shutdown-delay when no extending of the shutdown-delay is requested.
sets the value of shutdown-delay on startup.
max-shutdown-delay-s
sets the maximum time of the shutdown-delay. This is used to make sure the shutdown delay can’t be extended forever.
cutoff-voltage-mv
If the input voltage is lower than the cutoff-voltage the device will power-down.
Pending Shutdown¶
When the ignition signal is de-asserted the system-state shows shutdown-pending for the time located in the file remaining-shutdown-delay. Re-asserting the ignition signal during this time the system-state changes back to up.
Prolonging a pending shutdown is described in the next section.
Extending a Shutdown¶
As mentioned above the shut down can be delayed to have time to terminate applications properly. The following example shows about how to use it:
Example: Let’s assume the default shutdown is 60s and after 30s we notice that we need to delay it for 75s. Perform the following command:
echo "75" > /sys/kernel/broker/extend-shutdown-delay
With this command the shutdown countdown starts again from 75s.
Note
The maximum total delay is configured in the device-tree or is 300s by default.
RTC wake-up¶
The SSF provides a start reason to differentiate between RTC wake-up and ignition signal. To set up an RTC wake-up you can just use the linux command rtcwake.
Example: If I want to wake-up my device after 90s from now and in the meantime it shall be powered off, I can call this:
rtcwake -s 90 -m off
The start reason read from start-reason is wakeup;rtc-alarm.
Device is Shutting down¶
The system is rebooting if during the shutting down process the following events are given:
re-assertion of the ignition signal
wake-up event of an RTC alarm
reboot commanded
Powering the Device Off¶
The system is powering off on the following events:
poweroff commanded
RTC alarm set up with mode to power off
de-assertion of the ignition signal
Ping Request/Response¶
The kernel modules of the SSF can be tested by writing a string to ping-request and reading the response from ping-request. Any request is taken by the SSF broker and forwarded to the SSF sysstate which finally writes the response on the sysfs.
Watchdog Feature¶
The provided SSF manager includes a watchdog feature which is linked to the ping request/response mechanism checking that the kernel modules are working as expected. Thus it is using the watchdog feed interval to compare the ping response with the corresponsing request before feeding the watchdog. If the ping response and request are mismatching, the watchdog is not fed and will starve. This leads to a watchdog reset of the device. In this case the start-reason will be shown as watchdog.
SSF Manager¶
The SSF manager provides currently two features:
marking the system state of the SSF
hanlding the system watchdog by using the SSF Ping mechanism
See the following help for further details:
root@am335x:~# ssf-mgr -h
Usage: ssf-mgr [args]
-h | --help Show this help
-d | --daemonize Run as daemon
-p | --pidfile=path The PID file, see -d
-m | --mark-sys-state Mark the system state for the SSF
-w | --with-watchdog Enable watchdog and supervise SSF modules
-t | --wd-timeout=TIMEOUT_MS Configure watchdog timeout to TIMEOUT_MS
default=8000ms
-i | --wd-feed-interval=INTERVAL_MS Set watchdog feed interval to INTERVAL_MS
default=4000ms
Used loggers: - evtloop
- initSys
- systemState
- watchdogMgr
- brokerPinger
SysLogger OPTIONS:
--loglevel=n Set the max application log level (used for all logger
instances as default) to n (0=emcy, 7=dbg). If comma separated
list of separate logger instances is provided after this
number, the log level for each such instance will be overruled
accordingly (e.g. --loglevel=7,evtloop.5,fileOp.6).
--disable-syslog disable the log output to syslog
--enable-stdout enable output on stdout (e.g. for debugging purposes)
SysLogger Examples:
prog-name --disable-syslog
prog-name --disable-syslog --enable-stdout
prog-name --loglevel=6,config.5,serial.7
In our OEM Linux Release the ssf-mgr.service is starting with the default config where marking of the system state is activated and the watchdog feature is enabled:
root@am335x:~# cat /etc/default/ssf-mgr.conf
# Default settings for system-state-framework manager
# for details run ssf-mgr --help
MARK_SYS_STATE="-m"
WATCHDOG_CONFIG="-w"
LOGGER_CONFIG="--loglevel=6,evtloop.5,systemState.6,initSys.6,brokerPinger.6,watchdogMgr.6"
root@am335x:~# cat /usr/lib/systemd/system/ssf-mgr.service
[Unit]
Description=SystemStateFramework Manager daemon
[Service]
Type=forking
EnvironmentFile=-/etc/default/ssf-mgr.conf
ExecStart=/usr/bin/ssf-mgr $MARK_SYS_STATE $WATCHDOG_CONFIG -d -p /run/ssf-mgr.pid $LOGGER_CONFIG
[Install]
WantedBy=multi-user.target
Starting Options¶
Disable System State Marking and Watchdog Feature¶
Starting the SSF manager without watchdog and without marking the system state, needs to remove the options -w and -m:
root@am335x:~# cat /etc/default/ssf-mgr.conf
# Default settings for system-state-framework manager
# for details run ssf-mgr --help
MARK_SYS_STATE=""
WATCHDOG_CONFIG=""
LOGGER_CONFIG="--loglevel=6,evtloop.5,systemState.6,initSys.6,brokerPinger.6,watchdogMgr.6"
Disable System State Marking¶
Starting the SSF manager by handling only the watchdog part can be fulfilled by removing the -m option:
root@am335x:~# cat /etc/default/ssf-mgr.conf
# Default settings for system-state-framework manager
# for details run ssf-mgr --help
MARK_SYS_STATE=""
WATCHDOG_CONFIG="-w"
LOGGER_CONFIG="--loglevel=6,evtloop.5,systemState.6,initSys.6,brokerPinger.6,watchdogMgr.6"
Timeout Settings¶
The watchdog feed interval and the watchdog timeout are related, i.e. the watchdog timeout must be higher than the check interval. Those times can be changed by the following command line options:
-t watchdog timeout in [ms]
default = 8000ms
-i watchdog feed interval in [ms]
default = 4000ms
Example setting the timeout to 30s and the interval to 15s:
root@am335x:~# cat /etc/default/ssf-mgr.conf
# Default settings for system-state-framework manager
# for details run ssf-mgr --help
MARK_SYS_STATE="-m"
WATCHDOG_CONFIG="-w -t 30000 -i 15000"
LOGGER_CONFIG="--loglevel=6,evtloop.5,systemState.6,initSys.6,brokerPinger.6,watchdogMgr.6"
Note
The timeout may vary due to the PMIC setting which is a multiple of a specific base time, see the datasheet of the PMIC for more details.
Source for the System State Marking¶
The init system is systemd and the states of a finished start-up, rebooting or powering off can be collected from dbus messages. Find the dbus registration parameter in the following list.
State of finished start-up:
dbus registartion parameters: - sender/service = "org.freedesktop.systemd1"; - object path = "/org/freedesktop/systemd1"; - interface = "org.freedesktop.systemd1.Manager"; - signal = "StartupFinished" - item = "up" // this is not necessary as StartupFinished does not have any other items, it is just for the internal list
The same mechanism for the poweroff and reboot is used where only a different singal and different items are used:
- signal = "UnitNew" // same signal for poweroff and reboot - itemPoweroff = "poweroff.target" - itemReboot = "reboot.target"
System Watchdog Usage¶
The system watchdog work with the following principle:
/* The watchdog will be activated when opening the the watchdog device file */
fd = open(dev, O_RDWR);
if (-1 == fd)
{
fprintf(stderr, "Error: %s\n", strerror(errno));
exit(EXIT_FAILURE);
}
/* Setting the watchdog interval */
fprintf(stdout, "Set watchdog interval to %d\n", interval);
if (ioctl(fd, WDIOC_SETTIMEOUT, &interval) != 0)
{
fprintf(stderr, "Error: Set watchdog interval failed\n");
exit(EXIT_FAILURE);
}
/* Getting the current watchdog interval - which might be advisable when the
* watchdog timeout bases on a factor of a base time such as the PMIC
* watchdog does.
*/
if (ioctl(fd, WDIOC_GETTIMEOUT, &interval) == 0)
{
fprintf(stdout, "Current watchdog interval is %d\n", interval);
}
else
{
fprintf(stderr, "Error: Cannot read watchdog interval\n");
exit(EXIT_FAILURE);
}
/* Interval loop feeding the watchdog
* There are two ways to kick the watchdog:
* - by writing any dummy value into watchdog device file, or
* - by using IOCTL WDIOC_KEEPALIVE
*/
do
{
/* the device file way: */
write(fd, "w", 1);
fprintf(stdout, "Feed watchdog through writing over device file\n");
/* OR the ioctl way: */
ioctl(fd, WDIOC_KEEPALIVE, NULL);
fprintf(stdout, "Kick watchdog through IOCTL\n");
} while (isLoopRunning);
/* The 'V' value needs to be written into watchdog device file to
* indicate that we intend to close/stop the watchdog
*/
write(fd, "V", 1);
/* Closing the watchdog device deactivates the watchdog */
close(fd);
System Clock / Date Time¶
There might be several time giving sources like GNSS, NTP, etc that can be used to synchronize the system clock and other clock dependent parts.
Synchronization¶
Chrony is able to perform such clock synchronizations. For further information please have a look at Chrony. Chrony is also able to synchronize the HW clock (RTC) automatically if it drifts away.
Another tool to synchronize/handle/update the HW clock (RTC) is timedatectl
which competes against chrony. This means be cautious when synchronizing/updating the HW clock manually
HW Clock Synchronization/Update¶
As described in section above the RTC can be updated using different tools. The following sections show how this can be performed.
timedatectl¶
NOTE: Using timedatectl
you are able to update the HW clock manually.
If no time source is present no update takes place automatically. Then a manual update is possible with:
timedatectl set-local-rtc n
Please read also the timedatectl man page when using timedatectl
.
Data Volume Monitor¶
Introduction¶
We introduced a data volume monitor called vnstat in our develop image, see https://humdi.net/vnstat/ for more information about vnstat.
Configuration¶
vnstat can be configured with the config file /etc/vnstat.conf
Our configuration sets wwan0 as default interface and runs the used database on a ramdisk (volatile). The responsible configuration values are the follows:
DatabaseDir "/run/vnstat"
Interface "wwan0"
The database is on path /run/vnstat/vnstat.db.
Note
This volatile configuration gets lost at each reboot. If you want to persist the database then follow the guide in the next section.
The default configuration synchronizes the database every 5 minutes, so be aware that there is a latency in the displayed numbers.
Persisting Data base¶
The following lines show you about how you can persist the data volume over reboots:
Stop the service: systemctl stop vnstat
Adapt the configuration:
in /etc/vnstat.conf set the following setting: DatabaseDir “/var/lib/vnstat”
Start the service: systemctl start vnstat
The service runs then on the database residing on the emmc. It will create a new database if no one is existing or continuing with the database residing in /var/lib/vnstat.
How To use¶
The help of vnstat is somehow self explaining and shows you how to use it:
vnstat --help
vnStat 2.6 by Teemu Toivola <tst at iki dot fi>
-5, --fiveminutes [limit] show 5 minutes
-h, --hours [limit] show hours
-hg, --hoursgraph show hours graph
-d, --days [limit] show days
-m, --months [limit] show months
-y, --years [limit] show years
-t, --top [limit] show top days
-b, --begin <date> set list begin date
-e, --end <date> set list end date
--oneline [mode] show simple parsable format
--json [mode] [limit] show database in json format
--xml [mode] [limit] show database in xml format
-tr, --traffic [time] calculate traffic
-l, --live [mode] show transfer rate in real time
-i, --iface <interface> select interface (default: wwan0)
Use "--longhelp" or "man vnstat" for complete list of options.
Example: show only the wwan0 data volume:
vnstat -i wwan0
Database updated: 2021-03-24 10:55:01
wwan0 since 2021-03-24
rx: 84.78 KiB tx: 84.83 KiB total: 169.62 KiB
monthly
rx | tx | total | avg. rate
------------------------+-------------+-------------+---------------
2021-03 84.78 KiB | 84.83 KiB | 169.62 KiB | 0 bit/s
------------------------+-------------+-------------+---------------
estimated -- | -- | -- |
daily
rx | tx | total | avg. rate
------------------------+-------------+-------------+---------------
today 84.78 KiB | 84.83 KiB | 169.62 KiB | 35 bit/s
------------------------+-------------+-------------+---------------
estimated 186 KiB | 186 KiB | 371 KiB |
Wi-Fi¶
Overview¶
Used WIFI (and BT) Chip: WL1837MOD
linux-firmware repository:
git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git
Commit id: 4c0bf113a55975d702673e57c5542f150807ad66
Which is basically: wl18xx: update firmware file 8.9.0.0.76
NetworkManager (nmcli) connection configuration files are stored under
/etc/NetworkManager/system-connections
802-11 Standard¶
a: 5 GHz-Band, up to 54 Mbits/s
b: 2.4 GHz-Band, up to 11 Mbits/s
g: 2.4 GHz-Band, up to 54 Mbits/s
n: 2.4 & 5 GHz-Band, up to 600 Mbits/s
ac: 5 GHz-Band, up to 1.3 Gbits/s
Client Mode¶
Scan and connect to existing access point (AP)
$ nmcli d wifi list
$ nmcli d wifi connect <MYWLAN> password <my_password>
Access Point Mode¶
Note: Set region code to get right channels!
Create Access Point in 2.4 GHz Band¶
Create hotspot with SSID Hostspot24, no encryption
$ nmcli con add type wifi ifname wlan0 con-name Hostspot24 autoconnect yes ssid Hostspot24
$ nmcli con modify Hostspot24 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared
$ nmcli con up Hostspot24
Create hotspot with SSID SecSpot, wpa-psk encryption with password: 12345678
Note: for wpa-psk encryption password has to be 8 characters or more.
$ nmcli con add type wifi ifname wlan0 con-name SecSpot autoconnect yes ssid SecSpot
$ nmcli con modify SecSpot 802-11-wireless.mode ap 802-11-wireless.band bg ipv4.method shared
$ nmcli con modify SecSpot wifi-sec.key-mgmt wpa-psk
$ nmcli con modify SecSpot wifi-sec.psk "12345678"
$ nmcli con up SecSpot
Create Access Point in 5 GHz Band¶
Create hotspot with SSID Hostspot50, no encryption
$ nmcli con add type wifi ifname wlan0 con-name Hostspot50 autoconnect yes ssid Hostspot50
$ nmcli con modify Hostspot50 802-11-wireless.mode ap 802-11-wireless.band a ipv4.method shared
$ nmcli con up Hostspot50
Create hotspot with SSID SecSpot5, wpa-psk encryption with password: 12345678
Note: for wpa-psk encryption password has to be 8 characters or more.
$ nmcli con add type wifi ifname wlan0 con-name SecSpot5 autoconnect yes ssid SecSpot5
$ nmcli con modify SecSpot5 802-11-wireless.mode ap 802-11-wireless.band a ipv4.method shared
$ nmcli con modify SecSpot5 wifi-sec.key-mgmt wpa-psk
$ nmcli con modify SecSpot5 wifi-sec.psk "12345678"
$ nmcli con up SecSpot5
WWAN¶
Overview¶
Supported modems and firmware (Caution: older versions may not work stable or miss features!)
u-blox TOBY-L210, firmware 17.00,A01.01
u-blox LARA-L6, firmware 03.15,A00.01
Preparation¶
Insert SIM Card in sim slot
Usage¶
All the configuration can be done by NetworkManager but sometimes it can be useful to check lower level configurations with ModemManager.
Firmware update¶
Warning
Downgrading a WWAN modem will likely lead to a broken modem
On some devices, the modem is delivered with an old firmware, reported by list-devices as “obsolete” or “deprecated”. It is highly recommended to upgrade it.
How to check firmare version and upgrade is explain at Updating firmware.
Initial configuration¶
The WWAN modem is configured at each boot by a script named wwan-config. This script is using the configuration file /etc/wwan/wwan0.conf to setup the modem before letting ModemManager handle it.
- This configuration file is divided in three sections:
apn: must configured to use a private APN
sim: is used to choose between the different sim cards available on the device
ublox: low level configurations for ublox modem. This should normaly not be modified
APN configuration¶
Note
This section only applies on a device with a u-blox TOBY-L2 modem. for other modems, it will be ignored.
When using a private APN, this section has to be configured with the following fields:
[apn]
apn=<APN>
user=<USER>
password=<PASSWORD>
When the default APN provided by the network when using LTE must be used, make sure that this fields are not set.
After any change to this file, the system has to rebooted or the following command to be run:
$ systemctl restart wwan-config@wwan0
SIM card configuration¶
This section is used to choose which SIM card to use with the modem. There are four SIM cards slot that can be used by the modem.
[sim]
SIM=<value>
Where <value> can be :
auto: The script will detect if a physical SIM card is present and switch to m2m SIM card (soldered to the board) if it is not the case
sim1: Use the physical SIM card on the main board
m2m: Use the m2m SIM card soldered on the main board
ui-top: Use the SIM card that is on top of the User Interface
ui-btm: Use the SIM card that is on the bottom of the User Interface
After any change to this file, the system has to be rebooted or the following command to be run:
$ systemctl restart wwan-config@wwan0
NetworkManager commands¶
$ # Create connection
$ nmcli c add type gsm con-name wwan ifname "" ipv6.method ignore gsm.apn <APN>
$ # Create connection with APN authentication
$ nmcli c add type gsm con-name wwan ifname "" ipv6.method ignore \
gsm.apn <APN> gsm.username <USER> gsm.password <PASSWORD>
$ # Set PIN number
$ nmcli c modify wwan gsm.pin <pin number>
$ # Start the connection
$ nmcli c up wwan
ModemManager configuration¶
$ mmcli -L # list modems and get modem id
$ mmcli -M # list modems in a loop, useful when waiting after a reset
$ mmcli -m 0 # See state of the modem 0
$ mmcli -i 0 --pin=<pin number> # Entering pin on modem 0
$ mmcli -m 0 -r # Reset the modem
Low level configuration / modem debugging¶
It can sometimes be useful to send directly some commands to the modem. The preferred way to do this is to ask wwan-config to stop all modem operations and then use a tool like minicom to communicate directly with the modem as in the following commands:
Note
ModemManager is monitored by wwan-config so it cannot be stopped without wwan-config restarting it. Stopping wwan-config on the other hand will also power off the modem.
# USR1 asks wwan-config to stop modem operations
kill -s USR1 $(</run/wwan0.pid)
# Open minicom on AT interface
minicom -D /dev/wwan0
AT+CCID # This may not show up if echo is not enabled (ATE1)
+CCID: 894101182777XYXYXYXY
OK
# Exit minicom with Ctrl+A Q
# USR2 asks wwan-config to restart modem operations
kill -s USR2 $(</run/wwan0.pid)
ModemManager extensions¶
The ModemManager version used in NetModule linux is the version 1.14.X with some NetModule specific extensions.
It is maintained and up to date with latest bug and security fixes.
NetModule did the following changes to the community version :
1. Support configuration of default EPS bearer for u-blox toby-l2 modems¶
In 4G (LTE), the handling of the APN configuration is different than in 2G and 3G and specific to each vendor. Toby-l2 modems is not supported in the community version.
2. Handling of reconnect requests¶
Events like reconnection and disconnection on the radio side trigger AT messages that are not handled by ModemManager. The NetModule version handles this messages, leading to a faster reconnection.
3. Change AT commands timeout to 3 minutes¶
The u-blox modems can take up to 3 minutes before answering and AT command. The default timeout varies between 3 and 60 seconds depending on the commands. This difference made MM send more commands while the modem was still processing the first one, leading to a lock of the modem.
4. Show more precise signal quality in output of mmcli -m¶
By default MM is showing a pretty coarse value for signal quality when showing modem status with mmcli -m 0 (20% steps). With this change MM is showing a more precise value, more representative of what is retrieved with mmcli -m 0 –signal-get.
eUICC¶
Basic support for eUICC (Embedded Universal Integrated Circuit Card) is available through the “lpa” tool. Since the “lpa” tool is writing directly to the modem through the serial interface, it is better to stop ModemManager with the following command before using it :
# Disable control of wwan0
kill -s USR1 $(</run/wwan0.pid)
This can be later enabled again with the following:
# Enable control of wwan0
kill -s USR2 $(</run/wwan0.pid)
Warning
The lpa tool is closed source and can therefore only be built in an image by using the sstate-cache from NetModule. See Building with shared state
The following commands can show that the eUICC is properly detected and configurable :
lpa check
SIM_DETECTED=yes
SIM_IS_EUICC=yes
SUPPORTS_SGP22=yes
SGP22_VERSION=020200
lpa eid
EID=89033023425120000000005020685295
lpa profiles
No profiles installed on eUICC.
To load a profile on the eUICC, the following commands can be used:
lpa download
lpa download-smds
lpa download-default-smdp+
Their usage can be checked with :
lpa usage
Booting with custom Linux kernel or ramdisk¶
If it’s necessary, it is possible to boot custom a Linux kernel with existing OSTree controlled file system.
Provisioning over tftp¶
Load the ostree necessary variables.
run bootcmd_otenv
Load your own kernel.
tftp $kernel_addr_r fitImage
xor load the installed kernel:
ext4load mmc 1:1 $kernel_addr_r /boot$kernel_image
Load your own ramdisk.
tftp $ramdisk_addr_r ramdisk
xor load the installed ramdisk:
`ext4load mmc 1:1 \$ramdisk_addr_r /boot\$ramdisk_image;
Boot the system.
bootm $kernel_addr_r $ramdisk_addr_r
Provisioning over USB¶
Initialize USB
usb reset
Load the ostree necessary variables.
run bootcmd_otenv
Load your own kernel.
fatload usb 0:1 $kernel_addr_r fitImage
xor load the installed kernel:
ext4load mmc 1:1 $kernel_addr_r /boot$kernel_image
Load your own ramdisk.
fatload usb 0:1 $ramdisk_addr_r ramdisk
xor load the installed ramdisk:
ext4load mmc 1:1 $ramdisk_addr_r /boot$ramdisk_image;
Boot the system.
bootm $kernel_addr_r $ramdisk_addr_r
Create a fitImage¶
To create a fitImage you need a .its file. Luckily YoctoProject creates this
file for us. You find in the deployed image folder (e.g.
hancock-os/shared-build/tmp/deploy/images/am335x-nmhw21/fitImage-its-am335x-nmhw21.its
).
In this file, you will find this line in the kernel section:
data = /incbin/("linux.bin");
This tells us what the filename of your legacy kernel (zImage, uImage, Image) needs to be called.
You will also find this line in the dtb section:
data = /incbin/("arch/arm/boot/dts/am335x-nmhw21-prod1.dtb");
This tells us where the the dtb is expected.
Steps (nmhw21)¶
Create a folder structure that looks like this:
|-- fitImage-its-am335x-nmhw21.its
|
|-- linux.bin ( --> your kernel image)
|
|-- arch/arm/boot/dts/am335x-nmhw21-prod1.dtb
To create the fitimage now run in your folder:
mkimage -f fitImage-its-am335x-nmhw21.its fitImage