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.