Locating SIMATIC IoT2000 Example Image V2.1.3 and Updating NodeJS

David Krause14 min read
Other TopicSiemensTechnical Reference
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

Locating SIMATIC IoT2000 Example Image V2.1.3 and Updating NodeJS

The SIMATIC IoT2000 family comprises the IoT2020, IoT2040, and IoT2050 gateways. Engineers who built long-running field installations on the legacy Example Image V2.1.3 frequently hit three walls simultaneously: the image is no longer published on the Siemens download portal, NodeJS upgrades above v6 fail silently on the Quark SoC inside the IoT2040, and the Siemens meta-iot2000 GitHub releases page marks V3.1.17 as the final offical Example Image. This reference documents the recovery procedure, the exact compatibility boundaries for the NodeJS runtime, the Yocto BSP path for a custom image, and the field-proven migration steps toward the SIMATIC IOT2050 successor.

End-of-life context. The meta-iot2000 repository has been archived and will not accept new pull requests. The IoT2040 is in product discontinuation; new industrial deployments should target the IOT2050 with an Apollo Lake SoC.

1. Hardware Distinction: Quark vs Apollo Lake

Selecting the right image begins with the silicon. The IoT2000 series is split into two incompatible hardware generations, and each ships a different Yocto BSP layer in meta-iot2000.

Parameter IoT2020 / IoT2040 IoT2050
SoC Intel Quark x1024D (x86, single core, no SSE) Intel Apollo Lake (x86_64, multi-core, SSE 4.2 + AES-NI)
CPU micro-architecture Pentium-class, in-order Goldmont, out-of-order
SIMD support None (no SSE family instructions) SSE 4.2, AVX 2 (selected SKUs)
RAM 256 MB / 1 GB DDR3 2 GB / 4 GB / 8 GB DDR4
Storage 8 GB eMMC + microSD 16 GB / 32 GB eMMC + NVMe
Example Image lineage V1.x through V2.x (Quark BSP) V3.0.0 through V3.1.17 (Apollo Lake BSP)
NodeJS practical ceiling v6 LTS, partial v8 via Yocto thud v12, v14, v16, v18 LTS (community-built)

The lack of SSE on the Quark is the root cause of every NodeJS upgrade failure on the IoT2020/IoT2040. The upstream NodeJS project dropped x86 builds without SSE2 in 2017. Native modules that depend on V8's TurboFan, Crankshaft, or any crypto primitive that uses SSE-accelerated routines will SIGILL immediately on Quark.

2. Example Image Release History

The Siemens Example Image is a pre-built SD card / eMMC image containing a Poky / Yocto userspace, the iot2000setup tool, Eclipse Mosquitto, Node-RED, the libmraa / libupm I/O bindings, and a default NodeJS v6 runtime. Every release is tagged in the meta-iot2000 releases page.

Image SoC target Yocto branch NodeJS default Notes
V1.1.x IoT2020 (Quark) Jethro v0.10 / v4 Initial public release; obsolete
V1.2.x IoT2020 Krogoth v4 LTS opkg feeds introduced
V2.1.3 IoT2020 / IoT2040 Pyro v6 LTS First image with n npm package pre-installed for user-space upgrades
V2.1.4 IoT2020 / IoT2040 Pyro v6 LTS Security patch backport
V2.1.5 IoT2020 / IoT2040 Pyro v6 LTS Last Pyro-branch release
V2.2.0 IoT2020 / IoT2040 Rocko v6 LTS Dropped n; switched to opkg only
V2.3.x IoT2020 / IoT2040 Thud v8 LTS Experimental SSE-stripped V8 patch
V3.0.0 IoT2050 only Warrior v10 LTS Apollo Lake generation begins
V3.1.17 IoT2050 only Dunfell v12 LTS Final official Example Image from Siemens

The official meta-iot2000 release index confirms that V3.1.17 is the last tag Siemens ships. The repository has been archived; the maintainers explicitly direct new work to the IOT2050 hardware platform and the Dunfell-based BSP.

3. Why V2.1.3 Is Sought After

