The 2020 Raspbian distribution for the AVNET SmartEdge IIOT Gateway uses systemd services to manage the hardware customisations.

In this post, I review what they do, how they interact.

I'm trying to get some functional flow in this review: reveal the network of dependencies.

What can you modify if you want to use a subset of the functions.

 

 

Functionality

 

The AVNET image adds services related to:

  • the watchdog functionality that monitors the health (responsiveness) of the system. And the ATTiny controller that's supporting that.
  • the reset button and reset functionality
  • the status LEDs on the front (they in particular are shared amongst a lot of the services)
  • the AVNET IoTConnect online service, and the REST support for its API
  • optional hardware related services, e.g. for the PCi quectel comms module.

 

I want to find out what services impacts what.
Optionally, which ones you need to keep, stop, modify if you want to cherry pick the available options.

 

Services are available in /etc/systemd/system.

The SmartEdge specific ones are:

  • attinyupdate.service
  • buttonservice.service
  • iotconnectservice.service
  • ledservice.service
  • quectel.service
  • restservice.service
  • smartedgehalt.service
  • watchdogstart.service
  • watchdogstop.service
  • bootservice.com

 

Some are hardware related. Others with the IoTConnect infrastructure. Usually, a mix of both.

I'll try to start with the fundamental ones, and keep the strictly utility ones until the end.

 

buttonservice

 

The SmartEdge has a custom reset button. It can be engaged by inserting a small pin into the opening next to the power input.

 

Here's the service registry content:

 

[Unit]
Description=SmartEdge Reset Button service
[Service]
ExecStart=/bin/bash /opt/avnet-iot/iotservices/button
Restart=always
RestartSec=60
[Install]
WantedBy=default.target

 

In summary: no hard dependencies, start as a common service, execute a script at startup.

 

startup script:

/opt/avnet-iot/iotservices/button

 

Content:

# ...
cd /opt/avnet-iot/iotservices

echo "Starting Smartedge-iiot-gateway Button service"
rmmod attiny_btn
modprobe attiny_btn

# wait for device
while [ ! -c /dev/button ];
do
    sleep 2
    echo "waiting for button device"
done
# wait for device
while [ ! -c /dev/reset ];
do
    sleep 2
    echo "waiting for reset device"
done
# wait for device
while [ ! -c /dev/factoryreset ];
do
    sleep 2
    echo "waiting for factoryreset device"
done

/bin/bash /opt/avnet-iot/iotservices/stopwd
python -u /opt/avnet-iot/iotservices/button.py >>/var/log/button.log 2>&1
echo "Button python restart" >>/var/log/button.log

 

