Resolving Unipi Neuron evok Service Failure After Reboot

Daniel Price10 min read
Other ManufacturerOther TopicTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

This Neuron ran evok for two weeks and then refused to start it after a power outage. evok exits with status 255 because it cannot read the Neuron board EEPROM, and it cannot read the EEPROM because the unipi, at24 and i2c_dev kernel modules did not load on the kernel that booted. The usual trigger is an apt upgrade that installed a new kernel earlier without a reboot. The power cut was the first boot into that kernel, and the Unipi driver modules did not match it. The fix is to reinstall unipi-kernel-modules against the running kernel and reboot. The sections below build that fix one hop at a time, and each section ends with the check that proves it.

Which line in the systemd status is the real failure?

The evok.service unit wraps the Python process with nginx site swaps. Two of those shell steps report failure but have no effect on the outcome. Separate them from the one that matters before you chase anything else.

Unit step Command Exit Meaning
ExecStartPre /bin/cp -f /etc/nginx/sites-available/evok /etc/nginx/sites-enabled/ 0 evok web site enabled
ExecStartPre /bin/mv -f /etc/nginx/sites-enabled/mervis /etc/nginx/sites-available/ 1 No Mervis site was enabled, so there is nothing to move. Harmless.
ExecStartPre /bin/ln -sf /etc/nginx/sites-enabled/evok /etc/evok-nginx.conf 0 Web port config symlink created
ExecStart /opt/evok/bin/python /opt/evok/lib/python2.7/site-packages/evok/evok.py 255 evok exited deliberately. This is the fault.
ExecStopPost /bin/cp -f /etc/nginx/sites-available/mervis /etc/nginx/sites-enabled/ 1 No Mervis site file exists to restore. Harmless.

systemd restarted the service after each exit. When the restarts came too close together, it hit the unit start rate limit and logged Start request repeated too quickly, then left the unit in the failed state. That message is a consequence of the loop, not a cause. The journal will not show why the Python process returned 255 at log level ERROR, so run the ExecStart command in the foreground.

sudo systemctl stop evok
sudo /opt/evok/bin/python /opt/evok/lib/python2.7/site-packages/evok/evok.py

Check: the last two lines read NO NEURON EEPROM DATA DETECTED, EXITING and PLEASE USE A FRESH EVOK IMAGE, OR ENABLE I2C, I2C-DEV AND THE EEPROM OVERLAY. If they do, continue. If evok dies earlier with a different message, the rest of this procedure does not apply.

Where along evok's startup path does the request stop?

The foreground log shows each hop evok brings up, in order. Every hop succeeds until evok needs the board identity.

Hop Log evidence Result
Config parse Starting using config file /etc/evok.conf OK
Device definitions xS10.yaml, xS30.yaml, xS40.yaml, xS50.yaml, evok-alias.yaml loaded OK
Internal API HTTP server listening on port: 8080 OK
SPI transport SPI client started Client object created
RS485 extensions UART client started, Reading the UART board on Modbus address 2, 3, 4 Clients created
Neuron base board identity Reading SPI boards followed by NO NEURON EEPROM DATA DETECTED, EXITING Stops here

evok does not probe the SPI boards blind. It first reads the Neuron model data from an I2C EEPROM on the controller, then builds the matching board and register layout. The kernel exposes that EEPROM through the at24 EEPROM driver, which is bound by the EEPROM device-tree overlay. i2c_dev provides the userspace I2C device nodes, and the unipi module provides the Neuron SPI driver. If any link in that chain is missing, the EEPROM read returns nothing, and evok exits rather than guess the hardware.

The YAMLLoadWarning about yaml.load() without a Loader is a PyYAML deprecation notice. It appears on working systems too and has nothing to do with the exit.

lsmod | grep -E 'unipi|at24|i2c_dev'

Check: a healthy Neuron lists all three modules. If one or more is missing, the fault is in the driver layer, not in evok or in /etc/evok.conf.

Why would a power cycle change which drivers load?

A running Linux system keeps the kernel it booted with until the next reboot. apt upgrade can install a newer kernel image and its in-tree modules under a new /lib/modules/<version> directory. Nothing changes at runtime, so the controller keeps working for days or weeks. The out-of-tree Unipi modules, however, are built against a specific kernel.