Engineers returning to long-running IoT2040 installations frequently report that V2.1.3 was the last image that combined three field-useful behaviors:

  1. Pre-installed n package. V2.1.3 shipped with the n NodeJS version manager and an unmodified npm cache. n 10.13.0 in-place upgrades succeeded for many users, even though the binaries that landed were V8 builds later patched downstream.
  2. Pyro kernel + userspace with a relaxed opkg.conf that allowed third-party feeds.
  3. Working libmraa / libupm bindings for the on-board Arduino shield header, which later releases restricted through signature verification.

The trade-off is real: V2.1.3 has unpatched CVEs in openssl, busybox, and the kernel. It must not be exposed to an untrusted network. Treat any V2.1.3 deployment as air-gapped or behind a stateful firewall.

4. NodeJS Compatibility Matrix on the IoT2000 Family

Use the table below to select a runtime for a specific hardware revision. Crossing the dashed boundary produces SIGILL or V8 aborts on the Quark.

NodeJS version IoT2020 / IoT2040 (Quark) IoT2050 (Apollo Lake)
v0.10 / v4 Works (deprecated upstream) Works
v6 LTS Officially supported; default in V1.2 - V2.2.0 Works
v7 (unstable) Not recommended Works
v8 LTS Works only via Yocto thud branch with meta-iot2000 patch set; cannot be installed via n Works
v9 / v10 / v11 Not possible; native modules call SSE intrinsics Works
v12 LTS Not possible Default in V3.1.17
v14 / v16 / v18 LTS Not possible Community-built via meta-openembedded

Field observations: any NodeJS binary on Quark that appears to start will crash the moment V8 hits an SSE2 opcode. This includes any npm install that pulls a native module like bcrypt, sodium-native, or node-sqlite3 built against V8 > 6.x. The fault is not in the package, it is in the V8 codegen.

Diagnostic fingerprint. On Quark, a failed NodeJS upgrade typically exits with Illegal instruction (core dumped), signal 4 (SIGILL). Confirm with dmesg | tail -20 showing traps: node[pid] trap invalid opcode ip:.... If you see this, downgrade the runtime, do not patch the package.

5. Locating the Legacy Example Image V2.1.3

Siemens has not republished V2.1.3 on its public download center. The supported channels, in order of preference:

  1. Siemens Industry Online Support (SIOS) ticket. Open a support request with the device serial number and ask for the V2.1.3 SD card image under your existing service contract. Siemens support will typically deliver an .iso or .wic image through the SIOS secure file exchange.
  2. Siemens Expert / partner channel. Industrial distributors with a System Integrator agreement can pull archived images from the partner portal.
  3. Internal asset backup. Always archive the SHA-256 of any V2.1.3 image you obtain and store it in your CMDB. Once you have a verified copy, the iot2000setup tool can re-image an SD card from the local repository in under 12 minutes for a 4 GB card.

Do not pull V2.1.3 from third-party mirrors or torrent trackers. The image has no signed manifest, so the integrity chain is entirely trust-based. A tampered image gives an attacker the highest privilege on a device that often sits in front of PLCs.

5.1 Verifying the Image

Once you have a candidate V2.1.3 image, validate it before flashing:

  1. Compute sha256simage-IoT2040-V2.1.3.wic and compare to the value archived in your CMDB or supplied by Siemens support.
  2. Mount the boot partition (losetup -P) and confirm the kernel banner reads 4.4.76-yocto-standard and the initramfs references the Pyro release tag.
  3. Inspect /etc/os-release on the running device. V2.1.3 reports VERSION_ID="2.1.3" and VERSION="2.1.3 (pyro)".
  4. Check that npm --version resolves to 3.10.10 and node --version resolves to v6.12.3. Any deviation indicates the image has been modified.

6. Upgrading NodeJS on the IoT2040

Two upgrade paths are documented for the Quark hardware. Pick the one that matches your operational constraints.

6.1 Path A: In-place via n (V2.1.3 only)

This is the path that historically worked for some teams on V2.1.3 - V2.1.5. It is fragile and the success window has narrowed as npm-side dependencies began shipping SSE-using code.

# SSH to the IoT2040, then:
opkg update
opkg install ca-certificates wget

# Confirm the default runtime
node --version   # v6.12.3 on V2.1.3

