Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 1 addition & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,7 @@ endif()
# Include directories
include_directories(include)

# Core Library
set(IOLINKI_SOURCES
src/iolink_core.c
)
add_library(iolinki STATIC
src/iolink_core.c
src/phy_generic.c
src/phy_virtual.c
src/crc.c
Expand All @@ -34,6 +29,7 @@ add_library(iolinki STATIC
src/params.c
src/data_storage.c
src/device_info.c
src/device.c
src/platform_stubs.c
)

Expand Down
14 changes: 6 additions & 8 deletions Doxyfile
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ PROJECT_NAME = "iolinki"
PROJECT_NUMBER = "1.1.2"
PROJECT_BRIEF = "Open-Source IO-Link Device Stack"
OUTPUT_DIRECTORY = docs
INPUT = include/iolinki src/iolink_core.c src/dll.c src/isdu.c src/events.c src/params.c src/data_storage.c src/device_info.c src/phy_virtual.c src/crc.c
INPUT = include/iolinki src/device.c src/dll.c src/isdu.c src/events.c src/params.c src/data_storage.c src/device_info.c src/phy_virtual.c src/crc.c
RECURSIVE = NO
OPTIMIZE_OUTPUT_FOR_C = YES
EXTRACT_ALL = YES
Expand All @@ -14,13 +14,11 @@ GENERATE_MAN = NO
GENERATE_RTF = NO

# Graphviz Support
HAVE_DOT = YES
DOT_PATH = /usr/bin
CLASS_DIAGRAMS = NO
COLLABORATION_GRAPH = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
GRAPHICAL_HIERARCHY = YES
HAVE_DOT = NO
COLLABORATION_GRAPH = NO
INCLUDE_GRAPH = NO
INCLUDED_BY_GRAPH = NO
GRAPHICAL_HIERARCHY = NO

# Warning settings
WARN_IF_UNDOCUMENTED = YES
Expand Down
8 changes: 5 additions & 3 deletions examples/bare_metal_app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
* See LICENSE for details.
*/

#include "iolinki/iolink.h"
#include "iolinki/device.h"
#include "iolinki/phy_virtual.h"

/* Extern the volatile tick counter from time_utils_baremetal.c */
Expand All @@ -22,15 +22,17 @@ int main(void)
/* Initialize stack with virtual PHY (simplified for bare metal, typically uses UART/SPI) */
iolink_phy_virtual_set_port("/dev/null");
const iolink_phy_api_t* phy = iolink_phy_virtual_get();
iolink_device_ctx_t ctx;
iolink_device_config_t dev_config = {.phy = *phy};

if (iolink_init(phy, NULL) != 0) {
if (iolink_device_init(&ctx, &dev_config) != 0) {
return -1;
}

/* Main Super-Loop */
while (1) {
/* Process Stack */
iolink_process();
iolink_device_process(&ctx);

/* Simulate System Tick (Time Passage) */
sys_tick_handler();
Expand Down
17 changes: 13 additions & 4 deletions examples/freertos_app/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#define pdMS_TO_TICKS(x) ((x) / 10)
#endif

#include "iolinki/iolink.h"
#include "iolinki/device.h"
#include "iolinki/platform.h"
#include "iolinki/phy.h"

Expand All @@ -43,19 +43,27 @@ const iolink_phy_api_t g_phy_freertos = {
.recv_byte = NULL // Implement actual UART recv
};

static iolink_device_ctx_t g_device_ctx;
static iolink_device_config_t g_device_config = {
.phy = g_phy_freertos,
};

/* IO-Link Stack Task */
void iolink_task_entry(void* pvParameters)
{
(void) pvParameters;

/* Initialize Stack */
iolink_init(&g_phy_freertos);
if (iolink_device_init(&g_device_ctx, &g_device_config) != 0) {
printf("IO-Link init failed\n");
return;
}

printf("IO-Link Task Started\n");

for (;;) {
/* Process Stack */
iolink_process();
iolink_device_process(&g_device_ctx);

/* Yield / Sleep to allow other tasks (1ms cycle) */
vTaskDelay(pdMS_TO_TICKS(1));
Expand All @@ -69,7 +77,8 @@ void app_task_entry(void* pvParameters)

for (;;) {
/* Trigger an event every 5 seconds safely */
iolink_event_trigger(NULL /* ctx */, 0x1800, IOLINK_EVENT_TYPE_NOTIFICATION);
iolink_event_trigger(iolink_device_get_events_ctx(&g_device_ctx), 0x1800,
IOLINK_EVENT_TYPE_NOTIFICATION);

vTaskDelay(pdMS_TO_TICKS(5000));
}
Expand Down
14 changes: 8 additions & 6 deletions examples/host_demo/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "iolinki/iolink.h"
#include "iolinki/device.h"
#include "iolinki/phy_virtual.h"

int main(int argc, char* argv[])
Expand Down Expand Up @@ -68,8 +68,10 @@ int main(int argc, char* argv[])

/* Initialize stack with virtual PHY and config */
const iolink_phy_api_t* phy = iolink_phy_virtual_get();
iolink_device_ctx_t ctx;
iolink_device_config_t dev_config = {.phy = *phy, .stack = config};

if (iolink_init(phy, &config) != 0) {
if (iolink_device_init(&ctx, &dev_config) != 0) {
printf("ERROR: Failed to initialize IO-Link stack\n");
return -1;
}
Expand All @@ -80,22 +82,22 @@ int main(int argc, char* argv[])
/* Simulate periodic processing and PD exchange */

while (1) {
iolink_process();
iolink_device_process(&ctx);
// ...

/* Update input data (Device -> Master) */

iolink_process();
iolink_device_process(&ctx);

/* Check for output data (Master -> Device) */
uint8_t pd_buffer[32];
int len = iolink_pd_output_read(pd_buffer, sizeof(pd_buffer));
int len = iolink_device_pd_output_read(&ctx, pd_buffer, sizeof(pd_buffer));
if (len > 0) {
/* Echo + 1 */
for (int i = 0; i < len; i++) {
pd_buffer[i]++;
}
iolink_pd_input_update(pd_buffer, (size_t) len, true);
iolink_device_pd_input_update(&ctx, pd_buffer, (size_t) len, true);
}

/* 1ms cycle time simulation */
Expand Down
7 changes: 5 additions & 2 deletions examples/simple_device/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
*/

#include <stdio.h>
#include "iolinki/iolink.h"
#include "iolinki/device.h"

/**
* @brief Placeholder for a real hardware PHY implementation
Expand All @@ -23,7 +23,10 @@ int main(void)
printf("IO-Link Simple Device Example\n");

/* Use default configuration */
if (iolink_init(&g_hw_phy, NULL) != 0) {
iolink_device_ctx_t ctx;
iolink_device_config_t dev_config = {.phy = g_hw_phy};

if (iolink_device_init(&ctx, &dev_config) != 0) {
printf("Failed to initialize IO-Link stack\n");
return -1;
}
Expand Down
19 changes: 11 additions & 8 deletions examples/zephyr_app/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

#include <zephyr/kernel.h>
#include <zephyr/logging/log.h>
#include "iolinki/iolink.h"
#include "iolinki/device.h"

#ifdef CONFIG_IOLINK_PHY_UART
#include "platform/zephyr/phy_uart.h"
Expand All @@ -31,9 +31,9 @@ int main(void)
{
LOG_INF("Starting IO-Link Zephyr Demo");

#ifdef CONFIG_IOLINK_PHY_VIRTUAL
const char *port = NULL;

#ifdef CONFIG_IOLINK_PHY_VIRTUAL
port = getenv("IOLINK_PORT");
if (port) {
iolink_phy_virtual_set_port(port);
Expand Down Expand Up @@ -95,17 +95,20 @@ int main(void)
/* Send Master Command: Read Direct Parameter 1 (Index 0) */
/* MC = 0x80, CKT = 0x00, CK = 0x24 */
uint8_t frame[] = {0x80, 0x24};
phy_api->send(frame, 2);
phy_api->send(phy_api->user, frame, 2);

uint8_t rx;
while (phy_api->recv_byte(&rx) > 0) {
while (phy_api->recv_byte(phy_api->user, &rx) > 0) {
LOG_INF("Master RX: 0x%02X", rx);
}

k_msleep(2000);
}
#else
if (iolink_init(phy_api, &config) != 0) {
iolink_device_ctx_t ctx;
iolink_device_config_t dev_config = {.phy = *phy_api, .stack = config};

if (iolink_device_init(&ctx, &dev_config) != 0) {
LOG_ERR("Failed to init IO-Link");
return -1;
}
Expand All @@ -114,16 +117,16 @@ int main(void)
uint32_t last_update = 0;

while (1) {
iolink_process();
iolink_device_process(&ctx);

/* Simulating sensor data change every 2000ms */
uint32_t now = k_uptime_get_32();
if (now - last_update > 2000) {
last_update = now;
sensor_val++;

uint8_t pd[2] = {sensor_val, 0xA5};
iolink_pd_input_update(pd, 2, true);
const uint8_t pd[2] = {sensor_val, 0xA5};
iolink_device_pd_input_update(&ctx, pd, 2, true);

LOG_INF("Device PD Update: 0x%02X", sensor_val);
}
Expand Down
32 changes: 1 addition & 31 deletions include/iolinki/application.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,34 +18,14 @@
* @brief IO-Link Application Layer API for Process Data
*/

/**
* @brief Update Process Data Input (Device -> Master)
*
* @param data Pointer to input data
* @param len Length in bytes
* @param valid Data validity flag (true = valid, false = invalid)
* @return int 0 on success, negative on error
*/
int iolink_pd_input_update(const uint8_t* data, size_t len, bool valid);

/**
* @brief Read Process Data Output (Master -> Device)
*
* @param data Pointer to buffer to store output data
* @param len Max length to read
* @return int Number of bytes read, negative on error
*/
int iolink_pd_output_read(uint8_t* data, size_t len);

/**
* @brief Application lifecycle and Process Data callbacks.
*
* Any field may be NULL. Lifecycle callbacks fire once when the DLL enters the
* corresponding state (driven from iolink_process()). The PD callbacks fire on
* corresponding state. The PD callbacks fire on
* every processed OPERATE cycle: @ref on_pd_output reports the output Process
* Data received from the Master (Master -> Device), and @ref on_pd_input reports
* the input Process Data the Device is currently publishing (Device -> Master).
* They complement the polling API (iolink_pd_output_read / iolink_pd_input_update).
*/
typedef struct
{
Expand All @@ -56,14 +36,4 @@ typedef struct
void (*on_pd_output)(uint8_t* data, uint8_t len); /**< Output PD received */
} iolink_app_callbacks_t;

/**
* @brief Register application callbacks (or NULL to clear).
*
* The structure is referenced, not copied, so it must remain valid for the
* lifetime of the stack.
*
* @param callbacks Pointer to a callbacks structure, or NULL.
*/
void iolink_app_register(const iolink_app_callbacks_t* callbacks);

#endif // IOLINK_APPLICATION_H
3 changes: 3 additions & 0 deletions include/iolinki/data_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define IOLINK_DATA_STORAGE_H

#include "iolinki/protocol.h"
#include "iolinki/params.h"
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
Expand Down Expand Up @@ -91,6 +92,7 @@ typedef struct
{
iolink_ds_state_t state; /**< Current DS state machine position */
const iolink_ds_storage_api_t* storage; /**< Bound storage implementation API */
iolink_params_ctx_t* params_ctx; /**< Device-local writable parameter context */
uint16_t current_checksum; /**< Last calculated local parameter checksum */
uint16_t master_checksum; /**< Most recent checksum verified by Master */
uint8_t image[IOLINK_DS_IMAGE_MAX]; /**< Serialized parameter image (DS_Data 0x0003) */
Expand All @@ -104,6 +106,7 @@ typedef struct
* @param storage Optional storage implementation hooks (can be NULL for RAM-only)
*/
void iolink_ds_init(iolink_ds_ctx_t* ctx, const iolink_ds_storage_api_t* storage);
void iolink_ds_bind_params(iolink_ds_ctx_t* ctx, iolink_params_ctx_t* params_ctx);

/**
* @brief Calculate a standard 16-bit checksum for a parameter block
Expand Down
Loading
Loading