When the power returns, the bootloader starts the new kernel. modprobe then searches only /lib/modules/$(uname -r) and finds no unipi module there. In the reported cases the new kernel was from the 4.19 series, and evok could no longer reach the Neuron modules after an upgrade followed by a reboot.

uname -r
ls /lib/modules/
modinfo unipi
grep -iE 'kernel|unipi' /var/log/apt/history.log
Observation Interpretation Next action
modinfo unipi reports module not found for the running kernel Unipi driver not built or installed for this kernel Reinstall unipi-kernel-modules
apt history shows a kernel package upgraded since the last known-good boot Power cut was the first boot on the new kernel Reinstall modules, then plan kernel control
unipi loads but at24 or i2c_dev is absent I2C or EEPROM overlay configuration not applied Enable I2C, i2c-dev and the EEPROM overlay as the evok message instructs, then reboot
All three modules loaded, evok still reports no EEPROM data Driver layer is fine; suspect the EEPROM read itself See the hardware decision below

Check: record uname -r and whether modinfo unipi resolves. That pair decides whether the repair is a package reinstall or an overlay fix.

Is the Neuron EEPROM damaged, or just unreadable?

A dead EEPROM after a hard power loss is the first fear when production stops. The symptom pattern here points away from hardware. A failed chip would still leave at24 and i2c_dev loaded, and the Unipi modules would still resolve for the running kernel. Missing modules after a kernel change is a software condition that fully explains the exit.

Symptom Driver cause (kernel mismatch) Hardware cause (EEPROM or I2C fault)
lsmod output unipi and/or at24, i2c_dev missing All three present
uname -r vs. last good boot Changed Unchanged
modinfo unipi Not found for running kernel Resolves
After module reinstall and reboot evok starts evok still reports no EEPROM data

Rule out the driver layer before you pull the unit. Treat the EEPROM as suspect only when all three modules are loaded on a kernel that matches the installed Unipi package and evok still exits. At that point, contact Unipi support through the official channels with the lsmod, uname -r and foreground evok output.

Check: complete the reinstall in the next section before you draw any hardware conclusion.

How do I reinstall unipi-kernel-modules against the running kernel?

Before you change packages, copy /etc/evok.conf off the controller. It holds the extension map (global IDs, Modbus addresses, UART port) that you would otherwise rebuild by hand if you end up reflashing.

  1. Back up the configuration: sudo cp /etc/evok.conf /home/pi/evok.conf.bak, then copy it off the device.
  2. Confirm the Unipi repository is configured: grep -ri unipi /etc/apt/sources.list /etc/apt/sources.list.d/. If nothing matches, add the Unipi repository per Unipi's documentation before continuing.
  3. Become root: sudo su.
  4. Refresh the package index: apt-get update.
  5. Install the module package: apt-get install unipi-kernel-modules. If apt reports it is already the newest version, force it with apt-get install --reinstall unipi-kernel-modules so the modules are rebuilt or installed for the current kernel.
  6. Confirm the module now resolves for the running kernel: modinfo unipi.
  7. Reboot the controller: reboot. The EEPROM overlay and driver binding happen at boot, so a reboot is required.

This mismatch was fixed in a later update of the Unipi package. On a current repository, the reinstall normally restores the modules.

If modinfo unipi still fails after the reinstall, the repository has no module build for your kernel. In that case, reflash the controller with a current Unipi (Unipian) image, do not run apt upgrade on it, and restore /etc/evok.conf from the backup. In the reported cases, a clean Raspbian Stretch install built from the GitHub instructions failed in the same way, so use the vendor image rather than rebuilding from scratch.

Check: after the reboot, lsmod | grep -E 'unipi|at24|i2c_dev' lists all three modules.

Does the RS485 extension bus come back with the SPI side?

The three extensions in this installation share one UART port that the Neuron driver stack exposes. Confirm that port exists and matches the configuration before you trust evok's I/O view.