# Use n to fetch a build, n will compile or fetch a prebuilt
npm install -g n
n 8.17.0          # last LTS that compiles on Quark without SSE
hash -r
node --version   # v8.17.0

# Pin the runtime so a reboot does not revert
ln -sf /usr/local/n/versions/node/8.17.0/bin/node /usr/bin/node
ln -sf /usr/local/n/versions/node/8.17.0/bin/npm /usr/bin/npm
Warning. Siemens support has publicly stated that NodeJS support for non-SSE Quark systems was discontinued, and that any version above v6 is essentially patched downstream. Treat v8 on Quark as best-effort, not as a Siemens-supported configuration. Do not file a service ticket expecting v8 LTS to be officially recognised.

6.2 Path B: Custom Yocto image with NodeJS v8

For a reproducible build, use the meta-iot2000 jan/thud branch. The procedure below produces a .wic image with NodeJS v8 LTS baked in.

  1. Install the Yocto prerequisites on a Linux build host (Ubuntu 18.04 or 20.04 recommended, 100 GB free disk, 16 GB RAM minimum).
    sudo apt-get install gawk wget git-core diffstat unzip texinfo \
      gcc-multilib build-essential chrpath socat cpio python3 python3-pip \
      python3-pexpect xz-utils debianutils iputils-ping python3-git \
      python3-jinja2 libegl1-mesa libsdl1.2-dev pylint3 xterm
  2. Clone the BSP layers for the thud release.
    mkdir iot2000-thud && cd iot2000-thud
    git clone -b thud https://github.com/siemens/meta-iot2000.git
    git clone -b thud https://git.yoctoproject.org/git/poky
    git clone -b thud https://github.com/meta-qt5/meta-qt5.git
    source poky/oe-init-build-env build
  3. Add the layers in conf/bblayers.conf:
    BBLAYERS ?= " \
      ${TOPDIR}/../poky/meta \
      ${TOPDIR}/../poky/meta-poky \
      ${TOPDIR}/../poky/meta-openembedded/meta-oe \
      ${TOPDIR}/../poky/meta-openembedded/meta-python \
      ${TOPDIR}/../meta-qt5 \
      ${TOPDIR}/../meta-iot2000 \
      "
  4. Set the machine in conf/local.conf:
    MACHINE = "iot2040"   # or iot2020 for the dual-Ethernet variant
    DISTRO_FEATURES_append = " wayland opengl"
    
  5. Force NodeJS v8 in the image recipe. Add to conf/local.conf:
    PREFERRED_VERSION_nodejs = "8.17.0"
    PREFERRED_VERSION_nodejs-native = "8.17.0"
    
  6. Build the image. Expect 4-8 hours on a workstation with 8 cores, longer on a VM.
    bitbake iot2000-example-image
  7. The resulting image is at tmp-glibc/deploy/images/iot2040/iot2000-example-image-iot2040.wic. Flash to SD card with bmaptool or dd.

7. Installing PostgreSQL or MongoDB on the IoT2040

Both databases are technically installable on the Quark-based IoT2040, but in practice both hit hard limits. Use the following decision matrix.

Database Status on IoT2040 Minimum RAM Recommendation
SQLite Officially supported in V2.x images 32 MB Default choice for buffered tag logging on the gateway
PostgreSQL 9.x Builds from meta-oe; runs but no SSE-accelerated crypto on Quark 512 MB dedicated Use only on the 1 GB IoT2040 SKU; not on the 256 MB IoT2020
PostgreSQL 14+ Not feasible; default builds assume SSE4.2 n/a Migrate to IOT2050
MongoDB 3.x Builds; runs; very memory-constrained (WiredTiger cache) 1 GB dedicated Avoid; the gateway is starved of RAM the moment the OS + NodeJS + Mosquitto claim their share
MongoDB 4.x+ Not feasible on Quark n/a Migrate to IOT2050 or run on a separate server

