Release v1.1.0#11
Merged
Merged
Conversation
feat: Implement critical gaps for v1.0 release
Feature/release v1.0 critical gaps
Fix/release strategy enforcement
…t-queue docs - isdu: drop stray printf/fflush from the ISDU response hot path and the now-unused <stdio.h> so the protocol core stays stdio-free for bare-metal - dll: increment timeout_errors in the inactivity watchdog so the counter reported via ErrorStats (0x25) and DLL stats is actually meaningful - docs: correct event queue size (8 -> 4) in API.md/FRAMES.md to match IOLINK_EVENT_QUEUE_SIZE in config.h
…reset handler - isdu: remove dead inline DetailedDeviceStatus (0x1C) handler; the live path is handle_detailed_device_status() reached via handle_standard_commands() - isdu: encode EventQualifier per V1.1.5 (MODE=appears bits7-6, TYPE bits5-4, SOURCE=device, INSTANCE=DL) instead of the previous non-conformant layout - isdu: PDInDescriptor (0x1D) now reports the actual configured PD-in length from the DLL context instead of a hardcoded 2 - core: add iolink_set_reset_handler(); iolink_process() now consumes the reset_pending/app_reset_pending flags (0x80/0x81) and dispatches them - tests: update detailed-status and pdin-descriptor expectations accordingly - chore: ignore build_chk/ scratch build dir
Replaces the previous state-label stub with a working parameter backup/restore: - Serialize DS-backed parameters (ApplicationTag/FunctionTag/LocationTag) into a record image [Index(2)][Subindex(1)][Length(1)][Data] via iolink_ds_build_image - Apply a Master-provided image back through the parameter manager (persisted to NVM) via iolink_ds_apply_image, with full structural validation before write - Expose the image over ISDU index 0x0003 (DS_Data): read = upload/backup, write = download/restore; system commands 0x05-0x08 bracket the transfer - Fix dll_init so isdu.ds_ctx is bound to the DLL DS context (DS and DS system commands were unreachable end-to-end before this) - Image buffer lives in the DS context (static, IOLINK_DS_IMAGE_MAX=256) - Tests: DS module round-trip (build->wipe->restore byte-exact), truncated-image rejection, and an end-to-end ISDU 0x0003 upload/restore round-trip
- application.h: implement the documented iolink_app_register() / app callbacks (on_startup/on_preoperate/on_operate + PD in/out) that previously did not exist - dll: route every state transition through dll_set_state() and fire an optional state-change hook, so lifecycle callbacks never miss a (even transient) state - core: bind the DLL hook to a trampoline dispatching app lifecycle callbacks, announce initial STARTUP, and fire cyclic PD callbacks while in OPERATE - docs: correct conformance test count (33/36 -> actual 49 across 7 categories) in README/CONFORMANCE; ARCHITECTURE now lists all six DLL states and marks ISDU implemented; API.md uses the real 2-arg init and real config.h macro names - tests: lifecycle/PD callback coverage via move_to_operate()
- dll: dll_enter_fallback now transitions through IOLINK_DLL_STATE_FALLBACK on the SIO-revert path so the declared state is actually observable (was never assigned) before settling back to STARTUP - isdu: replace the misleading 'real implementation would poll' BUSY comment; ISDU services execute synchronously, BUSY is only transient collision state - docs(ROADMAP): mark the now-implemented items done — system command reset/ restore/DS subcommands (0x80-0x83, 0x95-0x97), indices 0x19/0x1A/0x1C/0x1D, and Data Storage real serialization + access-lock integration
- Implement ISDU index 0x0000 (Direct Parameter page 1): packed read of MasterCommand/MasterCycleTime/MinCycleTime/M-sequenceCapability/RevisionID (0x11)/ProcessDataIn/ProcessDataOut/VendorID/DeviceID per V1.1.5 Table B.1, with subindex octet addressing (sub 0 = full page, 1-16 = byte at sub-1) - Implement index 0x0001 (Direct Parameter page 2): RAM-backed device-specific read/write; page 1 correctly rejects writes (write-protected) - M-sequenceCapability and ProcessData length encodings derived from the live DLL config (Figures B.3/B.5) - tests: page 1 packed + single-octet read + write-protect; page 2 round-trip
- Add the standardized Device EventCodes from V1.1.5 Annex D Table D.1 as named IOLINK_EVENTCODE_* constants (temperature, hardware, power, software/parameter, wiring, application/maintenance, DS upload request) - Add iolink_event_classify() returning the spec EventType (notification/warning/ error) for a code, defaulting reserved/unknown codes to error - docs(ROADMAP): mark standard event-code ranges + event qualifier done - tests: classification coverage across notification/warning/error/unknown
- After applying a downloaded image, re-serialize from the device's actual parameters so the stored image and checksum reflect true device state. If the download could not be applied faithfully (e.g. unknown indices skipped), the checksum diverges from the Master's and the next iolink_ds_check() re-requests a download until both sides agree. - Add iolink_ds_verify() to confirm the stored image matches its checksum - tests: recovery test (known + unknown index -> device converges, re-download requested); existing faithful round-trip still preserves the checksum
- Add public iolink_set_pd_length(): valid only for TYPE_1_V/TYPE_2_V, clamps to the configured maximum, takes effect on the next cyclic exchange, and is reflected in the PD descriptors (0x001D, Direct Parameter page 1) so a Master can re-read the new length. Fixed M-sequence types reject the call (-2). - iolink_get_pd_in_len/out_len now report the current (runtime) length, which equals the configured value for fixed types - tests: shrink-and-reject runtime negotiation; fixed-type rejection
Make iolinki installable as a west module and buildable for real hardware as an IO-Link device. - module.yml: add name and samples pointer - west.yml: standalone manifest pulling a known-good Zephyr (v3.7.0) - Kconfig: expose buffer/PD-size tunables and default M-sequence type - CMakeLists: map Kconfig tunables onto core config.h macros via zephyr_compile_definitions; gate on CONFIG_IOLINKI - phy_uart: bind UART via zephyr,iolink-uart chosen node (iolink-uart alias fallback); interrupt-driven RX into a ring buffer; document that wake-up/SIO belong to the transceiver front-end - samples/iolink_device: idiomatic sample (sample.yaml, prj.conf, CMakeLists, main.c, nucleo_l476rg overlay) using app callbacks and per-cycle process-data publication - docs: zephyr/README.md (west install, Kconfig map, DT contract, PHY porting note, build via west and Docker); link from top-level README - build_zephyr_docker.sh: build the new sample
First open IO-Link device module for Zephyr: west-installable module manifest, Kconfig-driven config (buffer/PD sizes, PHY choice, M-sequence type), DT-bound UART PHY, and an idiomatic samples/iolink_device with twister coverage.
- build_zephyr_docker.sh: run as root (writable west topdir), cache the west workspace in a named volume, and build with the official ghcr.io image - west.yml: track Zephyr main (matches the SDK in the official build image) and document that production users pin their own Zephyr; native_sim sample now compiles and links green (zephyr.elf) - phy_virtual: define _DEFAULT_SOURCE so cfmakeraw() is declared under strict libc (silences the warning seen in the Zephyr native_sim build) Verified: 'west build -b native_sim samples/iolink_device' links zephyr.elf [117/117] with no warnings; host suite remains 21/21.
The CI strict compile uses -Wall -Wextra -Werror -Wpedantic -Wconversion -Wshadow, which caught two issues in test_isdu.c that a plain build missed: - test_isdu_data_storage_round_trip was defined but never added to the test runner array (so it never ran, and tripped -Werror=unused-function); register it with the other ISDU tests - the DS write request passed (size_t) for a uint8_t data_len parameter, a narrowing conversion flagged by -Wconversion; cast to (uint8_t) - iolink.h: correct the PD-length getter docs (now return the current/runtime length, not the configured value)
This file carried pre-existing clang-format-14 violations that failed the CI formatting gate (red since Feb 2026). The CI Docker image pins clang-format-14; formatted to match so the gate passes.
Doxygen could not resolve the bare '@ref current_checksum' struct-member references in iolink_ds_build_image/apply_image docs (CI Doxygen-warning gate). Qualify as iolink_ds_ctx_t::current_checksum, matching the existing ::image ref.
…ion test Investigation of the flaky test_02_rapid_state_transitions (2/5 under load, flaky locally too) found a real defect plus an unrealistic test sequence: - dll: a wake-up starts a fresh communication-establishment window, but last_activity_ms was only updated on byte RX, so a re-wake shortly after a prior exchange was immediately killed by the stale 1s inactivity watchdog. Reset last_activity_ms when a wake-up is detected. - test: the test sent wake-up, idled 1.0s, THEN read ISDU — but a real Master drives frames within microseconds of wake-up, and a spec-compliant Device correctly reverts to SIO during a 1s post-wake-up silence. Reordered to the realistic sequence (read promptly after wake-up; idle between cycles to let the Device fall back). Success threshold unchanged (>=3/5); now reliably 5/5. Verified: strict build clean, 21/21 unit, all 49 conformance pass; the rapid- transition test passes 5/5 across repeated local runs.
The Zephyr CI stage had two compounding, pre-existing failures unrelated to the stack: - SDK mismatch: Dockerfile.zephyr-base pinned Zephyr v3.5.0 but the base image (zephyr-build:latest) ships Zephyr SDK 1.0.1, which v3.5.0's FindHostTools rejects. Track Zephyr 'main' so the version matches the bundled SDK (verified: examples/zephyr_app links zephyr.elf green on native_sim). - Target mismatch: examples/zephyr_app forced CONFIG_IOLINK_PHY_UART, so it could not build on native_sim (no iolink_uart devicetree node) and could not use the IOLINK_PORT virtual-master PTY path. Switch the example to the virtual PHY for native_sim/CI; real-hardware builds opt into the UART PHY explicitly. - Bump the cache key so CI rebuilds the base image with the new Zephyr.
Bump project version to 1.1.0 (CMakeLists, Doxyfile) and add the 1.1.0 CHANGELOG entry covering Data Storage, Direct Parameters, standard EventCodes, variable-PD negotiation, application callbacks/reset handler, the Zephyr module, the wake-up/inactivity and descriptor fixes, and the CI pipeline restoration.
…nel visible The prior wording framed GPLv3 as a 90-day, non-production 'evaluation' and claimed any production use needs a commercial license regardless of open/closed source. That is unenforceable under GPLv3 (you cannot add field-of-use or time restrictions to the GPL grant) and confusing. - Restate the dual license correctly: GPLv3 is free for open-source use, including production, under copyleft; a commercial license is required only for closed-source / proprietary products that cannot accept copyleft. - Make the commercial path prominent in README (who needs it + contact + one-time pricing) so closed-source vendors are funneled rather than repelled. - Apply the same correction to LICENSE.COMMERCIAL.
The Zephyr device-over-PTY integration (test_type1.py) had no timeout and could hang indefinitely on a runner (observed stalling 40+ min on an otherwise-green build). Wrap it in 'timeout 240' so a hang fails fast and the gate stays deterministic instead of blocking the pipeline.
The six virtual-master integration scripts in the Docker host stage ran unbounded under 'set -e', so a single stuck PTY hung the whole pipeline for 40+ min (seen intermittently on loaded runners). Wrap each in 'timeout 180' so a hang fails fast and the gate stays deterministic; normal runtime is <30s each.
The Zephyr simulation stage caches/loads a ~10GB Docker image; on a free runner that (tar on disk + loaded image) exhausted resources and the runner lost communication, failing the whole pipeline. - Split run_all_tests_docker.sh into selectable 'host' and 'zephyr' stages. - docker-validation now runs ONLY the lightweight host stage (code quality, unit tests, virtual-master conformance) — the required merge gate. - New zephyr-validation job runs the heavy stage with continue-on-error and is NOT a required check, so a runner-resource failure can no longer block merges. It frees the cached tar immediately after docker load to avoid disk exhaustion. The Zephyr module build is also verified via tools/build_zephyr_docker.sh. - The branch-protection gate jobs depend only on docker-validation (host).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
iolinki v1.1.0
First feature release since v1.0.0. CI is green across all gates (strict compile, cppcheck, clang-format, Doxygen, unit tests, and the Zephyr build stage). Tagged candidate:
v1.1.0-rc2.Added
iolink_event_classify().iolink_set_pd_length().iolink_app_register) — lifecycle + process-data callbacks.iolink_set_reset_handler) for System Commands 0x80/0x81.native_simsample.Fixed
timeout_errorswired through.Changed
Verification
native_simlinks green.Known limitation
Release steps (Gitflow)
mainv1.1.0frommainrelease/1.1.0back intodevelop