Section global_id device_name modbus_uart_port address Serial settings
[EXTENSION_1] 4 xS50 /dev/extcomm/0/0 2 19200 baud, parity N, 1 stop bit
[EXTENSION_2] 5 xS40 /dev/extcomm/0/0 3 Not set; evok defaults apply
[EXTENSION_3] 6 xS40 /dev/extcomm/0/0 4 Not set; evok defaults apply

All devices on one RS485 segment must share baud rate, parity and stop bits. The xS50 is explicitly set to 19200 8N1, while the two xS40 units rely on defaults. Earlier in the startup sequence, evok creates one UART client per extension on the same port. If the defaults differ from 19200 8N1, the xS40 units will time out even when the driver layer is healthy. Read each module's configured serial settings and set baud_rate, parity and stop_bits explicitly in every [EXTENSION_n] section so the file documents the bus.

For commissioning, temporarily set log_level = INFO in [MAIN] so Modbus timeouts are visible. /var/log/evok.log is cleared on boot, so capture it before any further power cycle.

ls -l /dev/extcomm/0/0
sudo systemctl restart evok
sudo tail -n 50 /var/log/evok.log

Check: /dev/extcomm/0/0 exists, and the log shows no Modbus timeout or no-response errors for addresses 2, 3 and 4. Set log_level back to ERROR afterwards.

How do I stop the next apt upgrade from repeating this?

The failure stays hidden until the next boot, so a production controller can carry a broken kernel/module pair for weeks. Close that gap in one of these ways:

  • Reboot straight after any upgrade, while you are on site. Then run lsmod and systemctl status evok before you leave. A mismatch then appears in a supervised reboot, not during an outage.
  • Hold the kernel on production units. Identify the installed kernel package with dpkg -l | grep -i kernel and pin it with apt-mark hold <package>. Upgrade it only when unipi-kernel-modules for the new kernel is available from the Unipi repository.
  • Check the next boot before rebooting. Compare the newest directory in /lib/modules/ against uname -r. If a newer kernel is staged, confirm modinfo -k <new-version> unipi resolves before you allow a reboot.
  • Image the SD card once the system is verified, so an outage-induced failure can be recovered by swapping cards.

Check: apt-mark showhold lists the pinned kernel package, or your upgrade procedure includes the post-reboot module check.

How do I prove evok is serving end to end?

  1. Clear the rate-limit state: sudo systemctl reset-failed evok.
  2. Start the service: sudo systemctl restart evok.
  3. Confirm the unit state: systemctl status evok shows active (running). The ExecStartPre mv of the Mervis site may still show status 1; ignore it.
  4. Read this boot's journal: journalctl -u evok -b contains no EEPROM exit and no repeated restarts.
  5. Confirm the internal API is bound: sudo ss -ltnp | grep 8080 shows the evok Python process listening.
  6. Confirm nginx serves the evok site: ls -l /etc/nginx/sites-enabled/ contains evok, then open the web interface on the port set in /etc/evok-nginx.conf.
  7. Exercise I/O on each hop: read an input on the Neuron base board (SPI path), then read an input on the xS50 at address 2 and on each xS40 at addresses 3 and 4 (RS485 path).
  8. Cut and restore power to the controller once more. After it boots, rerun lsmod | grep -E 'unipi|at24|i2c_dev' and systemctl status evok, and confirm all three modules are loaded and evok is active (running) without manual intervention.

FAQ

Can a power outage damage the Unipi Neuron EEPROM and stop evok?

It is possible but unlikely when lsmod shows unipi, at24 or i2c_dev missing. That pattern means the drivers did not load, usually because the outage booted a newly upgraded kernel. Suspect the EEPROM only if all three modules are loaded on a matching kernel and evok still logs NO NEURON EEPROM DATA DETECTED.

Does the YAMLLoadWarning in the evok log cause the startup failure?

No. The yaml.load() without Loader warning is a PyYAML deprecation notice, and the YAML definitions still load. The exit comes from the EEPROM read that follows Reading SPI boards.

Can I just restart evok after reinstalling unipi-kernel-modules without rebooting?

Reboot the controller. The EEPROM overlay and the Neuron driver bind at boot, so a service restart alone can leave at24 or unipi unbound. After the reboot, confirm all three modules with lsmod before starting evok.

Back to blog