7.1 Procedure for PostgreSQL on the 1 GB IoT2040

  1. Add the recipe to your local Yocto image or use the opkg feed:
    opkg update
    opkg install postgresql
  2. Initialize the cluster on a USB-attached SSD, never on the eMMC (wear):
    mkdir -p /media/sda1/pgdata
    chown -R postgres:postgres /media/sda1/pgdata
    su - postgres -c "/usr/lib/postgresql/9.6/bin/initdb -D /media/sda1/pgdata"
  3. Tune postgresql.conf for 256 MB shared_buffers and disable the JIT (LLVM JIT is not available on Quark):
    shared_buffers = 256MB
    effective_cache_size = 512MB
    jit = off
    max_connections = 20
  4. Start the server and verify:
    /etc/init.d/postgresql start
    psql -U postgres -c "SELECT version();"
Field-proven caveat. PostgreSQL 9.6 on Quark works for archival logging of 1-5 Hz PLC tags. Do not attempt OLTP workloads, large JSON queries, or any workload that pushes shared_buffers above 50% of physical RAM, or the kernel OOM killer will reclaim the NodeJS process and crash the gateway.

7.2 Procedure for MongoDB on the 1 GB IoT2040

MongoDB 3.6 is the last version that builds without SSE4.2 requirements. The procedure mirrors PostgreSQL, with two extra steps:

  1. Build or install mongodb-server-core and mongodb-clients 3.6.x.
  2. Configure WiredTiger with a strict cache ceiling:
    storage:
      engine: wiredTiger
      wiredTiger:
        engineConfig:
          cacheSizeGB: 0.3
    
  3. Start with systemLog.verbosity: 1 only; every log level above 1 doubles memory pressure on Quark.

Operationally, if your application truly needs MongoDB features (TTL indexes, aggregation pipelines, change streams), the right answer is to push the database to a separate industrial server or migrate to the IOT2050.

8. Migration Path to SIMATIC IOT2050

The meta-iot2000 releases page states that the IOT2050 is the successor platform and that the IoT2040 has reached product discontinuation. The migration is mechanical, not architectural.

  1. Reflash the IOT2050 with Example Image V3.1.17 (the last official image) using iot2000setup from a USB stick or the SD card slot on the IOT2050.
  2. Re-target the BSP. Change MACHINE = "iot2040" to MACHINE = "iot2050" in your custom layer's local.conf. The Apollo Lake BSP is layered on Dunfell and uses linux-intel 5.10.
  3. Update the NodeJS runtime. V3.1.17 ships with NodeJS v12 LTS. If your application code targets v8, run it under v12 directly; the NodeJS compatibility layer is stable for typical OPC-UA, Modbus, and MQTT workloads.
  4. Re-validate the I/O bindings. The Arduino shield header pinout is identical between IoT2040 and IOT2050, but the libmraa major version moved from 1.x to 2.x. Re-test any custom C/C++ modules.
  5. Re-issue the security posture. The IOT2050 supports Secure Boot and a TPM 2.0. Enable both, regenerate SSH host keys, and re-sign your application containers.
Migration step Estimated downtime Risk
Reflash with V3.1.17 10 min Low (image is signed)
Port custom Yocto recipes 2-4 h per recipe Medium (Dunfell vs Pyro API changes)
Upgrade NodeJS v8 to v12 30 min + regression test Low to medium depending on native modules
Validate I/O bindings 1-2 h Low (pinout identical)
Enable Secure Boot + TPM 1 h Low (one-time)

9. Field-Proven Caveats and Verification

Use the checklist below before declaring any IoT2000 deployment production-ready.

  1. Verify the boot partition signature. V2.1.3 images do not ship signed kernels. Once migrated to V3.1.17 on the IOT2050, enable UEFI Secure Boot and confirm with mokutil --sb-state returning SecureBoot enabled.
  2. Monitor node process RSS. On Quark, a NodeJS v8 runtime with three active MQTT connections typically holds 90-130 MB resident. The kernel will OOM-kill at ~180 MB. Set a systemd memory limit of 150 MB and a restart policy.
  3. Avoid npm install on the device. Compile native modules on the Yocto build host with npm install --target_arch=ia32 and ship the node_modules tree as part of the application artifact. npm install on Quark is a frequent cause of flash wear and silent SSE faults.
  4. Watch the eMMC wear. cat /sys/block/mmcblk0/device/life_time returns a value of 0x00 to 0x0A. Anything above 0x07 means the eMMC is near end-of-life. Move write-intensive workloads (logs, databases) to the SD card or USB SSD.
  5. Network segmentation. Place the IoT2000 behind a stateful firewall. The V2.x images have unpatched CVEs in busybox (CVE-2021-42374 and related) and in the bundled dropbear SSH server.
  6. Time synchronisation. The default systemd-timesyncd is sufficient, but if you run OPC-UA, switch to chrony and configure NTP over the management VLAN.