Abstract:

  • load the custom ATTiny module (There's a bespoke ATMEL controller dealing with some of the led, button and watchdog functionality).
  • when all is started up and the button is registered, stop the watchdog, then button.py script is executed.

 

/opt/avnet-iot/iotservices/button.py

 

content

#!/usr/bin/env python
# ...

def check_switch_short(lock):
    try:
    while 1:
            os.system("cat /dev/button")
            with lock:
                print("SwitchShort Resetting")
                os.system("/bin/bash -c '/opt/avnet-iot/iotservices/switch_reset'")
    except Exception as ex:
        print("Reset Button Exception:" + str(ex))

def check_switch_long(lock):
    try:
        while 1:
            os.system("cat /dev/reset")
            with lock:
                print("LongPress Resetting to Configuration State")
                os.system("/bin/bash -c '/opt/avnet-iot/iotservices/switch_configuration_mode'")
    except Exception as ex:
        print("Ap Mode Button Exception:" + str(ex))

def check_switch_factory(lock):
    try:
        while 1:
            os.system("cat /dev/factoryreset")
            with lock:
                print("WARNING!!! LongPress Resetting to Factory State WARNING!!!")
                os.system("/bin/bash -c '/opt/avnet-iot/iotservices/switch_factory_reset'")
    except Exception as ex:
        print("Factory Button Exception:" + str(ex))

if __name__ == '__main__':
    print("Starting button service")
    print(os.path.exists('/dev/button'))

    SwitchLock = threading.Lock()
    t = threading.Thread(target=check_switch_long, args=(SwitchLock,))
    t.start()
    t1 = threading.Thread(target=check_switch_short, args=(SwitchLock,))
    t1.start()
    t2 = threading.Thread(target=check_switch_factory, args=(SwitchLock,))
    t2.start()
    while 1:
        time.sleep(60*60)

 

Depending on how long you press the button, it calls different functions.

Short push: it calls

opt/avnet-iot/iotservices/switch_reset

 

content:

/opt/avnet-iot/iotservices/reboot

 

The reboot script itself is subject to a later post.

 

Middle long push: reset settings:

 

/opt/avnet-iot/iotservices/switch_configuration_mode

 

There are a number of actions in this script that you may or may not want.

If you use the AVNET IoTConnect functions, you want everything.

If not, you may want to uncomment some service start and enablement calls, e.g.: restservice, ledservice, iotconnectservice.

These cervices will be reviewed in a future post.

 

content:

#!/bin/bash
## Perform reset into WiFi/AP mode and start REST API

if [[ $EUID -ne 0 ]]; then
  echo "This script must be run as root"
  exit 1
fi

if [[ "$1" == "soft" ]]; then
  # Enable WiFi/AP mode and start REST API (system will be in an odd mode)
  ifconfig wlan0 down
  #systemctl disable wpa_supplicant.service
  systemctl stop wpa_supplicant.service
  rm /etc/wpa_supplicant/wpa_supplicant.conf
  cp /etc/default/hostapd.ap /etc/default/hostapd
  cp /etc/dhcpcd.conf.ap /etc/dhcpcd.conf
  cp /etc/dnsmasq.conf.ap /etc/dnsmasq.conf
  ifconfig wlan0 up
  systemctl restart dhcpcd
  systemctl restart dnsmasq
  systemctl restart hostapd
  #systemctl enable restservice
  systemctl start restservice
  #systemctl start ledservice
else
  # Revert to Configuration mode
  ifconfig wlan0 down
  systemctl disable wpa_supplicant.service
  systemctl stop wpa_supplicant.service
  rm /etc/wpa_supplicant/wpa_supplicant.conf
  cp /etc/default/hostapd.ap /etc/default/hostapd
  cp /etc/dhcpcd.conf.ap /etc/dhcpcd.conf
  cp /etc/dnsmasq.conf.ap /etc/dnsmasq.conf
  ifconfig wlan0 up
  systemctl enable dhcpcd
  systemctl enable dnsmasq
  systemctl enable hostapd
  systemctl restart dhcpcd
  systemctl restart dnsmasq
  systemctl restart hostapd
  systemctl enable restservice
  systemctl start restservice
  systemctl enable ledservice
  systemctl start ledservice
  systemctl disable iotconnectservice
  /bin/bash /opt/avnet-iot/iotservices/reboot
fi

 

When you push the button very long (more than 15 seconds), the box does a factory reset.

 

/opt/avnet-iot/iotservices/switch_factory_reset

 

content:

## Perform factory reset
# ...
# cleanup removed
#...
cp /opt/avnet-iot/iotservices/files/dhcpcd.conf.* /etc/.
cp /opt/avnet-iot/iotservices/files/dnsmasq.conf.* /etc/.
cp /opt/avnet-iot/iotservices/files/default.script /usr/share/udhcpc/.
cp /opt/avnet-iot/iotservices/files/hostapd.ap /etc/default/.
cp /opt/avnet-iot/iotservices/files/hostapd.default /etc/default/.
cp /opt/avnet-iot/iotservices/files/*.service /etc/systemd/system/.

cp /opt/avnet-iot/IoTConnect/sample/IoTConnectSDK.conf.default /opt/avnet-iot/IoTConnect/sample/IoTConnectSDK.conf
cp /etc/default/hostapd.ap /etc/default/hostapd
cp /etc/dhcpcd.conf.ap /etc/dhcpcd.conf
cp /etc/dnsmasq.conf.ap /etc/dnsmasq.conf


systemctl daemon-reload
systemctl disable iotconnectservice
#Don't stop iotconnectservice; this script may be running under it.
#systemctl stop iotconnectservice
systemctl enable restservice
systemctl disable hostapd.service
systemctl disable dnsmasq.service
rm /etc/systemd/system/attinyupdate.service
ln -s /opt/avnet-iot/services/attinyupdate.service /etc/systemd/system/attinyupdate.service
rm /etc/systemd/system/bootservice.service
ln -s /opt/avnet-iot/services/bootservice.service /etc/systemd/system/bootservice.service
systemctl enable attinyupdate.service
systemctl enable bootservice.service
systemctl enable quectel.service


rm /sbin/reboot
ln -s /bin/systemctl /sbin/reboot
history -c

if [ -d /home/avnet ]; then
    echo "Already exists"
else
    deluser avnet
    useradd -m -d /home/avnet -g avnet -G root,crontab,adm,tty,dialout,sudo,ssh,iotedge,tss,gpio,i2c -s /bin/bash avnet
    cat /opt/avnet-iot/iotservices/default.txt | chpasswd
fi
systemctl disable wpa_supplicant.service
systemctl stop wpa_supplicant.service

/bin/bash /opt/avnet-iot/iotservices/reboot

 

Side effects:

loads the attiny_btn library

depending on how long you press, reinitialises WiFi settings, or factory resets most of the custom aspects.

 

Related Blog
Industrial I/O
Use the Industrial I/O
Control Industrial I/O directly from GPIO Pins
C Program for the Industrial I/O
Control Industrial I/O directly from Node-RED
Display Industrial I/O on Node-RED Dashboard
CAN Bus
Use the Isolated CAN
CAN programming in C on Linux: Filter and Mask
2020 Linux Image
The 2020 Linux Image and IoTConnect Scripts
Understand the Custom Scripts and Services (Pt. 1: intro and reset button service)
Understand the Custom Scripts and Services (Pt. 2: led service)
Understand the Custom Scripts and Services (Pt. 3: IoT Connect service)