10. Troubleshooting Matrix

Symptom Likely cause Resolution
node exits with SIGILL after upgrade to v10+ V8 SSE2 opcode on Quark Pin to v6.12.3 LTS or v8.17.0 (Yocto thud build)
opkg install nodejs fails with unknown package Repository index out of date or wrong branch Run opkg update; verify /etc/opkg/*.conf points to a meta-iot2000 Pyro or thud feed
PostgreSQL service exits with code 137 OOM killer Reduce shared_buffers to 128 MB, disable JIT, move data directory to USB SSD
MongoDB refuses to start, log shows "illegal instruction" MongoDB 4.x binary Downgrade to MongoDB 3.6.x or migrate to IOT2050
libmraa initialisation fails after reflash Arduino shield power rail not enabled Run iot2000setup -> "Configure Arduino shield" -> 5V/3.3V
Kernel oops on systemd shutdown Known bug in Pyro systemd 232 Upgrade to V2.1.5 or backport the systemd patch from thud

11. Summary of Constraints

  • The meta-iot2000 releases page marks V3.1.17 as the last offical Example Image and the IoT2040 as a discontinued product line.
  • V2.1.3 is not republished; recover it from Siemens support, a partner portal, or an internal archive, then checksum the image.
  • NodeJS on the Quark-based IoT2020 / IoT2040 is practically limited to v6 LTS, with v8 LTS possible only via a custom Yocto thud build on the meta-iot2000 jan/thud branch.
  • PostgreSQL works on the 1 GB IoT2040 SKU for archival logging only; MongoDB is feasible in version 3.6.x with strict cache ceilings, but is not recommended for new designs.
  • New industrial deployments should target the SIMATIC IOT2050 with Example Image V3.1.17.

12. Frequently Asked Questions

Where can I download the SIMATIC IoT2000 Example Image V2.1.3?

V2.1.3 is no longer published on the Siemens public download center. The supported recovery channel is to open a Siemens Industry Online Support (SIOS) ticket with the device serial number and request the archived image under your service contract. Partners with a System Integrator agreement can also pull it from the partner portal. Always verify the SHA-256 hash before flashing.

What is the highest NodeJS version that runs on the IoT2040?

NodeJS v6.12.3 LTS is the only version Siemens officially supports on the Quark-based IoT2040. NodeJS v8.17.0 LTS is possible by building a custom image from the meta-iot2000 jan/thud branch, but the V8 binaries are patched downstream and are not a Siemens-supported configuration. Anything above v8 will hit a SIGILL fault because the Quark has no SSE2 instructions.

Does the IoT2040 support PostgreSQL or MongoDB?

PostgreSQL 9.6 builds and runs on the 1 GB IoT2040 SKU for archival logging of 1-5 Hz PLC tags. MongoDB 3.6.x is feasible only with a strict WiredTiger cache ceiling of 0.3 GB and is not recommended for new designs. PostgreSQL 14+ and MongoDB 4.x+ require SSE4.2 and will not run on Quark; deploy them on the IOT2050 or on a separate industrial server.

Is the IoT2040 still in production?

No. The IoT2040 is in product discontinuation. The meta-iot2000 GitHub repository has been archived and no longer accepts pull requests; the meta-iot2000 releases page explicitly identifies the SIMATIC IOT2050 as the successor platform.

What is the last official Example Image for the IOT2050?

Example Image V3.1.17 is the final offical release for the SIMATIC IOT2050. It is based on the Yocto Dunfell branch, ships with NodeJS v12 LTS, and uses the Apollo Lake BSP layer. New deployments should start from V3.1.17 unless there is a documented reason to track a specific service pack.

Back to blog