浏览代码

add readme instructions

kurisaw 1 年之前
父节点
当前提交
6042a595fd
共有 53 个文件被更改,包括 304 次插入10979 次删除
  1. 0 41
      .clang-format
  2. 0 11
      .docker/rbpi.Dockerfile
  3. 0 12
      .git-blame-ignore-revs
  4. 0 24
      .gitattributes
  5. 0 16
      .github/README.md
  6. 0 3
      .gitmodules
  7. 23 138
      README.md
  8. 31 0
      README_en.md
  9. 241 0
      docs/P-Net_Getting_Started_Guide.md
  10. 9 4
      docs/P-Net上手指南.md
  11. 二进制
      docs/figures/image-20241213150409268.png
  12. 0 0
      docs/figures/image-20241213150426614.png
  13. 0 246
      options.h.in
  14. 0 33
      pnet_options.h.in
  15. 0 41
      pnet_version.h.in
  16. 0 21
      samples/pn_dev/CMakeLists.txt
  17. 二进制
      samples/pn_dev/GSDML-RT-LABS-STACK.bmp
  18. 0 313
      samples/pn_dev/GSDML-V2.4-RT-Labs-P-Net-Sample-App-20220324.xml
  19. 0 315
      samples/pn_dev/app_data.c
  20. 0 140
      samples/pn_dev/app_data.h
  21. 0 260
      samples/pn_dev/app_gsdml.c
  22. 0 184
      samples/pn_dev/app_gsdml.h
  23. 0 52
      samples/pn_dev/app_log.c
  24. 0 75
      samples/pn_dev/app_log.h
  25. 0 865
      samples/pn_dev/app_utils.c
  26. 0 519
      samples/pn_dev/app_utils.h
  27. 0 1759
      samples/pn_dev/sampleapp_common.c
  28. 0 169
      samples/pn_dev/sampleapp_common.h
  29. 0 23
      samples/pn_dev_lan9662/CMakeLists.txt
  30. 0 417
      samples/pn_dev_lan9662/GSDML-V2.4-RT-Labs-P-Net-LAN9662-20220511.xml
  31. 0 68
      samples/pn_dev_lan9662/S90_start_profinet.sh
  32. 0 442
      samples/pn_dev_lan9662/app_data.c
  33. 0 121
      samples/pn_dev_lan9662/app_data.h
  34. 0 394
      samples/pn_dev_lan9662/app_gsdml.c
  35. 0 221
      samples/pn_dev_lan9662/app_gsdml.h
  36. 0 52
      samples/pn_dev_lan9662/app_log.c
  37. 0 75
      samples/pn_dev_lan9662/app_log.h
  38. 0 318
      samples/pn_dev_lan9662/app_shm.c
  39. 0 104
      samples/pn_dev_lan9662/app_shm.h
  40. 0 749
      samples/pn_dev_lan9662/app_utils.c
  41. 0 438
      samples/pn_dev_lan9662/app_utils.h
  42. 0 1235
      samples/pn_dev_lan9662/sampleapp_common.c
  43. 0 148
      samples/pn_dev_lan9662/sampleapp_common.h
  44. 0 77
      samples/pn_dev_lan9662/switchdev-profinet-example.sh
  45. 0 17
      samples/pn_shm_tool/CMakeLists.txt
  46. 0 509
      samples/pn_shm_tool/pn_shm_tool.c
  47. 0 31
      samples/pn_shm_tool/shm_LED_handler.sh
  48. 0 39
      samples/pn_shm_tool/shm_button_handler.sh
  49. 0 15
      samples/pn_shm_tool/shm_echo_all.sh
  50. 0 33
      samples/pn_shm_tool/shm_read_all.sh
  51. 0 29
      samples/pn_shm_tool/shm_write_all_inputs.sh
  52. 0 122
      samples/pn_shm_tool/test.sh
  53. 0 61
      tools/clean_no_alarm.sh

+ 0 - 41
.clang-format

@@ -1,41 +0,0 @@
-AlignAfterOpenBracket: AlwaysBreak
-AlignConsecutiveAssignments: false
-AlignConsecutiveMacros: true
-AllowAllArgumentsOnNextLine: false
-AllowAllParametersOfDeclarationOnNextLine: false
-AllowShortCaseLabelsOnASingleLine: false
-AllowShortFunctionsOnASingleLine: None
-AllowShortIfStatementsOnASingleLine: Never
-BinPackArguments: false
-BinPackParameters: false
-BreakBeforeBraces: Custom
-BraceWrapping:
-  AfterCaseLabel: true
-  AfterClass: true
-  AfterControlStatement: true
-  AfterEnum: true
-  AfterFunction: true
-  AfterNamespace: true
-  AfterStruct: true
-  AfterUnion: true
-  BeforeCatch: true
-  BeforeElse: true
-  IndentBraces: false
-  SplitEmptyFunction: true
-  SplitEmptyRecord: true
-  SplitEmptyNamespace: false
-  AfterExternBlock: false
-ColumnLimit: 80
-ContinuationIndentWidth: 3
-IndentCaseLabels: false
-IndentWidth: 3
-PenaltyBreakAssignment: 10
-PenaltyBreakBeforeFirstCallParameter: 30
-PenaltyBreakComment: 10
-PenaltyBreakString: 100
-PenaltyExcessCharacter: 100
-PenaltyReturnTypeOnItsOwnLine: 100000
-PointerAlignment: Middle
-SortIncludes: false
-SpaceBeforeParens: NonEmptyParentheses
-UseTab: Never

+ 0 - 11
.docker/rbpi.Dockerfile

@@ -1,11 +0,0 @@
-FROM dockcross/linux-arm64-lts
-ENV DEFAULT_DOCKCROSS_IMAGE p-net-rbpi
-RUN apt-get install -y python3-venv
-
-RUN pip install --break-system-packages uv
-
-ARG BUILDER_UID=1001
-ARG BUILDER_GID=1001
-ARG BUILDER_USER=rtljenkins
-ARG BUILDER_GROUP=rtljenkins
-RUN BUILDER_UID=${BUILDER_GID} BUILDER_GID=${BUILDER_GID} BUILDER_USER=${BUILDER_USER} BUILDER_GROUP=${BUILDER_GROUP} /dockcross/entrypoint.sh echo "Setup jenkins user"

+ 0 - 12
.git-blame-ignore-revs

@@ -1,12 +0,0 @@
-# This file contains a list of commits that are not likely what you
-# are looking for in a blame, such as mass reformatting or renaming.
-# You can set this file as a default ignore file for blame by running
-# the following command.
-#
-# $ git config blame.ignoreRevsFile .git-blame-ignore-revs
-
-# Run clang-format
-723c3d2ea620328554e3f4ca6718d7359a807bdf
-
-# Clang format of earlier modifications
-71e73f071cb6c42a3c8ec8a209e7e979a43cce5a

+ 0 - 24
.gitattributes

@@ -1,24 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-
-# Do not perform LF normalization on bash scripts
-*.service text eol=lf
-*.raspberrypi text eol=lf
-*.sh text eol=lf
-src/ports/linux/set_network_parameters text eol=lf
-src/ports/linux/set_profinet_leds text eol=lf
-
-# Custom for Visual Studio
-*.cs     diff=csharp
-
-# Standard to msysgit
-*.doc	 diff=astextplain
-*.DOC	 diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot  diff=astextplain
-*.DOT  diff=astextplain
-*.pdf  diff=astextplain
-*.PDF	 diff=astextplain
-*.rtf	 diff=astextplain
-*.RTF	 diff=astextplain

+ 0 - 16
.github/README.md

@@ -1,16 +0,0 @@
-# Evaluation version
-
-This repository contains an evaluation version of **P-Net**, a P-Net stack
-for Profinet Device implementations. It is especially well suited for
-embedded systems where resources are limited and efficiency is crucial.
-It is written in C and can be run on an RTOS such as rt-kernel, FreeRTOS,
-or on Linux.
-
-It does not contain any ports and cannot be built without adding additional sources.
-
-See [readme](../README.md) for more information on the complete version of the stack and the [releases](https://github.com/rtlabs-com/p-net/releases)  for binary downloads for common targets.
-
-This version of P-Net can be used for evaluation purposes
-only. Contact <sales@rt-labs.com> if you intend to use this stack in a
-product or if you need assistance during evaluation. The commercial
-version of this stack is supplied with full sources.

+ 0 - 3
.gitmodules

@@ -1,3 +0,0 @@
-# [submodule "cmake/tools"]
-# 	path = cmake/tools
-# 	url = https://github.com/rtlabs-com/cmake-tools

+ 23 - 138
README.md

@@ -1,146 +1,31 @@
-# P-net
+# P-NET-RTT
 
-Profinet device stack for embedded systems
+中文页 | [English](./README_en.md)
 
-## Web resources
+## 介绍
 
-- Source repository: [https://github.com/rtlabs-com/p-net](https://github.com/rtlabs-com/p-net)
-- Documentation: [https://rt-labs.com/docs/p-net](https://rt-labs.com/docs/p-net)
-- Continuous integration: [https://github.com/rtlabs-com/p-net/actions](https://github.com/rtlabs-com/p-net/actions)
-- RT-Labs (stack integration, certification services and training): [https://rt-labs.com](https://rt-labs.com)
+此存储库是对开源 P-Net 评估版本在 RT-Thread 上的移植,用于 Profinet 设备实现的 P-Net 协议栈,适合于资源有限并且实时效率要求高的嵌入式系统。此外需要注意的是,P-Net项目仅提供开源评估版本,如需商用版本请联系 rt-labs 官方购买商业许可获得完整版P-Net协议栈源码!
 
-[![Build Status](https://github.com/rtlabs-com/p-net/workflows/Build/badge.svg?branch=master)](https://github.com/rtlabs-com/p-net/actions?workflow=Build)
-[![CodeQL](https://github.com/rtlabs-com/p-net/workflows/CodeQL/badge.svg?branch=master)](https://github.com/rtlabs-com/p-net/actions?workflow=CodeQL)
+## 上手文档
 
-## Key features
+* P-NET-RTT 入门文档:[P-Net上手指南.md](./docs/P-Net上手指南.md)
 
-- Profinet v2.43
-    - Conformance Class A and B
-    - Real Time Class 1
-    - Multiple Ethernet ports
-
-
-- Easy to use
-  - Extensive documentation and instructions on how to get started.
-  - Build and run sample application on Raspberry Pi in 30 minutes.
-- Portable
-  - Written in C.
-  - Linux, RTOS or bare metal.
-  - Sources for supported port layers provided.
-
-The RT-Labs Profinet stack p-net is used for Profinet device
-implementations. It is easy to use and provides a small footprint. It
-is especially well suited for embedded systems where resources are
-limited and efficiency is crucial.
-The stack is supplied with full sources including porting
-layers and a sample application.
-
-Also C++ (any version) is supported for application development.
-
-The main requirement on the platform
-is that it can send and receive raw Ethernet Layer 2 frames.
-
-This software is dual-licensed, with GPL version 3 and a commercial license.
-If you intend to use this stack in a commercial product, you likely need to
-buy a license. See LICENSE.md for more details.
-
-## Getting started
-
-See the tutorial in the documentation: [https://docs.rt-labs.com/p-net/running_sample_app.html](https://docs.rt-labs.com/p-net/running_sample_app.html)
-
-Note that you need to include submodules when cloning:
-
-```
-git clone --recurse-submodules https://github.com/rtlabs-com/p-net.git
-```
-
-## Features
-
-- Multiple Ethernet ports (for Linux only, so far)
-- TCP/IP
-- LLDP
-- SNMP
-- RT (real-time)
-- Address resolution
-- Parameterization
-- Process IO data exchange
-- Alarm handling
-- Configurable number of modules and sub-modules
-- Bare-metal or OS
-- Porting layer provided
-- Supports I&M0 - I&M4. The I&M data is supported for the device, but not for
-  individual modules.
-- Shared device (connection to multiple controllers)
-
-## Limitations
-
-- This is a device stack, which means that the IO-controller/master/PLC side is
-  not supported.
-- No media redundancy (No MRP support)
-- Legacy startup mode is not fully implemented
-- No support for RT_CLASS_UDP
-- No support for DHCP
-- No fast start-up
-- No MC multicast device-to-device
-- No support for shared inputs
-- Supports only full connections, not the limited "DeviceAccess" connection type.
-- No iPar (parameter server) support
-- No support for time synchronization
-- No UDP frames at alarm (just the default alarm mechanism is implemented)
-- No ProfiDrive or ProfiSafe profiles.
-
-## Requirements
+## 主要特点
 
-The platform must be able to send and receive raw Ethernet Layer 2 frames,
-and the Ethernet driver must be able to handle full size frames. It
-should also avoid copying data, for performance reasons.
-
-- cmake 3.14 or later
-
-For Linux:
-
-- gcc 4.6 or later
-- See the "Real-time properties of Linux" page in the documentation on how to
-  improve Linux timing
-
-For rt-kernel:
-
-- Workbench 2020.1 or later
-
-An example of microcontroller we have been using is the Infineon XMC4800,
-which has an ARM Cortex-M4 running at 144 MHz, with 2 MB Flash and 352 kB RAM.
-It runs rt-kernel, and we have tested it with 9 Profinet slots each
-having 8 digital inputs and 8 digital outputs (one bit each). The values are
-sent and received each millisecond (PLC watchdog setting 3 ms).
-
-## Dependencies
-
-Some of the platform-dependent parts are located in the OSAL repository and the
-cmake-tools repository.
-
-- [https://github.com/rtlabs-com/osal](https://github.com/rtlabs-com/osal)
-- [https://github.com/rtlabs-com/cmake-tools](https://github.com/rtlabs-com/cmake-tools)
-
-Those are downloaded automatically during install.
-
-The p-net stack contains no third party components. Its external dependencies are:
-
-- C-library
-- An operating system (if used)
-- For conformance class B you need an SNMP implementation. On Linux is
-  net-snmp (BSD License) used [http://www.net-snmp.org](http://www.net-snmp.org)
-
-Tools used for building, testing and documentation (not shipped in the resulting binaries):
-
-- cmake (BSD 3-clause License) [https://cmake.org](https://cmake.org)
-- gtest (BSD-3-Clause License) [https://github.com/google/googletest](https://github.com/google/googletest)
-- Sphinx (BSD license) [https://www.sphinx-doc.org](https://www.sphinx-doc.org)
-- Doxygen (GPL v2) [https://www.doxygen.nl](https://www.doxygen.nl/index.html)
-- clang-format (Apache License 2.0) [https://clang.llvm.org](https://clang.llvm.org/docs/ClangFormat.html)
-
-## Contributions
+- Profinet v2.43
+  - 符合Class A 和Class B
+  - Real Time Class 1
+  - 多个以太网端口
+- 易于使用
+  - 提供详细的文档和入门指南。
+- 可移植
+  - 使用 C 编写。
+  - 支持 RT-Thread。
+  - 提供支持的端口层源代码。
+
+## 联系方式
+
+- 维护:[Kurisaw](https://github.com/Kurisaw)
+- 主页:https://github.com/kurisaW/p-net-rtt
+- 邮箱:2053731441@qq.com
 
-Contributions are welcome. If you want to contribute you will need to
-sign a Contributor License Agreement and send it to us either by
-e-mail or by physical mail. More information is available
-on [https://rt-labs.com/contribution](https://rt-labs.com/contribution).

+ 31 - 0
README_en.md

@@ -0,0 +1,31 @@
+- # P-NET-RTT
+
+EnglishPage | [Chinese](./README.md)
+
+## Introduction
+
+This repository is a port of the open source P-Net evaluation version on RT-Thread for the P-Net protocol stack implemented by Profinet devices, suitable for embedded systems with limited resources and high real-time efficiency requirements. In addition, it should be noted that P-Net project only provides open source evaluation version, if you need a commercial version, please contact rt-labs official purchase commercial license to obtain the full version of P-Net protocol stack source code!
+
+## Getting Started Documentation
+
+- P-NET-RTT Getting Started Guide: [P-Net_Getting_Started_Guide](./docs/P-Net_Getting_Started_Guide.md)
+
+## Key Features
+
+- Profinet v2.43
+- Compliance Class A and B
+- Real-Time Class 1
+- Multiple Ethernet Ports
+- Easy to Use
+- Extensive documentation and instructions on how to get started.
+- Portable
+- Written in C.
+- Supports RT-Thread.
+- Provides source code for supported port layers.
+
+## Contact information
+
+- maintenance: [Kurisaw](https://github.com/Kurisaw)
+- Home page:https://github.com/kurisaW/p-net-rtt
+- email: 2053731441@qq.com
+

+ 241 - 0
docs/P-Net_Getting_Started_Guide.md

@@ -0,0 +1,241 @@
+# P-NET-RTT
+
+> This repository is a port of the open-source P-Net evaluation version to RT-Thread, used for implementing the P-Net protocol stack for Profinet devices.
+
+## 1. Preliminary Setup
+
+### Software Environment
+
+* [CODESYS](https://us.store.codesys.com/) (Profinet master simulation)
+  * CODESYS
+  * CODESYS Gateway (Gateway device)
+  * CODESYS Control Win SysTray (SoftPLC device)
+* [Npcap](https://npcap.com/dist/npcap-1.80.exe) (This software is required for running CODESYS and must be installed in advance!)
+* [PRONETA](https://support.industry.siemens.com/cs/attachments/67460624/proneta_3_8_0_0.zip)
+
+### Hardware Environment
+
+* Microcontroller with ETH (Ethernet driver must support RT-Thread Ethernet driver framework)
+
+## 2. Software Package Configuration
+
+Open the `bsp`'s `env` interface, go to **->RT-Thread online packages->IoT**, and find **[*] P-Net stack for Profinet device implementation --->** to enable it. Also, leave configurations for the user:
+
+```md
+-*- Default netif name for P-NET  ---> 
+	-> (e00) default ethernet interface name for p-net app, default as 'e00'
+-*- Enable P-NET sample board config  ---> 
+	-> (0x0209) p-net user led pin
+	-> (0x0005) p-net user key pin
+-*- Default root filesystem path for P-NET  ---> 
+    -> [*] p-net using ramfs filesystem by default, or you can turn this off and choose another way to enable the filesystem
+    -> (8192) default memory size for ramfs
+-*- P-NET sample slave network ip config  ---> 
+    -> (192.168.137.196) set static ip address for Profinet slave
+    -> (192.168.137.1) set static gateway address for Profinet slave
+    -> (255.255.255.0) set static mask address for Profinet slave
+    version (latest)  ---> 
+```
+
+* **Default netif name for p-net**: P-net network interface device name, default as e00.
+* **Enable pnet sample board config**: Configuration for P-net app user LED and button.
+* **Default root filesystem path for p-net**: P-net filesystem configuration, default using ramfs with 8KB memory space.
+* **P-NET sample slave network ip config**: Static IP configuration for Profinet slave device (**Make sure to disable RT_LWIP_DHCP feature and use static IP**).
+
+Next, configure DHCP to be disabled and use a static IP. Go to **→ RT-Thread Components → Network → LwIP: lightweight TCP/stack**, and disable DHCP:
+
+![image-20241213150409268](figures/image-20241213150409268.png)
+
+After completing the configuration, compile and download the program to the development board.
+
+## 3. Network Configuration
+
+Connect the development board to the PC using an Ethernet cable, and configure a static IP on the PC side:
+
+![image-20241108100915339](figures/image-20241108100915339.png)
+
+Check the IP information on the development board and test the connectivity:
+
+![image-20241108101125803](figures/image-20241108101125803.png)
+
+## 4. SoftPLC Master Startup
+
+> CODESYS Overview: CODESYS is a PLC software developed by the German company 3S. It integrates functions like PLC logic, motion control, and configuration displays. CODESYS, short for "Controller Development System," is an industrial automation programming tool based on the IEC 61131-3 standard. It supports multiple programming languages (e.g., ladder diagram, structured text, function block diagram) and offers a wide range of libraries and functional modules, helping engineers quickly develop and debug PLCs and industrial control systems. Its flexibility and powerful features make it widely used in industrial automation.
+
+### 4.1 Create a Standard CODESYS Project
+
+Ensure that the CODESYS software is installed. After installation, the following three pieces of software will be used:
+
+![image-20241108112037518](figures/image-20241108112037518.png)
+
+* CODESYS V3.5 SP20 Patch 3: Profinet master simulation
+* CODESYS Gateway V3: Gateway device
+* CODESYS Control Win V3 -x64 SysTray: SoftPLC device
+
+First, open **CODESYS V3.5 SP20 Patch 3**, select -> New Project -> Projects -> Standard Project, configure the project name and location, then click OK:
+
+![image-20241108112525402](figures/image-20241108112525402.png)
+
+After this popup window appears, click OK to keep the default configuration:
+
+![image-20241108113312173](figures/image-20241108113312173.png)
+
+> Note: If you purchased the **[CODESYS Control RTE SL](http://store.codesys.cn/codesys/store/detail.html?productId=58)**, you can choose the device: CODESYS Control RTE V3 (CODESYS) / x64 (CODESYS). For normal evaluation purposes, you can skip installing this extension package and select CODESYS Control Win V3 (CODESYS) / x64 (CODESYS) device to create the project.
+
+After the creation is successful, you will see the main interface:
+
+![image-20241108114000212](figures/image-20241108114000212.png)
+
+### 4.2 Gateway and SoftPLC Startup
+
+Open the following two software applications:
+
+* CODESYS Gateway V3 (Right-click Start Gateway)
+* CODESYS Control Win V3 -x64 SysTray (Right-click Start PLC)
+
+![image-20241213150426614](figures/image-20241213150426614.png)
+
+Go back to the CODESYS master software, double-click **Device (CODESYS Control Win V3 x64)** -> Communication Settings -> Scan Network:
+
+![image-20241108114527294](figures/image-20241108114527294.png)
+
+After the device user login window appears, configure the username and password (user-defined):
+
+![image-20241108114642325](figures/image-20241108114642325.png)
+
+Check if the gateway device and softPLC device are online:
+
+![image-20241108133523711](figures/image-20241108133523711.png)
+
+### 4.3 Add Profinet GSDML File
+
+> GSD (Generic Station Description) files: These are used in PROFIBUS DP (GSD files) and PROFINET IO (GSDML files) communication, acting as a bridge between the CPU module and IO modules in a PLC system. They typically include channel data, parameter data, diagnostic data, and user-defined data.
+
+The GSDML file for this project is located at:
+
+* ..\src\ports\rtthread\pn_dev
+
+Install the GSDML file from the device repository by selecting **GSDML-V2.4-RT-Labs-P-Net-Sample-App-20220324.xml** under the above path:
+
+![image-20241108133947330](figures/image-20241108133947330.png)
+
+After the installation is successful, you will see the P-net slave description file:
+
+![image-20241108134832574](figures/image-20241108134832574.png)
+
+### 4.4 Add Devices
+
+* Add Ethernet: Right-click **Device** on the left navigation panel and select **Ethernet Adapter**:
+
+![image-20241108153525467](figures/image-20241108153525467.png)
+
+* Add PROFINET IO Master: Right-click **Ethernet** on the left navigation panel and select **PN-Controller**:
+
+![image-20241108153722094](figures/image-20241108153722094.png)
+
+* Add PROFINET IO Slave: Right-click **PN-Controller** on the left navigation panel and select **P-Net-multiple-module sample app**:
+
+![image-20241108153920925](figures/image-20241108153920925.png)
+
+### 4.5 Task Configuration
+
+* **Main Tasks** configuration: On the left navigation panel, select **Application -> Task Configuration**, double-click **MainTask (IEC-Tasks)**, set the priority to 1, set the type to cyclic, and set the cycle to 4ms:
+
+![image-20241111101451572](figures/image-20241111101451572.png)
+
+* **Profinet_CommunicationTask** configuration: Double-click **Profinet_CommunicationTask (IEC-Tasks)**, set the priority to 14, set the type to cyclic, and set the cycle to 10ms:
+
+![image-20241111101828252](figures/image-20241111101828252.png)
+
+### 4.6 Network Configuration
+
+* **Ethernet configuration**: Double-click **Ethernet (Ethernet)** on the left navigation panel -> General, and change the network interface to the Ethernet port connected to the development board (since I enabled PRONETA, two master IPs are assigned within the same subnet, so make sure to choose the correct one):
+
+![image-20241111094138076](figures/image-20241111094138076.png)
+
+* **PN_Controller configuration**: Double-click **PN_Controller (PN-Controller)** on
+
+ the left navigation panel -> General, and modify the default slave IP parameters according to the prompts.
+* **P-Net Slave network configuration**: Double-click **P-Net-multiple-module sample app** on the left navigation panel -> General, and change the IP parameters to the development board's IP:
+
+![image-20241111095351359](figures/image-20241111095351359.png)
+
+![image-20241111095924136](figures/image-20241111095924136.png)
+
+### 4.7 Compile, Debug, and Start the Project
+
+* Step 1: In the project navigation bar, select **Build -> Generate Code**.
+* Step 2: Select **Online -> Login**.
+* Step 3: Click **Debug -> Start**.
+
+You should now see that the PN master has successfully come online:
+
+![image-20241111102052203](figures/image-20241111102052203.png)
+
+## 5. Profinet Slave Application Startup
+
+Start the PN slave on the development board by executing the command: `pnet_app`:
+
+![image-20241111102801463](figures/image-20241111102801463.png)
+
+![image-20241111102909056](figures/image-20241111102909056.png)
+
+## 6. PN Protocol Stack Demo
+
+> In this section, we will use CODESYS and PRONETA software to test the interaction between PN master and slave as well as network topology status.
+
+### 6.1 LED Blinking
+
+Go back to the CODESYS software, select **PN_Controller** from the left navigation panel, right-click and scan for devices. After clicking on the device name, click **Blink LED**:
+
+![image-20241111103530633](figures/image-20241111103530633.png)
+
+At this point, you will see the log output on the development board (PN slave IO), and the onboard User LED will blink:
+
+![image-20241111103913906](figures/image-20241111103913906.png)
+
+### 6.2 Modify Slave I&M Data
+
+In the device scanning interface, click the **I&M** button at the bottom left, modify the information, and write the new I&M data:
+
+![image-20241111104223774](figures/image-20241111104223774.png)
+
+PNIO will update the slave configuration information:
+
+![image-20241111104354793](figures/image-20241111104354793.png)
+
+Click **I&M** again to see that the I&M modification has been successfully applied!
+
+### 6.3 PN Network Topology
+
+> PRONETA Overview: PRONETA Basic is a simple tool for quickly analyzing and configuring PROFINET networks. It also supports basic testing of ET 200 distributed IO systems and other components.
+
+#### 6.3.1 Install GSDML Files
+
+Open the PRONETA software and add the GSDML file:
+
+![image-20241111105332226](figures/image-20241111105332226.png)
+
+After installation is successful, you can see the status information:
+
+![image-20241111105406072](figures/image-20241111105406072.png)
+
+#### 6.3.2 Select Network Adapter
+
+Click **Settings -> Network Adapter** and choose the PN corresponding Ethernet port:
+
+![image-20241111105548779](figures/image-20241111105548779.png)
+
+#### 6.3.3 View Online Network Status
+
+Select **Network Analysis -> Online** from the top left navigation panel, click **Refresh**, and after a moment, you should see the PN network status. The specific PNIO information can be viewed on the right sidebar. Since we modified the PNIO information in CODESYS, you can also see the updated information here.
+
+![image-20241111110153537](figures/image-20241111110153537.png)
+
+Since pnet only supports a single AR by default, we need to disable the gateway device and softPLC device on the CODESYS master:
+
+![image-20241111110443169](figures/image-20241111110443169.png)
+
+Then, refresh the device and right-click **rt-labs-dev** to test the LED and I&M data modification:
+
+![image-20241111110804487](figures/image-20241111110804487.png)

+ 9 - 4
docs/P-Net上手指南.md

@@ -1,4 +1,4 @@
-# P-NET
+# P-NET-RTT
 
 > 此存储库是对开源 P-Net 评估版本在 RT-Thread 上的移植,用于 Profinet 设备实现的 P-Net 协议栈。
 
@@ -9,7 +9,8 @@
 * [CODESYS](https://us.store.codesys.com/)(profinet主站模拟)
   * CODESYS
   * CODESYS Gateway(网关设备)
-  * CODESYS Control Win SysTray(PLC设备)
+  * CODESYS Control Win SysTray(软PLC设备)
+* [Npcap](https://npcap.com/dist/npcap-1.80.exe)(该软件是运行CODESYS必须的,需要提前安装好!)
 * [PRONETA](https://support.industry.siemens.com/cs/attachments/67460624/proneta_3_8_0_0.zip)
 
 硬件环境
@@ -41,6 +42,10 @@
 * **Default root filesystem path for p-net**:p-net 文件系统配置,默认使用 ramfs ,默认分配 8K 内存空间;
 * **P-NET sample slave network ip config**:p-net 从站设备静态IP配置(**请关闭 RT_LWIP_DHCP 功能,使用静态IP**)
 
+下面我们还需要配置禁用dhcp功能并使用静态IP,进入 **→ RT-Thread Components → Network → LwIP: light weight TCP/stack**,选择禁用DHCP;
+
+![image-20241213150409268](figures/image-20241213150409268.png)
+
 完成上述配置后,将程序编译下载至开发板。
 
 ## 3.网络配置
@@ -88,7 +93,7 @@
 * CODESYS Gateway V3(右键 Start Gateway)
 * CODESYS Control Win V3 -x64 SysTray(右键 Start PLC)
 
-![image-20241108114211620](figures/image-20241108114211620.png)
+![image-20241213150426614](figures/image-20241213150426614.png)
 
 回到 CODESYS 主站软件,双击 Device(CODESYS Control Win V3 x64) -> 通信设置 -> 扫描网络
 
@@ -149,7 +154,7 @@
 ![image-20241111094138076](figures/image-20241111094138076.png)
 
 * PN_Controller 配置:双击左侧导航栏 PN_Controller(PN-Controller) -> 通用,并正确修改默认从站IP参数的区间,根据提示修改即可。
-* P-Net 从站网络配置:双击左侧导航栏 P-Net-multiple-module sample app -> 通用, 修改IP参数为开发板IP
+* P-Net 从站网络配置:双击左侧导航栏 P-Net-multiple-module sample app -> 通用, 修改IP参数为开发板IP
 
 ![image-20241111095351359](figures/image-20241111095351359.png)
 

二进制
docs/figures/image-20241213150409268.png


+ 0 - 0
docs/figures/image-20241108114211620.png → docs/figures/image-20241213150426614.png


+ 0 - 246
options.h.in

@@ -1,246 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef OPTIONS_H
-#define OPTIONS_H
-
-/**
- * # Profinet Stack Options
- *
- * The defines named `PNET_OPTION_*` may be used to extend or reduce
- * the functionality of the stack. Setting these values to 0 excludes
- * the specific function and may also reduce the memory usage of the
- * Profinet stack.
- *
- * Note that none of these options are currently supported (even if
- * enabled by setting the value to 1), except for parsing the RPC
- * Connect request message and generating the connect RPC Connect
- * response message.
- */
-
-#if !defined (PNET_OPTION_FAST_STARTUP)
-#cmakedefine01 PNET_OPTION_FAST_STARTUP
-#endif
-
-#if !defined (PNET_OPTION_PARAMETER_SERVER)
-#cmakedefine01 PNET_OPTION_PARAMETER_SERVER
-#endif
-
-#if !defined (PNET_OPTION_IR)
-#cmakedefine01 PNET_OPTION_IR
-#endif
-
-#if !defined (PNET_OPTION_SR)
-#cmakedefine01 PNET_OPTION_SR
-#endif
-
-#if !defined (PNET_OPTION_REDUNDANCY)
-#cmakedefine01 PNET_OPTION_REDUNDANCY
-#endif
-
-#if !defined (PNET_OPTION_AR_VENDOR_BLOCKS)
-#cmakedefine01 PNET_OPTION_AR_VENDOR_BLOCKS
-#endif
-
-#if !defined (PNET_OPTION_RS)
-#cmakedefine01 PNET_OPTION_RS
-#endif
-
-#if !defined (PNET_OPTION_MC_CR)
-#cmakedefine01 PNET_OPTION_MC_CR
-#endif
-
-#if !defined (PNET_OPTION_SRL)
-#cmakedefine01 PNET_OPTION_SRL
-#endif
-
-#if !defined (PNET_OPTION_SNMP)
-#cmakedefine01 PNET_OPTION_SNMP
-#endif
-
-/**
- * Disable use of atomic operations (stdatomic.h).
- * If the compiler supports it then set this define to 1.
- */
-/* TODO: compiler abstraction should be handled by cc.h */
-#if !defined (PNET_USE_ATOMICS)
-#cmakedefine01 PNET_USE_ATOMICS
-#endif
-
-/**
- * # Memory Usage
- *
- * Memory usage is controlled by the `PNET_MAX_*` defines. Define the
- * required number of supported items.
- *
- * These values directly affect the memory usage of the
- * implementation. Sometimes in complicated ways.
- *
- * Please note that some defines have minimum requirements.
- * Only a few of the defines are validated.
- */
-
-#if !defined (PNET_MAX_AR)
-/** Number of connections. Must be > 0. "Automated RT Tester" uses 2 */
-#define PNET_MAX_AR               @PNET_MAX_AR@
-#endif
-
-#if !defined (PNET_MAX_API)
-/** Number of Application Processes. Must be > 0. */
-#define PNET_MAX_API              @PNET_MAX_API@
-#endif
-
-#if !defined (PNET_MAX_CR)
-/** Per AR. 1 input and 1 output. */
-#define PNET_MAX_CR               @PNET_MAX_CR@
-#endif
-
-#if !defined (PNET_MAX_SLOTS)
-/** Per API. Should be > 1 to allow at least one I/O module. */
-#define PNET_MAX_SLOTS          @PNET_MAX_SLOTS@
-#endif
-
-#if !defined (PNET_MAX_SUBSLOTS)
-/** Per slot (3 needed for DAP). */
-#define PNET_MAX_SUBSLOTS       @PNET_MAX_SUBSLOTS@
-#endif
-
-#if !defined (PNET_MAX_DFP_IOCR)
-/** Allowed values are 0 (zero) or 2. */
-#define PNET_MAX_DFP_IOCR         @PNET_MAX_DFP_IOCR@
-#endif
-
-#if !defined (PNET_MAX_LOG_BOOK_ENTRIES)
-#define PNET_MAX_LOG_BOOK_ENTRIES @PNET_MAX_LOG_BOOK_ENTRIES@
-#endif
-
-#if !defined (PNET_MAX_ALARMS)
-/** Per AR and queue. One queue for hi and one for lo alarms. */
-#define PNET_MAX_ALARMS           @PNET_MAX_ALARMS@
-#endif
-
-#if !defined (PNET_MAX_ALARM_PAYLOAD_DATA_SIZE)
-/** Max size of alarm payload */
-#define PNET_MAX_ALARM_PAYLOAD_DATA_SIZE    @PNET_MAX_ALARM_PAYLOAD_DATA_SIZE@
-#endif
-
-#if !defined (PNET_MAX_DIAG_ITEMS)
-/** Total, per device. Max is 65534 items. */
-#define PNET_MAX_DIAG_ITEMS       @PNET_MAX_DIAG_ITEMS@
-#endif
-
-#if !defined (PNET_MAX_DIAG_MANUF_DATA_SIZE)
-/** Max size of manufacturer specific diagnosis data */
-#define PNET_MAX_DIAG_MANUF_DATA_SIZE    @PNET_MAX_DIAG_MANUF_DATA_SIZE@
-#endif
-
-#if PNET_OPTION_MC_CR
-
-#if !defined (PNET_MAX_MC_CR)
-/**< Per AR. */
-#define PNET_MAX_MC_CR            @PNET_MAX_MC_CR@
-#endif
-
-#endif  /* PNET_OPTION_MC_CR */
-
-#if PNET_OPTION_AR_VENDOR_BLOCKS
-
-#if !defined (PNET_MAX_AR_VENDOR_BLOCKS)
-/**< Must be > 0 */
-#define PNET_MAX_AR_VENDOR_BLOCKS @PNET_MAX_AR_VENDOR_BLOCKS@
-#endif
-
-#if !defined (PNET_MAX_AR_VENDOR_BLOCK_DATA_LENGTH)
-#define PNET_MAX_AR_VENDOR_BLOCK_DATA_LENGTH @PNET_MAX_AR_VENDOR_BLOCK_DATA_LENGTH@
-#endif
-
-#endif  /* PNET_OPTION_AR_VENDOR_BLOCKS */
-
-#if !defined (PNET_MAX_MAN_SPECIFIC_FAST_STARTUP_DATA_LENGTH)
-/** or 512 (bytes) */
-#define PNET_MAX_MAN_SPECIFIC_FAST_STARTUP_DATA_LENGTH @PNET_MAX_MAN_SPECIFIC_FAST_STARTUP_DATA_LENGTH@
-#endif
-
-#if !defined (PNET_MAX_SESSION_BUFFER_SIZE)
-/** Max fragmented RPC request/response length */
-#define PNET_MAX_SESSION_BUFFER_SIZE @PNET_MAX_SESSION_BUFFER_SIZE@
-#endif
-
-#if !defined (PNET_MAX_FILENAME_SIZE)
-/** Max filename size, including termination  */
-#define PNET_MAX_FILENAME_SIZE @PNET_MAX_FILENAME_SIZE@
-#endif
-
-#if !defined (PNET_MAX_PORT_DESCRIPTION_SIZE)
-/** Max port description size, including termination  */
-#define PNET_MAX_PORT_DESCRIPTION_SIZE @PNET_MAX_PORT_DESCRIPTION_SIZE@
-#endif
-
-
-/**
- * # Logging
- *
- * The following options controlling logging.
- */
-
-#ifndef LOG_LEVEL
-#define LOG_LEVEL               (LOG_LEVEL_@LOG_LEVEL@)
-#endif
-
-#ifndef PF_ETH_LOG
-#define PF_ETH_LOG              (LOG_STATE_@PF_ETH_LOG@)
-#endif
-
-#ifndef PF_LLDP_LOG
-#define PF_LLDP_LOG             (LOG_STATE_@PF_LLDP_LOG@)
-#endif
-
-#ifndef PF_SNMP_LOG
-#define PF_SNMP_LOG             (LOG_STATE_@PF_SNMP_LOG@)
-#endif
-
-#ifndef PF_CPM_LOG
-#define PF_CPM_LOG              (LOG_STATE_@PF_CPM_LOG@)
-#endif
-
-#ifndef PF_PPM_LOG
-#define PF_PPM_LOG              (LOG_STATE_@PF_PPM_LOG@)
-#endif
-
-#ifndef PF_DCP_LOG
-#define PF_DCP_LOG              (LOG_STATE_@PF_DCP_LOG@)
-#endif
-
-#ifndef PF_RPC_LOG
-#define PF_RPC_LOG              (LOG_STATE_@PF_RPC_LOG@)
-#endif
-
-#ifndef PF_ALARM_LOG
-#define PF_ALARM_LOG            (LOG_STATE_@PF_ALARM_LOG@)
-#endif
-
-#ifndef PF_AL_BUF_LOG
-#define PF_AL_BUF_LOG           (LOG_STATE_@PF_AL_BUF_LOG@)
-#endif
-
-#ifndef PF_PNAL_LOG
-#define PF_PNAL_LOG             (LOG_STATE_@PF_PNAL_LOG@)
-#endif
-
-#ifndef PNET_LOG
-#define PNET_LOG                (LOG_STATE_@PNET_LOG@)
-#endif
-
-#endif  /* OPTIONS_H */

+ 0 - 33
pnet_options.h.in

@@ -1,33 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef PNET_OPTIONS_H
-#define PNET_OPTIONS_H
-
-#if !defined (PNET_MAX_PHYSICAL_PORTS)
-/** Max number of physical ports */
-#define PNET_MAX_PHYSICAL_PORTS @PNET_MAX_PHYSICAL_PORTS@
-#endif
-
-#if !defined (PNET_MAX_DIRECTORYPATH_SIZE)
-/** Max directory path size, including termination */
-#define PNET_MAX_DIRECTORYPATH_SIZE @PNET_MAX_DIRECTORYPATH_SIZE@
-#endif
-
-#if !defined (PNET_OPTION_DRIVER_ENABLE)
-#cmakedefine01 PNET_OPTION_DRIVER_ENABLE
-#endif
-
-#endif  /* PNET_OPTIONS_H */

+ 0 - 41
pnet_version.h.in

@@ -1,41 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef PNET_VERSION_H
-#define PNET_VERSION_H
-
-#cmakedefine PNET_GIT_REVISION "@PNET_GIT_REVISION@"
-
-#if !defined(PNET_VERSION_BUILD) && defined(PNET_GIT_REVISION)
-#define PNET_VERSION_BUILD PNET_GIT_REVISION
-#endif
-
-/* clang-format-off */
-
-#define PNET_VERSION_MAJOR @PNET_VERSION_MAJOR@
-#define PNET_VERSION_MINOR @PNET_VERSION_MINOR@
-#define PNET_VERSION_PATCH @PNET_VERSION_PATCH@
-
-#if defined(PNET_VERSION_BUILD)
-#define PNET_VERSION \
-   "@PNET_VERSION_MAJOR@.@PNET_VERSION_MINOR@.@PNET_VERSION_PATCH@+" PNET_VERSION_BUILD
-#else
-#define PNET_VERSION \
-   "@PNET_VERSION_MAJOR@.@PNET_VERSION_MINOR@.@PNET_VERSION_PATCH@"
-#endif
-
-/* clang-format-on */
-
-#endif /* PNET_VERSION_H */

+ 0 - 21
samples/pn_dev/CMakeLists.txt

@@ -1,21 +0,0 @@
-#********************************************************************
-#        _       _         _
-#  _ __ | |_  _ | |  __ _ | |__   ___
-# | '__|| __|(_)| | / _` || '_ \ / __|
-# | |   | |_  _ | || (_| || |_) |\__ \
-# |_|    \__|(_)|_| \__,_||_.__/ |___/
-#
-# http://www.rt-labs.com
-# Copyright 2017 rt-labs AB, Sweden.
-# See LICENSE file in the project root for full license information.
-#*******************************************************************/
-
-target_include_directories(pn_dev
-  PRIVATE
-  ${PROFINET_SOURCE_DIR}/src
-  ${PROFINET_BINARY_DIR}/src
-  )
-
-target_link_libraries (pn_dev PUBLIC profinet)
-
-install (TARGETS pn_dev DESTINATION bin)

二进制
samples/pn_dev/GSDML-RT-LABS-STACK.bmp


+ 0 - 313
samples/pn_dev/GSDML-V2.4-RT-Labs-P-Net-Sample-App-20220324.xml

@@ -1,313 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.4.xsd">
-   <!-- ProfileHeader definition as defined in ISO 15745-1. Please do not change the content. -->
-   <ProfileHeader>
-      <ProfileIdentification>PROFINET Device Profile</ProfileIdentification>
-      <ProfileRevision>1.00</ProfileRevision>
-      <ProfileName>Device Profile for PROFINET Devices</ProfileName>
-      <ProfileSource>PROFIBUS Nutzerorganisation e. V. (PNO)</ProfileSource>
-      <ProfileClassID>Device</ProfileClassID>
-      <ISO15745Reference>
-         <ISO15745Part>4</ISO15745Part>
-         <ISO15745Edition>1</ISO15745Edition>
-         <ProfileTechnology>GSDML</ProfileTechnology>
-      </ISO15745Reference>
-   </ProfileHeader>
-   <ProfileBody>
-      <DeviceIdentity VendorID="0x0493" DeviceID="0x0002">
-         <InfoText TextId="IDT_INFO_Device"/>
-         <VendorName Value="RT-Labs"/>
-      </DeviceIdentity>
-      <DeviceFunction>
-         <Family MainFamily="I/O" ProductFamily="P-Net Samples"/>
-      </DeviceFunction>
-      <ApplicationProcess>
-         <DeviceAccessPointList>
-            <DeviceAccessPointItem ID="IDD_1" PNIO_Version="V2.4" PhysicalSlots="0..4" ModuleIdentNumber="0x00000001" MinDeviceInterval="32" DNS_CompatibleName="rt-labs-dev" FixedInSlots="0" ObjectUUID_LocalIndex="1" DeviceAccessSupported="false" MultipleWriteSupported="true" CheckDeviceID_Allowed="true" NameOfStationNotTransferable="false" LLDP_NoD_Supported="true" ResetToFactoryModes="1..2">
-            <!--
-Replace the tag above with the one below to support shared device.
--->
-            <!--
-            <DeviceAccessPointItem ID="IDD_1" PNIO_Version="V2.4" PhysicalSlots="0..4" ModuleIdentNumber="0x00000001" MinDeviceInterval="32" DNS_CompatibleName="rt-labs-dev" FixedInSlots="0" ObjectUUID_LocalIndex="1" DeviceAccessSupported="false" MultipleWriteSupported="true" SharedDeviceSupported="true" CheckDeviceID_Allowed="true" NameOfStationNotTransferable="false" LLDP_NoD_Supported="true" ResetToFactoryModes="1..2">
--->
-               <ModuleInfo>
-                  <Name TextId="IDT_MODULE_NAME_DAP1"/>
-                  <InfoText TextId="IDT_INFO_DAP1"/>
-                  <VendorName Value="RT-Labs"/>
-                  <OrderNumber Value="12345 Abcdefghijk"/>
-                  <HardwareRelease Value="A1.0"/>
-                  <SoftwareRelease Value="V0.1.0"/>
-               </ModuleInfo>
-               <CertificationInfo ConformanceClass="B" ApplicationClass="" NetloadClass="I"/>
-               <IOConfigData MaxInputLength="244" MaxOutputLength="244"/>
-               <UseableModules>
-                  <ModuleItemRef ModuleItemTarget="IDM_30" AllowedInSlots="1..4"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_31" AllowedInSlots="1..4"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_32" AllowedInSlots="1..4"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_40" AllowedInSlots="1..4"/>
-               </UseableModules>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDS_1" SubmoduleIdentNumber="0x00000001" Writeable_IM_Records="1 2 3" MayIssueProcessAlarm="false">
-                     <IOData/>
-                     <ModuleInfo>
-                        <Name TextId="IDT_MODULE_NAME_DAP1"/>
-                        <InfoText TextId="IDT_INFO_DAP1"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-               <SystemDefinedSubmoduleList>
-                  <InterfaceSubmoduleItem ID="IDS_I" SubmoduleIdentNumber="0x00008000" SubslotNumber="32768" TextId="IDT_NAME_IS" SupportedRT_Classes="RT_CLASS_1" SupportedProtocols="SNMP;LLDP" NetworkComponentDiagnosisSupported="false" PTP_BoundarySupported="true" DCP_BoundarySupported="true">
-                     <!--
-If shared device is supported, add a "NumberOfAR" attribute to the following ApplicationRelations element.
-The number should match the p-net configuration variable PNET_MAX_AR.
-Example, for PNET_MAX_AR = 3:
-                     <ApplicationRelations StartupMode="Advanced" NumberOfAR="3">
--->
-                     <ApplicationRelations StartupMode="Advanced">
-                        <TimingProperties SendClock="32" ReductionRatio="1 2 4 8 16 32 64 128 256 512"/>
-                     </ApplicationRelations>
-                  </InterfaceSubmoduleItem>
-                  <PortSubmoduleItem ID="IDS_P1" SubmoduleIdentNumber="0x00008001" SubslotNumber="32769" TextId="IDT_NAME_PS1" MaxPortRxDelay="350" MaxPortTxDelay="160">
-                     <MAUTypeList>
-                        <!--
-MAUTypeItems shall match the actual network interfaces of the device.
-Current list works for Raspberry Pi, Linksys usb/ethernet dongle and xmc sample targets
--->
-                        <MAUTypeItem Value="30"/>
-                        <MAUTypeItem Value="16"/>
-                        <MAUTypeItem Value="5"/>
-                     </MAUTypeList>
-                  </PortSubmoduleItem>
-                  <!--
-Enable to support additional port. (PNET_MAX_PHYSICAL_PORTS == 2)
-Add additional PortSubmoduleItems to support additional ports
--->
-                  <!--
-                  <PortSubmoduleItem ID="IDS_P2" SubmoduleIdentNumber="0x00008002" SubslotNumber="32770" TextId="IDT_NAME_PS2" MaxPortRxDelay="350" MaxPortTxDelay="160">
-                     <MAUTypeList>
-                        <MAUTypeItem Value="30"/>
-                        <MAUTypeItem Value="16"/>
-                        <MAUTypeItem Value="5"/>
-                     </MAUTypeList>
-                  </PortSubmoduleItem>
--->
-               </SystemDefinedSubmoduleList>
-               <Graphics>
-                  <GraphicItemRef Type="DeviceSymbol" GraphicItemTarget="RT-LabsStackImage"/>
-               </Graphics>
-            </DeviceAccessPointItem>
-         </DeviceAccessPointList>
-         <ModuleList>
-            <ModuleItem ID="IDM_30" ModuleIdentNumber="0x00000030">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_I8"/>
-                  <InfoText TextId="TOK_InfoText_Module_I8"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_130" SubmoduleIdentNumber="0x0130" MayIssueProcessAlarm="true">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Unsigned8" TextId="TOK_Input_DataItem_8" UseAsBits="true">
-                              <BitDataItem BitOffset="0" TextId="TOK_Input_DataItem_Bit0"/>
-                              <BitDataItem BitOffset="1" TextId="TOK_Input_DataItem_Bit1"/>
-                              <BitDataItem BitOffset="2" TextId="TOK_Input_DataItem_Bit2"/>
-                              <BitDataItem BitOffset="3" TextId="TOK_Input_DataItem_Bit3"/>
-                              <BitDataItem BitOffset="4" TextId="TOK_Input_DataItem_Bit4"/>
-                              <BitDataItem BitOffset="5" TextId="TOK_Input_DataItem_Bit5"/>
-                              <BitDataItem BitOffset="6" TextId="TOK_Input_DataItem_Bit6"/>
-                              <BitDataItem BitOffset="7" TextId="TOK_Input_DataItem_Bit7"/>
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_I8"/>
-                        <InfoText TextId="TOK_InfoText_Module_I8"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_31" ModuleIdentNumber="0x00000031">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_O8"/>
-                  <InfoText TextId="TOK_InfoText_Module_O8"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_131" SubmoduleIdentNumber="0x0131" MayIssueProcessAlarm="true">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned8" TextId="TOK_Output_DataItem_8" UseAsBits="true">
-                              <BitDataItem BitOffset="0" TextId="TOK_Output_DataItem_Bit0"/>
-                              <BitDataItem BitOffset="1" TextId="TOK_Output_DataItem_Bit1"/>
-                              <BitDataItem BitOffset="2" TextId="TOK_Output_DataItem_Bit2"/>
-                              <BitDataItem BitOffset="3" TextId="TOK_Output_DataItem_Bit3"/>
-                              <BitDataItem BitOffset="4" TextId="TOK_Output_DataItem_Bit4"/>
-                              <BitDataItem BitOffset="5" TextId="TOK_Output_DataItem_Bit5"/>
-                              <BitDataItem BitOffset="6" TextId="TOK_Output_DataItem_Bit6"/>
-                              <BitDataItem BitOffset="7" TextId="TOK_Output_DataItem_Bit7"/>
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_O8"/>
-                        <InfoText TextId="TOK_InfoText_Module_O8"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_32" ModuleIdentNumber="0x00000032">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_I8O8"/>
-                  <InfoText TextId="TOK_InfoText_Module_I8O8"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_132" SubmoduleIdentNumber="0x0132" MayIssueProcessAlarm="true">
-                     <IOData>
-                        <Input>
-                           <DataItem DataType="Unsigned8" UseAsBits="true" TextId="TOK_Input_DataItem_8">
-                              <BitDataItem BitOffset="0" TextId="TOK_Input_DataItem_Bit0"/>
-                              <BitDataItem BitOffset="1" TextId="TOK_Input_DataItem_Bit1"/>
-                              <BitDataItem BitOffset="2" TextId="TOK_Input_DataItem_Bit2"/>
-                              <BitDataItem BitOffset="3" TextId="TOK_Input_DataItem_Bit3"/>
-                              <BitDataItem BitOffset="4" TextId="TOK_Input_DataItem_Bit4"/>
-                              <BitDataItem BitOffset="5" TextId="TOK_Input_DataItem_Bit5"/>
-                              <BitDataItem BitOffset="6" TextId="TOK_Input_DataItem_Bit6"/>
-                              <BitDataItem BitOffset="7" TextId="TOK_Input_DataItem_Bit7"/>
-                           </DataItem>
-                        </Input>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned8" TextId="TOK_Output_DataItem_8" UseAsBits="true">
-                              <BitDataItem BitOffset="0" TextId="TOK_Output_DataItem_Bit0"/>
-                              <BitDataItem BitOffset="1" TextId="TOK_Output_DataItem_Bit1"/>
-                              <BitDataItem BitOffset="2" TextId="TOK_Output_DataItem_Bit2"/>
-                              <BitDataItem BitOffset="3" TextId="TOK_Output_DataItem_Bit3"/>
-                              <BitDataItem BitOffset="4" TextId="TOK_Output_DataItem_Bit4"/>
-                              <BitDataItem BitOffset="5" TextId="TOK_Output_DataItem_Bit5"/>
-                              <BitDataItem BitOffset="6" TextId="TOK_Output_DataItem_Bit6"/>
-                              <BitDataItem BitOffset="7" TextId="TOK_Output_DataItem_Bit7"/>
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <RecordDataList>
-                        <ParameterRecordDataItem Index="123" Length="4">
-                           <Name TextId="TOK_sample_parameter_1"/>
-                           <Ref DataType="Unsigned32" ByteOffset="0" DefaultValue="1" AllowedValues="0..99" Changeable="true" Visible="true" TextId="TOK_Demo_1"/>
-                        </ParameterRecordDataItem>
-                        <ParameterRecordDataItem Index="124" Length="4">
-                           <Name TextId="TOK_sample_parameter_2"/>
-                           <Ref DataType="Unsigned32" ByteOffset="0" DefaultValue="2" AllowedValues="0..999" Changeable="true" Visible="true" TextId="TOK_Demo_2"/>
-                        </ParameterRecordDataItem>
-                     </RecordDataList>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_I8O8"/>
-                        <InfoText TextId="TOK_InfoText_Module_I8O8"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_40" ModuleIdentNumber="0x00000040">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_Echo"/>
-                  <InfoText TextId="TOK_InfoText_Module_Echo"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_140" SubmoduleIdentNumber="0x0140" MayIssueProcessAlarm="true">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Float32" TextId="TOK_Input_DataItem_Echo_Float32"/>
-                           <DataItem DataType="Unsigned32" TextId="TOK_Input_DataItem_Echo_Unsigned32"/>
-                        </Input>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Float32" TextId="TOK_Output_DataItem_Echo_Float32"/>
-                           <DataItem DataType="Unsigned32" TextId="TOK_Output_DataItem_Echo_Unsigned32"/>
-                        </Output>
-                     </IOData>
-                     <RecordDataList>
-                        <ParameterRecordDataItem Index="125" Length="4">
-                           <Name TextId="TOK_sample_parameter_Echo"/>
-                           <Ref DataType="Unsigned32" ByteOffset="0" DefaultValue="2" AllowedValues="1..4" Changeable="true" Visible="true" TextId="TOK_Echo_Gain"/>
-                        </ParameterRecordDataItem>
-                     </RecordDataList>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_Echo"/>
-                        <InfoText TextId="TOK_InfoText_Module_Echo"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-         </ModuleList>
-         <LogBookEntryList>
-            <LogBookEntryItem Status="2130510">
-               <!--Custom log book entry for sample application-->
-               <!--Error code 0x20  Error decode 0x82  Error code 1 0x4E-->
-               <ErrorCode2Value>
-                  <Name TextId="IDT_CUSTOM_LOGBOOK_1"/>
-               </ErrorCode2Value>
-            </LogBookEntryItem>
-         </LogBookEntryList>
-         <GraphicsList>
-            <GraphicItem ID="RT-LabsStackImage" GraphicFile="GSDML-RT-LABS-STACK"/>
-         </GraphicsList>
-         <ExternalTextList>
-            <PrimaryLanguage>
-               <Text TextId="IDT_INFO_Device" Value="https://github.com/rtlabs-com/p-net"/>
-               <Text TextId="IDT_MODULE_NAME_DAP1" Value="P-Net multi-module sample app"/>
-               <Text TextId="IDT_INFO_DAP1" Value="Profinet device sample app https://github.com/rtlabs-com/p-net"/>
-               <Text TextId="IDT_CUSTOM_DIAG_1" Value="Custom diagnosis in USI format"/>
-               <Text TextId="IDT_CUSTOM_DIAG_1_VALUE" Value="Custom diagnosis value"/>
-               <Text TextId="IDT_CUSTOM_LOGBOOK_1" Value="Custom Logbook entry"/>
-               <Text TextId="IDT_NAME_IS" Value="X1"/>
-               <Text TextId="IDT_NAME_PS1" Value="X1 P1"/>
-               <Text TextId="IDT_NAME_PS2" Value="X1 P2"/>
-               <!--module name-->
-               <Text TextId="TOK_Name_Module_I8" Value="DI 8xLogicLevel"/>
-               <Text TextId="TOK_Name_Module_O8" Value="DO 8xLogicLevel"/>
-               <Text TextId="TOK_Name_Module_I8O8" Value="DIO 8xLogicLevel"/>
-               <Text TextId="TOK_Name_Module_Echo" Value="Echo Module"/>
-               <!--module info -->
-               <Text TextId="TOK_InfoText_Module_I8" Value="Digital In 8xLogicLevel"/>
-               <Text TextId="TOK_InfoText_Module_O8" Value="Digital Out 8xLogicLevel"/>
-               <Text TextId="TOK_InfoText_Module_I8O8" Value="Digital In+Out 8xLogicLevel"/>
-               <Text TextId="TOK_InfoText_Module_Echo" Value="Echo with adjustable gain"/>
-               <!--dataitem name-->
-               <Text TextId="TOK_Input_DataItem_8" Value="Input 8 bits"/>
-               <Text TextId="TOK_Output_DataItem_8" Value="Output 8 bits"/>
-               <Text TextId="TOK_Input_DataItem_Bit0" Value="Input Bit 0"/>
-               <Text TextId="TOK_Input_DataItem_Bit1" Value="Input Bit 1"/>
-               <Text TextId="TOK_Input_DataItem_Bit2" Value="Input Bit 2"/>
-               <Text TextId="TOK_Input_DataItem_Bit3" Value="Input Bit 3"/>
-               <Text TextId="TOK_Input_DataItem_Bit4" Value="Input Bit 4"/>
-               <Text TextId="TOK_Input_DataItem_Bit5" Value="Input Bit 5"/>
-               <Text TextId="TOK_Input_DataItem_Bit6" Value="Input Bit 6"/>
-               <Text TextId="TOK_Input_DataItem_Bit7" Value="Input Bit 7"/>
-               <Text TextId="TOK_Output_DataItem_Bit0" Value="Output Bit 0"/>
-               <Text TextId="TOK_Output_DataItem_Bit1" Value="Output Bit 1"/>
-               <Text TextId="TOK_Output_DataItem_Bit2" Value="Output Bit 2"/>
-               <Text TextId="TOK_Output_DataItem_Bit3" Value="Output Bit 3"/>
-               <Text TextId="TOK_Output_DataItem_Bit4" Value="Output Bit 4"/>
-               <Text TextId="TOK_Output_DataItem_Bit5" Value="Output Bit 5"/>
-               <Text TextId="TOK_Output_DataItem_Bit6" Value="Output Bit 6"/>
-               <Text TextId="TOK_Output_DataItem_Bit7" Value="Output Bit 7"/>
-               <Text TextId="TOK_Input_DataItem_Echo_Float32" Value="Input float to controller (output from controller multiplied by gain)"/>
-               <Text TextId="TOK_Input_DataItem_Echo_Unsigned32" Value="Input int to controller (output from controller multiplied by gain)"/>
-               <Text TextId="TOK_Output_DataItem_Echo_Float32" Value="Output float from controller"/>
-               <Text TextId="TOK_Output_DataItem_Echo_Unsigned32" Value="Output int from controller"/>
-               <!--ParameterRecordDataItem name-->
-               <Text TextId="TOK_sample_parameter_1" Value="Parameter 1"/>
-               <Text TextId="TOK_sample_parameter_2" Value="Parameter 2"/>
-               <Text TextId="TOK_sample_parameter_Echo" Value="Gain for echo module"/>
-               <Text TextId="TOK_Demo_1" Value="Demo 1"/>
-               <Text TextId="TOK_Demo_2" Value="Demo 2"/>
-               <Text TextId="TOK_Echo_Gain" Value="Gain"/>
-            </PrimaryLanguage>
-         </ExternalTextList>
-      </ApplicationProcess>
-   </ProfileBody>
-</ISO15745Profile>

+ 0 - 315
samples/pn_dev/app_data.c

@@ -1,315 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "app_data.h"
-#include "app_utils.h"
-#include "app_gsdml.h"
-#include "app_log.h"
-#include "sampleapp_common.h"
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define APP_DATA_DEFAULT_OUTPUT_DATA 0
-
-/* Parameter data for digital submodules
- * The stored value is shared between all digital submodules in this example.
- *
- * Todo: Data is always in pnio data format. Add conversion to uint32_t.
- */
-static uint32_t app_param_1 = 0; /* Network endianness */
-static uint32_t app_param_2 = 0; /* Network endianness */
-
-/* Parameter data for echo submodules
- * The stored value is shared between all echo submodules in this example.
- *
- * Todo: Data is always in pnio data format. Add conversion to uint32_t.
- */
-static uint32_t app_param_echo_gain = 1; /* Network endianness */
-
-/* Digital submodule process data
- * The stored value is shared between all digital submodules in this example. */
-static uint8_t inputdata[APP_GSDML_INPUT_DATA_DIGITAL_SIZE] = {0};
-static uint8_t outputdata[APP_GSDML_OUTPUT_DATA_DIGITAL_SIZE] = {0};
-static uint8_t counter = 0;
-
-/* Network endianness */
-static uint8_t echo_inputdata[APP_GSDML_INPUT_DATA_ECHO_SIZE] = {0};
-static uint8_t echo_outputdata[APP_GSDML_OUTPUT_DATA_ECHO_SIZE] = {0};
-
-CC_PACKED_BEGIN
-typedef struct CC_PACKED app_echo_data
-{
-   /* Network endianness.
-      Used as a float, but we model it as a 4-byte integer to easily
-      do endianness conversion */
-   uint32_t echo_float_bytes;
-
-   /* Network endianness */
-   uint32_t echo_int;
-} app_echo_data_t;
-CC_PACKED_END
-CC_STATIC_ASSERT (sizeof (app_echo_data_t) == APP_GSDML_INPUT_DATA_ECHO_SIZE);
-CC_STATIC_ASSERT (sizeof (app_echo_data_t) == APP_GSDML_OUTPUT_DATA_ECHO_SIZE);
-
-/**
- * Set LED state.
- *
- * Compares new state with previous state, to minimize system calls.
- *
- * Uses the hardware specific app_set_led() function.
- *
- * @param led_state        In:    New LED state
- */
-static void app_handle_data_led_state (bool led_state)
-{
-   static bool previous_led_state = false;
-
-   if (led_state != previous_led_state)
-   {
-      app_set_led (APP_DATA_LED_ID, led_state);
-   }
-   previous_led_state = led_state;
-}
-
-uint8_t * app_data_get_input_data (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   bool button_pressed,
-   uint16_t * size,
-   uint8_t * iops)
-{
-   float inputfloat;
-   float outputfloat;
-   uint32_t hostorder_inputfloat_bytes;
-   uint32_t hostorder_outputfloat_bytes;
-   app_echo_data_t * p_echo_inputdata = (app_echo_data_t *)&echo_inputdata;
-   app_echo_data_t * p_echo_outputdata = (app_echo_data_t *)&echo_outputdata;
-
-   if (size == NULL || iops == NULL)
-   {
-      return NULL;
-   }
-
-   if (
-      submodule_id == APP_GSDML_SUBMOD_ID_DIGITAL_IN ||
-      submodule_id == APP_GSDML_SUBMOD_ID_DIGITAL_IN_OUT)
-   {
-      /* Prepare digital input data
-       * Lowest 7 bits: Counter    Most significant bit: Button
-       */
-      inputdata[0] = counter++;
-      if (button_pressed)
-      {
-         inputdata[0] |= 0x80;
-      }
-      else
-      {
-         inputdata[0] &= 0x7F;
-      }
-
-      *size = APP_GSDML_INPUT_DATA_DIGITAL_SIZE;
-      *iops = PNET_IOXS_GOOD;
-      return inputdata;
-   }
-
-   if (submodule_id == APP_GSDML_SUBMOD_ID_ECHO)
-   {
-      /* Calculate echodata input (to the PLC)
-       * by multiplying the output (from the PLC) with a gain factor
-       */
-
-      /* Integer */
-      p_echo_inputdata->echo_int = CC_TO_BE32 (
-         CC_FROM_BE32 (p_echo_outputdata->echo_int) *
-         CC_FROM_BE32 (app_param_echo_gain));
-
-      /* Float */
-      /* Use memcopy to avoid strict-aliasing rule warnings */
-      hostorder_outputfloat_bytes =
-         CC_FROM_BE32 (p_echo_outputdata->echo_float_bytes);
-      memcpy (&outputfloat, &hostorder_outputfloat_bytes, sizeof (outputfloat));
-      inputfloat = outputfloat * CC_FROM_BE32 (app_param_echo_gain);
-      memcpy (&hostorder_inputfloat_bytes, &inputfloat, sizeof (outputfloat));
-      p_echo_inputdata->echo_float_bytes =
-         CC_TO_BE32 (hostorder_inputfloat_bytes);
-
-      *size = APP_GSDML_INPUT_DATA_ECHO_SIZE;
-      *iops = PNET_IOXS_GOOD;
-      return echo_inputdata;
-   }
-
-   /* Automated RT Tester scenario 2 - unsupported (sub)module */
-   return NULL;
-}
-
-int app_data_set_output_data (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   uint8_t * data,
-   uint16_t size)
-{
-   bool led_state;
-
-   if (data == NULL)
-   {
-      return -1;
-   }
-
-   if (
-      submodule_id == APP_GSDML_SUBMOD_ID_DIGITAL_OUT ||
-      submodule_id == APP_GSDML_SUBMOD_ID_DIGITAL_IN_OUT)
-   {
-      if (size == APP_GSDML_OUTPUT_DATA_DIGITAL_SIZE)
-      {
-         memcpy (outputdata, data, size);
-
-         /* Most significant bit: LED */
-         led_state = (outputdata[0] & 0x80) > 0;
-         app_handle_data_led_state (led_state);
-
-         return 0;
-      }
-   }
-   else if (submodule_id == APP_GSDML_SUBMOD_ID_ECHO)
-   {
-      if (size == APP_GSDML_OUTPUT_DATA_ECHO_SIZE)
-      {
-         memcpy (echo_outputdata, data, size);
-
-         return 0;
-      }
-   }
-
-   return -1;
-}
-
-int app_data_set_default_outputs (void)
-{
-   outputdata[0] = APP_DATA_DEFAULT_OUTPUT_DATA;
-   app_handle_data_led_state (false);
-   return 0;
-}
-
-int app_data_write_parameter (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   uint32_t index,
-   const uint8_t * data,
-   uint16_t length)
-{
-   const app_gsdml_param_t * par_cfg;
-
-   par_cfg = app_gsdml_get_parameter_cfg (submodule_id, index);
-   if (par_cfg == NULL)
-   {
-      APP_LOG_WARNING (
-         "PLC write request unsupported submodule/parameter. "
-         "Submodule id: %u Index: %u\n",
-         (unsigned)submodule_id,
-         (unsigned)index);
-      return -1;
-   }
-
-   if (length != par_cfg->length)
-   {
-      APP_LOG_WARNING (
-         "PLC write request unsupported length. "
-         "Index: %u Length: %u Expected length: %u\n",
-         (unsigned)index,
-         (unsigned)length,
-         par_cfg->length);
-      return -1;
-   }
-
-   if (index == APP_GSDML_PARAMETER_1_IDX)
-   {
-      memcpy (&app_param_1, data, length);
-   }
-   else if (index == APP_GSDML_PARAMETER_2_IDX)
-   {
-      memcpy (&app_param_2, data, length);
-   }
-   else if (index == APP_GSDML_PARAMETER_ECHO_IDX)
-   {
-      memcpy (&app_param_echo_gain, data, length);
-   }
-
-   APP_LOG_DEBUG ("  Writing parameter \"%s\"\n", par_cfg->name);
-   app_log_print_bytes (APP_LOG_LEVEL_DEBUG, data, length);
-
-   return 0;
-}
-
-int app_data_read_parameter (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   uint32_t index,
-   uint8_t ** data,
-   uint16_t * length)
-{
-   const app_gsdml_param_t * par_cfg;
-
-   par_cfg = app_gsdml_get_parameter_cfg (submodule_id, index);
-   if (par_cfg == NULL)
-   {
-      APP_LOG_WARNING (
-         "PLC read request unsupported submodule/parameter. "
-         "Submodule id: %u Index: %u\n",
-         (unsigned)submodule_id,
-         (unsigned)index);
-      return -1;
-   }
-
-   if (*length < par_cfg->length)
-   {
-      APP_LOG_WARNING (
-         "PLC read request unsupported length. "
-         "Index: %u Max length: %u Data length for our parameter: %u\n",
-         (unsigned)index,
-         (unsigned)*length,
-         par_cfg->length);
-      return -1;
-   }
-
-   APP_LOG_DEBUG ("  Reading \"%s\"\n", par_cfg->name);
-   if (index == APP_GSDML_PARAMETER_1_IDX)
-   {
-      *data = (uint8_t *)&app_param_1;
-      *length = sizeof (app_param_1);
-   }
-   else if (index == APP_GSDML_PARAMETER_2_IDX)
-   {
-      *data = (uint8_t *)&app_param_2;
-      *length = sizeof (app_param_2);
-   }
-   else if (index == APP_GSDML_PARAMETER_ECHO_IDX)
-   {
-      *data = (uint8_t *)&app_param_echo_gain;
-      *length = sizeof (app_param_echo_gain);
-   }
-
-   app_log_print_bytes (APP_LOG_LEVEL_DEBUG, *data, *length);
-
-   return 0;
-}

+ 0 - 140
samples/pn_dev/app_data.h

@@ -1,140 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_DATA_H
-#define APP_DATA_H
-
-/**
- * @file
- * @brief Sample application data interface
- *
- * Functions for:
- * - Getting input data (Button 1 and counter value)
- * - Setting output data (LED 1)
- * - Setting default output state. This should be
- *   part of all device implementations for setting
- *   defined state when device is not connected to PLC
- * - Reading and writing parameters
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <stdbool.h>
-
-/**
- * Get application specific PNIO input data (for sending to PLC)
- *
- * The main sample application keeps track
- * of button so it is a parameter to this function.
- *
- * This function is not called for the DAP submodules (slot_nbr==0).
- *
- * @param slot_nbr      In:  Slot number
- * @param subslot_nbr   In:  Subslot number
- * @param submodule_id  In:  Submodule id
- * @param button_state  In:  State of button 1
- * @param size          Out: Size of pnio data.
- *                           Not modified on error.
- * @param iops          Out: Provider status. If for example
- *                           a sensor is failing or a short
- *                           circuit is detected on digital
- *                           input this shall be set to BAD.
- *                           Not modified on error.
- * @return Reference to PNIO data, NULL on error
- */
-uint8_t * app_data_get_input_data (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   bool button_state,
-   uint16_t * size,
-   uint8_t * iops);
-
-/**
- * Set application specific PNIO output data (received from PLC)
- *
- * This function is not called for the DAP submodules (slot_nbr==0).
- *
- * @param slot_nbr      In:  Slot number
- * @param subslot_nbr   In:  Subslot number
- * @param submodule_id  In:  Submodule id
- * @param data          In:  Reference to output data
- * @param size          In:  Length of output data
- * @return 0 on success, -1 on error
- */
-int app_data_set_output_data (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   uint8_t * data,
-   uint16_t size);
-
-/**
- * Set default outputs for all subslots.
- *
- * For the sample application this means that
- * LED 1 is turned off.
- *
- * @return 0 on success, -1 on error
- */
-int app_data_set_default_outputs (void);
-
-/**
- * Write parameter index for a subslot
- *
- * @param slot_nbr      In:  Slot number
- * @param subslot_nbr   In:  Subslot number
- * @param submodule_id  In:  Submodule id
- * @param index         In:  Parameter index
- * @param data          In:  New parameter value
- * @param write_length  In:  Length of parameter data
- * @return 0 on success, -1 on error
- */
-int app_data_write_parameter (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   uint32_t index,
-   const uint8_t * data,
-   uint16_t write_length);
-
-/**
- * Read parameter index from a subslot
- *
- * @param slot_nbr      In:    Slot number
- * @param subslot_nbr   In:    Subslot number
- * @param submodule_id  In:    Submodule id
- * @param index         In:    Parameter index
- * @param data          In:    Reference to parameter data
- * @param length        InOut: The maximum (in) and actual (out) length in
- *                             bytes of the data.
- * @return 0 on success, -1 on error
- */
-int app_data_read_parameter (
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   uint32_t index,
-   uint8_t ** data,
-   uint16_t * length);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_DATA_H */

+ 0 - 260
samples/pn_dev/app_gsdml.c

@@ -1,260 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "sampleapp_common.h"
-#include "app_utils.h"
-#include "app_gsdml.h"
-#include "app_log.h"
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/******************* Supported modules ***************************/
-
-static const app_gsdml_module_t dap_1 = {
-   .id = PNET_MOD_DAP_IDENT,
-   .name = "DAP 1",
-   .submodules = {
-      PNET_SUBMOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_2_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_3_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_4_IDENT,
-      0}};
-
-static const app_gsdml_module_t module_digital_in = {
-   .id = APP_GSDML_MOD_ID_8_0_DIGITAL_IN,
-   .name = "DI 8xLogicLevel",
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN, 0},
-};
-
-static const app_gsdml_module_t module_digital_out = {
-   .id = APP_GSDML_MOD_ID_0_8_DIGITAL_OUT,
-   .name = "DO 8xLogicLevel",
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT, 0}};
-
-static const app_gsdml_module_t module_digital_in_out = {
-   .id = APP_GSDML_MOD_ID_8_8_DIGITAL_IN_OUT,
-   .name = "DIO 8xLogicLevel",
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_OUT, 0}};
-
-static const app_gsdml_module_t module_echo = {
-   .id = APP_GSDML_MOD_ID_ECHO,
-   .name = "Echo module",
-   .submodules = {APP_GSDML_SUBMOD_ID_ECHO, 0}};
-
-/******************* Supported submodules ************************/
-
-static const app_gsdml_submodule_t dap_indentity_1 = {
-   .name = "DAP Identity 1",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_interface_1 = {
-   .name = "DAP Interface 1",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_1 = {
-   .name = "DAP Port 1",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_2 = {
-   .name = "DAP Port 2",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_2_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_3 = {
-   .name = "DAP Port 3",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_3_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_4 = {
-   .name = "DAP Port 4",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_4_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submod_digital_in = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN,
-   .name = "Digital Input",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = APP_GSDML_INPUT_DATA_DIGITAL_SIZE,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submod_digital_out = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT,
-   .name = "Digital Output",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_OUTPUT_DATA_DIGITAL_SIZE,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submod_digital_inout = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_OUT,
-   .name = "Digital Input/Output",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_IO,
-   .insize = APP_GSDML_INPUT_DATA_DIGITAL_SIZE,
-   .outsize = APP_GSDML_OUTPUT_DATA_DIGITAL_SIZE,
-   .parameters = {APP_GSDML_PARAMETER_1_IDX, APP_GSDML_PARAMETER_2_IDX, 0}};
-
-static const app_gsdml_submodule_t submod_echo = {
-   .id = APP_GSDML_SUBMOD_ID_ECHO,
-   .name = "Echo submodule",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_IO,
-   .insize = APP_GSDML_INPUT_DATA_ECHO_SIZE,
-   .outsize = APP_GSDML_OUTPUT_DATA_ECHO_SIZE,
-   .parameters = {APP_GSDML_PARAMETER_ECHO_IDX, 0}};
-
-/** List of supported modules */
-static const app_gsdml_module_t * app_gsdml_modules[] = {
-   &dap_1,
-   &module_digital_in,
-   &module_digital_out,
-   &module_digital_in_out,
-   &module_echo};
-
-/** List of supported submodules */
-static const app_gsdml_submodule_t * app_gsdml_submodules[] = {
-   &dap_indentity_1,
-   &dap_interface_1,
-   &dap_port_1,
-   &dap_port_2,
-   &dap_port_3,
-   &dap_port_4,
-
-   &submod_digital_in,
-   &submod_digital_out,
-   &submod_digital_inout,
-
-   &submod_echo,
-};
-
-/* List of supported parameters.
- * Note that parameters are submodule attributes.
- * This list contain all parameters while each
- * submodule list its supported parameters using
- * their indexes.
- */
-static app_gsdml_param_t app_gsdml_parameters[] = {
-   {
-      .index = APP_GSDML_PARAMETER_1_IDX,
-      .name = "Demo 1",
-      .length = APP_GSDML_PARAMETER_LENGTH,
-   },
-   {
-      .index = APP_GSDML_PARAMETER_2_IDX,
-      .name = "Demo 2",
-      .length = APP_GSDML_PARAMETER_LENGTH,
-   },
-   {
-      .index = APP_GSDML_PARAMETER_ECHO_IDX,
-      .name = "Echo gain setting",
-      .length = APP_GSDML_PARAMETER_LENGTH,
-   }};
-
-const app_gsdml_module_t * app_gsdml_get_module_cfg (uint32_t id)
-{
-   uint32_t i;
-   for (i = 0; i < NELEMENTS (app_gsdml_modules); i++)
-   {
-      if (app_gsdml_modules[i]->id == id)
-      {
-         return app_gsdml_modules[i];
-      }
-   }
-   return NULL;
-}
-
-const app_gsdml_submodule_t * app_gsdml_get_submodule_cfg (uint32_t id)
-{
-   uint32_t i;
-   for (i = 0; i < NELEMENTS (app_gsdml_submodules); i++)
-   {
-      if (app_gsdml_submodules[i]->id == id)
-      {
-         return app_gsdml_submodules[i];
-      }
-   }
-   return NULL;
-}
-
-const app_gsdml_param_t * app_gsdml_get_parameter_cfg (
-   uint32_t submodule_id,
-   uint32_t index)
-{
-   uint16_t i;
-   uint16_t j;
-
-   const app_gsdml_submodule_t * submodule_cfg =
-      app_gsdml_get_submodule_cfg (submodule_id);
-
-   if (submodule_cfg == NULL)
-   {
-      /* Unsupported submodule id */
-      return NULL;
-   }
-
-   /* Search for parameter index in submodule configuration */
-   for (i = 0; submodule_cfg->parameters[i] != 0; i++)
-   {
-      if (submodule_cfg->parameters[i] == index)
-      {
-         /* Find parameter configuration */
-         for (j = 0; j < NELEMENTS (app_gsdml_parameters); j++)
-         {
-            if (app_gsdml_parameters[j].index == index)
-            {
-               return &app_gsdml_parameters[j];
-            }
-         }
-      }
-   }
-
-   return NULL;
-}

+ 0 - 184
samples/pn_dev/app_gsdml.h

@@ -1,184 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_GSDML_H
-#define APP_GSDML_H
-
-/**
- * @file
- * @brief Device properties defined by the GSDML device definition
- *
- * Functions for getting module, submodule and parameter
- * configurations using their ids.
- *
- * Important:
- * Any change in this file may require an update of the GSDML file.
- * Note that when the GSDML file is updated it has to be reloaded
- * in your Profinet engineering tool. PLC applications may be affected.
- *
- * Design requires unique submodule IDs and unique parameter indexes.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <pnet_api.h>
-
-#define APP_GSDML_API 0
-
-#define APP_GSDML_DEFAULT_STATION_NAME "rt-labs-dev"
-
-/* GSDML tag: VendorID */
-#define APP_GSDML_VENDOR_ID 0x0493
-
-/* GSDML tag: DeviceID */
-#define APP_GSDML_DEVICE_ID 0x0002
-
-/* Used in DCP communication */
-#define APP_GSDML_OEM_VENDOR_ID 0xcafe
-#define APP_GSDML_OEM_DEVICE_ID 0xee02
-
-/* Used in I&M0 */
-#define APP_GSDML_IM_HARDWARE_REVISION 3
-#define APP_GSDML_IM_VERSION_MAJOR     1
-#define APP_GSDML_IM_VERSION_MINOR     2
-
-/* Allowed: 'V', 'R', 'P', 'U', 'T' */
-#define APP_GSDML_SW_REV_PREFIX       'V'
-#define APP_GSDML_PROFILE_ID          0x1234
-#define APP_GSDML_PROFILE_SPEC_TYPE   0x5678
-#define APP_GSDML_IM_REVISION_COUNTER 0 /* Typically 0 */
-
-/* Note: You need to read out the actual hardware serial number instead */
-#define APP_GSDML_EXAMPLE_SERIAL_NUMBER "007"
-
-/* Initial values. Can be overwritten by PLC */
-#define APP_GSDML_TAG_FUNCTION "my function"
-#define APP_GSDML_TAG_LOCATION "my location"
-#define APP_GSDML_IM_DATE      "2022-03-01 10:03"
-#define APP_GSDML_DESCRIPTOR   "my descriptor"
-#define APP_GSDML_SIGNATURE    ""
-
-/* GSDML tag: Writeable_IM_Records */
-#define APP_GSDML_IM_SUPPORTED                                                 \
-   (PNET_SUPPORTED_IM1 | PNET_SUPPORTED_IM2 | PNET_SUPPORTED_IM3)
-
-/* GSDML tag: OrderNumber */
-#define APP_GSDML_ORDER_ID "12345 Abcdefghijk"
-
-/* GSDML tag: ModuleInfo / Name */
-#define APP_GSDML_PRODUCT_NAME "P-Net Sample Application"
-
-/* GSDML tag: MinDeviceInterval */
-#define APP_GSDML_MIN_DEVICE_INTERVAL 32 /* 1 ms */
-
-#define APP_GSDML_DIAG_CUSTOM_USI 0x1234
-
-/* See "Specification for GSDML" 8.26 LogBookEntryItem for allowed values */
-#define APP_GSDML_LOGBOOK_ERROR_CODE   0x20 /* Manufacturer specific */
-#define APP_GSDML_LOGBOOK_ERROR_DECODE 0x82 /* Manufacturer specific */
-#define APP_GSDML_LOGBOOK_ERROR_CODE_1 PNET_ERROR_CODE_1_FSPM
-#define APP_GSDML_LOGBOOK_ERROR_CODE_2 0x00       /* Manufacturer specific */
-#define APP_GSDML_LOGBOOK_ENTRY_DETAIL 0xFEE1DEAD /* Manufacturer specific */
-
-#define APP_GSDML_PARAMETER_1_IDX    123
-#define APP_GSDML_PARAMETER_2_IDX    124
-#define APP_GSDML_PARAMETER_ECHO_IDX 125
-
-/* Use same size for all parameters in example */
-#define APP_GSDML_PARAMETER_LENGTH 4
-
-#define APP_GSDML_DEFAULT_MAUTYPE 0x10 /* Copper 100 Mbit/s Full duplex */
-
-typedef struct app_gsdml_module
-{
-   uint32_t id;
-
-   /** Module name */
-   const char * name;
-
-   /** Submodule IDs. Variable length, ends with 0. */
-   uint32_t submodules[];
-} app_gsdml_module_t;
-
-typedef struct app_gsdml_submodule
-{
-   uint32_t id;
-
-   /** Submodule name */
-   const char * name;
-
-   uint32_t api;
-   pnet_submodule_dir_t data_dir;
-   uint16_t insize;
-   uint16_t outsize;
-
-   /** Parameter indexes. See app_gsdml_parameters.
-    * Variable length, ends with 0. */
-   uint16_t parameters[];
-} app_gsdml_submodule_t;
-
-typedef struct
-{
-   uint32_t index;
-   const char * name;
-   uint16_t length;
-} app_gsdml_param_t;
-
-#define APP_GSDML_MOD_ID_8_0_DIGITAL_IN     0x00000030
-#define APP_GSDML_MOD_ID_0_8_DIGITAL_OUT    0x00000031
-#define APP_GSDML_MOD_ID_8_8_DIGITAL_IN_OUT 0x00000032
-#define APP_GSDML_MOD_ID_ECHO               0x00000040
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN      0x00000130
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT     0x00000131
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_OUT  0x00000132
-#define APP_GSDML_SUBMOD_ID_ECHO            0x00000140
-#define APP_GSDML_INPUT_DATA_DIGITAL_SIZE   1 /* bytes */
-#define APP_GSDML_OUTPUT_DATA_DIGITAL_SIZE  1 /* bytes */
-#define APP_GSDML_INPUT_DATA_ECHO_SIZE      8 /* bytes */
-#define APP_GSDML_OUTPUT_DATA_ECHO_SIZE     APP_GSDML_INPUT_DATA_ECHO_SIZE
-#define APP_GSDML_ALARM_PAYLOAD_SIZE        1 /* bytes */
-
-/**
- * Get module configuration from module ID
- * @param module_id  In: Module ID
- * @return Module configuration, NULL if not found
- */
-const app_gsdml_module_t * app_gsdml_get_module_cfg (uint32_t module_id);
-
-/**
- * Get submodule module configuration from submodule ID
- * @param submodule_id  In: Submodule ID
- * @return Submodule configuration, NULL if not found
- */
-const app_gsdml_submodule_t * app_gsdml_get_submodule_cfg (
-   uint32_t submodule_id);
-
-/**
- * Get parameter configuration from parameter index
- * @param submodule_id  In: Submodule ID
- * @param index         In: Parameters index
- * @return Parameter configuration, NULL if not found
- */
-const app_gsdml_param_t * app_gsdml_get_parameter_cfg (
-   uint32_t submodule_id,
-   uint32_t index);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_GSDML_H */

+ 0 - 52
samples/pn_dev/app_log.c

@@ -1,52 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "app_log.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-
-static int32_t log_level = APP_DEFAULT_LOG_LEVEL;
-
-void app_log_set_log_level (int32_t level)
-{
-   log_level = level;
-}
-
-void app_log (int32_t level, const char * fmt, ...)
-{
-   va_list list;
-
-   if (level >= log_level)
-   {
-      va_start (list, fmt);
-      vprintf (fmt, list);
-      va_end (list);
-      fflush (stdout);
-   }
-}
-
-void app_log_print_bytes (int32_t level, const uint8_t * bytes, uint32_t len)
-{
-   if (level >= log_level)
-   {
-      printf ("  Bytes: ");
-      for (uint32_t i = 0; i < len; i++)
-      {
-         printf ("%02X ", bytes[i]);
-      }
-      printf ("\n");
-   }
-}

+ 0 - 75
samples/pn_dev/app_log.h

@@ -1,75 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_LOG_H
-#define APP_LOG_H
-
-/**
- * @file
- * @brief Application debug log utility
- *
- * Runtime configurable debug log using printf()
- * Levels matches levels used in P-Net.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#define APP_LOG_LEVEL_DEBUG   0x00
-#define APP_LOG_LEVEL_INFO    0x01
-#define APP_LOG_LEVEL_WARNING 0x02
-#define APP_LOG_LEVEL_ERROR   0x03
-#define APP_LOG_LEVEL_FATAL   0x04
-
-#define APP_DEFAULT_LOG_LEVEL APP_LOG_LEVEL_FATAL
-
-#define APP_LOG(level, ...) app_log (level, __VA_ARGS__)
-
-#define APP_LOG_DEBUG(...)   APP_LOG (APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define APP_LOG_INFO(...)    APP_LOG (APP_LOG_LEVEL_INFO, __VA_ARGS__)
-#define APP_LOG_WARNING(...) APP_LOG (APP_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define APP_LOG_ERROR(...)   APP_LOG (APP_LOG_LEVEL_ERROR, __VA_ARGS__)
-#define APP_LOG_FATAL(...)   APP_LOG (APP_LOG_LEVEL_FATAL, __VA_ARGS__)
-
-/**
- * Print log message depending on level
- * Use the APP_LOG_xxxxx macros instead of this function.
- * @param level         In: Message log level
- * @param fmt           In: Log message format string
- */
-void app_log (int32_t level, const char * fmt, ...);
-
-/**
- * Log an array of bytes
- * @param level         In: Log level
- * @param bytes         In: Array of bytes
- * @param length        In: Length of array
- */
-void app_log_print_bytes (int32_t level, const uint8_t * bytes, uint32_t length);
-
-/**
- * Set log level
- * @param level         In: Log level
- */
-void app_log_set_log_level (int32_t level);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_LOG_H */

+ 0 - 865
samples/pn_dev/app_utils.c

@@ -1,865 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#define _GNU_SOURCE /* For asprintf() */
-
-#include "app_utils.h"
-#include "app_log.h"
-#include "app_gsdml.h"
-#include "sampleapp_common.h"
-#include "osal.h"
-#include "osal_log.h" /* For LOG_LEVEL */
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define GET_HIGH_BYTE(id) ((id >> 8) & 0xFF)
-#define GET_LOW_BYTE(id)  (id & 0xFF)
-
-int app_ar_add_arep (app_api_t * api, uint32_t arep, app_ar_t ** ar)
-{
-   uint16_t i;
-
-   CC_ASSERT (api != NULL);
-   CC_ASSERT (ar != NULL);
-   for (i = 0; i < PNET_MAX_AR; ++i)
-   {
-      if (api->ar[i].arep == UINT32_MAX)
-      {
-         api->ar[i].arep = arep;
-         api->ar[i].events = 0;
-         *ar = api->ar + i;
-         return 1;
-      }
-   }
-   return 0;
-}
-
-uint32_t app_ar_arep (app_ar_t * ar)
-{
-   CC_ASSERT (ar != NULL);
-   return ar->arep;
-}
-
-void app_ar_event_set (app_ar_t * ar, uint32_t event)
-{
-   CC_ASSERT (ar != NULL);
-   ar->events |= event;
-}
-
-int app_ar_event_clr (app_ar_t * ar, uint32_t event)
-{
-   CC_ASSERT (ar != NULL);
-   if (ar->events & event)
-   {
-      ar->events &= ~event;
-      return 1;
-   }
-   return 0;
-}
-
-void app_ar_iterator_init (
-   app_ar_iterator_t * iterator,
-   app_api_t * api)
-{
-   CC_ASSERT (iterator != NULL);
-   CC_ASSERT (api != NULL);
-   iterator->ar = api->ar;
-   iterator->index = -1;
-   iterator->modified = false;
-}
-
-int app_ar_iterator_next (app_ar_iterator_t * iterator, app_ar_t ** ar)
-{
-#if PNET_MAX_AR > 1
-   uint16_t i;
-   uint16_t j;
-#endif
-
-   CC_ASSERT (iterator != NULL);
-   CC_ASSERT (ar != NULL);
-   ++iterator->index;
-   if (
-      (iterator->index < PNET_MAX_AR) &&
-      (iterator->ar[iterator->index].arep != UINT32_MAX))
-   {
-      *ar = iterator->ar + iterator->index;
-      return 1;
-   }
-#if PNET_MAX_AR > 1
-   else if (iterator->modified)
-   {
-      for (i = 0; i < PNET_MAX_AR; ++i)
-      {
-         if (iterator->ar[i].arep == UINT32_MAX)
-         {
-            for (j = i + 1; j < PNET_MAX_AR; ++j)
-            {
-               if (iterator->ar[j].arep != UINT32_MAX)
-               {
-                  iterator->ar[i] = iterator->ar[j];
-                  iterator->ar[j].arep = UINT32_MAX;
-                  break;
-               }
-            }
-            if (j >= PNET_MAX_AR - 1)
-            {
-               break;
-            }
-         }
-      }
-   }
-#endif
-   return 0;
-}
-
-int app_ar_iterator_done (app_ar_iterator_t * iterator)
-{
-   CC_ASSERT (iterator != NULL);
-   if (
-      (iterator->index < 0) ||
-      ((iterator->index < PNET_MAX_AR) &&
-       (iterator->ar[iterator->index].arep != UINT32_MAX)))
-   {
-      return 0;
-   }
-   return 1;
-}
-
-void app_ar_iterator_delete_current (app_ar_iterator_t * iterator)
-{
-   CC_ASSERT (iterator != NULL);
-   CC_ASSERT (iterator->index >= 0);
-   if (iterator->index < PNET_MAX_AR)
-   {
-      iterator->ar[iterator->index].arep = UINT32_MAX;
-      iterator->modified = true;
-   }
-}
-
-void app_utils_ip_to_string (pnal_ipaddr_t ip, char * outputstring)
-{
-   snprintf (
-      outputstring,
-      PNAL_INET_ADDRSTR_SIZE,
-      "%u.%u.%u.%u",
-      (uint8_t)((ip >> 24) & 0xFF),
-      (uint8_t)((ip >> 16) & 0xFF),
-      (uint8_t)((ip >> 8) & 0xFF),
-      (uint8_t)(ip & 0xFF));
-}
-
-void app_utils_mac_to_string (pnet_ethaddr_t mac, char * outputstring)
-{
-   snprintf (
-      outputstring,
-      PNAL_ETH_ADDRSTR_SIZE,
-      "%02X:%02X:%02X:%02X:%02X:%02X",
-      mac.addr[0],
-      mac.addr[1],
-      mac.addr[2],
-      mac.addr[3],
-      mac.addr[4],
-      mac.addr[5]);
-}
-
-const char * app_utils_submod_dir_to_string (pnet_submodule_dir_t direction)
-{
-   const char * s = "<error>";
-
-   switch (direction)
-   {
-   case PNET_DIR_NO_IO:
-      s = "NO_IO";
-      break;
-   case PNET_DIR_INPUT:
-      s = "INPUT";
-      break;
-   case PNET_DIR_OUTPUT:
-      s = "OUTPUT";
-      break;
-   case PNET_DIR_IO:
-      s = "INPUT_OUTPUT";
-      break;
-   }
-
-   return s;
-}
-
-const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs)
-{
-   const char * s = "<error>";
-   switch (ioxs)
-   {
-   case PNET_IOXS_BAD:
-      s = "IOXS_BAD";
-      break;
-   case PNET_IOXS_GOOD:
-      s = "IOXS_GOOD";
-      break;
-   }
-
-   return s;
-}
-
-void app_utils_get_error_code_strings (
-   uint16_t err_cls,
-   uint16_t err_code,
-   const char ** err_cls_str,
-   const char ** err_code_str)
-{
-   if (err_cls_str == NULL || err_code_str == NULL)
-   {
-      return;
-   }
-   *err_cls_str = "Not decoded";
-   *err_code_str = "Not decoded";
-
-   switch (err_cls)
-   {
-   case PNET_ERROR_CODE_1_RTA_ERR_CLS_PROTOCOL:
-      *err_cls_str = "Real-Time Acyclic Protocol";
-      switch (err_code)
-      {
-      case PNET_ERROR_CODE_2_ABORT_AR_CONSUMER_DHT_EXPIRED:
-         *err_code_str = "Device missed cyclic data "
-                         "deadline, device terminated AR";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_AR_CMI_TIMEOUT:
-         *err_code_str = "Communication initialization "
-                         "timeout, device terminated AR";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_AR_RELEASE_IND_RECEIVED:
-         *err_code_str = "AR release indication received";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_AR_RPC_READ_ERROR:
-         *err_code_str = "AR RPC-Read error";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_DCP_STATION_NAME_CHANGED:
-         *err_code_str = "DCP station name changed, "
-                         "device terminated AR";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_DCP_RESET_TO_FACTORY:
-         *err_code_str = "DCP reset to factory or factory "
-                         "reset, device terminated AR";
-         break;
-      }
-      break;
-
-   case PNET_ERROR_CODE_1_CTLDINA:
-      *err_cls_str = "CTLDINA = Name and IP assignment from controller";
-      switch (err_code)
-      {
-      case PNET_ERROR_CODE_2_CTLDINA_ARP_MULTIPLE_IP_ADDRESSES:
-         *err_code_str = "Multiple users of same IP address";
-         break;
-      }
-      break;
-   }
-}
-
-void app_utils_copy_ip_to_struct (
-   pnet_cfg_ip_addr_t * destination_struct,
-   pnal_ipaddr_t ip)
-{
-   destination_struct->a = ((ip >> 24) & 0xFF);
-   destination_struct->b = ((ip >> 16) & 0xFF);
-   destination_struct->c = ((ip >> 8) & 0xFF);
-   destination_struct->d = (ip & 0xFF);
-}
-
-const char * app_utils_dcontrol_cmd_to_string (
-   pnet_control_command_t control_command)
-{
-   const char * s = NULL;
-
-   switch (control_command)
-   {
-   case PNET_CONTROL_COMMAND_PRM_BEGIN:
-      s = "PRM_BEGIN";
-      break;
-   case PNET_CONTROL_COMMAND_PRM_END:
-      s = "PRM_END";
-      break;
-   case PNET_CONTROL_COMMAND_APP_RDY:
-      s = "APP_RDY";
-      break;
-   case PNET_CONTROL_COMMAND_RELEASE:
-      s = "RELEASE";
-      break;
-   default:
-      s = "<error>";
-      break;
-   }
-
-   return s;
-}
-
-const char * app_utils_event_to_string (pnet_event_values_t event)
-{
-   const char * s = "<error>";
-
-   switch (event)
-   {
-   case PNET_EVENT_ABORT:
-      s = "PNET_EVENT_ABORT";
-      break;
-   case PNET_EVENT_STARTUP:
-      s = "PNET_EVENT_STARTUP";
-      break;
-   case PNET_EVENT_PRMEND:
-      s = "PNET_EVENT_PRMEND";
-      break;
-   case PNET_EVENT_APPLRDY:
-      s = "PNET_EVENT_APPLRDY";
-      break;
-   case PNET_EVENT_DATA:
-      s = "PNET_EVENT_DATA";
-      break;
-   }
-
-   return s;
-}
-
-int app_utils_pnet_cfg_init_default (pnet_cfg_t * cfg)
-{
-   memset (cfg, 0, sizeof (pnet_cfg_t));
-
-   cfg->tick_us = APP_TICK_INTERVAL_US;
-
-   /* Identification & Maintenance */
-
-   cfg->im_0_data.im_vendor_id_hi = GET_HIGH_BYTE (APP_GSDML_VENDOR_ID);
-   cfg->im_0_data.im_vendor_id_lo = GET_LOW_BYTE (APP_GSDML_VENDOR_ID);
-
-   cfg->im_0_data.im_hardware_revision = APP_GSDML_IM_HARDWARE_REVISION;
-   cfg->im_0_data.im_sw_revision_prefix = APP_GSDML_SW_REV_PREFIX;
-   cfg->im_0_data.im_sw_revision_functional_enhancement = PNET_VERSION_MAJOR;
-   cfg->im_0_data.im_sw_revision_bug_fix = PNET_VERSION_MINOR;
-   cfg->im_0_data.im_sw_revision_internal_change = PNET_VERSION_PATCH;
-   cfg->im_0_data.im_revision_counter = APP_GSDML_IM_REVISION_COUNTER;
-   cfg->im_0_data.im_profile_id = APP_GSDML_PROFILE_ID;
-   cfg->im_0_data.im_profile_specific_type = APP_GSDML_PROFILE_SPEC_TYPE;
-   cfg->im_0_data.im_version_major = 1; /** Always 1 */
-   cfg->im_0_data.im_version_minor = 1; /** Always 1 */
-   cfg->im_0_data.im_supported = APP_GSDML_IM_SUPPORTED;
-
-   snprintf (
-      cfg->im_0_data.im_order_id,
-      sizeof (cfg->im_0_data.im_order_id),
-      "%s",
-      APP_GSDML_ORDER_ID);
-   snprintf (
-      cfg->im_0_data.im_serial_number,
-      sizeof (cfg->im_0_data.im_serial_number),
-      "%s",
-      APP_GSDML_EXAMPLE_SERIAL_NUMBER);
-   snprintf (
-      cfg->im_1_data.im_tag_function,
-      sizeof (cfg->im_1_data.im_tag_function),
-      "%s",
-      APP_GSDML_TAG_FUNCTION);
-   snprintf (
-      cfg->im_1_data.im_tag_location,
-      sizeof (cfg->im_1_data.im_tag_location),
-      "%s",
-      APP_GSDML_TAG_LOCATION);
-   snprintf (
-      cfg->im_2_data.im_date,
-      sizeof (cfg->im_2_data.im_date),
-      "%s",
-      APP_GSDML_IM_DATE);
-   snprintf (
-      cfg->im_3_data.im_descriptor,
-      sizeof (cfg->im_3_data.im_descriptor),
-      "%s",
-      APP_GSDML_DESCRIPTOR);
-   snprintf (
-      cfg->im_4_data.im_signature,
-      sizeof (cfg->im_4_data.im_signature),
-      "%s",
-      APP_GSDML_SIGNATURE);
-
-   /* Device configuration */
-   cfg->device_id.vendor_id_hi = GET_HIGH_BYTE (APP_GSDML_VENDOR_ID);
-   cfg->device_id.vendor_id_lo = GET_LOW_BYTE (APP_GSDML_VENDOR_ID);
-   cfg->device_id.device_id_hi = GET_HIGH_BYTE (APP_GSDML_DEVICE_ID);
-   cfg->device_id.device_id_lo = GET_LOW_BYTE (APP_GSDML_DEVICE_ID);
-   cfg->oem_device_id.vendor_id_hi = GET_HIGH_BYTE (APP_GSDML_OEM_VENDOR_ID);
-   cfg->oem_device_id.vendor_id_lo = GET_LOW_BYTE (APP_GSDML_OEM_VENDOR_ID);
-   cfg->oem_device_id.device_id_hi = GET_HIGH_BYTE (APP_GSDML_OEM_DEVICE_ID);
-   cfg->oem_device_id.device_id_lo = GET_LOW_BYTE (APP_GSDML_OEM_DEVICE_ID);
-
-   snprintf (
-      cfg->product_name,
-      sizeof (cfg->product_name),
-      "%s",
-      APP_GSDML_PRODUCT_NAME);
-
-   cfg->send_hello = true;
-
-   /* Timing */
-   cfg->min_device_interval = APP_GSDML_MIN_DEVICE_INTERVAL;
-
-   /* Should be set by application as part of network configuration. */
-   cfg->num_physical_ports = 1;
-
-   snprintf (
-      cfg->station_name,
-      sizeof (cfg->station_name),
-      "%s",
-      APP_GSDML_DEFAULT_STATION_NAME);
-
-   /* Diagnosis mechanism */
-   /* We prefer using "Extended channel diagnosis" instead of
-    * "Qualified channel diagnosis" format on the wire,
-    * as this is better supported by Wireshark.
-    */
-   cfg->use_qualified_diagnosis = false;
-
-   return 0;
-}
-
-int app_utils_get_netif_namelist (
-   const char * arg_str,
-   uint16_t max_port,
-   app_utils_netif_namelist_t * p_if_list,
-   uint16_t * p_num_ports)
-{
-   int ret = 0;
-   uint16_t i = 0;
-   uint16_t j = 0;
-   uint16_t if_index = 0;
-   uint16_t number_of_given_names = 1;
-   uint16_t if_list_size = max_port + 1;
-   char c;
-
-   if (max_port == 0)
-   {
-      printf ("Error: max_port is 0.\n");
-      return -1;
-   }
-
-   memset (p_if_list, 0, sizeof (*p_if_list));
-   c = arg_str[i++];
-   while (c != '\0')
-   {
-      if (c != ',')
-      {
-         if (if_index < if_list_size)
-         {
-            p_if_list->netif[if_index].name[j++] = c;
-         }
-      }
-      else
-      {
-         if (if_index < if_list_size)
-         {
-            p_if_list->netif[if_index].name[j++] = '\0';
-            j = 0;
-            if_index++;
-         }
-         number_of_given_names++;
-      }
-
-      c = arg_str[i++];
-   }
-
-   if (max_port == 1 && number_of_given_names > 1)
-   {
-      printf ("Error: Only 1 network interface expected as max_port is 1.\n");
-      return -1;
-   }
-   if (number_of_given_names == 2)
-   {
-      printf ("Error: It is illegal to give 2 interface names. Use 1, or one "
-              "more than the number of physical interfaces.\n");
-      return -1;
-   }
-   if (number_of_given_names > max_port + 1)
-   {
-      printf (
-         "Error: You have given %u interface names, but max is %u as "
-         "PNET_MAX_PHYSICAL_PORTS is %u.\n",
-         number_of_given_names,
-         max_port + 1,
-         max_port);
-      return -1;
-   }
-
-   if (number_of_given_names == 1)
-   {
-      if (strlen (p_if_list->netif[0].name) == 0)
-      {
-         printf ("Error: Zero length network interface name.\n");
-         return -1;
-      }
-      else
-      {
-         p_if_list->netif[1] = p_if_list->netif[0];
-         *p_num_ports = 1;
-      }
-   }
-   else
-   {
-      for (i = 0; i < number_of_given_names; i++)
-      {
-         if (strlen (p_if_list->netif[i].name) == 0)
-         {
-            printf ("Error: Zero length network interface name (%d).\n", i);
-            return -1;
-         }
-      }
-
-      *p_num_ports = number_of_given_names - 1;
-   }
-
-   return ret;
-}
-
-int app_utils_pnet_cfg_init_netifs (
-   const char * netif_list_str,
-   app_utils_netif_namelist_t * if_list,
-   uint16_t * number_of_ports,
-   pnet_if_cfg_t * if_cfg)
-{
-   int ret = 0;
-   int i = 0;
-   pnal_ipaddr_t ip;
-   pnal_ipaddr_t netmask;
-   pnal_ipaddr_t gateway;
-
-   ret = app_utils_get_netif_namelist (
-      netif_list_str,
-      PNET_MAX_PHYSICAL_PORTS,
-      if_list,
-      number_of_ports);
-   if (ret != 0)
-   {
-      return ret;
-   }
-   if_cfg->main_netif_name = if_list->netif[0].name;
-
-   for (i = 1; i <= *number_of_ports; i++)
-   {
-      if_cfg->physical_ports[i - 1].netif_name = if_list->netif[i].name;
-      if_cfg->physical_ports[i - 1].default_mau_type =
-         APP_GSDML_DEFAULT_MAUTYPE;
-   }
-
-   /* Read IP, netmask, gateway from operating system */
-   ip = pnal_get_ip_address (if_cfg->main_netif_name);
-   netmask = pnal_get_netmask (if_cfg->main_netif_name);
-   gateway = pnal_get_gateway (if_cfg->main_netif_name);
-
-   app_utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_addr, ip);
-   app_utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_gateway, gateway);
-   app_utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_mask, netmask);
-
-   return ret;
-}
-
-static void app_utils_print_mac_address (const char * netif_name)
-{
-   pnal_ethaddr_t pnal_mac_addr;
-   if (pnal_get_macaddress (netif_name, &pnal_mac_addr) == 0)
-   {
-      APP_LOG_INFO (
-         "%02X:%02X:%02X:%02X:%02X:%02X\n",
-         pnal_mac_addr.addr[0],
-         pnal_mac_addr.addr[1],
-         pnal_mac_addr.addr[2],
-         pnal_mac_addr.addr[3],
-         pnal_mac_addr.addr[4],
-         pnal_mac_addr.addr[5]);
-   }
-   else
-   {
-      APP_LOG_ERROR ("Failed read mac address\n");
-   }
-}
-
-void app_utils_print_network_config (
-   pnet_if_cfg_t * if_cfg,
-   uint16_t number_of_ports)
-{
-   uint16_t i;
-   char hostname_string[PNAL_HOSTNAME_MAX_SIZE]; /* Terminated string */
-
-   APP_LOG_INFO ("Management port:      %s ", if_cfg->main_netif_name);
-   app_utils_print_mac_address (if_cfg->main_netif_name);
-   for (i = 1; i <= number_of_ports; i++)
-   {
-      APP_LOG_INFO (
-         "Physical port [%u]:    %s ",
-         i,
-         if_cfg->physical_ports[i - 1].netif_name);
-
-      app_utils_print_mac_address (if_cfg->physical_ports[i - 1].netif_name);
-   }
-
-   if (pnal_get_hostname (hostname_string) != 0)
-   {
-      hostname_string[0] = '\0';
-   }
-
-   APP_LOG_INFO ("Hostname:             %s\n", hostname_string);
-   APP_LOG_INFO (
-      "IP address:           %u.%u.%u.%u\n",
-      if_cfg->ip_cfg.ip_addr.a,
-      if_cfg->ip_cfg.ip_addr.b,
-      if_cfg->ip_cfg.ip_addr.c,
-      if_cfg->ip_cfg.ip_addr.d);
-   APP_LOG_INFO (
-      "Netmask:              %u.%u.%u.%u\n",
-      if_cfg->ip_cfg.ip_mask.a,
-      if_cfg->ip_cfg.ip_mask.b,
-      if_cfg->ip_cfg.ip_mask.c,
-      if_cfg->ip_cfg.ip_mask.d);
-   APP_LOG_INFO (
-      "Gateway:              %u.%u.%u.%u\n",
-      if_cfg->ip_cfg.ip_gateway.a,
-      if_cfg->ip_cfg.ip_gateway.b,
-      if_cfg->ip_cfg.ip_gateway.c,
-      if_cfg->ip_cfg.ip_gateway.d);
-}
-
-void app_utils_print_ioxs_change (
-   const app_subslot_t * subslot,
-   const char * ioxs_str,
-   uint8_t ioxs_current,
-   uint8_t ioxs_new)
-{
-   if (ioxs_current != ioxs_new)
-   {
-      if (ioxs_new == PNET_IOXS_BAD)
-      {
-         APP_LOG_DEBUG (
-            "PLC reports %s BAD for slot %u subslot %u \"%s\"\n",
-            ioxs_str,
-            subslot->slot_nbr,
-            subslot->subslot_nbr,
-            subslot->submodule_name);
-      }
-      else if (ioxs_new == PNET_IOXS_GOOD)
-      {
-         APP_LOG_DEBUG (
-            "PLC reports %s GOOD for slot %u subslot %u \"%s\".\n",
-            ioxs_str,
-            subslot->slot_nbr,
-            subslot->subslot_nbr,
-            subslot->submodule_name);
-      }
-      else if (ioxs_new != PNET_IOXS_GOOD)
-      {
-         APP_LOG_DEBUG (
-            "PLC reports %s %u for slot %u subslot %u \"%s\".\n"
-            "  Is the PLC in STOP mode?\n",
-            ioxs_str,
-            ioxs_new,
-            subslot->slot_nbr,
-            subslot->subslot_nbr,
-            subslot->submodule_name);
-      }
-   }
-}
-
-int app_utils_plug_module (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint32_t id,
-   const char * name)
-{
-   if (slot_nbr >= PNET_MAX_SLOTS)
-   {
-      return -1;
-   }
-
-   p_api->slots[slot_nbr].module_id = id;
-   p_api->slots[slot_nbr].plugged = true;
-   p_api->slots[slot_nbr].name = name;
-
-   return 0;
-}
-
-int app_utils_pull_module (app_api_t * p_api, uint16_t slot_nbr)
-{
-   if (slot_nbr >= PNET_MAX_SLOTS)
-   {
-      return -1;
-   }
-
-   p_api->slots[slot_nbr].plugged = false;
-
-   return 0;
-}
-
-app_subslot_t * app_utils_plug_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_ident,
-   const pnet_data_cfg_t * p_data_cfg,
-   const char * submodule_name,
-   app_utils_cyclic_callback cyclic_callback,
-   void * tag)
-{
-   uint16_t subslot_ix;
-
-   if (slot_nbr >= PNET_MAX_SLOTS || p_api == NULL || p_data_cfg == NULL)
-   {
-      return NULL;
-   }
-
-   /** Find a free subslot */
-   for (subslot_ix = 0; subslot_ix < PNET_MAX_SUBSLOTS; subslot_ix++)
-   {
-      if (p_api->slots[slot_nbr].subslots[subslot_ix].used == false)
-      {
-         app_subslot_t * p_subslot =
-            &p_api->slots[slot_nbr].subslots[subslot_ix];
-
-         p_subslot->used = true;
-         p_subslot->plugged = true;
-         p_subslot->slot_nbr = slot_nbr;
-         p_subslot->subslot_nbr = subslot_nbr;
-         p_subslot->submodule_name = submodule_name;
-         p_subslot->submodule_id = submodule_ident;
-         p_subslot->data_cfg = *p_data_cfg;
-         p_subslot->cyclic_callback = cyclic_callback;
-         p_subslot->tag = tag;
-         p_subslot->indata_iocs = PNET_IOXS_BAD;
-         p_subslot->outdata_iops = PNET_IOXS_BAD;
-         return p_subslot;
-      }
-   }
-
-   return NULL;
-}
-
-int app_utils_pull_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr)
-{
-   app_subslot_t * p_subslot = NULL;
-
-   if (slot_nbr >= PNET_MAX_SUBSLOTS || p_api == NULL)
-   {
-      return -1;
-   }
-
-   p_subslot = app_utils_subslot_get (p_api, slot_nbr, subslot_nbr);
-   if (p_subslot == NULL)
-   {
-      return -1;
-   }
-
-   memset (p_subslot, 0, sizeof (app_subslot_t));
-   p_subslot->used = false;
-
-   return 0;
-}
-
-app_subslot_t * app_utils_subslot_get (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr)
-{
-   uint16_t subslot_ix;
-
-   if (slot_nbr >= PNET_MAX_SLOTS || p_api == NULL)
-   {
-      return NULL;
-   }
-
-   for (subslot_ix = 0; subslot_ix < PNET_MAX_SUBSLOTS; subslot_ix++)
-   {
-      if (p_api->slots[slot_nbr].subslots[subslot_ix].subslot_nbr == subslot_nbr)
-      {
-         return &p_api->slots[slot_nbr].subslots[subslot_ix];
-      }
-   }
-
-   return NULL;
-}
-
-bool app_utils_subslot_is_input (const app_subslot_t * p_subslot)
-{
-   if (p_subslot == NULL || p_subslot->used == false)
-   {
-      return false;
-   }
-
-   if (
-      p_subslot->data_cfg.data_dir == PNET_DIR_INPUT ||
-      p_subslot->data_cfg.data_dir == PNET_DIR_IO)
-   {
-      return true;
-   }
-
-   return false;
-}
-
-bool app_utils_subslot_is_no_io (const app_subslot_t * p_subslot)
-{
-   if (p_subslot == NULL || p_subslot->used == false)
-   {
-      return false;
-   }
-
-   return p_subslot->data_cfg.data_dir == PNET_DIR_NO_IO;
-}
-
-bool app_utils_subslot_is_output (const app_subslot_t * p_subslot)
-{
-   if (p_subslot == NULL || p_subslot->used == false)
-   {
-      return false;
-   }
-
-   if (
-      p_subslot->data_cfg.data_dir == PNET_DIR_OUTPUT ||
-      p_subslot->data_cfg.data_dir == PNET_DIR_IO)
-   {
-      return true;
-   }
-
-   return false;
-}
-
-void app_utils_cyclic_data_poll (app_api_t * p_api)
-{
-   uint16_t slot_nbr;
-   uint16_t subslot_index;
-   app_subslot_t * p_subslot;
-
-   for (slot_nbr = 0; slot_nbr < PNET_MAX_SLOTS; slot_nbr++)
-   {
-      for (subslot_index = 0; subslot_index < PNET_MAX_SUBSLOTS;
-           subslot_index++)
-      {
-         p_subslot = &p_api->slots[slot_nbr].subslots[subslot_index];
-         if (p_subslot->plugged && p_subslot->cyclic_callback != NULL)
-         {
-            p_subslot->cyclic_callback (p_subslot, p_subslot->tag);
-         }
-      }
-   }
-}

+ 0 - 519
samples/pn_dev/app_utils.h

@@ -1,519 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_UTILS_H
-#define APP_UTILS_H
-
-/**
- * @file
- * @brief Application utilities and helper functions
- *
- * Functions for getting string representation of
- * P-Net events, error codes and more.
- *
- * API, slot and subslot administration.
- *
- * Initialization of P-Net configuration from app_gsdml.h.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-typedef struct app_utils_netif_name
-{
-   char name[PNET_INTERFACE_NAME_MAX_SIZE];
-} app_utils_netif_name_t;
-
-typedef struct app_utils_netif_namelist
-{
-   app_utils_netif_name_t netif[PNET_MAX_PHYSICAL_PORTS + 1];
-} app_utils_netif_namelist_t;
-
-/* Forward declaration */
-typedef struct app_subslot app_subslot_t;
-
-/**
- * Callback for updated cyclic data
- *
- * @param subslot    InOut: Subslot structure
- * @param tag        InOut: Typically a handle to a submodule
- */
-typedef void (*app_utils_cyclic_callback) (app_subslot_t * subslot, void * tag);
-
-/**
- * Information of submodule plugged into a subslot.
- *
- * Note that submodule data is not stored here but must
- * be handled by the submodule implementation.
- *
- * All parameters are initialized by the app_utils_plug_submodule()
- * function.
- *
- * The cyclic_callback is used when app_utils_cyclic_data_poll()
- * is called. Typically on the tick event in the main task.
- * The \a tag parameter is passed with the cyclic_callback and
- * is typically a handle to a submodule on application.
- */
-typedef struct app_subslot
-{
-   /** True when the position in the subslot array is occupied */
-   bool used;
-
-   /** True when the subslot is plugged */
-   bool plugged;
-
-   uint16_t slot_nbr;
-   uint16_t subslot_nbr;
-   uint32_t submodule_id;
-   const char * submodule_name;
-   pnet_data_cfg_t data_cfg;
-
-   /** Status indicator from PLC */
-   uint8_t indata_iocs;
-
-   /** Status indicator from PLC */
-   uint8_t outdata_iops;
-
-   /** Callback for cyclic input- or output data, or NULL if not implemented */
-   app_utils_cyclic_callback cyclic_callback;
-   void * tag;
-} app_subslot_t;
-
-/**
- * Information of module plugged into a slot,
- * and array of subslots for admin of submodules.
- */
-typedef struct app_slot
-{
-   bool plugged;
-   uint32_t module_id;
-   const char * name; /** Module name */
-
-   /** Subslots. Use a separate index, as the subslot number might be large.
-    *  For example the subslot for DAP port 1 has number 0x8001 */
-   app_subslot_t subslots[PNET_MAX_SUBSLOTS];
-} app_slot_t;
-
-/**
- * Information relating to an application relation.
- */
-typedef struct app_ar
-{
-   uint32_t arep;
-   uint32_t events;
-} app_ar_t;
-
-/**
- * AR list iterator state.
- */
-typedef struct app_ar_iterator
-{
-   app_ar_t *ar;
-   int16_t index;
-   bool modified;
-} app_ar_iterator_t;
-
-/**
- * Profinet API state for application
- *
- * Used to manage plugged modules into slots (and submodules into subslots).
- */
-typedef struct app_api_t
-{
-   uint32_t api_id;
-
-   /**
-    * Active AR:s.
-    * A list which is terminated by an entry with arep == UINT32_MAX.
-    */
-   app_ar_t ar[PNET_MAX_AR];
-
-   /** Slots. Use slot number as index */
-   app_slot_t slots[PNET_MAX_SLOTS];
-} app_api_t;
-
-/**
- * Add an arep to the AR list of an API.
- * @param api              InOut: The \a app_api_t instance.
- * @param arep             In:    The arep to add.
- * @param ar               Out:   The AR entry, if successful.
- *
- * @return 0 if the arep could not be added.
- *         1 if the arep was added.
- */
-int app_ar_add_arep (app_api_t * api, uint32_t arep, app_ar_t ** ar);
-
-/**
- * Get the arep of an AR.
- * @param ar               In: The AR.
- * @return the arep of the AR.
- */
-uint32_t app_ar_arep (app_ar_t * ar);
-
-/**
- * Clear an event from the events value of the AR.
- * @param ar               InOut: The AR to modify.
- * @param event            In:    The event(s) (bitmask) that should be cleared.
- * @return 0 if none of the set bits in \a event were set for the AR.
- *         1 if at least one of the set bits in \a event were set for the AR.
- */
-int app_ar_event_clr (app_ar_t * ar, uint32_t event);
-
-/**
- * Set an event from the events value of the AR.
- * @param ar               InOut: The AR to modify.
- * @param event            In:    The event(s) (bitmask) that should be set.
- */
-void app_ar_event_set (app_ar_t * ar, uint32_t event);
-
-/**
- * Initialize a list iterator for the AR list of an API.
- * @param iterator         InOut: The iterator to be initialized.
- * @param api              In:    The \a app_api_t instance.
- */
-void app_ar_iterator_init (
-   app_ar_iterator_t * iterator,
-   app_api_t * api);
-
-/**
- * Get the next AR from a list iterator.
- * @param iterator         InOut: The iterator to use.
- * @param ar               Out:   If the return value is 1, the next AR from
- *                                the list.
- * @return 0 if there were no more items in the list.
- *         1 if there was another item in the list.
- */
-int app_ar_iterator_next (app_ar_iterator_t * iterator, app_ar_t ** ar);
-
-/**
- * Check whether the iterator has run to the end of entries.
- * @param iterator         InOut: The iterator.
- * @return 0 if the iterator is finished.
- *         1 if the iterator is finished.
- */
-int app_ar_iterator_done (app_ar_iterator_t * iterator);
-
-/**
- * Delete the current AR entry of the list iterator.
- * @param ar               InOut: The AR.
- */
-void app_ar_iterator_delete_current (app_ar_iterator_t * iterator);
-
-/**
- * Convert IP address to string
- * @param ip               In:    IP address
- * @param outputstring     Out:   Resulting string buffer. Should have size
- *                                PNAL_INET_ADDRSTR_SIZE.
- */
-void app_utils_ip_to_string (pnal_ipaddr_t ip, char * outputstring);
-
-/**
- * Get string description of data direction
- * @param direction               In:    Submodule data direction
- * @return String representation of data direction
- */
-const char * app_utils_submod_dir_to_string (pnet_submodule_dir_t direction);
-
-/**
- * Get string description of PNIO producer or consumer status
- * @param ioxs               In:    Producer or consumer status (IOPS/IOCS)
- * @return String representation of ioxs (IOPS/IOCS)
- */
-const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs);
-
-/**
- * Convert MAC address to string
- * @param mac              In:    MAC address
- * @param outputstring     Out:   Resulting string buffer. Should have size
- *                                PNAL_ETH_ADDRSTR_SIZE.
- */
-void app_utils_mac_to_string (pnet_ethaddr_t mac, char * outputstring);
-
-/**
- * Convert error code to string format
- * Only common error codes supported.
- * Todo: Add rest of error codes.
- *
- * @param err_cls        In:   The error class. See PNET_ERROR_CODE_1_*
- * @param err_code       In:   The error code. See PNET_ERROR_CODE_2_*
- * @param err_cls_str    Out:   The error class string
- * @param err_code_str   Out:   The error code string
- */
-void app_utils_get_error_code_strings (
-   uint16_t err_cls,
-   uint16_t err_code,
-   const char ** err_cls_str,
-   const char ** err_code_str);
-
-/**
- * Copy an IP address (as an integer) to a struct
- * @param destination_struct  Out:   Destination
- * @param ip                  In:    IP address
- */
-void app_utils_copy_ip_to_struct (
-   pnet_cfg_ip_addr_t * destination_struct,
-   pnal_ipaddr_t ip);
-
-/**
- * Return a string representation of
- * the given dcontrol command.
- * @param event            In:    control_command
- * @return  A string representing the command
- */
-const char * app_utils_dcontrol_cmd_to_string (
-   pnet_control_command_t control_command);
-
-/**
- * Return a string representation of the given event.
- * @param event            In:    event
- * @return  A string representing the event
- */
-const char * app_utils_event_to_string (pnet_event_values_t event);
-
-/**
- * Update network configuration from a string
- * defining a list of network interfaces examples:
- * "eth0" or "br0,eth0,eth1"
- *
- * Read IP, netmask etc from operating system.
- *
- * @param netif_list_str      In:  Comma separated string of network ifs
- * @param if_list             Out: Array of network ifs
- * @param number_of_ports     Out: Number of ports
- * @param if_cfg              Out: P-Net network configuration to be updated
- * @return 0 on success, -1 on error
- */
-int app_utils_pnet_cfg_init_netifs (
-   const char * netif_list_str,
-   app_utils_netif_namelist_t * if_list,
-   uint16_t * number_of_ports,
-   pnet_if_cfg_t * if_cfg);
-
-/**
- * Parse a comma separated list of network interfaces and check
- * that the number of interfaces match the PNET_MAX_PHYSICAL_PORTS
- * configuration.
- *
- * For a single Ethernet interface, the \a arg_str should consist of
- * one name. For two Ethernet interfaces, the  \a arg_str should consist of
- * three names, as we also need a bridge interface.
- *
- * Does only consider the number of comma separated names. No check of the
- * names themselves are done.
- *
- * Examples:
- * arg_str                 num_ports
- * "eth0"                  1
- * "eth0,eth1"             error (We need a bridge as well)
- * "br0,eth0,eth1"         2
- *
- * @param arg_str      In:   Network interface list as comma separated,
- *                           terminated string. For example "eth0" or
- *                           "br0,eth0,eth1".
- * @param max_port     In:   PNET_MAX_PHYSICAL_PORTS, passed as argument to
- *                           allow test.
- * @param p_if_list    Out:  List of network interfaces
- * @param p_num_ports  Out:  Resulting number of physical ports
- * @return  0  on success
- *         -1  on error
- */
-int app_utils_get_netif_namelist (
-   const char * arg_str,
-   uint16_t max_port,
-   app_utils_netif_namelist_t * p_if_list,
-   uint16_t * p_num_ports);
-
-/**
- * Print network configuration using APP_LOG_INFO().
- *
- * @param if_cfg           In:   Network configuration
- * @param number_of_ports  In:   Number of used ports
- */
-void app_utils_print_network_config (
-   pnet_if_cfg_t * if_cfg,
-   uint16_t number_of_ports);
-
-/**
- * Print message if IOXS has changed.
- *
- * Uses APP_LOG_INFO()
- *
- * @param subslot          In: Subslot
- * @param ioxs_str         In: String description Producer or Consumer
- * @param ioxs_current     In: Current status
- * @param ioxs_new         In: New status
- */
-void app_utils_print_ioxs_change (
-   const app_subslot_t * subslot,
-   const char * ioxs_str,
-   uint8_t ioxs_current,
-   uint8_t ioxs_new);
-
-/**
- * Init the p-net configuration to default values.
- *
- * Most values are picked from app_gsdml.h
- *
- * Network configuration not initialized.
- * This means that \a '.if_cfg' must be set by application.
- *
- * Use this function to init P-Net configuration before
- * before passing config to app_init().
- *
- * @param pnet_cfg     Out:   Configuration for use by p-net
- * @return  0  if the operation succeeded.
- *          -1 if an error occurred.
- */
-int app_utils_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg);
-
-/**
- * Plug application module
- *
- * This is for the application to remember which slots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @param id               In:    Module identity
- * @param name             In:    Module name
- * @return 0 on success, -1 on error
- */
-int app_utils_plug_module (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint32_t id,
-   const char * name);
-
-/**
- * Pull any application module in given slot.
- *
- * This is for the application to remember which slots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @return 0 on success, -1 on error
- */
-int app_utils_pull_module (app_api_t * p_api, uint16_t slot_nbr);
-
-/**
- * Plug application submodule.
- *
- * This is for the application to remember which subslots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @param subslot_nbr      In:    Subslot number
- * @param submodule_id     In:    Submodule identity
- * @param p_data_cfg       In:    Data configuration,
- *                                direction, in and out sizes
- * @param submodule_name   In:    Submodule name
- * @param cyclic_callback  In:    Submodule data callback
- * @param tag              In:    Tag passed in cyclic callback
- *                                Typically application or
- *                                submodule handle
- * @return Reference to allocated subslot,
- *         NULL if no free subslot is available. This should
- *         never happen if application is aligned with p-net state.
- */
-app_subslot_t * app_utils_plug_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   const pnet_data_cfg_t * p_data_cfg,
-   const char * submodule_name,
-   app_utils_cyclic_callback cyclic_callback,
-   void * tag);
-
-/**
- * Unplug any application submodule from given subslot.
- *
- * This is for the application to remember which subslots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @param subslot_nbr      In:    Subslot number
- * @return 0 on success, -1 on error.
- */
-int app_utils_pull_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr);
-
-/**
- * Trigger data callback for all plugged submodules in all slots.
- *
- * The callbacks given in \a app_utils_plug_submodule() are used.
- *
- * @param p_api         In:   API
- */
-void app_utils_cyclic_data_poll (app_api_t * p_api);
-
-/**
- * Get subslot application information.
- *
- * @param p_appdata        InOut: Application state.
- * @param slot_nbr         In:    Slot number.
- * @param subslot_nbr      In:    Subslot number. Range 0 - 0x9FFF.
- * @return Reference to application subslot,
- *         NULL if subslot is not found/plugged.
- */
-app_subslot_t * app_utils_subslot_get (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr);
-
-/**
- * Return true if subslot is input.
- *
- * @param p_subslot        In:    Reference to subslot.
- * @return true if subslot is input or input/output.
- *         false if not.
- */
-bool app_utils_subslot_is_input (const app_subslot_t * p_subslot);
-
-/**
- * Return true if subslot is neither input or output.
- *
- * This is applies for DAP submodules/slots
- *
- * @param p_subslot     In: Reference to subslot.
- * @return true if subslot is input or input/output.
- *         false if not.
- */
-bool app_utils_subslot_is_no_io (const app_subslot_t * p_subslot);
-
-/**
- * Return true if subslot is output.
- *
- * @param p_subslot     In: Reference to subslot.
- * @return true if subslot is output or input/output,
- *         false if not.
- */
-bool app_utils_subslot_is_output (const app_subslot_t * p_subslot);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_UTILS_H */

+ 0 - 1759
samples/pn_dev/sampleapp_common.c

@@ -1,1759 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "sampleapp_common.h"
-
-#include "app_utils.h"
-#include "app_gsdml.h"
-#include "app_data.h"
-#include "app_log.h"
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Events handled by main task */
-#define APP_EVENT_READY_FOR_DATA BIT (0)
-#define APP_EVENT_TIMER          BIT (1)
-#define APP_EVENT_ALARM          BIT (2)
-#define APP_EVENT_SM_RELEASED    BIT (3)
-#define APP_EVENT_ABORT          BIT (15)
-
-/* Defines used for alarm demo functionality */
-#define CHANNEL_ERRORTYPE_SHORT_CIRCUIT                       0x0001
-#define CHANNEL_ERRORTYPE_LINE_BREAK                          0x0006
-#define CHANNEL_ERRORTYPE_DATA_TRANSMISSION_IMPOSSIBLE        0x8000
-#define CHANNEL_ERRORTYPE_NETWORK_COMPONENT_FUNCTION_MISMATCH 0x8008
-#define EXTENDED_CHANNEL_ERRORTYPE_FRAME_DROPPED              0x8000
-#define EXTENDED_CHANNEL_ERRORTYPE_MAUTYPE_MISMATCH           0x8001
-#define EXTENDED_CHANNEL_ERRORTYPE_LINE_DELAY_MISMATCH        0x8002
-
-#define APP_ALARM_USI                       0x0010
-#define APP_DIAG_CHANNEL_NUMBER             4
-#define APP_DIAG_CHANNEL_DIRECTION          PNET_DIAG_CH_PROP_DIR_INPUT
-#define APP_DIAG_CHANNEL_NUMBER_OF_BITS     PNET_DIAG_CH_PROP_TYPE_1_BIT
-#define APP_DIAG_CHANNEL_SEVERITY           PNET_DIAG_CH_PROP_MAINT_FAULT
-#define APP_DIAG_CHANNEL_ERRORTYPE          CHANNEL_ERRORTYPE_SHORT_CIRCUIT
-#define APP_DIAG_CHANNEL_ADDVALUE_A         0
-#define APP_DIAG_CHANNEL_ADDVALUE_B         1234
-#define APP_DIAG_CHANNEL_EXTENDED_ERRORTYPE 0
-#define APP_DIAG_CHANNEL_QUAL_SEVERITY      0 /* Not used (Max one bit set) */
-
-typedef enum app_demo_state
-{
-   APP_DEMO_STATE_ALARM_SEND = 0,
-   APP_DEMO_STATE_LOGBOOK_ENTRY,
-   APP_DEMO_STATE_ABORT_AR,
-   APP_DEMO_STATE_CYCLIC_REDUNDANT,
-   APP_DEMO_STATE_CYCLIC_NORMAL,
-   APP_DEMO_STATE_DIAG_STD_ADD,
-   APP_DEMO_STATE_DIAG_STD_UPDATE,
-   APP_DEMO_STATE_DIAG_STD_REMOVE,
-   APP_DEMO_STATE_DIAG_USI_ADD,
-   APP_DEMO_STATE_DIAG_USI_UPDATE,
-   APP_DEMO_STATE_DIAG_USI_REMOVE,
-} app_demo_state_t;
-
-typedef struct app_data_t
-{
-   pnet_t * net;
-
-   /* P-Net configuration passed in app_init(). */
-   const pnet_cfg_t * pnet_cfg;
-
-   /* Application API for administration of plugged
-    * (sub)modules and connection state. */
-   app_api_t main_api;
-
-   os_timer_t * main_timer;
-   os_event_t * main_events;
-
-   bool alarm_allowed;
-   pnet_alarm_argument_t alarm_arg;
-   app_demo_state_t alarm_demo_state;
-   uint8_t alarm_payload[APP_GSDML_ALARM_PAYLOAD_SIZE];
-
-   bool button1_pressed;
-   bool button2_pressed;
-   bool button2_pressed_previous;
-
-   /* Counters used to control when buttons are checked
-    * and process data is updated */
-   uint32_t buttons_tick_counter;
-   uint32_t process_data_tick_counter;
-
-} app_data_t;
-
-/* Forward declarations */
-static void app_plug_dap (app_data_t * app, uint16_t number_of_ports);
-static int app_set_initial_data_and_ioxs (app_data_t * app);
-static void app_cyclic_data_callback (app_subslot_t * subslot, void * tag);
-
-/** Static app data */
-static app_data_t app_state;
-
-pnet_t * app_get_pnet_instance (app_data_t * app)
-{
-   if (app == NULL)
-   {
-      return NULL;
-   }
-
-   return app->net;
-}
-
-/** Check if we are connected to the controller
- *
- * @param app             InOut:    Application handle
- * @return true if we are connected to the IO-controller
- */
-static bool app_is_connected_to_controller (app_data_t * app)
-{
-   return app->main_api.ar[0].arep != UINT32_MAX;
-}
-
-app_data_t * app_init (const pnet_cfg_t * pnet_cfg, const app_args_t * app_args)
-{
-   app_data_t * app;
-   uint16_t i;
-
-   APP_LOG_INFO ("Init P-Net stack and sample application\n");
-
-   app = &app_state;
-
-   app->alarm_allowed = true;
-   for (i = 0; i < PNET_MAX_AR; ++i)
-   {
-      app->main_api.ar[i].arep = UINT32_MAX;
-      app->main_api.ar[i].events = 0;
-   }
-   app->pnet_cfg = pnet_cfg;
-
-   app->net = pnet_init (app->pnet_cfg);
-
-   if (app->net == NULL)
-   {
-      return NULL;
-   }
-
-   return app;
-}
-
-/**
- * Callback for timer tick.
- *
- * This is a callback for the timer defined in OSAL.
- * See \a os_timer_create() for details.
- *
- * @param timer   InOut: Timer instance
- * @param arg     InOut: User defined argument, app_data_t pointer
- */
-static void main_timer_tick (os_timer_t * timer, void * arg)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   os_event_set (app->main_events, APP_EVENT_TIMER);
-}
-
-int app_start (app_data_t * app, app_run_in_separate_task_t task_config)
-{
-   APP_LOG_INFO ("Start sample application main loop\n");
-   if (app == NULL)
-   {
-      return -1;
-   }
-
-   app->main_events = os_event_create();
-   if (app->main_events == NULL)
-   {
-      return -1;
-   }
-
-   app->main_timer = os_timer_create (
-      APP_TICK_INTERVAL_US,
-      main_timer_tick,
-      (void *)app,
-      false);
-
-   if (app->main_timer == NULL)
-   {
-      os_event_destroy (app->main_events);
-      return -1;
-   }
-
-   if (task_config == RUN_IN_SEPARATE_THREAD)
-   {
-      os_thread_create (
-         "p-net_sample_app",
-         APP_MAIN_THREAD_PRIORITY,
-         APP_MAIN_THREAD_STACKSIZE,
-         app_loop_forever,
-         (void *)app);
-   }
-
-   os_timer_start (app->main_timer);
-
-   return 0;
-}
-
-/**
- * Set outputs to default value
- */
-static void app_set_outputs_default_value (void)
-{
-   APP_LOG_DEBUG ("Setting outputs to default values.\n");
-   app_data_set_default_outputs();
-}
-
-/**
- * Set event flag(s) for one arep.
- */
-static void app_event_set (
-   app_data_t * app,
-   uint32_t arep,
-   uint32_t event,
-   bool add_arep)
-{
-   app_ar_iterator_t iter;
-   app_ar_t * ar;
-
-   app_ar_iterator_init (&iter, &app->main_api);
-   while (app_ar_iterator_next (&iter, &ar))
-   {
-      if (app_ar_arep (ar) == arep)
-      {
-         app_ar_event_set (ar, event);
-         break;
-      }
-   }
-   if (add_arep)
-   {
-      if (app_ar_iterator_done (&iter))
-      {
-         if (app_ar_add_arep (&app->main_api, arep, &ar))
-         {
-            app_ar_event_set (ar, event);
-         }
-      }
-   }
-   os_event_set (app->main_events, event);
-}
-
-/*********************************** Callbacks ********************************/
-
-static int app_connect_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG ("PLC connect indication. AREP: %u\n", arep);
-   /*
-    *  Handle the request on an application level.
-    *  This is a very simple application which does not need to handle anything.
-    *  All the needed information is in the AR data structure.
-    */
-
-   return 0;
-}
-
-static int app_release_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG ("PLC release (disconnect) indication. AREP: %u\n", arep);
-
-   app_set_outputs_default_value();
-
-   return 0;
-}
-
-static int app_dcontrol_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_control_command_t control_command,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG (
-      "PLC dcontrol message (The PLC is done with parameter writing). "
-      "AREP: %u  Command: %s\n",
-      arep,
-      app_utils_dcontrol_cmd_to_string (control_command));
-
-   return 0;
-}
-
-static int app_sm_released_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t api,
-   uint16_t slot_number,
-   uint16_t subslot_number,
-   pnet_result_t * p_result)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "SM released indication.\n"
-      "  AREP: %u API: %u Slot: 0x%x Subslot: 0x%x\n",
-      arep,
-      api,
-      slot_number,
-      subslot_number);
-
-   app_event_set (app, arep, APP_EVENT_SM_RELEASED, false);
-
-   return 0;
-}
-
-static int app_ccontrol_cnf (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG (
-      "PLC ccontrol message confirmation (The PLC has received our Application "
-      "Ready message). AREP: %u  Status codes: %d %d %d %d\n",
-      arep,
-      p_result->pnio_status.error_code,
-      p_result->pnio_status.error_decode,
-      p_result->pnio_status.error_code_1,
-      p_result->pnio_status.error_code_2);
-
-   return 0;
-}
-
-static int app_write_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint16_t idx,
-   uint16_t sequence_number,
-   uint16_t write_length,
-   const uint8_t * p_write_data,
-   pnet_result_t * p_result)
-{
-   int result = 0;
-   app_data_t * app = (app_data_t *)arg;
-   app_subslot_t * subslot;
-   APP_LOG_DEBUG (
-      "PLC write record indication.\n"
-      "  AREP: %u API: %u Slot: %2u Subslot: %u Index: %u Sequence: %2u "
-      "Length: %u\n",
-      arep,
-      api,
-      slot_nbr,
-      subslot_nbr,
-      (unsigned)idx,
-      sequence_number,
-      write_length);
-
-   subslot = app_utils_subslot_get (&app->main_api, slot_nbr, subslot_nbr);
-   if (subslot == NULL)
-   {
-      APP_LOG_WARNING (
-         "No submodule plugged in AREP: %u API: %u Slot: %2u Subslot: %u "
-         "Index will not be written.\n",
-         arep,
-         api,
-         slot_nbr,
-         subslot_nbr);
-      p_result->pnio_status.error_code = PNET_ERROR_CODE_WRITE;
-      p_result->pnio_status.error_decode = PNET_ERROR_DECODE_PNIORW;
-      p_result->pnio_status.error_code_1 = PNET_ERROR_CODE_1_APP_WRITE_ERROR;
-      p_result->pnio_status.error_code_2 = 0; /* User specific */
-
-      return -1;
-   }
-
-   result = app_data_write_parameter (
-      slot_nbr,
-      subslot_nbr,
-      subslot->submodule_id,
-      idx,
-      p_write_data,
-      write_length);
-   if (result != 0)
-   {
-      APP_LOG_WARNING (
-         "Failed to write index for AREP: %u API: %u Slot: %2u Subslot: %u "
-         "index %u.\n",
-         arep,
-         api,
-         slot_nbr,
-         subslot_nbr,
-         idx);
-      p_result->pnio_status.error_code = PNET_ERROR_CODE_WRITE;
-      p_result->pnio_status.error_decode = PNET_ERROR_DECODE_PNIORW;
-      p_result->pnio_status.error_code_1 = PNET_ERROR_CODE_1_APP_WRITE_ERROR;
-      p_result->pnio_status.error_code_2 = 0; /* User specific */
-   }
-
-   return result;
-}
-
-static int app_read_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint16_t idx,
-   uint16_t sequence_number,
-   uint8_t ** pp_read_data,
-   uint16_t * p_read_length,
-   pnet_result_t * p_result)
-{
-   int result = 0;
-   app_data_t * app = (app_data_t *)arg;
-   app_subslot_t * subslot;
-
-   APP_LOG_DEBUG (
-      "PLC read record indication.\n"
-      "  AREP: %u API: %u Slot: %2u Subslot: %u Index: %u Sequence: %2u Max "
-      "length: %u\n",
-      arep,
-      api,
-      slot_nbr,
-      subslot_nbr,
-      (unsigned)idx,
-      sequence_number,
-      (unsigned)*p_read_length);
-
-   subslot = app_utils_subslot_get (&app->main_api, slot_nbr, subslot_nbr);
-   if (subslot == NULL)
-   {
-      APP_LOG_WARNING (
-         "No submodule plugged in AREP: %u API: %u Slot: %2u Subslot: %u "
-         "Index will not be read.\n",
-         arep,
-         api,
-         slot_nbr,
-         subslot_nbr);
-      p_result->pnio_status.error_code = PNET_ERROR_CODE_READ;
-      p_result->pnio_status.error_decode = PNET_ERROR_DECODE_PNIORW;
-      p_result->pnio_status.error_code_1 = PNET_ERROR_CODE_1_APP_READ_ERROR;
-      p_result->pnio_status.error_code_2 = 0; /* User specific */
-      return -1;
-   }
-
-   result = app_data_read_parameter (
-      slot_nbr,
-      subslot_nbr,
-      subslot->submodule_id,
-      idx,
-      pp_read_data,
-      p_read_length);
-
-   if (result != 0)
-   {
-      APP_LOG_WARNING (
-         "Failed to read index for AREP: %u API: %u Slot: %2u Subslot: %u "
-         "index %u.\n",
-         arep,
-         api,
-         slot_nbr,
-         subslot_nbr,
-         idx);
-      p_result->pnio_status.error_code = PNET_ERROR_CODE_READ;
-      p_result->pnio_status.error_decode = PNET_ERROR_DECODE_PNIORW;
-      p_result->pnio_status.error_code_1 = PNET_ERROR_CODE_1_APP_READ_ERROR;
-      p_result->pnio_status.error_code_2 = 0; /* User specific */
-   }
-
-   return result;
-}
-
-static int app_state_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_event_values_t event)
-{
-   uint16_t err_cls = 0;  /* Error code 1 */
-   uint16_t err_code = 0; /* Error code 2 */
-   const char * error_class_description = "";
-   const char * error_code_description = "";
-
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "Event indication %s   AREP: %u\n",
-      app_utils_event_to_string (event),
-      arep);
-
-   if (event == PNET_EVENT_ABORT)
-   {
-      if (pnet_get_ar_error_codes (net, arep, &err_cls, &err_code) == 0)
-      {
-         app_utils_get_error_code_strings (
-            err_cls,
-            err_code,
-            &error_class_description,
-            &error_code_description);
-         APP_LOG_DEBUG (
-            "    Error class: 0x%02x %s \n"
-            "    Error code:  0x%02x %s \n",
-            (unsigned)err_cls,
-            error_class_description,
-            (unsigned)err_code,
-            error_code_description);
-      }
-      else
-      {
-         APP_LOG_DEBUG ("    No error status available\n");
-      }
-      /* Set output values */
-      app_set_outputs_default_value();
-
-      app_event_set (app, arep, APP_EVENT_ABORT, false);
-   }
-   else if (event == PNET_EVENT_PRMEND)
-   {
-      app_set_initial_data_and_ioxs (app);
-
-      (void)pnet_set_provider_state (net, true);
-
-      /* Send application ready at next tick
-         Do not call pnet_application_ready() here as it will affect
-         the internal stack states */
-      app_event_set (app, arep, APP_EVENT_READY_FOR_DATA, true);
-   }
-   else if (event == PNET_EVENT_DATA)
-   {
-      APP_LOG_DEBUG ("Cyclic data transmission started\n\n");
-   }
-
-   return 0;
-}
-
-static int app_reset_ind (
-   pnet_t * net,
-   void * arg,
-   bool should_reset_application,
-   uint16_t reset_mode)
-{
-   APP_LOG_DEBUG (
-      "PLC reset indication. Application reset mandatory: %u  Reset mode: %d\n",
-      should_reset_application,
-      reset_mode);
-
-   return 0;
-}
-
-static int app_signal_led_ind (pnet_t * net, void * arg, bool led_state)
-{
-   APP_LOG_INFO ("Profinet signal LED indication. New state: %u\n", led_state);
-
-   app_set_led (APP_PROFINET_SIGNAL_LED_ID, led_state);
-   return 0;
-}
-
-static int app_exp_module_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t api,
-   uint16_t slot,
-   uint32_t module_ident)
-{
-   int ret = -1;
-   int result = 0;
-   app_data_t * app = (app_data_t *)arg;
-   const char * module_name = "unknown";
-   const app_gsdml_module_t * module_config;
-
-   APP_LOG_DEBUG ("Module plug indication\n");
-
-   if (slot >= PNET_MAX_SLOTS)
-   {
-      APP_LOG_ERROR (
-         "Wrong slot number received: %u  It should be less than %u\n",
-         slot,
-         PNET_MAX_SLOTS);
-      return -1;
-   }
-
-   module_config = app_gsdml_get_module_cfg (module_ident);
-   if (module_config == NULL)
-   {
-      APP_LOG_ERROR ("  Module ID %08x not found.\n", (unsigned)module_ident);
-      /*
-       * Needed to pass Behavior scenario 2
-       */
-      APP_LOG_DEBUG ("  Plug expected module anyway\n");
-   }
-   else
-   {
-      module_name = module_config->name;
-   }
-
-   APP_LOG_DEBUG ("  Pull old module.    API: %u Slot: %2u\n", api, slot);
-   result = pnet_pull_module (net, api, slot);
-
-   if (result == 0)
-   {
-      (void)app_utils_pull_module (&app->main_api, slot);
-   }
-
-   APP_LOG_DEBUG (
-      "  Plug module.        API: %u Slot: %2u Module ID: 0x%x \"%s\"\n",
-      api,
-      slot,
-      (unsigned)module_ident,
-      module_name);
-
-   ret = pnet_plug_module (net, api, slot, module_ident);
-   if (ret == 0)
-   {
-      (void)app_utils_plug_module (
-         &app->main_api,
-         slot,
-         module_ident,
-         module_name);
-   }
-   else
-   {
-      APP_LOG_ERROR (
-         "Plug module failed. Ret: %u API: %u Slot: %2u Module ID: 0x%x\n",
-         ret,
-         api,
-         slot,
-         (unsigned)module_ident);
-   }
-
-   return ret;
-}
-
-static int app_exp_submodule_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t api,
-   uint16_t slot,
-   uint16_t subslot,
-   uint32_t module_id,
-   uint32_t submodule_id,
-   const pnet_data_cfg_t * p_exp_data)
-{
-   int ret = -1;
-   int result = 0;
-   pnet_data_cfg_t data_cfg = {0};
-   app_data_t * app = (app_data_t *)arg;
-   const app_gsdml_submodule_t * submod_cfg;
-   const char * name = "Unsupported";
-   app_utils_cyclic_callback cyclic_data_callback = NULL;
-
-   APP_LOG_DEBUG ("Submodule plug indication.\n");
-
-   submod_cfg = app_gsdml_get_submodule_cfg (submodule_id);
-   if (submod_cfg != NULL)
-   {
-      data_cfg.data_dir = submod_cfg->data_dir;
-      data_cfg.insize = submod_cfg->insize;
-      data_cfg.outsize = submod_cfg->outsize;
-      name = submod_cfg->name;
-
-      if (data_cfg.insize > 0 || data_cfg.outsize > 0)
-      {
-         cyclic_data_callback = app_cyclic_data_callback;
-      }
-   }
-   else
-   {
-      APP_LOG_WARNING (
-         "  Submodule ID 0x%x in module ID 0x%x not found. API: %u Slot: %2u "
-         "Subslot %u \n",
-         (unsigned)submodule_id,
-         (unsigned)module_id,
-         api,
-         slot,
-         subslot);
-
-      /*
-       * Needed for behavior scenario 2 to pass.
-       * Iops will be set to bad for this subslot
-       */
-      APP_LOG_WARNING ("  Plug expected submodule anyway \n");
-
-      data_cfg.data_dir = p_exp_data->data_dir;
-      data_cfg.insize = p_exp_data->insize;
-      data_cfg.outsize = p_exp_data->outsize;
-   }
-
-   APP_LOG_DEBUG (
-      "  Pull old submodule. API: %u Slot: %2u Subslot: %u\n",
-      api,
-      slot,
-      subslot);
-
-   result = pnet_pull_submodule (net, api, slot, subslot);
-   if (result == 0)
-   {
-      (void)app_utils_pull_submodule (&app->main_api, slot, subslot);
-   }
-
-   APP_LOG_DEBUG (
-      "  Plug submodule.     API: %u Slot: %2u Module ID: 0x%-4x\n"
-      "                      Subslot: %u Submodule ID: 0x%x \"%s\"\n",
-      api,
-      slot,
-      (unsigned)module_id,
-      subslot,
-      (unsigned)submodule_id,
-      name);
-
-   APP_LOG_DEBUG (
-      "                      Data Dir: %s  In: %u bytes  Out: %u bytes\n",
-      app_utils_submod_dir_to_string (data_cfg.data_dir),
-      data_cfg.insize,
-      data_cfg.outsize);
-
-   if (
-      data_cfg.data_dir != p_exp_data->data_dir ||
-      data_cfg.insize != p_exp_data->insize ||
-      data_cfg.outsize != p_exp_data->outsize)
-   {
-      APP_LOG_WARNING (
-         "    Warning expected  Data Dir: %s  In: %u bytes  Out: %u bytes\n",
-         app_utils_submod_dir_to_string (p_exp_data->data_dir),
-         p_exp_data->insize,
-         p_exp_data->outsize);
-   }
-   ret = pnet_plug_submodule (
-      net,
-      api,
-      slot,
-      subslot,
-      module_id,
-      submodule_id,
-      data_cfg.data_dir,
-      data_cfg.insize,
-      data_cfg.outsize);
-
-   if (ret == 0)
-   {
-      (void)app_utils_plug_submodule (
-         &app->main_api,
-         slot,
-         subslot,
-         submodule_id,
-         &data_cfg,
-         name,
-         cyclic_data_callback,
-         app);
-   }
-   else
-   {
-      APP_LOG_ERROR (
-         "  Plug submodule failed. Ret: %u API: %u Slot: %2u Subslot %u "
-         "Module ID: 0x%x Submodule ID: 0x%x \n",
-         ret,
-         api,
-         slot,
-         subslot,
-         (unsigned)module_id,
-         (unsigned)submodule_id);
-   }
-
-   return ret;
-}
-
-static int app_new_data_status_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t crep,
-   uint8_t changes,
-   uint8_t data_status)
-{
-   bool is_running = data_status & BIT (PNET_DATA_STATUS_BIT_PROVIDER_STATE);
-   bool is_valid = data_status & BIT (PNET_DATA_STATUS_BIT_DATA_VALID);
-
-   APP_LOG_DEBUG (
-      "Data status indication. AREP: %u  Data status changes: 0x%02x  "
-      "Data status: 0x%02x\n",
-      arep,
-      changes,
-      data_status);
-   APP_LOG_DEBUG (
-      "   %s, %s, %s, %s, %s\n",
-      is_running ? "Run" : "Stop",
-      is_valid ? "Valid" : "Invalid",
-      (data_status & BIT (PNET_DATA_STATUS_BIT_STATE)) ? "Primary" : "Backup",
-      (data_status & BIT (PNET_DATA_STATUS_BIT_STATION_PROBLEM_INDICATOR))
-         ? "Normal operation"
-         : "Problem",
-      (data_status & BIT (PNET_DATA_STATUS_BIT_IGNORE))
-         ? "Ignore data status"
-         : "Evaluate data status");
-
-   if (is_running == false || is_valid == false)
-   {
-      app_set_outputs_default_value();
-   }
-
-   return 0;
-}
-
-static int app_alarm_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   const pnet_alarm_argument_t * p_alarm_arg,
-   uint16_t data_len,
-   uint16_t data_usi,
-   const uint8_t * p_data)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "Alarm indication. AREP: %u API: %d Slot: %d Subslot: %d "
-      "Type: %d Seq: %d Length: %d USI: %d\n",
-      arep,
-      p_alarm_arg->api_id,
-      p_alarm_arg->slot_nbr,
-      p_alarm_arg->subslot_nbr,
-      p_alarm_arg->alarm_type,
-      p_alarm_arg->sequence_number,
-      data_len,
-      data_usi);
-
-   app->alarm_arg = *p_alarm_arg;
-
-   app_event_set (app, arep, APP_EVENT_ALARM, false);
-
-   return 0;
-}
-
-static int app_alarm_cnf (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   const pnet_pnio_status_t * p_pnio_status)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "PLC alarm confirmation. AREP: %u  Status code %u, "
-      "%u, %u, %u\n",
-      arep,
-      p_pnio_status->error_code,
-      p_pnio_status->error_decode,
-      p_pnio_status->error_code_1,
-      p_pnio_status->error_code_2);
-
-   app->alarm_allowed = true;
-
-   return 0;
-}
-
-static int app_alarm_ack_cnf (pnet_t * net, void * arg, uint32_t arep, int res)
-{
-   APP_LOG_DEBUG (
-      "PLC alarm ACK confirmation. AREP: %u  Result: "
-      "%d\n",
-      arep,
-      res);
-
-   return 0;
-}
-
-/******************************************************************************/
-
-/**
- * Plug all DAP (sub)modules
- * Use existing callback functions to plug the (sub-)modules
- * @param app              InOut:   Application handle
- * @param number_of_ports  In:      Number of active ports
- */
-static void app_plug_dap (app_data_t * app, uint16_t number_of_ports)
-{
-   const pnet_data_cfg_t cfg_dap_data = {
-      .data_dir = PNET_DIR_NO_IO,
-      .insize = 0,
-      .outsize = 0,
-   };
-
-   APP_LOG_DEBUG ("\nPlug DAP module and its submodules\n");
-
-   app_exp_module_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_MOD_DAP_IDENT);
-
-   app_exp_submodule_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_SUBSLOT_DAP_IDENT,
-      PNET_MOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_IDENT,
-      &cfg_dap_data);
-
-   app_exp_submodule_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_SUBSLOT_DAP_INTERFACE_1_IDENT,
-      PNET_MOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_IDENT,
-      &cfg_dap_data);
-
-   app_exp_submodule_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_SUBSLOT_DAP_INTERFACE_1_PORT_1_IDENT,
-      PNET_MOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
-      &cfg_dap_data);
-
-   if (number_of_ports >= 2)
-   {
-      app_exp_submodule_ind (
-         app->net,
-         app,
-         APP_GSDML_API,
-         PNET_SLOT_DAP_IDENT,
-         PNET_SUBSLOT_DAP_INTERFACE_1_PORT_2_IDENT,
-         PNET_MOD_DAP_IDENT,
-         PNET_SUBMOD_DAP_INTERFACE_1_PORT_2_IDENT,
-         &cfg_dap_data);
-   }
-
-   if (number_of_ports >= 3)
-   {
-      app_exp_submodule_ind (
-         app->net,
-         app,
-         APP_GSDML_API,
-         PNET_SLOT_DAP_IDENT,
-         PNET_SUBSLOT_DAP_INTERFACE_1_PORT_3_IDENT,
-         PNET_MOD_DAP_IDENT,
-         PNET_SUBMOD_DAP_INTERFACE_1_PORT_3_IDENT,
-         &cfg_dap_data);
-   }
-
-   if (number_of_ports >= 4)
-   {
-      app_exp_submodule_ind (
-         app->net,
-         app,
-         APP_GSDML_API,
-         PNET_SLOT_DAP_IDENT,
-         PNET_SUBSLOT_DAP_INTERFACE_1_PORT_4_IDENT,
-         PNET_MOD_DAP_IDENT,
-         PNET_SUBMOD_DAP_INTERFACE_1_PORT_4_IDENT,
-         &cfg_dap_data);
-   }
-
-   APP_LOG_DEBUG ("Done plugging DAP\n\n");
-}
-
-/**
- * Handle cyclic input- and output data for a subslot.
- *
- * Data is read and written using functions in the .c file,
- * which handles the data and update the physical input and outputs.
- *
- * @param subslot    InOut: Subslot reference
- * @param tag        In:    Application handle, here \a app_data_t pointer
- */
-static void app_cyclic_data_callback (app_subslot_t * subslot, void * tag)
-{
-   app_data_t * app = (app_data_t *)tag;
-   uint8_t indata_iops = PNET_IOXS_BAD;
-   uint8_t indata_iocs = PNET_IOXS_BAD;
-   uint8_t * indata;
-   uint16_t indata_size = 0;
-   bool outdata_updated;
-   uint16_t outdata_length;
-   uint8_t outdata_iops;
-   uint8_t outdata_buf[20]; /* Todo: Remove temporary buffer */
-
-   if (app == NULL)
-   {
-      APP_LOG_ERROR ("Application tag not set in subslot?\n");
-      return;
-   }
-
-   if (subslot->slot_nbr != PNET_SLOT_DAP_IDENT && subslot->data_cfg.outsize > 0)
-   {
-      outdata_length = subslot->data_cfg.outsize;
-      CC_ASSERT (outdata_length < sizeof (outdata_buf));
-
-      /* Get output data from the PLC */
-      (void)pnet_output_get_data_and_iops (
-         app->net,
-         APP_GSDML_API,
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         &outdata_updated,
-         outdata_buf,
-         &outdata_length,
-         &outdata_iops);
-
-      app_utils_print_ioxs_change (
-         subslot,
-         "Provider Status (IOPS)",
-         subslot->outdata_iops,
-         outdata_iops);
-      subslot->outdata_iops = outdata_iops;
-
-      if (outdata_length != subslot->data_cfg.outsize)
-      {
-         APP_LOG_ERROR ("Wrong outputdata length: %u\n", outdata_length);
-         app_set_outputs_default_value();
-      }
-      else if (outdata_iops == PNET_IOXS_GOOD)
-      {
-         /* Application specific handling of the output data to a submodule.
-            For the sample application, the data sets a LED. */
-         (void)app_data_set_output_data (
-            subslot->slot_nbr,
-            subslot->subslot_nbr,
-            subslot->submodule_id,
-            outdata_buf,
-            outdata_length);
-      }
-      else
-      {
-         app_set_outputs_default_value();
-      }
-   }
-
-   if (subslot->slot_nbr != PNET_SLOT_DAP_IDENT && subslot->data_cfg.insize > 0)
-   {
-      /* Get application specific input data from a submodule (not DAP)
-       *
-       * For the sample application, the data includes a button
-       * state and a counter value. */
-      indata = app_data_get_input_data (
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         subslot->submodule_id,
-         app->button1_pressed,
-         &indata_size,
-         &indata_iops);
-
-      /* Send input data to the PLC */
-      (void)pnet_input_set_data_and_iops (
-         app->net,
-         APP_GSDML_API,
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         indata,
-         indata_size,
-         indata_iops);
-
-      (void)pnet_input_get_iocs (
-         app->net,
-         APP_GSDML_API,
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         &indata_iocs);
-
-      app_utils_print_ioxs_change (
-         subslot,
-         "Consumer Status (IOCS)",
-         subslot->indata_iocs,
-         indata_iocs);
-      subslot->indata_iocs = indata_iocs;
-   }
-}
-
-/**
- * Set initial input data, provider and consumer status for a subslot.
- *
- * @param app              In:    Application handle
- */
-static int app_set_initial_data_and_ioxs (app_data_t * app)
-{
-   int ret;
-   uint16_t slot;
-   uint16_t subslot_index;
-   const app_subslot_t * p_subslot;
-   uint8_t * indata;
-   uint16_t indata_size;
-   uint8_t indata_iops;
-
-   for (slot = 0; slot < PNET_MAX_SLOTS; slot++)
-   {
-      for (subslot_index = 0; subslot_index < PNET_MAX_SUBSLOTS;
-           subslot_index++)
-      {
-         p_subslot = &app->main_api.slots[slot].subslots[subslot_index];
-         if (p_subslot->plugged)
-         {
-            indata = NULL;
-            indata_size = 0;
-            indata_iops = PNET_IOXS_BAD;
-
-            if (
-               p_subslot->data_cfg.insize > 0 ||
-               p_subslot->data_cfg.data_dir == PNET_DIR_NO_IO)
-            {
-
-               /* Get input data for submodule
-                *
-                * For the sample application data includes
-                * includes button state and a counter value
-                */
-               if (
-                  p_subslot->slot_nbr != PNET_SLOT_DAP_IDENT &&
-                  p_subslot->data_cfg.insize > 0)
-               {
-                  indata = app_data_get_input_data (
-                     p_subslot->slot_nbr,
-                     p_subslot->subslot_nbr,
-                     p_subslot->submodule_id,
-                     app->button1_pressed,
-                     &indata_size,
-                     &indata_iops);
-               }
-               else if (p_subslot->slot_nbr == PNET_SLOT_DAP_IDENT)
-               {
-                  indata_iops = PNET_IOXS_GOOD;
-               }
-
-               ret = pnet_input_set_data_and_iops (
-                  app->net,
-                  app->main_api.api_id,
-                  p_subslot->slot_nbr,
-                  p_subslot->subslot_nbr,
-                  indata,
-                  indata_size,
-                  indata_iops);
-
-               /*
-                * If a submodule is still plugged but not used in current AR,
-                * setting the data and IOPS will fail.
-                * This is not a problem.
-                * Log message below will only be printed for active submodules.
-                */
-               if (ret == 0)
-               {
-                  APP_LOG_DEBUG (
-                     "  Set initial input data and IOPS for slot %2u subslot "
-                     "%5u %9s size %3d \"%s\" \n",
-                     p_subslot->slot_nbr,
-                     p_subslot->subslot_nbr,
-                     app_utils_ioxs_to_string (indata_iops),
-                     p_subslot->data_cfg.insize,
-                     p_subslot->submodule_name);
-               }
-            }
-
-            if (p_subslot->data_cfg.outsize > 0)
-            {
-               ret = pnet_output_set_iocs (
-                  app->net,
-                  app->main_api.api_id,
-                  p_subslot->slot_nbr,
-                  p_subslot->subslot_nbr,
-                  PNET_IOXS_GOOD);
-
-               if (ret == 0)
-               {
-                  APP_LOG_DEBUG (
-                     "  Set initial output         IOCS for slot %2u subslot "
-                     "%5u %9s          \"%s\"\n",
-                     p_subslot->slot_nbr,
-                     p_subslot->subslot_nbr,
-                     app_utils_ioxs_to_string (PNET_IOXS_GOOD),
-                     p_subslot->submodule_name);
-               }
-            }
-         }
-      }
-   }
-   return 0;
-}
-
-/**
- * Send and receive cyclic/process data for all subslots.
- *
- * Updates the data only on every APP_TICKS_UPDATE_DATA invocation
- *
- * @param app        In:    Application handle
- */
-static void app_handle_cyclic_data (app_data_t * app)
-{
-   /* For the sample application cyclic data is updated
-    * with a period defined by APP_TICKS_UPDATE_DATA
-    */
-   app->process_data_tick_counter++;
-   if (app->process_data_tick_counter < APP_TICKS_UPDATE_DATA)
-   {
-      return;
-   }
-   app->process_data_tick_counter = 0;
-
-   app_utils_cyclic_data_poll (&app->main_api);
-}
-
-/**
- * Set alarm, diagnostics and logbook entries.
- *
- * Alternates between these functions each time the button2 is pressed:
- *  - pnet_alarm_send_process_alarm()
- *  - pnet_diag_std_add()
- *  - pnet_set_redundancy_state()
- *  - pnet_set_state()
- *  - pnet_diag_std_update()
- *  - pnet_diag_usi_add()
- *  - pnet_diag_usi_update()
- *  - pnet_diag_usi_remove()
- *  - pnet_diag_std_remove()
- *  - pnet_create_log_book_entry()
- *  - pnet_ar_abort()
- *
- * Uses first 8-bit digital input module, if available.
- *
- * @param app             InOut:    Application handle
- */
-static void app_handle_demo_pnet_api (app_data_t * app)
-{
-   uint16_t slot = 0;
-   bool found_inputsubslot = false;
-   uint16_t subslot_ix = 0;
-   const app_subslot_t * p_subslot = NULL;
-   pnet_pnio_status_t pnio_status = {0};
-   pnet_diag_source_t diag_source = {
-      .api = APP_GSDML_API,
-      .slot = 0,
-      .subslot = 0,
-      .ch = APP_DIAG_CHANNEL_NUMBER,
-      .ch_grouping = PNET_DIAG_CH_INDIVIDUAL_CHANNEL,
-      .ch_direction = APP_DIAG_CHANNEL_DIRECTION};
-
-   /* Loop though all subslots to find first digital 8-bit input subslot */
-   while (!found_inputsubslot && (slot < PNET_MAX_SLOTS))
-   {
-      for (subslot_ix = 0;
-           !found_inputsubslot && (subslot_ix < PNET_MAX_SUBSLOTS);
-           subslot_ix++)
-      {
-         p_subslot = &app->main_api.slots[slot].subslots[subslot_ix];
-         if (
-            app_utils_subslot_is_input (p_subslot) &&
-            (p_subslot->submodule_id == APP_GSDML_SUBMOD_ID_DIGITAL_IN ||
-             p_subslot->submodule_id == APP_GSDML_SUBMOD_ID_DIGITAL_IN_OUT))
-         {
-            found_inputsubslot = true;
-            break;
-         }
-      }
-      if (!found_inputsubslot)
-      {
-         slot++;
-      }
-   }
-   if (!found_inputsubslot)
-   {
-      APP_LOG_DEBUG ("Did not find any input module in the slots. Skipping.\n");
-      return;
-   }
-
-   diag_source.slot = slot;
-   diag_source.subslot = p_subslot->subslot_nbr;
-
-   switch (app->alarm_demo_state)
-   {
-   case APP_DEMO_STATE_ALARM_SEND:
-      if (app->alarm_allowed == true && app_is_connected_to_controller (app))
-      {
-         app->alarm_payload[0]++;
-         APP_LOG_INFO (
-            "Sending process alarm from slot %u subslot %u USI %u to "
-            "PLC. Payload: 0x%x\n",
-            slot,
-            p_subslot->subslot_nbr,
-            APP_ALARM_USI,
-            app->alarm_payload[0]);
-         pnet_alarm_send_process_alarm (
-            app->net,
-            app->main_api.ar[0].arep,
-            APP_GSDML_API,
-            slot,
-            p_subslot->subslot_nbr,
-            APP_ALARM_USI,
-            APP_GSDML_ALARM_PAYLOAD_SIZE,
-            app->alarm_payload);
-         app->alarm_allowed = false; /* Not allowed until ACK received */
-
-         /* todo handle return code on pnet_alarm_send_process_alarm */
-      }
-      else
-      {
-         APP_LOG_WARNING (
-            "Could not send process alarm, as alarm_allowed == false or "
-            "no connection available\n");
-      }
-      break;
-
-   case APP_DEMO_STATE_CYCLIC_REDUNDANT:
-      APP_LOG_INFO (
-         "Setting cyclic data to backup and to redundant. See Wireshark.\n");
-      if (pnet_set_primary_state (app->net, false) != 0)
-      {
-         APP_LOG_WARNING ("   Could not set cyclic data state to backup.\n");
-      }
-      if (pnet_set_redundancy_state (app->net, true) != 0)
-      {
-         APP_LOG_WARNING ("   Could not set cyclic data state to redundant.\n");
-      }
-      break;
-
-   case APP_DEMO_STATE_CYCLIC_NORMAL:
-      APP_LOG_INFO (
-         "Setting cyclic data back to primary and non-redundant. See "
-         "Wireshark.\n");
-      if (pnet_set_primary_state (app->net, true) != 0)
-      {
-         APP_LOG_ERROR ("   Could not set cyclic data state to primary.\n");
-      }
-      if (pnet_set_redundancy_state (app->net, false) != 0)
-      {
-         APP_LOG_ERROR (
-            "   Could not set cyclic data state to non-redundant.\n");
-      }
-      break;
-
-   case APP_DEMO_STATE_DIAG_STD_ADD:
-      APP_LOG_INFO (
-         "Adding standard diagnosis. Slot %u subslot %u channel %u Errortype "
-         "%u\n",
-         diag_source.slot,
-         diag_source.subslot,
-         diag_source.ch,
-         APP_DIAG_CHANNEL_ERRORTYPE);
-      (void)pnet_diag_std_add (
-         app->net,
-         &diag_source,
-         APP_DIAG_CHANNEL_NUMBER_OF_BITS,
-         APP_DIAG_CHANNEL_SEVERITY,
-         APP_DIAG_CHANNEL_ERRORTYPE,
-         APP_DIAG_CHANNEL_EXTENDED_ERRORTYPE,
-         APP_DIAG_CHANNEL_ADDVALUE_A,
-         APP_DIAG_CHANNEL_QUAL_SEVERITY);
-      break;
-
-   case APP_DEMO_STATE_DIAG_STD_UPDATE:
-      APP_LOG_INFO (
-         "Updating standard diagnosis. Slot %u subslot %u channel %u\n",
-         diag_source.slot,
-         diag_source.subslot,
-         diag_source.ch);
-      pnet_diag_std_update (
-         app->net,
-         &diag_source,
-         APP_DIAG_CHANNEL_ERRORTYPE,
-         APP_DIAG_CHANNEL_EXTENDED_ERRORTYPE,
-         APP_DIAG_CHANNEL_ADDVALUE_B);
-      break;
-
-   case APP_DEMO_STATE_DIAG_STD_REMOVE:
-      APP_LOG_INFO (
-         "Removing standard diagnosis. Slot %u subslot %u channel %u\n",
-         diag_source.slot,
-         diag_source.subslot,
-         diag_source.ch);
-      pnet_diag_std_remove (
-         app->net,
-         &diag_source,
-         APP_DIAG_CHANNEL_ERRORTYPE,
-         APP_DIAG_CHANNEL_EXTENDED_ERRORTYPE);
-      break;
-
-   case APP_DEMO_STATE_DIAG_USI_ADD:
-      APP_LOG_INFO (
-         "Adding USI diagnosis. Slot %u subslot %u\n",
-         slot,
-         p_subslot->subslot_nbr);
-      pnet_diag_usi_add (
-         app->net,
-         APP_GSDML_API,
-         slot,
-         p_subslot->subslot_nbr,
-         APP_GSDML_DIAG_CUSTOM_USI,
-         11,
-         (uint8_t *)"diagdata_1");
-      break;
-
-   case APP_DEMO_STATE_DIAG_USI_UPDATE:
-      APP_LOG_INFO (
-         "Updating USI diagnosis. Slot %u subslot %u\n",
-         slot,
-         p_subslot->subslot_nbr);
-      pnet_diag_usi_update (
-         app->net,
-         APP_GSDML_API,
-         slot,
-         p_subslot->subslot_nbr,
-         APP_GSDML_DIAG_CUSTOM_USI,
-         13,
-         (uint8_t *)"diagdata_123");
-      break;
-
-   case APP_DEMO_STATE_DIAG_USI_REMOVE:
-      APP_LOG_INFO (
-         "Removing USI diagnosis. Slot %u subslot %u\n",
-         slot,
-         p_subslot->subslot_nbr);
-      pnet_diag_usi_remove (
-         app->net,
-         APP_GSDML_API,
-         slot,
-         p_subslot->subslot_nbr,
-         APP_GSDML_DIAG_CUSTOM_USI);
-      break;
-
-   case APP_DEMO_STATE_LOGBOOK_ENTRY:
-      if (app_is_connected_to_controller (app))
-      {
-         APP_LOG_INFO (
-            "Writing to logbook. Error_code1: %02X Error_code2: %02X  Entry "
-            "detail: 0x%08X\n",
-            APP_GSDML_LOGBOOK_ERROR_CODE_1,
-            APP_GSDML_LOGBOOK_ERROR_CODE_2,
-            APP_GSDML_LOGBOOK_ENTRY_DETAIL);
-         pnio_status.error_code = APP_GSDML_LOGBOOK_ERROR_CODE;
-         pnio_status.error_decode = APP_GSDML_LOGBOOK_ERROR_DECODE;
-         pnio_status.error_code_1 = APP_GSDML_LOGBOOK_ERROR_CODE_1;
-         pnio_status.error_code_2 = APP_GSDML_LOGBOOK_ERROR_CODE_2;
-         pnet_create_log_book_entry (
-            app->net,
-            app->main_api.ar[0].arep,
-            &pnio_status,
-            APP_GSDML_LOGBOOK_ENTRY_DETAIL);
-      }
-      else
-      {
-         APP_LOG_WARNING (
-            "Could not add logbook entry as no connection is available\n");
-      }
-      break;
-
-   case APP_DEMO_STATE_ABORT_AR:
-      if (app_is_connected_to_controller (app))
-      {
-         APP_LOG_INFO (
-            "Sample app will disconnect and reconnect. Executing "
-            "pnet_ar_abort()  AREP: %u\n",
-            app->main_api.ar[0].arep);
-         (void)pnet_ar_abort (app->net, app->main_api.ar[0].arep);
-      }
-      else
-      {
-         APP_LOG_WARNING (
-            "Could not execute pnet_ar_abort(), as no connection is "
-            "available\n");
-      }
-      break;
-   }
-
-   switch (app->alarm_demo_state)
-   {
-   case APP_DEMO_STATE_ALARM_SEND:
-      app->alarm_demo_state = APP_DEMO_STATE_CYCLIC_REDUNDANT;
-      break;
-   case APP_DEMO_STATE_CYCLIC_REDUNDANT:
-      app->alarm_demo_state = APP_DEMO_STATE_CYCLIC_NORMAL;
-      break;
-   case APP_DEMO_STATE_CYCLIC_NORMAL:
-      app->alarm_demo_state = APP_DEMO_STATE_DIAG_STD_ADD;
-      break;
-   case APP_DEMO_STATE_DIAG_STD_ADD:
-      app->alarm_demo_state = APP_DEMO_STATE_DIAG_STD_UPDATE;
-      break;
-   case APP_DEMO_STATE_DIAG_STD_UPDATE:
-      app->alarm_demo_state = APP_DEMO_STATE_DIAG_USI_ADD;
-      break;
-   case APP_DEMO_STATE_DIAG_USI_ADD:
-      app->alarm_demo_state = APP_DEMO_STATE_DIAG_USI_UPDATE;
-      break;
-   case APP_DEMO_STATE_DIAG_USI_UPDATE:
-      app->alarm_demo_state = APP_DEMO_STATE_DIAG_USI_REMOVE;
-      break;
-   case APP_DEMO_STATE_DIAG_USI_REMOVE:
-      app->alarm_demo_state = APP_DEMO_STATE_DIAG_STD_REMOVE;
-      break;
-   case APP_DEMO_STATE_DIAG_STD_REMOVE:
-      app->alarm_demo_state = APP_DEMO_STATE_LOGBOOK_ENTRY;
-      break;
-   case APP_DEMO_STATE_LOGBOOK_ENTRY:
-      app->alarm_demo_state = APP_DEMO_STATE_ABORT_AR;
-      break;
-   default:
-   case APP_DEMO_STATE_ABORT_AR:
-      app->alarm_demo_state = APP_DEMO_STATE_ALARM_SEND;
-      break;
-   }
-}
-
-void app_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg)
-{
-   app_utils_pnet_cfg_init_default (pnet_cfg);
-
-   pnet_cfg->state_cb = app_state_ind;
-   pnet_cfg->connect_cb = app_connect_ind;
-   pnet_cfg->release_cb = app_release_ind;
-   pnet_cfg->dcontrol_cb = app_dcontrol_ind;
-   pnet_cfg->ccontrol_cb = app_ccontrol_cnf;
-   pnet_cfg->read_cb = app_read_ind;
-   pnet_cfg->write_cb = app_write_ind;
-   pnet_cfg->exp_module_cb = app_exp_module_ind;
-   pnet_cfg->exp_submodule_cb = app_exp_submodule_ind;
-   pnet_cfg->new_data_status_cb = app_new_data_status_ind;
-   pnet_cfg->alarm_ind_cb = app_alarm_ind;
-   pnet_cfg->alarm_cnf_cb = app_alarm_cnf;
-   pnet_cfg->alarm_ack_cnf_cb = app_alarm_ack_cnf;
-   pnet_cfg->reset_cb = app_reset_ind;
-   pnet_cfg->signal_led_cb = app_signal_led_ind;
-   pnet_cfg->sm_released_cb = app_sm_released_ind;
-
-   pnet_cfg->cb_arg = (void *)&app_state;
-}
-
-/**
- * Read button states from operating system
- *
- * Actual reading is done every APP_TICKS_READ_BUTTONS invocation
- *
- * @param app             InOut:    Application handle
- */
-static void update_button_states (app_data_t * app)
-{
-   app->buttons_tick_counter++;
-   if (app->buttons_tick_counter > APP_TICKS_READ_BUTTONS)
-   {
-      app->button1_pressed = app_get_button (0);
-      app->button2_pressed = app_get_button (1);
-      app->buttons_tick_counter = 0;
-   }
-}
-
-/* Event handlers for the main loop. */
-
-static void app_handle_event_timer (app_data_t * app)
-{
-   os_event_clr (app->main_events, APP_EVENT_TIMER);
-
-   update_button_states (app);
-   if (app_is_connected_to_controller (app))
-   {
-      app_handle_cyclic_data (app);
-   }
-
-   /* Run alarm demo function if button2 is pressed */
-   if ((app->button2_pressed == true) && (app->button2_pressed_previous == false))
-   {
-      app_handle_demo_pnet_api (app);
-   }
-   app->button2_pressed_previous = app->button2_pressed;
-
-   /* Run p-net stack */
-   pnet_handle_periodic (app->net);
-}
-
-/**
- * Handle AR specific events.
- *
- * Calls the \a handler for each AR that has a pending \a event.
- *
- * @param app              InOut: Application handle
- * @param event            In:    Event
- * @param handler          In:    Event handling function
- */
-static void app_handle_event_ar (
-   app_data_t * app,
-   uint32_t event,
-   app_ar_event_handler_t handler)
-{
-   app_ar_iterator_t iter;
-   app_ar_t * ar;
-
-   os_event_clr (app->main_events, event);
-   app_ar_iterator_init (&iter, &app->main_api);
-   while (app_ar_iterator_next (&iter, &ar))
-   {
-      if (app_ar_event_clr (ar, event))
-      {
-         if (handler (app, app_ar_arep (ar)))
-         {
-            app_ar_iterator_delete_current (&iter);
-         }
-      }
-   }
-}
-
-/* AR specific event handlers */
-
-/**
- * Handle an AR connection PrmEnd.
- *
- * @param app              InOut: Application handle
- * @param arep             In:    Arep
- *
- * @return 0 to indicate that the arep should not be removed.
- */
-static int app_ar_ready_for_data_handler (app_data_t * app, uint32_t arep)
-{
-   int err;
-
-   APP_LOG_DEBUG (
-      "Application will signal that it is ready for data, for AREP %u.\n",
-      arep);
-   /* When the PLC sends a confirmation to this message, the
-      pnet_ccontrol_cnf() callback will be triggered.  */
-   err = pnet_application_ready (app->net, arep);
-   if (err)
-   {
-      APP_LOG_ERROR (
-         "Error returned when application telling that it is ready for "
-         "data. Have you set IOCS or IOPS for all subslots?\n");
-   }
-   return 0;
-}
-
-/**
- * Handle an AR alarm.
- *
- * @param app              InOut: Application handle
- * @param arep             In:    Arep
- *
- * @return 0 to indicate that the arep should not be removed.
- */
-static int app_ar_alarm_handler (app_data_t * app, uint32_t arep)
-{
-   pnet_pnio_status_t pnio_status = {0, 0, 0, 0};
-   int err;
-
-   err = pnet_alarm_send_ack (app->net, arep, &app->alarm_arg, &pnio_status);
-   if (err)
-   {
-      APP_LOG_DEBUG ("Error when sending alarm ACK. Error: %d\n", err);
-   }
-   else
-   {
-      APP_LOG_DEBUG ("Alarm ACK sent\n");
-   }
-   return 0;
-}
-
-/**
- * Handle a released submodule.
- *
- * @param app              InOut: Application handle
- * @param arep             In:    Arep
- *
- * @return 0 to indicate that the arep should not be removed.
- */
-static int app_ar_sm_released_handler (app_data_t * app, uint32_t arep)
-{
-   /* Ideally, we should only set data for the indicated submodule,
-      but setting everything works. */
-   app_set_initial_data_and_ioxs (app);
-   pnet_sm_released_cnf (app->net, arep);
-   return 0;
-}
-
-/**
- * Handle an AR abort.
- *
- * @param app              InOut: Application handle
- * @param arep             In:    Arep
- *
- * @return 1 to indicate that the arep should be removed.
- */
-static int app_ar_abort_handler (app_data_t * app, uint32_t arep)
-{
-   APP_LOG_DEBUG ("Connection (AREP %u) closed\n", arep);
-   return 1;
-}
-
-/**
- * Wait for events generated elsewhere in this program.
- *
- * @param app              InOut: Application handle
- * @param mask             In:    Bitmask of events to wait for
- * @param flags            Out:   Bitmask of pending events
- */
-static void app_event_wait (app_data_t * app, uint32_t mask, uint32_t * flags)
-{
-   os_event_wait (app->main_events, mask, flags, OS_WAIT_FOREVER);
-}
-
-void app_loop_forever (void * arg)
-{
-   app_data_t * app = (app_data_t *)arg;
-   uint32_t mask = APP_EVENT_READY_FOR_DATA | APP_EVENT_TIMER |
-                   APP_EVENT_ALARM | APP_EVENT_SM_RELEASED | APP_EVENT_ABORT;
-   uint32_t flags = 0;
-
-   app_set_led (APP_DATA_LED_ID, false);
-   app_plug_dap (app, app->pnet_cfg->num_physical_ports);
-   APP_LOG_INFO ("Waiting for PLC connect request\n\n");
-
-   /* Main event loop */
-   for (;;)
-   {
-      app_event_wait (app, mask, &flags);
-      if (flags & APP_EVENT_READY_FOR_DATA)
-      {
-         app_handle_event_ar (
-            app,
-            APP_EVENT_READY_FOR_DATA,
-            app_ar_ready_for_data_handler);
-      }
-      if (flags & APP_EVENT_ALARM)
-      {
-         app_handle_event_ar (app, APP_EVENT_ALARM, app_ar_alarm_handler);
-      }
-      if (flags & APP_EVENT_TIMER)
-      {
-         app_handle_event_timer (app);
-      }
-      if (flags & APP_EVENT_SM_RELEASED)
-      {
-         app_handle_event_ar (
-            app,
-            APP_EVENT_SM_RELEASED,
-            app_ar_sm_released_handler);
-      }
-      if (flags & APP_EVENT_ABORT)
-      {
-         app_handle_event_ar (app, APP_EVENT_ABORT, app_ar_abort_handler);
-         app->alarm_allowed = true;
-      }
-   }
-}

+ 0 - 169
samples/pn_dev/sampleapp_common.h

@@ -1,169 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2018 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef SAMPLEAPP_COMMON_H
-#define SAMPLEAPP_COMMON_H
-
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define APP_TICK_INTERVAL_US 1000 /* 1 ms */
-
-/* Thread configuration for targets where sample
- * event loop is run in a separate thread (not main).
- * This applies for linux sample app implementation.
- */
-#define APP_MAIN_THREAD_PRIORITY  15
-#define APP_MAIN_THREAD_STACKSIZE 4096 /* bytes */
-
-#define APP_DATA_LED_ID            1
-#define APP_PROFINET_SIGNAL_LED_ID 2
-
-#define APP_TICKS_READ_BUTTONS 10
-#define APP_TICKS_UPDATE_DATA  100
-
-/** HW Offload configuration. */
-typedef enum
-{
-   MODE_HW_OFFLOAD_NONE = 0,
-   MODE_HW_OFFLOAD_CPU,
-   MODE_HW_OFFLOAD_FULL,
-} app_mode_t;
-
-/** Command line arguments for sample application */
-typedef struct app_args
-{
-   char path_button1[PNET_MAX_FILE_FULLPATH_SIZE]; /** Terminated string */
-   char path_button2[PNET_MAX_FILE_FULLPATH_SIZE]; /** Terminated string */
-   char path_storage_directory[PNET_MAX_DIRECTORYPATH_SIZE]; /** Terminated */
-   char station_name[PNET_STATION_NAME_MAX_SIZE]; /** Terminated string */
-   char eth_interfaces
-      [PNET_INTERFACE_NAME_MAX_SIZE * (PNET_MAX_PHYSICAL_PORTS + 1) +
-       PNET_MAX_PHYSICAL_PORTS]; /** Terminated string */
-   int verbosity;
-   int show;
-   bool factory_reset;
-   bool remove_files;
-   app_mode_t mode;
-} app_args_t;
-
-typedef enum
-{
-   RUN_IN_SEPARATE_THREAD,
-   RUN_IN_MAIN_THREAD
-} app_run_in_separate_task_t;
-
-typedef struct app_data_t app_data_t;
-
-/**
- * AR specific event handler type.
- *
- * Handles an AR specific event.
- *
- * @param app          InOut: Application handle
- * @param arep         In:    Arep of the AR.
- *
- * @return 0 to indicate that the arep should be kept
- *         1 to indicate that the arep should be forgotten
- */
-typedef int (*app_ar_event_handler_t) (app_data_t * app, uint32_t arep);
-
-/** Partially initialise config values, and use proper callbacks
- *
- * @param pnet_cfg     Out:   Configuration to be updated
- */
-void app_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg);
-
-/**
- * Initialize P-Net stack and application.
- *
- * The \a pnet_cfg argument shall have been initialized using
- * \a app_pnet_cfg_init_default() before this function is
- * called.
- *
- * @param pnet_cfg               In:    P-Net configuration
- * @param app_args               In:    Application arguments
- * @return Application handle, NULL on error
- */
-app_data_t * app_init (const pnet_cfg_t * pnet_cfg, const app_args_t * app_args);
-
-/**
- * Start application main loop
- *
- * Application must have been initialized using \a app_init() before
- * this function is called.
- *
- * If \a task_config parameters is set to RUN_IN_SEPARATE_THREAD a
- * thread execution the \a app_loop_forever() function is started.
- * If task_config is set to RUN_IN_MAIN_THREAD no such thread is
- * started and the caller must call the \a app_loop_forever() after
- * calling this function.
- *
- * RUN_IN_MAIN_THREAD is intended for rt-kernel targets.
- * RUN_IN_SEPARATE_THREAD is intended for linux targets.
- *
- * @param app                 In:    Application handle
- * @param task_config         In:    Defines if stack and application
- *                                   is run in main or separate task.
- * @return 0 on success, -1 on error
- */
-int app_start (app_data_t * app, app_run_in_separate_task_t task_config);
-
-/**
- * Application task definition. Handles events in eternal loop.
- *
- * @param arg                 In: Application handle
- */
-void app_loop_forever (void * arg);
-
-/**
- * Get P-Net instance from application
- *
- * @param app                 In:    Application handle
- * @return P-Net instance, NULL on failure
- */
-pnet_t * app_get_pnet_instance (app_data_t * app);
-
-/**
- * Set LED state
- * Hardware specific. Implemented in sample app main file for
- * each supported platform.
- *
- * @param id               In:    LED number, starting from 0.
- * @param led_state        In:    LED state. Use true for on and false for off.
- */
-void app_set_led (uint16_t id, bool led_state);
-
-/**
- * Read button state
- *
- * Hardware specific. Implemented in sample app main file for
- * each supported platform.
- *
- * @param id               In:    Button number, starting from 0.
- * @return  true if button is pressed, false if not
- */
-bool app_get_button (uint16_t id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SAMPLEAPP_COMMON_H */

+ 0 - 23
samples/pn_dev_lan9662/CMakeLists.txt

@@ -1,23 +0,0 @@
-#********************************************************************
-#        _       _         _
-#  _ __ | |_  _ | |  __ _ | |__   ___
-# | '__|| __|(_)| | / _` || '_ \ / __|
-# | |   | |_  _ | || (_| || |_) |\__ \
-# |_|    \__|(_)|_| \__,_||_.__/ |___/
-#
-# http://www.rt-labs.com
-# Copyright 2017 rt-labs AB, Sweden.
-# See LICENSE file in the project root for full license information.
-#*******************************************************************/
-
-target_include_directories(pn_lan9662
-  PRIVATE
-  ${PROFINET_SOURCE_DIR}/src
-  ${PROFINET_SOURCE_DIR}/src/drivers/lan9662
-  ${PROFINET_BINARY_DIR}/src
-  )
-
-
-target_link_libraries (pn_lan9662 PUBLIC profinet mera)
-
-install (TARGETS pn_lan9662 DESTINATION bin)

+ 0 - 417
samples/pn_dev_lan9662/GSDML-V2.4-RT-Labs-P-Net-LAN9662-20220511.xml

@@ -1,417 +0,0 @@
-<?xml version="1.0" encoding="iso-8859-1"?>
-<ISO15745Profile xmlns="http://www.profibus.com/GSDML/2003/11/DeviceProfile" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.profibus.com/GSDML/2003/11/DeviceProfile ..\xsd\GSDML-DeviceProfile-V2.4.xsd">
-   <!-- ProfileHeader definition as defined in ISO 15745-1. Please do not change the content. -->
-   <ProfileHeader>
-      <ProfileIdentification>PROFINET Device Profile</ProfileIdentification>
-      <ProfileRevision>1.00</ProfileRevision>
-      <ProfileName>Device Profile for PROFINET Devices</ProfileName>
-      <ProfileSource>PROFIBUS Nutzerorganisation e. V. (PNO)</ProfileSource>
-      <ProfileClassID>Device</ProfileClassID>
-      <ISO15745Reference>
-         <ISO15745Part>4</ISO15745Part>
-         <ISO15745Edition>1</ISO15745Edition>
-         <ProfileTechnology>GSDML</ProfileTechnology>
-      </ISO15745Reference>
-   </ProfileHeader>
-   <ProfileBody>
-      <DeviceIdentity VendorID="0x0493" DeviceID="0x9662">
-         <InfoText TextId="IDT_INFO_Device"/>
-         <VendorName Value="RT-Labs"/>
-      </DeviceIdentity>
-      <DeviceFunction>
-         <Family MainFamily="I/O" ProductFamily="P-Net Samples"/>
-      </DeviceFunction>
-      <ApplicationProcess>
-         <DeviceAccessPointList>
-            <DeviceAccessPointItem ID="IDD_1" PNIO_Version="V2.4" PhysicalSlots="0..12" ModuleIdentNumber="0x00000001" MinDeviceInterval="32" DNS_CompatibleName="lan9662-dev" FixedInSlots="0" ObjectUUID_LocalIndex="1" DeviceAccessSupported="false" MultipleWriteSupported="true" CheckDeviceID_Allowed="true" NameOfStationNotTransferable="false" LLDP_NoD_Supported="true" ResetToFactoryModes="1..2">
-               <ModuleInfo>
-                  <Name TextId="IDT_MODULE_NAME_DAP1"/>
-                  <InfoText TextId="IDT_INFO_DAP1"/>
-                  <VendorName Value="RT-Labs"/>
-                  <OrderNumber Value="12345 Abcdefghijk"/>
-                  <HardwareRelease Value="A1.0"/>
-                  <SoftwareRelease Value="V0.1.0"/>
-               </ModuleInfo>
-               <CertificationInfo ConformanceClass="A" ApplicationClass="" NetloadClass="I"/>
-               <IOConfigData MaxInputLength="1440" MaxOutputLength="1440"/>
-               <UseableModules>
-                  <ModuleItemRef ModuleItemTarget="IDM_1" AllowedInSlots="1"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_2" AllowedInSlots="2"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_3" AllowedInSlots="3"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_4" AllowedInSlots="4"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_5" AllowedInSlots="5"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_6" AllowedInSlots="6"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_7" AllowedInSlots="7"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_8" AllowedInSlots="8"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_9" AllowedInSlots="9"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_10" AllowedInSlots="10"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_11" AllowedInSlots="11"/>
-                  <ModuleItemRef ModuleItemTarget="IDM_12" AllowedInSlots="12"/>
-               </UseableModules>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDS_1" SubmoduleIdentNumber="0x00000001" Writeable_IM_Records="1 2 3" MayIssueProcessAlarm="false">
-                     <IOData/>
-                     <ModuleInfo>
-                        <Name TextId="IDT_MODULE_NAME_DAP1"/>
-                        <InfoText TextId="IDT_INFO_DAP1"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-               <SystemDefinedSubmoduleList>
-                  <InterfaceSubmoduleItem ID="IDS_I" SubmoduleIdentNumber="0x00008000" SubslotNumber="32768" TextId="IDT_NAME_IS" SupportedRT_Classes="RT_CLASS_1" SupportedProtocols="LLDP" NetworkComponentDiagnosisSupported="false" PTP_BoundarySupported="true" DCP_BoundarySupported="true">
-                     <ApplicationRelations StartupMode="Advanced">
-                        <TimingProperties SendClock="32" ReductionRatio="1 2 4 8 16 32 64 128 256 512"/>
-                     </ApplicationRelations>
-                  </InterfaceSubmoduleItem>
-                  <PortSubmoduleItem ID="IDS_P1" SubmoduleIdentNumber="0x00008001" SubslotNumber="32769" TextId="IDT_NAME_PS1" MaxPortRxDelay="350" MaxPortTxDelay="160">
-                     <MAUTypeList>
-                        <MAUTypeItem Value="30"/>
-                        <MAUTypeItem Value="16"/>
-                        <MAUTypeItem Value="5"/>
-                     </MAUTypeList>
-                  </PortSubmoduleItem>
-                  <PortSubmoduleItem ID="IDS_P2" SubmoduleIdentNumber="0x00008002" SubslotNumber="32770" TextId="IDT_NAME_PS2" MaxPortRxDelay="350" MaxPortTxDelay="160">
-                     <MAUTypeList>
-                        <MAUTypeItem Value="30"/>
-                        <MAUTypeItem Value="16"/>
-                        <MAUTypeItem Value="5"/>
-                     </MAUTypeList>
-                  </PortSubmoduleItem>
-               </SystemDefinedSubmoduleList>
-            </DeviceAccessPointItem>
-         </DeviceAccessPointList>
-         <ModuleList>
-            <ModuleItem ID="IDM_1" ModuleIdentNumber="0x00001001">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_1"/>
-                  <InfoText TextId="TOK_InfoText_Module_1"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_1" SubmoduleIdentNumber="0x00002001" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Unsigned8" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_1"/>
-                        <InfoText TextId="TOK_InfoText_Module_1"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_2" ModuleIdentNumber="0x00001002">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_2"/>
-                  <InfoText TextId="TOK_InfoText_Module_2"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_2" SubmoduleIdentNumber="0x00002002" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned8" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_2"/>
-                        <InfoText TextId="TOK_InfoText_Module_2"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_3" ModuleIdentNumber="0x00001003">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_3"/>
-                  <InfoText TextId="TOK_InfoText_Module_3"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_3" SubmoduleIdentNumber="0x00002003" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Unsigned64" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_3"/>
-                        <InfoText TextId="TOK_InfoText_Module_3"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_4" ModuleIdentNumber="0x00001004">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_4"/>
-                  <InfoText TextId="TOK_InfoText_Module_4"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_4" SubmoduleIdentNumber="0x00002004" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_4"/>
-                        <InfoText TextId="TOK_InfoText_Module_4"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_5" ModuleIdentNumber="0x00001005">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_5"/>
-                  <InfoText TextId="TOK_InfoText_Module_5"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_5" SubmoduleIdentNumber="0x00002005" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_5"/>
-                        <InfoText TextId="TOK_InfoText_Module_5"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_6" ModuleIdentNumber="0x00001006">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_6"/>
-                  <InfoText TextId="TOK_InfoText_Module_6"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_6" SubmoduleIdentNumber="0x00002006" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="OctetString" Length="100" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_6"/>
-                        <InfoText TextId="TOK_InfoText_Module_6"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_7" ModuleIdentNumber="0x00001007">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_7"/>
-                  <InfoText TextId="TOK_InfoText_Module_7"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_7" SubmoduleIdentNumber="0x00002007" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned64" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_7"/>
-                        <InfoText TextId="TOK_InfoText_Module_7"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_8" ModuleIdentNumber="0x00001008">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_8"/>
-                  <InfoText TextId="TOK_InfoText_Module_8"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_8" SubmoduleIdentNumber="0x00002008" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_8"/>
-                        <InfoText TextId="TOK_InfoText_Module_8"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_9" ModuleIdentNumber="0x00001009">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_9"/>
-                  <InfoText TextId="TOK_InfoText_Module_9"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_9" SubmoduleIdentNumber="0x00002009" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                           <DataItem DataType="Unsigned32" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_9"/>
-                        <InfoText TextId="TOK_InfoText_Module_9"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_10" ModuleIdentNumber="0x0000100A">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_10"/>
-                  <InfoText TextId="TOK_InfoText_Module_10"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_10" SubmoduleIdentNumber="0x0000200A" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="OctetString" Length="100" TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_10"/>
-                        <InfoText TextId="TOK_InfoText_Module_10"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-            <ModuleItem ID="IDM_11" ModuleIdentNumber="0x0000100B">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_11"/>
-                  <InfoText TextId="TOK_InfoText_Module_11"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_11" SubmoduleIdentNumber="0x0000200B" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Input Consistency="All items consistency">
-                           <DataItem DataType="Unsigned32"  TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Input>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_11"/>
-                        <InfoText TextId="TOK_InfoText_Module_11"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-             <ModuleItem ID="IDM_12" ModuleIdentNumber="0x0000100C">
-               <ModuleInfo>
-                  <Name TextId="TOK_Name_Module_12"/>
-                  <InfoText TextId="TOK_InfoText_Module_12"/>
-                  <HardwareRelease Value="1.0"/>
-                  <SoftwareRelease Value="1.0"/>
-               </ModuleInfo>
-               <VirtualSubmoduleList>
-                  <VirtualSubmoduleItem ID="IDSM_12" SubmoduleIdentNumber="0x0000200C" MayIssueProcessAlarm="false">
-                     <IOData>
-                        <Output Consistency="All items consistency">
-                           <DataItem DataType="Unsigned32"  TextId="TOK_Dummy" UseAsBits="false">
-                           </DataItem>
-                        </Output>
-                     </IOData>
-                     <ModuleInfo>
-                        <Name TextId="TOK_Name_Module_12"/>
-                        <InfoText TextId="TOK_InfoText_Module_12"/>
-                     </ModuleInfo>
-                  </VirtualSubmoduleItem>
-               </VirtualSubmoduleList>
-            </ModuleItem>
-         </ModuleList>
-         <LogBookEntryList>
-            <LogBookEntryItem Status="2130510">
-               <!--Custom log book entry for sample application-->
-               <!--Error code 0x20  Error decode 0x82  Error code 1 0x4E-->
-               <ErrorCode2Value>
-                  <Name TextId="IDT_CUSTOM_LOGBOOK_1"/>
-               </ErrorCode2Value>
-            </LogBookEntryItem>
-         </LogBookEntryList>
-         <GraphicsList>
-            <GraphicItem ID="RT-LabsStackImage" GraphicFile="GSDML-RT-LABS-STACK" />
-         </GraphicsList>
-         <ExternalTextList>
-            <PrimaryLanguage>
-               <Text TextId="IDT_INFO_Device" Value="https://github.com/rtlabs-com/p-net"/>
-               <Text TextId="IDT_MODULE_NAME_DAP1" Value="P-Net LAN9662 Sample"/>
-               <Text TextId="IDT_INFO_DAP1" Value="Profinet LAN9662 sample https://github.com/rtlabs-com/p-net"/>
-               <Text TextId="IDT_CUSTOM_DIAG_1" Value="Custom diagnosis in USI format"/>
-               <Text TextId="IDT_CUSTOM_DIAG_1_VALUE" Value="Custom diagnosis value"/>
-               <Text TextId="IDT_CUSTOM_LOGBOOK_1" Value="Custom Logbook entry"/>
-
-               <Text TextId="IDT_NAME_IS" Value="X1"/>
-               <Text TextId="IDT_NAME_PS1" Value="X1 P1"/>
-               <Text TextId="IDT_NAME_PS2" Value="X1 P2"/>
-
-               <!--module names-->
-               <Text TextId="TOK_Name_Module_1" Value="DI 1x8"/>
-               <Text TextId="TOK_Name_Module_2" Value="DO 1x8"/>
-               <Text TextId="TOK_Name_Module_3" Value="DI 1x64"/>
-               <Text TextId="TOK_Name_Module_4" Value="DI 2x32a"/>
-               <Text TextId="TOK_Name_Module_5" Value="DI 2x32b"/>
-               <Text TextId="TOK_Name_Module_6" Value="DI 1x800"/>
-               <Text TextId="TOK_Name_Module_7" Value="DO 1x64"/>
-               <Text TextId="TOK_Name_Module_8" Value="DO 2x32a"/>
-               <Text TextId="TOK_Name_Module_9" Value="DO 2x32b"/>
-               <Text TextId="TOK_Name_Module_10" Value="DO 1x800"/>
-               <Text TextId="TOK_Name_Module_11" Value="DI Port A"/>
-               <Text TextId="TOK_Name_Module_12" Value="DO Port A"/>
-
-               <!--module info -->
-               <Text TextId="TOK_InfoText_Module_1" Value="Digital In 1x8"/>
-               <Text TextId="TOK_InfoText_Module_2" Value="Digital Out 1x8"/>
-               <Text TextId="TOK_InfoText_Module_3" Value="Digital In 1x64"/>
-               <Text TextId="TOK_InfoText_Module_4" Value="Digital In 2x32"/>
-               <Text TextId="TOK_InfoText_Module_5" Value="Digital In 2x32"/>
-               <Text TextId="TOK_InfoText_Module_6" Value="Digital In 1x800"/>
-               <Text TextId="TOK_InfoText_Module_7" Value="Digital Out 1x64"/>
-               <Text TextId="TOK_InfoText_Module_8" Value="Digital Out 2x32"/>
-               <Text TextId="TOK_InfoText_Module_9" Value="Digital Out 2x32"/>
-               <Text TextId="TOK_InfoText_Module_10" Value="Digital Out 1x800"/>
-               <Text TextId="TOK_InfoText_Module_11" Value="Digital In Port A"/>
-               <Text TextId="TOK_InfoText_Module_12" Value="Digital Out Port A"/>
-
-               <!--dataitem name-->
-               <Text TextId="TOK_Dummy" Value="Dummy"/>
-
-            </PrimaryLanguage>
-         </ExternalTextList>
-      </ApplicationProcess>
-   </ProfileBody>
-</ISO15745Profile>

+ 0 - 68
samples/pn_dev_lan9662/S90_start_profinet.sh

@@ -1,68 +0,0 @@
-#!/bin/sh
-#
-# Initialization script for automatic
-# start of the pn_lan9662 sample application.
-# Copy this script to overlay/etc/init.d/
-# to start the application automatically.
-#
-
-start() {
-    # Assume a valid partition on /dev/mmcblk0p2
-    mkdir /tmp/pn_data
-    mount -o sync /dev/mmcblk0p2 /tmp/pn_data
-
-    echo "Configure network settings for pn_lan9662 profinet sample application"
-    # Create bridge
-    ip link add name br0 type bridge
-    symreg ANA_PGID[61] 0x1ff
-    ip link set br0 address 12:A9:2D:16:93:89
-    ip link set br0 up
-    sysctl -w net.ipv6.conf.br0.disable_ipv6=1
-
-    ip link set eth0 master br0
-    ip link set eth1 master br0
-
-    ip link set eth0 up
-    ip link set eth1 up
-
-    # Enable forwarding to chip port 4 (RTE)
-    symreg qsys_sw_port_mode[4] 0x45000
-
-    # Start Profinet application
-    # Supported modes: none, cpu, full
-    # Read mode from file
-    mode="full"
-    if test -f /tmp/pn_data/mode.txt; then
-        mode=$(cat /tmp/pn_data/mode.txt)
-    fi
-
-    echo "Starting LAN9662 Profinet sample application"
-    echo "RTE mode: $mode"
-
-    /usr/bin/pn_lan9662 -m $mode -vvvv -p /tmp/pn_data &
-
-    # Enable for interleaved ART-Tester logs
-    #tcpdump -i br0 udp port 514 -v -a &
-}
-
-stop() {
-    printf "Todo - Stop Profinet application"
-}
-
-case "$1" in
-  start)
-        start
-        ;;
-  stop)
-        stop
-        ;;
-  restart|reload)
-        stop
-        start
-        ;;
-  *)
-        echo "Usage: $0 {start|stop|restart}"
-        exit 1
-esac
-
-exit $?

+ 0 - 442
samples/pn_dev_lan9662/app_data.c

@@ -1,442 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "app_data.h"
-#include "app_shm.h"
-#include "app_utils.h"
-#include "app_gsdml.h"
-#include "app_log.h"
-#include "sampleapp_common.h"
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/**
- * IO FPGA address mapping.
- */
-#define APP_DATA_FPGA_START_ADDRESS 0x100
-#define ALIGN32(x)                  ((((x)) + 3) & ~3)
-
-#define APP_FPGA_ADDRESS_DIGITAL_IN_1x8 (APP_DATA_FPGA_START_ADDRESS)
-#define APP_FPGA_ADDRESS_DIGITAL_OUT_1x8                                       \
-   (APP_FPGA_ADDRESS_DIGITAL_IN_1x8 + ALIGN32 (APP_GSDML_SIZE_DIGITAL_IN_1x8))
-#define APP_FPGA_ADDRESS_DIGITAL_IN_1x64                                       \
-   (APP_FPGA_ADDRESS_DIGITAL_OUT_1x8 + ALIGN32 (APP_GSDML_SIZE_DIGITAL_OUT_1x8))
-#define APP_FPGA_ADDRESS_DIGITAL_IN_2x32a                                      \
-   (APP_FPGA_ADDRESS_DIGITAL_IN_1x64 + ALIGN32 (APP_GSDML_SIZE_DIGITAL_IN_1x64))
-#define APP_FPGA_ADDRESS_DIGITAL_IN_2x32b                                      \
-   (APP_FPGA_ADDRESS_DIGITAL_IN_2x32a +                                        \
-    ALIGN32 (APP_GSDML_SIZE_DIGITAL_IN_2x32a))
-#define APP_FPGA_ADDRESS_DIGITAL_IN_1x800                                      \
-   (APP_FPGA_ADDRESS_DIGITAL_IN_2x32b +                                        \
-    ALIGN32 (APP_GSDML_SIZE_DIGITAL_IN_2x32b))
-#define APP_FPGA_ADDRESS_DIGITAL_OUT_1x64                                      \
-   (APP_FPGA_ADDRESS_DIGITAL_IN_1x800 +                                        \
-    ALIGN32 (APP_GSDML_SIZE_DIGITAL_IN_1x800))
-#define APP_FPGA_ADDRESS_DIGITAL_OUT_2x32a                                     \
-   (APP_FPGA_ADDRESS_DIGITAL_OUT_1x64 +                                        \
-    ALIGN32 (APP_GSDML_SIZE_DIGITAL_OUT_1x64))
-#define APP_FPGA_ADDRESS_DIGITAL_OUT_2x32b                                     \
-   (APP_FPGA_ADDRESS_DIGITAL_OUT_2x32a +                                       \
-    ALIGN32 (APP_GSDML_SIZE_DIGITAL_OUT_2x32a))
-#define APP_FPGA_ADDRESS_DIGITAL_OUT_1x800                                     \
-   (APP_FPGA_ADDRESS_DIGITAL_OUT_2x32b +                                       \
-    ALIGN32 (APP_GSDML_SIZE_DIGITAL_OUT_2x32b))
-
-#define APP_FPGA_ADDRESS_DIGITAL_IN_PORT_A  0x200
-#define APP_FPGA_ADDRESS_DIGITAL_OUT_PORT_A 0x10
-
-typedef struct submodule_fpga_config
-{
-   uint16_t address;
-   const uint8_t * default_data;
-} submodule_fpga_config_t;
-
-typedef struct submodule
-{
-   const app_gsdml_submodule_t * info;
-
-   /* shm -> pnet*/
-   app_shm_t * indata_shm;
-   uint8_t * in_data;
-
-   /* pnet -> shm */
-   app_shm_t * outdata_shm;
-   uint8_t * out_data;
-
-   /* FPGA address for full offload mode */
-   const submodule_fpga_config_t * fpga_config;
-
-} submodule_t;
-
-typedef struct fpga_map
-{
-   uint32_t submodule_id;
-   submodule_fpga_config_t fpga_config;
-} fpga_map_t;
-
-static const uint8_t app_data_default[APP_GSDML_MAX_SUBMODULE_DATA_SIZE] = {0};
-
-/**
- * Configuration of FPGA addresses for the different
- * submodules when running full offload.
- */
-static const fpga_map_t fpga[] = {
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x8,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_IN_1x8,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x8,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_OUT_1x8,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x64,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_IN_1x64,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32a,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_IN_2x32a,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32b,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_IN_2x32b,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x800,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_IN_1x800,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x64,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_OUT_1x64,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32a,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_OUT_2x32a,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32b,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_OUT_2x32b,
-        .default_data = app_data_default}},
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x800,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_OUT_1x800,
-        .default_data = app_data_default}},
-
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_PORT_A,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_IN_PORT_A,
-        .default_data = app_data_default}},
-
-   {.submodule_id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_PORT_A,
-    .fpga_config =
-       {.address = APP_FPGA_ADDRESS_DIGITAL_OUT_PORT_A,
-        .default_data = app_data_default}},
-};
-
-submodule_t submodules[APP_GSDML_MAX_SUBMODULES] = {0};
-
-/**
- * Get a submodule using its submodule id
- * @param id            In:  Submodule id
- * @return Reference to submodule. NULL if id is not found.
- **/
-static submodule_t * get_submodule_by_id (uint32_t id)
-{
-   uint16_t i;
-
-   for (i = 0; i < NELEMENTS (submodules); i++)
-   {
-      if (submodules[i].info != NULL && submodules[i].info->id == id)
-      {
-         return &submodules[i];
-      }
-   }
-
-   return NULL;
-}
-
-/**
- * Get submodule fpga config using its id.
- * @param id            In:  Submodule id
- * @return Reference to fgpa mapping. NULL if id is not found.
- **/
-static const submodule_fpga_config_t * get_fpga_config_by_id (uint32_t id)
-{
-   uint32_t i = 0;
-
-   while (i < NELEMENTS (fpga))
-   {
-      if (fpga[i].submodule_id == id)
-      {
-         return &fpga[i].fpga_config;
-      }
-      i++;
-   }
-   return NULL;
-}
-
-int app_data_get_fpga_info_by_id (
-   uint32_t id,
-   uint16_t * address,
-   const uint8_t ** default_data)
-{
-   const submodule_fpga_config_t * config = get_fpga_config_by_id (id);
-
-   if (config != NULL)
-   {
-      *address = config->address;
-      *default_data = config->default_data;
-      return 0;
-   }
-   return -1;
-}
-
-/**
- * Allocate a submodule from submodules array.
- * The returned submodule is uninitialized.
- * @return Reference to submodule. NULL if allocation fails.
- **/
-static submodule_t * alloc_submodule (void)
-{
-   uint32_t i = 0;
-
-   while (i < NELEMENTS (submodules))
-   {
-      if (submodules[i].info == NULL)
-      {
-         return &submodules[i];
-      }
-      i++;
-   }
-   return NULL;
-}
-
-/**
- * Initialize submodule
- * Set module and submodule configurations.
- * Configure shared memory regions.
- * Allocate buffers.
- * Will generate assert on failure.
- * @param module_cfg       In:  Module configuration
- * @param submodule_cfg    In:  Submodule configuration
- * @param app_mode         In:  Application mode
- **/
-static void app_data_init_submodule (
-   const app_gsdml_module_t * module_cfg,
-   const app_gsdml_submodule_t * submodule_cfg,
-   app_mode_t app_mode)
-{
-   submodule_t * submodule;
-
-   CC_ASSERT (module_cfg != NULL);
-   CC_ASSERT (submodule_cfg != NULL);
-
-   submodule = alloc_submodule();
-   CC_ASSERT (submodule != NULL);
-
-   submodule->info = submodule_cfg;
-   if (app_mode == MODE_HW_OFFLOAD_FULL)
-   {
-      submodule->fpga_config = get_fpga_config_by_id (submodule_cfg->id);
-      CC_ASSERT (submodule->fpga_config != NULL);
-   }
-   else
-   {
-      submodule->fpga_config = NULL;
-   }
-
-   if (submodule->info->insize > 0)
-   {
-      submodule->in_data = malloc (submodule->info->insize);
-      CC_ASSERT (submodule->in_data != NULL);
-
-      if (app_mode != MODE_HW_OFFLOAD_FULL)
-      {
-         submodule->indata_shm = app_shm_create_input (
-            submodule->info->name,
-            module_cfg->fixed_slot,
-            submodule_cfg->fixed_subslot,
-            submodule->info->insize);
-         CC_ASSERT (submodule->indata_shm != NULL);
-      }
-      else
-      {
-         APP_LOG_INFO (
-            "[%u,%u,\"%s\"] mapped to FPGA address 0x%x\n",
-            module_cfg->fixed_slot,
-            submodule_cfg->fixed_subslot,
-            submodule->info->name,
-            submodule->fpga_config->address);
-      }
-   }
-
-   if (submodule->info->outsize > 0)
-   {
-      submodule->out_data = malloc (submodule->info->outsize);
-      CC_ASSERT (submodule->out_data != NULL);
-
-      if (app_mode != MODE_HW_OFFLOAD_FULL)
-      {
-         submodule->outdata_shm = app_shm_create_output (
-            submodule->info->name,
-            module_cfg->fixed_slot,
-            submodule_cfg->fixed_subslot,
-            submodule->info->outsize);
-         CC_ASSERT (submodule->outdata_shm != NULL);
-      }
-      else
-      {
-         APP_LOG_INFO (
-            "[%u,%u,\"%s\"] mapped to FPGA address 0x%x\n",
-            module_cfg->fixed_slot,
-            submodule_cfg->fixed_subslot,
-            submodule->info->name,
-            submodule->fpga_config->address);
-      }
-   }
-}
-
-int app_data_init (app_mode_t app_mode)
-{
-   uint16_t i, j;
-   const app_gsdml_module_t * module_cfg;
-   const app_gsdml_submodule_t * submodule_cfg;
-   uint32_t modules_array_len;
-   const app_gsdml_module_t ** app_gsdml_modules;
-
-   app_gsdml_modules = app_gsdml_get_modules (&modules_array_len);
-
-   for (i = 0; i < modules_array_len; i++)
-   {
-      module_cfg = app_gsdml_modules[i];
-
-      j = 0;
-      while (module_cfg->submodules[j] != 0)
-      {
-         submodule_cfg =
-            app_gsdml_get_submodule_cfg (module_cfg->submodules[j]);
-         app_data_init_submodule (module_cfg, submodule_cfg, app_mode);
-         j++;
-      }
-   }
-   return 0;
-}
-
-uint8_t * app_data_get_input_data (
-   uint32_t submodule_id,
-   uint16_t * size,
-   uint8_t * iops)
-{
-   int error = -1;
-   submodule_t * submodule;
-
-   if (size == NULL || iops == NULL)
-   {
-      return NULL;
-   }
-
-   submodule = get_submodule_by_id (submodule_id);
-
-   if (submodule == NULL)
-   {
-      /* Handle unsupported submodules part of process data */
-      *iops = PNET_IOXS_BAD;
-      return NULL;
-   }
-
-   *size = submodule->info->insize;
-   if (submodule->fpga_config == NULL)
-   {
-      error = app_shm_read (submodule->indata_shm, submodule->in_data, *size);
-      CC_ASSERT (error == 0);
-   }
-   else
-   {
-      /* Input is mapped to FPGA. Data is not available to
-       * application. Use default value set status.
-       * P-Net needs an initial value during initialization.
-       */
-      memcpy (submodule->in_data, submodule->fpga_config->default_data, *size);
-   }
-   *iops = PNET_IOXS_GOOD;
-
-   return submodule->in_data;
-}
-
-uint8_t * app_data_get_output_data_buffer (
-   uint32_t submodule_id,
-   uint16_t * size)
-{
-   submodule_t * submodule = get_submodule_by_id (submodule_id);
-
-   CC_ASSERT (size != NULL);
-   if (submodule == NULL)
-   {
-      *size = 0;
-      return NULL;
-   }
-
-   *size = submodule->info->outsize;
-   return submodule->out_data;
-}
-
-int app_data_set_output_data (
-   uint32_t submodule_id,
-   uint8_t * data,
-   uint16_t size)
-{
-   int error = 0;
-   submodule_t * submodule = get_submodule_by_id (submodule_id);
-
-   if (data == NULL || submodule == NULL || size == 0)
-   {
-      return -1;
-   }
-
-   if (submodule->fpga_config == NULL)
-   {
-      /* Only write shared memory if output is not mapped
-       * to FPGA.
-       */
-      error = app_shm_write (submodule->outdata_shm, data, size);
-   }
-
-   return error;
-}
-
-int app_data_set_default_outputs (void)
-{
-   uint16_t i;
-
-   for (i = 0; i < NELEMENTS (submodules); i++)
-   {
-      if (submodules[i].outdata_shm != NULL)
-      {
-         if (submodules[i].fpga_config == NULL)
-         {
-            /* Only write shared memory if output is not mapped
-             * to FPGA.
-             */
-            app_shm_reset (submodules[i].outdata_shm);
-         }
-      }
-   }
-   return 0;
-}

+ 0 - 121
samples/pn_dev_lan9662/app_data.h

@@ -1,121 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_DATA_H
-#define APP_DATA_H
-
-#include "sampleapp_common.h"
-
-/**
- * @file
- * @brief Sample application data interface
- *
- * Functions for:
- * - Getting input data
- * - Setting output data
- * - Setting default output state
- *
- * In this LAN9662 sample application the submodule data
- * is mapped to shared memory found in /dev/shm on Linux.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-#include <stdbool.h>
-
-/**
- * Initialize data submodules.
- * During the initialization the shared memory areas
- * supported by the application are created and the
- * mapping between the shared memory and the submodules
- * is configured.
- * @param app_mode  In:  Application mode
- * @return 0 on success, -1 on error
- */
-int app_data_init (app_mode_t app_mode);
-
-/**
- * Get PNIO input data using submodule id.
- * When this function is called the mapped shared
- * memory is copied to the submodule input buffer.
- * A reference to the the input buffer is returned.
- * @param submodule_id  In:  Submodule id
- * @param size          Out: Size of pnio data
- * @param iops          Out: Provider status. If for example
- *                           a sensor is failing or a short
- *                           circuit detected on digital
- *                           input this shall be set to BAD.
- *                           Set to BAD for unsupported submodules
- *                           or data can not be provided.
- * @return Reference to PNIO data, NULL on error
- */
-uint8_t * app_data_get_input_data (
-   uint32_t submodule_id,
-   uint16_t * size,
-   uint8_t * iops);
-
-/**
- * Get FPGA data start address for submodule data
- * @param id            In:  Submodule id
- * @param address       Out: FPGA start address
- * @param default_data  Out: Submodule default data
- * @return 0 on success, -1 on error
- */
-int app_data_get_fpga_info_by_id (
-   uint32_t id,
-   uint16_t * address,
-   const uint8_t ** default_data);
-
-/**
- * Get PNIO output data buffer using submodule id.
- * @param submodule_id  In:  Submodule id
- * @param size          Out: Size of pnio data. If submodule
- *                           is not supported size is set to 0.
- * @return Reference to PNIO data, NULL on error
- */
-uint8_t * app_data_get_output_data_buffer (
-   uint32_t submodule_id,
-   uint16_t * size);
-
-/**
- * Set PNIO output data using module id.
- * When this operation is called the data is
- * written the mapped shared memory.
- * @param submodule_id  In:  Submodule id
- * @param data          In:  Reference to output data
- * @param size          In:  Length of output data
- * @return 0 on success, -1 on error
- */
-int app_data_set_output_data (
-   uint32_t submodule_id,
-   uint8_t * data,
-   uint16_t size);
-
-/**
- * Set default values for all outputs.
- * When this operation is called the mapped
- * shared memory is set to 0.
- * @return 0 on success, -1 on error
- */
-int app_data_set_default_outputs (void);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_DATA_H */

+ 0 - 394
samples/pn_dev_lan9662/app_gsdml.c

@@ -1,394 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-/**
- * @file
- * @brief Device properties defined by the GSDML device definition
- *
- * Functions for getting module, submodule and parameter
- * configurations using their IDs.
- *
- * Important:
- * Any change in this file may require an update of the GSDML file.
- * Note that when the GSDML file is updated it has to be reloaded
- * in your Profinet engineering tool. PLC applications may be affected.
- *
- * Design requires unique submodule IDs.
- */
-
-#include "sampleapp_common.h"
-#include "app_utils.h"
-#include "app_gsdml.h"
-#include "app_log.h"
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/************************* Modules ***************************/
-
-static const app_gsdml_module_t dap_1 = {
-   .id = PNET_MOD_DAP_IDENT,
-   .name = "DAP 1",
-   .fixed_slot = 0,
-   .submodules = {
-      PNET_SUBMOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_2_IDENT,
-      0}};
-
-static const app_gsdml_module_t module_di_1x8 = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_IN_1x8,
-   .name = "DI 1x8",
-   .fixed_slot = 1,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x8, 0},
-};
-
-static const app_gsdml_module_t module_do_1x8 = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_OUT_1x8,
-   .name = "DO 1x8",
-   .fixed_slot = 2,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x8, 0}};
-
-static const app_gsdml_module_t module_di_1x64 = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_IN_1x64,
-   .name = "DI 1x64",
-   .fixed_slot = 3,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x64, 0},
-};
-
-static const app_gsdml_module_t module_di_2x32a = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_IN_2x32a,
-   .name = "DI 2x32a",
-   .fixed_slot = 4,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32a, 0},
-};
-
-static const app_gsdml_module_t module_di_2x32b = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_IN_2x32b,
-   .name = "DI 2x32b",
-   .fixed_slot = 5,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32b, 0},
-};
-
-static const app_gsdml_module_t module_di_1x800 = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_IN_1x800,
-   .name = "DI 1x800",
-   .fixed_slot = 6,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x800, 0},
-};
-
-static const app_gsdml_module_t module_do_1x64 = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_OUT_1x64,
-   .name = "DO 1x64",
-   .fixed_slot = 7,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x64, 0},
-};
-
-static const app_gsdml_module_t module_do_2x32a = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_OUT_2x32a,
-   .name = "DO 2x32a",
-   .fixed_slot = 8,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32a, 0},
-};
-
-static const app_gsdml_module_t module_do_2x32b = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_OUT_2x32b,
-   .name = "DO 2x32b",
-   .fixed_slot = 9,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32b, 0},
-};
-
-static const app_gsdml_module_t module_do_1x800 = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_OUT_1x800,
-   .name = "DO 1x800",
-   .fixed_slot = 10,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x800, 0},
-};
-
-static const app_gsdml_module_t module_di_port_a = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_IN_PORT_A,
-   .name = "DI Port A",
-   .fixed_slot = 11,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_IN_PORT_A, 0},
-};
-
-static const app_gsdml_module_t module_do_port_a = {
-   .id = APP_GSDML_MOD_ID_DIGITAL_OUT_PORT_A,
-   .name = "DO Port A",
-   .fixed_slot = 12,
-   .submodules = {APP_GSDML_SUBMOD_ID_DIGITAL_OUT_PORT_A, 0},
-};
-/************************* Submodules ***************************/
-
-static const app_gsdml_submodule_t dap_identity_1 = {
-   .name = "DAP Identity 1",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_IDENT,
-   .fixed_subslot = PNET_SUBSLOT_DAP_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_interface_1 = {
-   .name = "DAP Interface 1",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_IDENT,
-   .fixed_subslot = PNET_SUBSLOT_DAP_INTERFACE_1_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_1 = {
-   .name = "DAP Port 1",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
-   .fixed_subslot = PNET_SUBSLOT_DAP_INTERFACE_1_PORT_1_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_2 = {
-   .name = "DAP Port 2",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_2_IDENT,
-   .fixed_subslot = PNET_SUBSLOT_DAP_INTERFACE_1_PORT_2_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_3 = {
-   .name = "DAP Port 3",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_3_IDENT,
-   .fixed_subslot = PNET_SUBSLOT_DAP_INTERFACE_1_PORT_3_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t dap_port_4 = {
-   .name = "DAP Port 4",
-   .api = APP_GSDML_API,
-   .id = PNET_SUBMOD_DAP_INTERFACE_1_PORT_4_IDENT,
-   .fixed_subslot = PNET_SUBSLOT_DAP_INTERFACE_1_PORT_4_IDENT,
-   .data_dir = PNET_DIR_NO_IO,
-   .insize = 0,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_di_1x8 = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x8,
-   .fixed_subslot = 1,
-   .name = "Digital Input 1x8",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = APP_GSDML_SIZE_DIGITAL_IN_1x8,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_do_1x8 = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x8,
-   .fixed_subslot = 1,
-   .name = "Digital Output 1x8",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_SIZE_DIGITAL_OUT_1x8,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_di_1x64 = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x64,
-   .fixed_subslot = 1,
-   .name = "Digital Input 1x64",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = APP_GSDML_SIZE_DIGITAL_IN_1x64,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_di_2x32a = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32a,
-   .fixed_subslot = 1,
-   .name = "Digital Input 2x32 a",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = 8,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_di_2x32b = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32b,
-   .fixed_subslot = 1,
-   .name = "Digital Input 2x32 b",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = APP_GSDML_SIZE_DIGITAL_IN_2x32b,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_di_1x800 = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x800,
-   .fixed_subslot = 1,
-   .name = "Digital Input 1x800",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = APP_GSDML_SIZE_DIGITAL_IN_1x800,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_do_1x64 = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x64,
-   .fixed_subslot = 1,
-   .name = "Digital Output 1x64",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_SIZE_DIGITAL_OUT_1x64,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_do_2x32a = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32a,
-   .fixed_subslot = 1,
-   .name = "Digital Output 2x32 a",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_SIZE_DIGITAL_OUT_2x32a,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_do_2x32b = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32b,
-   .fixed_subslot = 1,
-   .name = "Digital Output 2x32 b",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_SIZE_DIGITAL_OUT_2x32b,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_do_1x800 = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x800,
-   .fixed_subslot = 1,
-   .name = "Digital Output 1x800",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_SIZE_DIGITAL_OUT_1x800,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_di_port_a = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_IN_PORT_A,
-   .fixed_subslot = 1,
-   .name = "Digital Input Port A",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_INPUT,
-   .insize = APP_GSDML_SIZE_DIGITAL_IN_PORT_A,
-   .outsize = 0,
-   .parameters = {0}};
-
-static const app_gsdml_submodule_t submodule_do_port_a = {
-   .id = APP_GSDML_SUBMOD_ID_DIGITAL_OUT_PORT_A,
-   .fixed_subslot = 1,
-   .name = "Digital Output Port A",
-   .api = APP_GSDML_API,
-   .data_dir = PNET_DIR_OUTPUT,
-   .insize = 0,
-   .outsize = APP_GSDML_SIZE_DIGITAL_OUT_PORT_A,
-   .parameters = {0}};
-
-/* List of supported modules */
-static const app_gsdml_module_t * app_gsdml_modules[] = {
-   &dap_1,
-   &module_di_1x8,
-   &module_do_1x8,
-   &module_di_1x64,
-   &module_di_2x32a,
-   &module_di_2x32b,
-   &module_di_1x800,
-   &module_do_1x64,
-   &module_do_2x32a,
-   &module_do_2x32b,
-   &module_do_1x800,
-   &module_di_port_a,
-   &module_do_port_a};
-
-/* List of supported submodules */
-static const app_gsdml_submodule_t * app_gsdml_submodules[] = {
-   &dap_identity_1,
-   &dap_interface_1,
-   &dap_port_1,
-   &dap_port_2,
-   &dap_port_3,
-   &dap_port_4,
-
-   &submodule_di_1x8,
-   &submodule_do_1x8,
-   &submodule_di_1x64,
-   &submodule_di_2x32a,
-   &submodule_di_2x32b,
-   &submodule_di_1x800,
-   &submodule_do_1x64,
-   &submodule_do_2x32a,
-   &submodule_do_2x32b,
-   &submodule_do_1x800,
-   &submodule_di_port_a,
-   &submodule_do_port_a};
-
-const app_gsdml_module_t * app_gsdml_get_module_cfg (uint32_t id)
-{
-   uint32_t i;
-   for (i = 0; i < NELEMENTS (app_gsdml_modules); i++)
-   {
-      if (app_gsdml_modules[i]->id == id)
-      {
-         return app_gsdml_modules[i];
-      }
-   }
-   return NULL;
-}
-
-const app_gsdml_module_t ** app_gsdml_get_modules (uint32_t * array_len)
-{
-   *array_len = NELEMENTS (app_gsdml_modules);
-   return app_gsdml_modules;
-}
-
-const app_gsdml_submodule_t ** app_gsdml_get_submodules (uint32_t * array_len)
-{
-   *array_len = NELEMENTS (app_gsdml_submodules);
-   return app_gsdml_submodules;
-}
-
-const app_gsdml_submodule_t * app_gsdml_get_submodule_cfg (uint32_t id)
-{
-   uint32_t i;
-   for (i = 0; i < NELEMENTS (app_gsdml_submodules); i++)
-   {
-      if (app_gsdml_submodules[i]->id == id)
-      {
-         return app_gsdml_submodules[i];
-      }
-   }
-   return NULL;
-}

+ 0 - 221
samples/pn_dev_lan9662/app_gsdml.h

@@ -1,221 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_GSDML_H
-#define APP_GSDML_H
-
-/**
- * @file
- * @brief Device properties defined by the GSDML device definition
- *
- * Functions for getting module, submodule and parameter
- * configurations using their ids.
- *
- * Important:
- * Any change in this file may require an update of the GSDML file.
- * Note that when the GSDML file is updated it has to be reloaded
- * in your Profinet engineering tool. PLC applications may be affected.
- *
- * Design requires unique submodule IDs and unique parameter indexes.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <pnet_api.h>
-
-#define APP_GSDML_API 0
-
-#define APP_GSDML_DEFAULT_STATION_NAME "lan9662-dev"
-
-/* GSDML tag: VendorID */
-#define APP_GSDML_VENDOR_ID 0x0493
-
-/* GSDML tag: DeviceID */
-#define APP_GSDML_DEVICE_ID 0x9662
-
-/* Used in DCP communication */
-#define APP_GSDML_OEM_VENDOR_ID 0xcafe
-#define APP_GSDML_OEM_DEVICE_ID 0xee02
-
-/* Used in I&M0 */
-#define APP_GSDML_IM_HARDWARE_REVISION 3
-#define APP_GSDML_IM_VERSION_MAJOR     1
-#define APP_GSDML_IM_VERSION_MINOR     2
-
-/* Allowed: 'V', 'R', 'P', 'U', 'T' */
-#define APP_GSDML_SW_REV_PREFIX       'V'
-#define APP_GSDML_PROFILE_ID          0x1234
-#define APP_GSDML_PROFILE_SPEC_TYPE   0x5678
-#define APP_GSDML_IM_REVISION_COUNTER 0 /* Typically 0 */
-
-/* Note: You need to read out the actual hardware serial number instead */
-#define APP_GSDML_EXAMPLE_SERIAL_NUMBER "007"
-
-/* Initial values. Can be overwritten by PLC */
-#define APP_GSDML_TAG_FUNCTION "my function"
-#define APP_GSDML_TAG_LOCATION "my location"
-#define APP_GSDML_IM_DATE      "2022-03-01 10:03"
-#define APP_GSDML_DESCRIPTOR   "my descriptor"
-#define APP_GSDML_SIGNATURE    ""
-
-/* GSDML tag: Writeable_IM_Records */
-#define APP_GSDML_IM_SUPPORTED                                                 \
-   (PNET_SUPPORTED_IM1 | PNET_SUPPORTED_IM2 | PNET_SUPPORTED_IM3)
-
-/* GSDML tag: OrderNumber */
-#define APP_GSDML_ORDER_ID "12345 Abcdefghijk"
-/* GSDML tag: ModuleInfo / Name */
-#define APP_GSDML_PRODUCT_NAME "P-Net LAN9662 Sample"
-
-/* GSDML tag: MinDeviceInterval */
-#define APP_GSDML_MIN_DEVICE_INTERVAL 32 /* 1ms */
-
-#define APP_GSDML_DIAG_CUSTOM_USI 0x1234
-
-/* See "Specification for GSDML" 8.26 LogBookEntryItem for allowed values */
-#define APP_GSDML_LOGBOOK_ERROR_CODE   0x20 /* Manufacturer specific */
-#define APP_GSDML_LOGBOOK_ERROR_DECODE 0x82 /* Manufacturer specific */
-#define APP_GSDML_LOGBOOK_ERROR_CODE_1 PNET_ERROR_CODE_1_FSPM
-#define APP_GSDML_LOGBOOK_ERROR_CODE_2 0x00       /* Manufacturer specific */
-#define APP_GSDML_LOGBOOK_ENTRY_DETAIL 0xFEE1DEAD /* Manufacturer specific */
-
-#define APP_GSDML_MAX_SUBMODULES 20
-
-#define APP_GSDML_DEFAULT_MAUTYPE 0x10 /* Copper 100 Mbit/s Full duplex */
-
-#define APP_GSDML_ALARM_PAYLOAD_SIZE 1 /* bytes */
-
-#define APP_GSDML_MOD_ID_DIGITAL_IN_1x8     0x00001001
-#define APP_GSDML_MOD_ID_DIGITAL_OUT_1x8    0x00001002
-#define APP_GSDML_MOD_ID_DIGITAL_IN_1x64    0x00001003
-#define APP_GSDML_MOD_ID_DIGITAL_IN_2x32a   0x00001004
-#define APP_GSDML_MOD_ID_DIGITAL_IN_2x32b   0x00001005
-#define APP_GSDML_MOD_ID_DIGITAL_IN_1x800   0x00001006
-#define APP_GSDML_MOD_ID_DIGITAL_OUT_1x64   0x00001007
-#define APP_GSDML_MOD_ID_DIGITAL_OUT_2x32a  0x00001008
-#define APP_GSDML_MOD_ID_DIGITAL_OUT_2x32b  0x00001009
-#define APP_GSDML_MOD_ID_DIGITAL_OUT_1x800  0x0000100A
-#define APP_GSDML_MOD_ID_DIGITAL_IN_PORT_A  0x0000100B
-#define APP_GSDML_MOD_ID_DIGITAL_OUT_PORT_A 0x0000100C
-
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x8     0x00002001
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x8    0x00002002
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x64    0x00002003
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32a   0x00002004
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_2x32b   0x00002005
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_1x800   0x00002006
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x64   0x00002007
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32a  0x00002008
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT_2x32b  0x00002009
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT_1x800  0x0000200A
-#define APP_GSDML_SUBMOD_ID_DIGITAL_IN_PORT_A  0x0000200B
-#define APP_GSDML_SUBMOD_ID_DIGITAL_OUT_PORT_A 0x0000200C
-
-#define APP_GSDML_SIZE_DIGITAL_IN_1x8     1
-#define APP_GSDML_SIZE_DIGITAL_OUT_1x8    1
-#define APP_GSDML_SIZE_DIGITAL_IN_1x64    8
-#define APP_GSDML_SIZE_DIGITAL_IN_2x32a   8
-#define APP_GSDML_SIZE_DIGITAL_IN_2x32b   8
-#define APP_GSDML_SIZE_DIGITAL_IN_1x800   100
-#define APP_GSDML_SIZE_DIGITAL_OUT_1x64   8
-#define APP_GSDML_SIZE_DIGITAL_OUT_2x32a  8
-#define APP_GSDML_SIZE_DIGITAL_OUT_2x32b  8
-#define APP_GSDML_SIZE_DIGITAL_OUT_1x800  100
-#define APP_GSDML_SIZE_DIGITAL_IN_PORT_A  4
-#define APP_GSDML_SIZE_DIGITAL_OUT_PORT_A 4
-
-#define APP_GSDML_MAX_SUBMODULE_DATA_SIZE 100
-
-/* TODO support virtual and pluggable submodules. */
-typedef struct cfg_module
-{
-   uint32_t id;
-   const char * name;
-   uint32_t fixed_slot;   /* Set to UINT32_MAX if not fixed */
-   uint32_t submodules[]; /* Variable length, ends with 0*/
-} app_gsdml_module_t;
-
-typedef struct app_gsdml_submodule
-{
-   uint32_t id;
-   const char * name;
-   uint32_t api;
-   uint32_t fixed_subslot; /* Set to UINT32_MAX if not fixed */
-   pnet_submodule_dir_t data_dir;
-   uint16_t insize;
-   uint16_t outsize;
-   uint16_t parameters[]; /* Variable length, ends with 0 */
-} app_gsdml_submodule_t;
-
-typedef struct app_gsdml_param
-{
-   uint32_t index;
-   const char * name;
-   uint16_t length;
-} app_gsdml_param_t;
-
-/**
- * Get array of supported modules
- * @param array_len  Out: Length of array
- * @return Modules array
- */
-const app_gsdml_module_t ** app_gsdml_get_modules (uint32_t * array_len);
-
-/**
- * Get array of supported submodules
- * @param array_len  Out: Length of array
- * @return Submodules array
- */
-const app_gsdml_submodule_t ** app_gsdml_get_submodules (uint32_t * array_len);
-
-/**
- * Get array of supported parameters
- * @param array_len  Out: Length of array
- * @return Parameters array
- */
-const app_gsdml_param_t ** app_gsdml_get_parameters (uint32_t * array_len);
-
-/**
- * Get module configuration from module id
- * @param module_id  In: Module id
- * @return Module configuration, NULL if not found
- */
-const app_gsdml_module_t * app_gsdml_get_module_cfg (uint32_t module_id);
-
-/**
- * Get submodule module configuration from submodule id
- * @param submodule_id  In: Submodule id
- * @return Submodule configuration, NULL if not found
- */
-const app_gsdml_submodule_t * app_gsdml_get_submodule_cfg (
-   uint32_t submodule_id);
-
-/**
- * Get parameter configuration from parameter index
- * @param submodule_id  In: Submodule id
- * @param index         In: Parameters index
- * @return Parameter configuration, NULL if not found
- */
-const app_gsdml_param_t * app_gsdml_get_parameter_cfg (
-   uint32_t submodule_id,
-   uint32_t index);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_GSDML_H */

+ 0 - 52
samples/pn_dev_lan9662/app_log.c

@@ -1,52 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "app_log.h"
-
-#include <stdarg.h>
-#include <stdio.h>
-
-static int32_t log_level = APP_DEFAULT_LOG_LEVEL;
-
-void app_log_set_log_level (int32_t level)
-{
-   log_level = level;
-}
-
-void app_log (int32_t level, const char * fmt, ...)
-{
-   va_list list;
-
-   if (level >= log_level)
-   {
-      va_start (list, fmt);
-      vprintf (fmt, list);
-      va_end (list);
-      fflush (stdout);
-   }
-}
-
-void app_log_print_bytes (int32_t level, const uint8_t * bytes, uint32_t len)
-{
-   if (level >= log_level)
-   {
-      printf ("  Bytes: ");
-      for (uint32_t i = 0; i < len; i++)
-      {
-         printf ("%02X ", bytes[i]);
-      }
-      printf ("\n");
-   }
-}

+ 0 - 75
samples/pn_dev_lan9662/app_log.h

@@ -1,75 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_LOG_H
-#define APP_LOG_H
-
-/**
- * @file
- * @brief Application debug log utility
- *
- * Runtime configurable debug log using printf()
- * Levels matches levels used in P-Net.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#define APP_LOG_LEVEL_DEBUG   0x00
-#define APP_LOG_LEVEL_INFO    0x01
-#define APP_LOG_LEVEL_WARNING 0x02
-#define APP_LOG_LEVEL_ERROR   0x03
-#define APP_LOG_LEVEL_FATAL   0x04
-
-#define APP_DEFAULT_LOG_LEVEL APP_LOG_LEVEL_FATAL
-
-#define APP_LOG(level, ...) app_log (level, __VA_ARGS__)
-
-#define APP_LOG_DEBUG(...)   APP_LOG (APP_LOG_LEVEL_DEBUG, __VA_ARGS__)
-#define APP_LOG_INFO(...)    APP_LOG (APP_LOG_LEVEL_INFO, __VA_ARGS__)
-#define APP_LOG_WARNING(...) APP_LOG (APP_LOG_LEVEL_WARNING, __VA_ARGS__)
-#define APP_LOG_ERROR(...)   APP_LOG (APP_LOG_LEVEL_ERROR, __VA_ARGS__)
-#define APP_LOG_FATAL(...)   APP_LOG (APP_LOG_LEVEL_FATAL, __VA_ARGS__)
-
-/**
- * Print log message depending on level
- * Use the APP_LOG_xxxxx macros instead of this function.
- * @param level         In: Message log level
- * @param fmt           In: Log message format string
- */
-void app_log (int32_t level, const char * fmt, ...);
-
-/**
- * Log an array of bytes
- * @param level         In: Log level
- * @param bytes         In: Array of bytes
- * @param length        In: Length of array
- */
-void app_log_print_bytes (int32_t level, const uint8_t * bytes, uint32_t length);
-
-/**
- * Set log level
- * @param level         In: Log level
- */
-void app_log_set_log_level (int32_t level);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_LOG_H */

+ 0 - 318
samples/pn_dev_lan9662/app_shm.c

@@ -1,318 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "app_shm.h"
-#include "app_log.h"
-
-#include <semaphore.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <ctype.h>
-#include <fcntl.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define APP_SHM_MAX_FILE_NAME_LEN 40
-
-typedef struct app_shm_t
-{
-   char name[APP_SHM_MAX_FILE_NAME_LEN];
-   int fd;
-   caddr_t mem_address;
-   sem_t * sem;
-   size_t size;
-} app_shm_t;
-
-/**
- * Format name string
- *
- * Replace space " " with "-"
- * Convert uppercase characters to lowercase.
- * @param name  In:  NULL terminated string
- * @return 0 on success, -1 on error
- **/
-static int format_name (char * name)
-{
-   uint32_t i;
-
-   if (name == NULL)
-   {
-      return -1;
-   }
-
-   for (i = 0; name[i] != '\0'; i++)
-   {
-      name[i] = tolower (name[i]);
-      if (name[i] == ' ')
-      {
-         name[i] = '_';
-      }
-   }
-
-   return 0;
-}
-
-/**
- * Initialise an existing shared memory area handle
- *
- * @param handle     In:    Handle
- * @param name       In:    Name
- * @param slot       In:    Slot number
- * @param subslot    In:    Subslot number
- * @param size       In:    Size in bytes
- * @param is_output  In:    True if the shared memory area is an output
- * @return 0 on success, -1 on error
- **/
-static int app_shm_init (
-   app_shm_t * handle,
-   const char * name,
-   uint32_t slot,
-   uint32_t subslot,
-   uint32_t size,
-   bool is_output)
-{
-   const int shm_flags = O_RDWR | O_CREAT;
-
-   if (handle == NULL || name == NULL || size == 0)
-   {
-      return -1;
-   }
-   memset (handle, 0, sizeof (app_shm_t));
-
-   /* Only include slot and subslot numbers if both module and
-      submodules are fixed in slot and subslot */
-   if (slot != UINT32_MAX && subslot != UINT32_MAX)
-   {
-      snprintf (
-         handle->name,
-         APP_SHM_MAX_FILE_NAME_LEN - 1,
-         "pnet-%s-%d-%d-%s",
-         is_output ? "out" : "in",
-         slot,
-         subslot,
-         name);
-   }
-   else
-   {
-      snprintf (
-         handle->name,
-         APP_SHM_MAX_FILE_NAME_LEN - 1,
-         "pnet-%s-%s",
-         is_output ? "out" : "in",
-         name);
-   }
-
-   format_name (handle->name);
-
-   handle->size = size;
-
-   handle->fd = shm_open (handle->name, shm_flags, 0666);
-
-   if (handle->fd < 0)
-   {
-      APP_LOG_ERROR (
-         "Failed to open shared memory\n"
-         "  file name: %s\n"
-         "  Input files is expected to be created by data generating "
-         "  application\n",
-         handle->name);
-
-      return -1;
-   }
-
-   if (ftruncate (handle->fd, handle->size) != 0)
-   {
-      return -1;
-   }
-
-   handle->mem_address = mmap (
-      NULL,
-      handle->size,
-      PROT_READ | PROT_WRITE,
-      MAP_SHARED,
-      handle->fd,
-      0);
-
-   if (handle->mem_address == MAP_FAILED)
-   {
-      return -1;
-   }
-
-   handle->sem = sem_open (handle->name, O_CREAT, 0666, 1);
-
-   if (handle->sem == NULL)
-   {
-      return -1;
-   }
-
-   /* sem_unlink (handle->name); TODO */
-   APP_LOG_DEBUG ("shared memory area created\n");
-   APP_LOG_DEBUG ("  name=%s\n", handle->name);
-   APP_LOG_DEBUG ("  size=%lu\n", handle->size);
-   APP_LOG_DEBUG ("  backing file = /dev/shm/%s\n", handle->name);
-
-   return 0;
-}
-
-app_shm_t * app_shm_create_input (
-   const char * name,
-   int slot,
-   int subslot,
-   int size)
-{
-   app_shm_t * handle = (app_shm_t *)malloc (sizeof (app_shm_t));
-
-   if (handle != NULL)
-   {
-      if (app_shm_init (handle, name, slot, subslot, size, false) != 0)
-      {
-         app_shm_destroy (handle);
-         handle = NULL;
-      }
-   }
-
-   return handle;
-}
-
-app_shm_t * app_shm_create_output (
-   const char * name,
-   int slot,
-   int subslot,
-   int size)
-{
-   app_shm_t * handle = (app_shm_t *)malloc (sizeof (app_shm_t));
-
-   if (handle != NULL)
-   {
-      if (app_shm_init (handle, name, slot, subslot, size, true) != 0)
-      {
-         app_shm_destroy (handle);
-         handle = NULL;
-      }
-   }
-
-   return handle;
-}
-
-/**
- * Free resources related to a shared memory area.
- *
- * Does not free the memory allocated for the handle itself.
- *
- * @param handle     In:    Handle
- **/
-static void app_shm_free_resources (app_shm_t * handle)
-{
-   if (handle == NULL)
-   {
-      return;
-   }
-
-   if (handle->mem_address != 0)
-   {
-      munmap (handle->mem_address, handle->size);
-   }
-
-   if (handle->fd >= 0)
-   {
-      close (handle->fd);
-   }
-
-   if (handle->sem != NULL)
-   {
-      sem_close (handle->sem);
-      /* sem_unlink TODO */
-   }
-
-   unlink (handle->name);
-}
-
-void app_shm_destroy (app_shm_t * handle)
-{
-   if (handle != NULL)
-   {
-      app_shm_free_resources (handle);
-      free (handle);
-   }
-}
-
-int app_shm_read (app_shm_t * handle, void * data, size_t size)
-{
-   if (handle == NULL || size == 0)
-   {
-      return -1;
-   }
-
-   if (sem_wait (handle->sem) != 0)
-   {
-      return -1;
-   }
-
-   memcpy (data, handle->mem_address, size);
-
-   if (sem_post (handle->sem) != 0)
-   {
-      return -1;
-   }
-
-   return 0;
-}
-
-int app_shm_write (app_shm_t * handle, void * data, size_t size)
-{
-   if (handle == NULL || data == NULL || size > handle->size)
-   {
-      return -1;
-   }
-
-   if (sem_wait (handle->sem) != 0)
-   {
-      return -1;
-   }
-
-   memcpy (handle->mem_address, data, size);
-
-   if (sem_post (handle->sem) != 0)
-   {
-      return -1;
-   }
-
-   return 0;
-}
-
-int app_shm_reset (app_shm_t * handle)
-{
-   if (handle == NULL)
-   {
-      return -1;
-   }
-
-   if (sem_wait (handle->sem) != 0)
-   {
-      return -1;
-   }
-
-   memset (handle->mem_address, 0, handle->size);
-
-   if (sem_post (handle->sem) != 0)
-   {
-      return -1;
-   }
-
-   return 0;
-}

+ 0 - 104
samples/pn_dev_lan9662/app_shm.h

@@ -1,104 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_SHM_H
-#define APP_SHM_H
-
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct app_shm_t app_shm_t;
-
-/**
- * Create a shared memory area used as input.
- *
- * Shared memory is read by this application.
- * Intended for submodule input data.
- * The slot and and subslot info is used to
- * generate the name of the shared memory area.
- *
- * @param name       In:  Submodule id
- * @param slot       In:  Slot number
- * @param subslot    In:  Subslot number
- * @param size       In:  Size of area
- * @return Handle to created shared memory area. NULL on error.
- */
-app_shm_t * app_shm_create_input (
-   const char * name,
-   int slot,
-   int subslot,
-   int size);
-
-/**
- * Create a shared memory area used as output.
- *
- * Shared memory is written by this application.
- * Intended for submodule output data.
- * The slot and and subslot info is used to
- * generate the name of the shared memory area.
- *
- * @param name       In:  Submodule id
- * @param slot       In:  Slot number
- * @param subslot    In:  Subslot number
- * @param size       In:  Size of area
- * @return Handle to created shared memory area. NULL on error.
- */
-app_shm_t * app_shm_create_output (
-   const char * name,
-   int slot,
-   int subslot,
-   int size);
-
-/**
- * Free the resources of a shared memory area
- *
- * @param handle       In:  Shared memory object handle
- */
-void app_shm_destroy (app_shm_t * handle);
-
-/**
- * Read shared memory area into a buffer
- *
- * @param handle     In:  Shared memory object handle
- * @param data       In:  Start of buffer
- * @param size       In:  Number of bytes to read
- * @return 0 on success, -1 on error
- */
-int app_shm_read (app_shm_t * handle, void * data, size_t size);
-
-/**
- * Write to shared memory
- *
- * @param handle     In:  Shared memory object handle
- * @param data       In:  Start of buffer
- * @param size       In:  Number of bytes to write
- * @return 0 on success, -1 on error
- */
-int app_shm_write (app_shm_t * handle, void * data, size_t size);
-
-/**
- * Set shared memory to zero
- *
- * @param handle     In:  Shared memory object handle
- * @return 0 on success, -1 on error
- */
-int app_shm_reset (app_shm_t * handle);
-
-#endif /* APP_SHM_H */

+ 0 - 749
samples/pn_dev_lan9662/app_utils.c

@@ -1,749 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#define _GNU_SOURCE /* For asprintf() */
-
-#include "app_utils.h"
-#include "app_log.h"
-#include "app_gsdml.h"
-#include "sampleapp_common.h"
-#include "osal.h"
-#include "osal_log.h" /* For LOG_LEVEL */
-#include "pnal.h"
-#include <pnet_api.h>
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define GET_HIGH_BYTE(id) ((id >> 8) & 0xFF)
-#define GET_LOW_BYTE(id)  (id & 0xFF)
-
-void app_utils_ip_to_string (pnal_ipaddr_t ip, char * outputstring)
-{
-   snprintf (
-      outputstring,
-      PNAL_INET_ADDRSTR_SIZE,
-      "%u.%u.%u.%u",
-      (uint8_t) ((ip >> 24) & 0xFF),
-      (uint8_t) ((ip >> 16) & 0xFF),
-      (uint8_t) ((ip >> 8) & 0xFF),
-      (uint8_t) (ip & 0xFF));
-}
-
-void app_utils_mac_to_string (pnet_ethaddr_t mac, char * outputstring)
-{
-   snprintf (
-      outputstring,
-      PNAL_ETH_ADDRSTR_SIZE,
-      "%02X:%02X:%02X:%02X:%02X:%02X",
-      mac.addr[0],
-      mac.addr[1],
-      mac.addr[2],
-      mac.addr[3],
-      mac.addr[4],
-      mac.addr[5]);
-}
-
-const char * app_utils_submod_dir_to_string (pnet_submodule_dir_t direction)
-{
-   const char * s = "<error>";
-
-   switch (direction)
-   {
-   case PNET_DIR_NO_IO:
-      s = "NO_IO";
-      break;
-   case PNET_DIR_INPUT:
-      s = "INPUT";
-      break;
-   case PNET_DIR_OUTPUT:
-      s = "OUTPUT";
-      break;
-   case PNET_DIR_IO:
-      s = "INPUT_OUTPUT";
-      break;
-   }
-
-   return s;
-}
-
-const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs)
-{
-   const char * s = "<error>";
-   switch (ioxs)
-   {
-   case PNET_IOXS_BAD:
-      s = "IOXS_BAD";
-      break;
-   case PNET_IOXS_GOOD:
-      s = "IOXS_GOOD";
-      break;
-   }
-
-   return s;
-}
-
-char * app_utils_get_subslot_string (const app_subslot_t * subslot)
-{
-   static char buf[40];
-   snprintf (
-      buf,
-      sizeof (buf),
-      "[%u,%u,\"%s\"]",
-      subslot->slot_nbr,
-      subslot->subslot_nbr,
-      subslot->submodule_name);
-   return buf;
-}
-
-void app_utils_get_error_code_strings (
-   uint16_t err_cls,
-   uint16_t err_code,
-   const char ** err_cls_str,
-   const char ** err_code_str)
-{
-   if (err_cls_str == NULL || err_code_str == NULL)
-   {
-      return;
-   }
-   *err_cls_str = "Not decoded";
-   *err_code_str = "Not decoded";
-
-   switch (err_cls)
-   {
-   case PNET_ERROR_CODE_1_RTA_ERR_CLS_PROTOCOL:
-      *err_cls_str = "Real-Time Acyclic Protocol";
-      switch (err_code)
-      {
-      case PNET_ERROR_CODE_2_ABORT_AR_CONSUMER_DHT_EXPIRED:
-         *err_code_str = "Device missed cyclic data "
-                         "deadline, device terminated AR";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_AR_CMI_TIMEOUT:
-         *err_code_str = "Communication initialization "
-                         "timeout, device terminated AR";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_AR_RELEASE_IND_RECEIVED:
-         *err_code_str = "AR release indication received";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_DCP_STATION_NAME_CHANGED:
-         *err_code_str = "DCP station name changed, "
-                         "device terminated AR";
-         break;
-      case PNET_ERROR_CODE_2_ABORT_DCP_RESET_TO_FACTORY:
-         *err_code_str = "DCP reset to factory or factory "
-                         "reset, device terminated AR";
-         break;
-      }
-      break;
-
-   case PNET_ERROR_CODE_1_CTLDINA:
-      *err_cls_str = "CTLDINA = Name and IP assignment from controller";
-      switch (err_code)
-      {
-      case PNET_ERROR_CODE_2_CTLDINA_ARP_MULTIPLE_IP_ADDRESSES:
-         *err_code_str = "Multiple users of same IP address";
-         break;
-      }
-      break;
-   }
-}
-
-void app_utils_copy_ip_to_struct (
-   pnet_cfg_ip_addr_t * destination_struct,
-   pnal_ipaddr_t ip)
-{
-   destination_struct->a = ((ip >> 24) & 0xFF);
-   destination_struct->b = ((ip >> 16) & 0xFF);
-   destination_struct->c = ((ip >> 8) & 0xFF);
-   destination_struct->d = (ip & 0xFF);
-}
-
-const char * app_utils_dcontrol_cmd_to_string (
-   pnet_control_command_t control_command)
-{
-   const char * s = NULL;
-
-   switch (control_command)
-   {
-   case PNET_CONTROL_COMMAND_PRM_BEGIN:
-      s = "PRM_BEGIN";
-      break;
-   case PNET_CONTROL_COMMAND_PRM_END:
-      s = "PRM_END";
-      break;
-   case PNET_CONTROL_COMMAND_APP_RDY:
-      s = "APP_RDY";
-      break;
-   case PNET_CONTROL_COMMAND_RELEASE:
-      s = "RELEASE";
-      break;
-   default:
-      s = "<error>";
-      break;
-   }
-
-   return s;
-}
-
-const char * app_utils_event_to_string (pnet_event_values_t event)
-{
-   const char * s = "<error>";
-
-   switch (event)
-   {
-   case PNET_EVENT_ABORT:
-      s = "PNET_EVENT_ABORT";
-      break;
-   case PNET_EVENT_STARTUP:
-      s = "PNET_EVENT_STARTUP";
-      break;
-   case PNET_EVENT_PRMEND:
-      s = "PNET_EVENT_PRMEND";
-      break;
-   case PNET_EVENT_APPLRDY:
-      s = "PNET_EVENT_APPLRDY";
-      break;
-   case PNET_EVENT_DATA:
-      s = "PNET_EVENT_DATA";
-      break;
-   }
-
-   return s;
-}
-
-int app_utils_pnet_cfg_init_default (pnet_cfg_t * cfg)
-{
-   memset (cfg, 0, sizeof (pnet_cfg_t));
-
-   cfg->tick_us = APP_TICK_INTERVAL_US;
-
-   /* Identification & Maintenance */
-
-   cfg->im_0_data.im_vendor_id_hi = GET_HIGH_BYTE (APP_GSDML_VENDOR_ID);
-   cfg->im_0_data.im_vendor_id_lo = GET_LOW_BYTE (APP_GSDML_VENDOR_ID);
-
-   cfg->im_0_data.im_hardware_revision = APP_GSDML_IM_HARDWARE_REVISION;
-   cfg->im_0_data.im_sw_revision_prefix = APP_GSDML_SW_REV_PREFIX;
-   cfg->im_0_data.im_sw_revision_functional_enhancement = PNET_VERSION_MAJOR;
-   cfg->im_0_data.im_sw_revision_bug_fix = PNET_VERSION_MINOR;
-   cfg->im_0_data.im_sw_revision_internal_change = PNET_VERSION_PATCH;
-   cfg->im_0_data.im_revision_counter = APP_GSDML_IM_REVISION_COUNTER;
-   cfg->im_0_data.im_profile_id = APP_GSDML_PROFILE_ID;
-   cfg->im_0_data.im_profile_specific_type = APP_GSDML_PROFILE_SPEC_TYPE;
-   cfg->im_0_data.im_version_major = 1; /** Always 1 */
-   cfg->im_0_data.im_version_minor = 1; /** Always 1 */
-   cfg->im_0_data.im_supported = APP_GSDML_IM_SUPPORTED;
-
-   snprintf (
-      cfg->im_0_data.im_order_id,
-      sizeof (cfg->im_0_data.im_order_id),
-      "%s",
-      APP_GSDML_ORDER_ID);
-   snprintf (
-      cfg->im_0_data.im_serial_number,
-      sizeof (cfg->im_0_data.im_serial_number),
-      "%s",
-      APP_GSDML_EXAMPLE_SERIAL_NUMBER);
-   snprintf (
-      cfg->im_1_data.im_tag_function,
-      sizeof (cfg->im_1_data.im_tag_function),
-      "%s",
-      APP_GSDML_TAG_FUNCTION);
-   snprintf (
-      cfg->im_1_data.im_tag_location,
-      sizeof (cfg->im_1_data.im_tag_location),
-      "%s",
-      APP_GSDML_TAG_LOCATION);
-   snprintf (
-      cfg->im_2_data.im_date,
-      sizeof (cfg->im_2_data.im_date),
-      "%s",
-      APP_GSDML_IM_DATE);
-   snprintf (
-      cfg->im_3_data.im_descriptor,
-      sizeof (cfg->im_3_data.im_descriptor),
-      "%s",
-      APP_GSDML_DESCRIPTOR);
-   snprintf (
-      cfg->im_4_data.im_signature,
-      sizeof (cfg->im_4_data.im_signature),
-      "%s",
-      APP_GSDML_SIGNATURE);
-
-   /* Device configuration */
-   cfg->device_id.vendor_id_hi = GET_HIGH_BYTE (APP_GSDML_VENDOR_ID);
-   cfg->device_id.vendor_id_lo = GET_LOW_BYTE (APP_GSDML_VENDOR_ID);
-   cfg->device_id.device_id_hi = GET_HIGH_BYTE (APP_GSDML_DEVICE_ID);
-   cfg->device_id.device_id_lo = GET_LOW_BYTE (APP_GSDML_DEVICE_ID);
-   cfg->oem_device_id.vendor_id_hi = GET_HIGH_BYTE (APP_GSDML_OEM_VENDOR_ID);
-   cfg->oem_device_id.vendor_id_lo = GET_LOW_BYTE (APP_GSDML_OEM_VENDOR_ID);
-   cfg->oem_device_id.device_id_hi = GET_HIGH_BYTE (APP_GSDML_OEM_DEVICE_ID);
-   cfg->oem_device_id.device_id_lo = GET_LOW_BYTE (APP_GSDML_OEM_DEVICE_ID);
-
-   snprintf (
-      cfg->product_name,
-      sizeof (cfg->product_name),
-      "%s",
-      APP_GSDML_PRODUCT_NAME);
-
-   cfg->send_hello = true;
-
-   /* Timing */
-   cfg->min_device_interval = APP_GSDML_MIN_DEVICE_INTERVAL;
-
-   /* Should be set by application as part of network configuration. */
-   cfg->num_physical_ports = 1;
-
-   snprintf (
-      cfg->station_name,
-      sizeof (cfg->station_name),
-      "%s",
-      APP_GSDML_DEFAULT_STATION_NAME);
-
-   /* Diagnosis mechanism */
-   /* We prefer using "Extended channel diagnosis" instead of
-    * "Qualified channel diagnosis" format on the wire,
-    * as this is better supported by Wireshark.
-    */
-   cfg->use_qualified_diagnosis = false;
-
-#if PNET_OPTION_DRIVER_ENABLE
-   cfg->driver_enable = false;
-   cfg->driver_config.mera.vcam_base_id = PNET_LAN9662_VCAM_BASE;
-   cfg->driver_config.mera.rtp_base_id = PNET_LAN9662_RTP_BASE;
-   cfg->driver_config.mera.wal_base_id = PNET_LAN9662_WAL_BASE;
-   cfg->driver_config.mera.ral_base_id = PNET_LAN9662_RAL_BASE;
-#endif
-
-   return 0;
-}
-
-int app_utils_get_netif_namelist (
-   const char * arg_str,
-   uint16_t max_port,
-   app_utils_netif_namelist_t * p_if_list,
-   uint16_t * p_num_ports)
-{
-   int ret = 0;
-   uint16_t i = 0;
-   uint16_t j = 0;
-   uint16_t if_index = 0;
-   uint16_t number_of_given_names = 1;
-   uint16_t if_list_size = max_port + 1;
-   char c;
-
-   if (max_port == 0)
-   {
-      printf ("Error: max_port is 0.\n");
-      return -1;
-   }
-
-   memset (p_if_list, 0, sizeof (*p_if_list));
-   c = arg_str[i++];
-   while (c != '\0')
-   {
-      if (c != ',')
-      {
-         if (if_index < if_list_size)
-         {
-            p_if_list->netif[if_index].name[j++] = c;
-         }
-      }
-      else
-      {
-         if (if_index < if_list_size)
-         {
-            p_if_list->netif[if_index].name[j++] = '\0';
-            j = 0;
-            if_index++;
-         }
-         number_of_given_names++;
-      }
-
-      c = arg_str[i++];
-   }
-
-   if (max_port == 1 && number_of_given_names > 1)
-   {
-      printf ("Error: Only 1 network interface expected as max_port is 1.\n");
-      return -1;
-   }
-   if (number_of_given_names == 2)
-   {
-      printf ("Error: It is illegal to give 2 interface names. Use 1, or one "
-              "more than the number of physical interfaces.\n");
-      return -1;
-   }
-   if (number_of_given_names > max_port + 1)
-   {
-      printf (
-         "Error: You have given %u interface names, but max is %u as "
-         "PNET_MAX_PHYSICAL_PORTS is %u.\n",
-         number_of_given_names,
-         max_port + 1,
-         max_port);
-      return -1;
-   }
-
-   if (number_of_given_names == 1)
-   {
-      if (strlen (p_if_list->netif[0].name) == 0)
-      {
-         printf ("Error: Zero length network interface name.\n");
-         return -1;
-      }
-      else
-      {
-         p_if_list->netif[1] = p_if_list->netif[0];
-         *p_num_ports = 1;
-      }
-   }
-   else
-   {
-      for (i = 0; i < number_of_given_names; i++)
-      {
-         if (strlen (p_if_list->netif[i].name) == 0)
-         {
-            printf ("Error: Zero length network interface name (%d).\n", i);
-            return -1;
-         }
-      }
-
-      *p_num_ports = number_of_given_names - 1;
-   }
-
-   return ret;
-}
-
-int app_utils_pnet_cfg_init_netifs (
-   const char * netif_list_str,
-   app_utils_netif_namelist_t * if_list,
-   uint16_t * number_of_ports,
-   pnet_if_cfg_t * if_cfg)
-{
-   int ret = 0;
-   int i = 0;
-   pnal_ipaddr_t ip;
-   pnal_ipaddr_t netmask;
-   pnal_ipaddr_t gateway;
-
-   ret = app_utils_get_netif_namelist (
-      netif_list_str,
-      PNET_MAX_PHYSICAL_PORTS,
-      if_list,
-      number_of_ports);
-   if (ret != 0)
-   {
-      return ret;
-   }
-   if_cfg->main_netif_name = if_list->netif[0].name;
-
-   for (i = 1; i <= *number_of_ports; i++)
-   {
-      if_cfg->physical_ports[i - 1].netif_name = if_list->netif[i].name;
-      if_cfg->physical_ports[i - 1].default_mau_type =
-         APP_GSDML_DEFAULT_MAUTYPE;
-   }
-
-   /* Read IP, netmask, gateway from operating system */
-   ip = pnal_get_ip_address (if_cfg->main_netif_name);
-   netmask = pnal_get_netmask (if_cfg->main_netif_name);
-   gateway = pnal_get_gateway (if_cfg->main_netif_name);
-
-   app_utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_addr, ip);
-   app_utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_gateway, gateway);
-   app_utils_copy_ip_to_struct (&if_cfg->ip_cfg.ip_mask, netmask);
-
-   return ret;
-}
-
-static void app_utils_print_mac_address (const char * netif_name)
-{
-   pnal_ethaddr_t pnal_mac_addr;
-   if (pnal_get_macaddress (netif_name, &pnal_mac_addr) == 0)
-   {
-      APP_LOG_INFO (
-         "%02X:%02X:%02X:%02X:%02X:%02X\n",
-         pnal_mac_addr.addr[0],
-         pnal_mac_addr.addr[1],
-         pnal_mac_addr.addr[2],
-         pnal_mac_addr.addr[3],
-         pnal_mac_addr.addr[4],
-         pnal_mac_addr.addr[5]);
-   }
-   else
-   {
-      APP_LOG_ERROR ("Failed read mac address\n");
-   }
-}
-
-void app_utils_print_network_config (
-   pnet_if_cfg_t * if_cfg,
-   uint16_t number_of_ports)
-{
-   uint16_t i;
-   char hostname_string[PNAL_HOSTNAME_MAX_SIZE]; /* Terminated string */
-
-   APP_LOG_INFO ("Management port:      %s ", if_cfg->main_netif_name);
-   app_utils_print_mac_address (if_cfg->main_netif_name);
-   for (i = 1; i <= number_of_ports; i++)
-   {
-      APP_LOG_INFO (
-         "Physical port [%u]:    %s ",
-         i,
-         if_cfg->physical_ports[i - 1].netif_name);
-
-      app_utils_print_mac_address (if_cfg->physical_ports[i - 1].netif_name);
-   }
-
-   if (pnal_get_hostname (hostname_string) != 0)
-   {
-      hostname_string[0] = '\0';
-   }
-
-   APP_LOG_INFO ("Hostname:             %s\n", hostname_string);
-   APP_LOG_INFO (
-      "IP address:           %u.%u.%u.%u\n",
-      if_cfg->ip_cfg.ip_addr.a,
-      if_cfg->ip_cfg.ip_addr.b,
-      if_cfg->ip_cfg.ip_addr.c,
-      if_cfg->ip_cfg.ip_addr.d);
-   APP_LOG_INFO (
-      "Netmask:              %u.%u.%u.%u\n",
-      if_cfg->ip_cfg.ip_mask.a,
-      if_cfg->ip_cfg.ip_mask.b,
-      if_cfg->ip_cfg.ip_mask.c,
-      if_cfg->ip_cfg.ip_mask.d);
-   APP_LOG_INFO (
-      "Gateway:              %u.%u.%u.%u\n",
-      if_cfg->ip_cfg.ip_gateway.a,
-      if_cfg->ip_cfg.ip_gateway.b,
-      if_cfg->ip_cfg.ip_gateway.c,
-      if_cfg->ip_cfg.ip_gateway.d);
-}
-
-void app_utils_print_ioxs_change (
-   const app_subslot_t * subslot,
-   const char * ioxs_str,
-   uint8_t iocs_current,
-   uint8_t iocs_new)
-{
-   if (iocs_current != iocs_new)
-   {
-      if (iocs_new == PNET_IOXS_BAD || iocs_new == PNET_IOXS_GOOD)
-      {
-         APP_LOG_DEBUG (
-            "  %-40s PLC reports %s %s \n",
-            app_utils_get_subslot_string (subslot),
-            ioxs_str,
-            app_utils_ioxs_to_string (iocs_new));
-      }
-      else if (iocs_new != PNET_IOXS_GOOD)
-      {
-         APP_LOG_WARNING (
-            "  %-40s PLC reports %s 0x%x Is it in STOP mode?\n",
-            app_utils_get_subslot_string (subslot),
-            ioxs_str,
-            iocs_new);
-      }
-   }
-}
-
-int app_utils_plug_module (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint32_t id,
-   const char * name)
-{
-   if (slot_nbr >= PNET_MAX_SLOTS)
-   {
-      return -1;
-   }
-
-   p_api->slots[slot_nbr].module_id = id;
-   p_api->slots[slot_nbr].plugged = true;
-   p_api->slots[slot_nbr].name = name;
-
-   return 0;
-}
-
-int app_utils_pull_module (app_api_t * p_api, uint16_t slot_nbr)
-{
-   if (slot_nbr >= PNET_MAX_SLOTS)
-   {
-      return -1;
-   }
-
-   p_api->slots[slot_nbr].plugged = false;
-
-   return 0;
-}
-
-app_subslot_t * app_utils_plug_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_ident,
-   const pnet_data_cfg_t * p_data_cfg,
-   const char * submodule_name,
-   app_utils_cyclic_callback cyclic_callback,
-   void * tag)
-{
-   uint16_t subslot_ix;
-
-   if (slot_nbr >= PNET_MAX_SLOTS || p_api == NULL || p_data_cfg == NULL)
-   {
-      return NULL;
-   }
-
-   /** Find a free subslot */
-   for (subslot_ix = 0; subslot_ix < PNET_MAX_SUBSLOTS; subslot_ix++)
-   {
-      if (p_api->slots[slot_nbr].subslots[subslot_ix].used == false)
-      {
-         app_subslot_t * p_subslot =
-            &p_api->slots[slot_nbr].subslots[subslot_ix];
-
-         p_subslot->used = true;
-         p_subslot->plugged = true;
-         p_subslot->slot_nbr = slot_nbr;
-         p_subslot->subslot_nbr = subslot_nbr;
-         p_subslot->submodule_name = submodule_name;
-         p_subslot->submodule_id = submodule_ident;
-         p_subslot->data_cfg = *p_data_cfg;
-         p_subslot->cyclic_callback = cyclic_callback;
-         p_subslot->tag = tag;
-         p_subslot->indata_iocs = PNET_IOXS_BAD;
-         p_subslot->outdata_iops = PNET_IOXS_BAD;
-         return p_subslot;
-      }
-   }
-
-   return NULL;
-}
-
-int app_utils_pull_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr)
-{
-   app_subslot_t * p_subslot = NULL;
-
-   if (slot_nbr >= PNET_MAX_SUBSLOTS || p_api == NULL)
-   {
-      return -1;
-   }
-
-   p_subslot = app_utils_subslot_get (p_api, slot_nbr, subslot_nbr);
-   if (p_subslot == NULL)
-   {
-      return -1;
-   }
-
-   memset (p_subslot, 0, sizeof (app_subslot_t));
-   p_subslot->used = false;
-
-   return 0;
-}
-
-app_subslot_t * app_utils_subslot_get (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr)
-{
-   uint16_t subslot_ix;
-
-   if (slot_nbr >= PNET_MAX_SLOTS || p_api == NULL)
-   {
-      return NULL;
-   }
-
-   for (subslot_ix = 0; subslot_ix < PNET_MAX_SUBSLOTS; subslot_ix++)
-   {
-      if (p_api->slots[slot_nbr].subslots[subslot_ix].subslot_nbr == subslot_nbr)
-      {
-         return &p_api->slots[slot_nbr].subslots[subslot_ix];
-      }
-   }
-
-   return NULL;
-}
-
-bool app_utils_subslot_is_input (const app_subslot_t * p_subslot)
-{
-   if (p_subslot == NULL || p_subslot->used == false)
-   {
-      return false;
-   }
-
-   if (
-      p_subslot->data_cfg.data_dir == PNET_DIR_INPUT ||
-      p_subslot->data_cfg.data_dir == PNET_DIR_IO)
-   {
-      return true;
-   }
-
-   return false;
-}
-
-bool app_utils_subslot_is_no_io (const app_subslot_t * p_subslot)
-{
-   if (p_subslot == NULL || p_subslot->used == false)
-   {
-      return false;
-   }
-
-   return p_subslot->data_cfg.data_dir == PNET_DIR_NO_IO;
-}
-
-bool app_utils_subslot_is_output (const app_subslot_t * p_subslot)
-{
-   if (p_subslot == NULL || p_subslot->used == false)
-   {
-      return false;
-   }
-
-   if (
-      p_subslot->data_cfg.data_dir == PNET_DIR_OUTPUT ||
-      p_subslot->data_cfg.data_dir == PNET_DIR_IO)
-   {
-      return true;
-   }
-
-   return false;
-}
-
-void app_utils_cyclic_data_poll (app_api_t * p_api)
-{
-   uint16_t slot_nbr;
-   uint16_t subslot_index;
-   app_subslot_t * p_subslot;
-
-   for (slot_nbr = 0; slot_nbr < PNET_MAX_SLOTS; slot_nbr++)
-   {
-      for (subslot_index = 0; subslot_index < PNET_MAX_SUBSLOTS;
-           subslot_index++)
-      {
-         p_subslot = &p_api->slots[slot_nbr].subslots[subslot_index];
-         if (p_subslot->plugged && p_subslot->cyclic_callback != NULL)
-         {
-            p_subslot->cyclic_callback (p_subslot, p_subslot->tag);
-         }
-      }
-   }
-}

+ 0 - 438
samples/pn_dev_lan9662/app_utils.h

@@ -1,438 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef APP_UTILS_H
-#define APP_UTILS_H
-
-/**
- * @file
- * @brief Application utilities and helper functions
- *
- * Functions for getting string representation of
- * P-Net events, error codes and more.
- *
- * API, slot and subslot administration.
- *
- * Initialization of P-Net configuration from app_gsdml.h.
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-typedef struct app_utils_netif_name
-{
-   char name[PNET_INTERFACE_NAME_MAX_SIZE];
-} app_utils_netif_name_t;
-
-typedef struct app_utils_netif_namelist
-{
-   app_utils_netif_name_t netif[PNET_MAX_PHYSICAL_PORTS + 1];
-} app_utils_netif_namelist_t;
-
-/* Forward declaration */
-typedef struct app_subslot app_subslot_t;
-
-/**
- * Callback for updated cyclic data
- *
- * @param subslot    InOut: Subslot structure
- * @param tag        InOut: Typically a handle to a submodule
- */
-typedef void (*app_utils_cyclic_callback) (app_subslot_t * subslot, void * tag);
-
-/**
- * Information of submodule plugged into a subslot.
- *
- * Note that submodule data is not stored here but must
- * be handled by the submodule implementation.
- *
- * All parameters are initialized by the app_utils_plug_submodule()
- * function.
- *
- * The cyclic_callback is used when app_utils_cyclic_data_poll()
- * is called. Typically on the tick event in the main task.
- * The \a tag parameter is passed with the cyclic_callback and
- * is typically a handle to a submodule on application.
- */
-typedef struct app_subslot
-{
-   /** True when the position in the subslot array is occupied */
-   bool used;
-
-   /** True when the subslot is plugged */
-   bool plugged;
-
-   uint16_t slot_nbr;
-   uint16_t subslot_nbr;
-   uint32_t submodule_id;
-   const char * submodule_name;
-   pnet_data_cfg_t data_cfg;
-
-   /** Status indicator from PLC */
-   uint8_t indata_iocs;
-
-   /** Status indicator from PLC */
-   uint8_t outdata_iops;
-
-   /** Callback for cyclic input- or output data, or NULL if not implemented */
-   app_utils_cyclic_callback cyclic_callback;
-   void * tag;
-} app_subslot_t;
-
-/**
- * Information of module plugged into a slot,
- * and array of subslots for admin of submodules.
- */
-typedef struct app_slot
-{
-   bool plugged;
-   uint32_t module_id;
-   const char * name; /** Module name */
-
-   /** Subslots. Use a separate index, as the subslot number might be large.
-    *  For example the subslot for DAP port 1 has number 0x8001 */
-   app_subslot_t subslots[PNET_MAX_SUBSLOTS];
-} app_slot_t;
-
-/**
- * Profinet API state for application
- *
- * Used to manage plugged modules into slots (and submodules into subslots).
- */
-typedef struct app_api_t
-{
-   uint32_t api_id;
-   uint32_t arep;
-
-   /** Slots. Use slot number as index */
-   app_slot_t slots[PNET_MAX_SLOTS];
-} app_api_t;
-
-/**
- * Convert IP address to string
- * @param ip               In:    IP address
- * @param outputstring     Out:   Resulting string buffer. Should have size
- *                                PNAL_INET_ADDRSTR_SIZE.
- */
-void app_utils_ip_to_string (pnal_ipaddr_t ip, char * outputstring);
-
-/**
- * Get string description of data direction
- * @param direction               In:    Submodule data direction
- * @return String representation of data direction
- */
-const char * app_utils_submod_dir_to_string (pnet_submodule_dir_t direction);
-
-/**
- * Get string description of PNIO producer or consumer status
- * @param ioxs               In:    Producer or consumer status (IOPS/IOCS)
- * @return String representation of ioxs (IOPS/IOCS)
- */
-const char * app_utils_ioxs_to_string (pnet_ioxs_values_t ioxs);
-
-/**
- * Get string representation of application subslot in format
- * [slot,subslot,module name]
- * This function has an internal buffer for temp storage
- * of the generated string.
- * @param subslot            In: Subslot
- * @return String representation of subslot.
- */
-char * app_utils_get_subslot_string (const app_subslot_t * subslot);
-
-/**
- * Convert MAC address to string
- * @param mac              In:    MAC address
- * @param outputstring     Out:   Resulting string buffer. Should have size
- *                                PNAL_ETH_ADDRSTR_SIZE.
- */
-void app_utils_mac_to_string (pnet_ethaddr_t mac, char * outputstring);
-
-/**
- * Convert error code to string format
- * Only common error codes supported.
- * Todo: Add rest of error codes.
- *
- * @param err_cls        In:   The error class. See PNET_ERROR_CODE_1_*
- * @param err_code       In:   The error code. See PNET_ERROR_CODE_2_*
- * @param err_cls_str    Out:   The error class string
- * @param err_code_str   Out:   The error code string
- */
-void app_utils_get_error_code_strings (
-   uint16_t err_cls,
-   uint16_t err_code,
-   const char ** err_cls_str,
-   const char ** err_code_str);
-
-/**
- * Copy an IP address (as an integer) to a struct
- * @param destination_struct  Out:   Destination
- * @param ip                  In:    IP address
- */
-void app_utils_copy_ip_to_struct (
-   pnet_cfg_ip_addr_t * destination_struct,
-   pnal_ipaddr_t ip);
-
-/**
- * Return a string representation of
- * the given dcontrol command.
- * @param event            In:    control_command
- * @return  A string representing the command
- */
-const char * app_utils_dcontrol_cmd_to_string (
-   pnet_control_command_t control_command);
-
-/**
- * Return a string representation of the given event.
- * @param event            In:    event
- * @return  A string representing the event
- */
-const char * app_utils_event_to_string (pnet_event_values_t event);
-
-/**
- * Update network configuration from a string
- * defining a list of network interfaces examples:
- * "eth0" or "br0,eth0,eth1"
- *
- * Read IP, netmask etc from operating system.
- *
- * @param netif_list_str      In:  Comma separated string of network ifs
- * @param if_list             Out: Array of network ifs
- * @param number_of_ports     Out: Number of ports
- * @param if_cfg              Out: P-Net network configuration to be updated
- * @return 0 on success, -1 on error
- */
-int app_utils_pnet_cfg_init_netifs (
-   const char * netif_list_str,
-   app_utils_netif_namelist_t * if_list,
-   uint16_t * number_of_ports,
-   pnet_if_cfg_t * if_cfg);
-
-/**
- * Parse a comma separated list of network interfaces and check
- * that the number of interfaces match the PNET_MAX_PHYSICAL_PORTS
- * configuration.
- *
- * For a single Ethernet interface, the \a arg_str should consist of
- * one name. For two Ethernet interfaces, the  \a arg_str should consist of
- * three names, as we also need a bridge interface.
- *
- * Does only consider the number of comma separated names. No check of the
- * names themselves are done.
- *
- * Examples:
- * arg_str                 num_ports
- * "eth0"                  1
- * "eth0,eth1"             error (We need a bridge as well)
- * "br0,eth0,eth1"         2
- *
- * @param arg_str      In:   Network interface list as comma separated,
- *                           terminated string. For example "eth0" or
- *                           "br0,eth0,eth1".
- * @param max_port     In:   PNET_MAX_PHYSICAL_PORTS, passed as argument to
- *                           allow test.
- * @param p_if_list    Out:  List of network interfaces
- * @param p_num_ports  Out:  Resulting number of physical ports
- * @return  0  on success
- *         -1  on error
- */
-int app_utils_get_netif_namelist (
-   const char * arg_str,
-   uint16_t max_port,
-   app_utils_netif_namelist_t * p_if_list,
-   uint16_t * p_num_ports);
-
-/**
- * Print network configuration using APP_LOG_INFO().
- *
- * @param if_cfg           In:   Network configuration
- * @param number_of_ports  In:   Number of used ports
- */
-void app_utils_print_network_config (
-   pnet_if_cfg_t * if_cfg,
-   uint16_t number_of_ports);
-
-/**
- * Print message if IOXS has changed.
- *
- * Uses APP_LOG_INFO()
- *
- * @param subslot          In: Subslot
- * @param ioxs_str         In: String description Producer or Consumer
- * @param ioxs_current     In: Current status
- * @param ioxs_new         In: New status
- */
-void app_utils_print_ioxs_change (
-   const app_subslot_t * subslot,
-   const char * ioxs_str,
-   uint8_t ioxs_current,
-   uint8_t ioxs_new);
-
-/**
- * Init the p-net configuration to default values.
- *
- * Most values are picked from app_gsdml.h
- *
- * Network configuration not initialized.
- * This means that \a '.if_cfg' must be set by application.
- *
- * Use this function to init P-Net configuration before
- * before passing config to app_init().
- *
- * @param pnet_cfg     Out:   Configuration for use by p-net
- * @return  0  if the operation succeeded.
- *          -1 if an error occurred.
- */
-int app_utils_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg);
-
-/**
- * Plug application module
- *
- * This is for the application to remember which slots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @param id               In:    Module identity
- * @param name             In:    Module name
- * @return 0 on success, -1 on error
- */
-int app_utils_plug_module (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint32_t id,
-   const char * name);
-
-/**
- * Pull any application module in given slot.
- *
- * This is for the application to remember which slots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @return 0 on success, -1 on error
- */
-int app_utils_pull_module (app_api_t * p_api, uint16_t slot_nbr);
-
-/**
- * Plug application submodule.
- *
- * This is for the application to remember which subslots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @param subslot_nbr      In:    Subslot number
- * @param submodule_id     In:    Submodule identity
- * @param p_data_cfg       In:    Data configuration,
- *                                direction, in and out sizes
- * @param submodule_name   In:    Submodule name
- * @param cyclic_callback  In:    Submodule data callback
- * @param tag              In:    Tag passed in cyclic callback
- *                                Typically application or
- *                                submodule handle
- * @return Reference to allocated subslot,
- *         NULL if no free subslot is available. This should
- *         never happen if application is aligned with p-net state.
- */
-app_subslot_t * app_utils_plug_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint32_t submodule_id,
-   const pnet_data_cfg_t * p_data_cfg,
-   const char * submodule_name,
-   app_utils_cyclic_callback cyclic_callback,
-   void * tag);
-
-/**
- * Unplug any application submodule from given subslot.
- *
- * This is for the application to remember which subslots are
- * populated in the p-net stack.
- *
- * @param p_api            InOut: API
- * @param slot_nbr         In:    Slot number
- * @param subslot_nbr      In:    Subslot number
- * @return 0 on success, -1 on error.
- */
-int app_utils_pull_submodule (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr);
-
-/**
- * Trigger data callback for all plugged submodules in all slots.
- *
- * The callbacks given in \a app_utils_plug_submodule() are used.
- *
- * @param p_api         In:   API
- */
-void app_utils_cyclic_data_poll (app_api_t * p_api);
-
-/**
- * Get subslot application information.
- *
- * @param p_appdata        InOut: Application state.
- * @param slot_nbr         In:    Slot number.
- * @param subslot_nbr      In:    Subslot number. Range 0 - 0x9FFF.
- * @return Reference to application subslot,
- *         NULL if subslot is not found/plugged.
- */
-app_subslot_t * app_utils_subslot_get (
-   app_api_t * p_api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr);
-
-/**
- * Return true if subslot is input.
- *
- * @param p_subslot        In:    Reference to subslot.
- * @return true if subslot is input or input/output.
- *         false if not.
- */
-bool app_utils_subslot_is_input (const app_subslot_t * p_subslot);
-
-/**
- * Return true if subslot is neither input or output.
- *
- * This is applies for DAP submodules/slots
- *
- * @param p_subslot     In: Reference to subslot.
- * @return true if subslot is input or input/output.
- *         false if not.
- */
-bool app_utils_subslot_is_no_io (const app_subslot_t * p_subslot);
-
-/**
- * Return true if subslot is output.
- *
- * @param p_subslot     In: Reference to subslot.
- * @return true if subslot is output or input/output,
- *         false if not.
- */
-bool app_utils_subslot_is_output (const app_subslot_t * p_subslot);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* APP_UTILS_H */

+ 0 - 1235
samples/pn_dev_lan9662/sampleapp_common.c

@@ -1,1235 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#include "sampleapp_common.h"
-#include "app_utils.h"
-#include "app_gsdml.h"
-#include "app_data.h"
-#include "app_log.h"
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-#include "pnet_lan9662_api.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* Events handled by main task */
-#define APP_EVENT_READY_FOR_DATA BIT (0)
-#define APP_EVENT_TIMER          BIT (1)
-#define APP_EVENT_ALARM          BIT (2)
-#define APP_EVENT_ABORT          BIT (15)
-
-/* Defines used for alarm demo functionality */
-#define CHANNEL_ERRORTYPE_SHORT_CIRCUIT                       0x0001
-#define CHANNEL_ERRORTYPE_LINE_BREAK                          0x0006
-#define CHANNEL_ERRORTYPE_DATA_TRANSMISSION_IMPOSSIBLE        0x8000
-#define CHANNEL_ERRORTYPE_NETWORK_COMPONENT_FUNCTION_MISMATCH 0x8008
-#define EXTENDED_CHANNEL_ERRORTYPE_FRAME_DROPPED              0x8000
-#define EXTENDED_CHANNEL_ERRORTYPE_MAUTYPE_MISMATCH           0x8001
-#define EXTENDED_CHANNEL_ERRORTYPE_LINE_DELAY_MISMATCH        0x8002
-
-#define APP_ALARM_USI                       0x0010
-#define APP_DIAG_CHANNEL_NUMBER             4
-#define APP_DIAG_CHANNEL_DIRECTION          PNET_DIAG_CH_PROP_DIR_INPUT
-#define APP_DIAG_CHANNEL_NUMBER_OF_BITS     PNET_DIAG_CH_PROP_TYPE_1_BIT
-#define APP_DIAG_CHANNEL_SEVERITY           PNET_DIAG_CH_PROP_MAINT_FAULT
-#define APP_DIAG_CHANNEL_ERRORTYPE          CHANNEL_ERRORTYPE_SHORT_CIRCUIT
-#define APP_DIAG_CHANNEL_ADDVALUE_A         0
-#define APP_DIAG_CHANNEL_ADDVALUE_B         1234
-#define APP_DIAG_CHANNEL_EXTENDED_ERRORTYPE 0
-#define APP_DIAG_CHANNEL_QUAL_SEVERITY      0 /* Not used (Max one bit set) */
-
-typedef struct app_data_t
-{
-   pnet_t * net;
-
-   /* P-Net configuration passed in app_init(). */
-   pnet_cfg_t * pnet_cfg;
-
-   /* Application api for administration of plugged
-    *(sub)modules and connection state.
-    */
-   app_api_t main_api;
-
-   os_timer_t * main_timer;
-   os_event_t * main_events;
-
-   bool alarm_allowed;
-   pnet_alarm_argument_t alarm_arg;
-   uint8_t alarm_payload[APP_GSDML_ALARM_PAYLOAD_SIZE];
-
-   uint32_t arep_for_appl_ready;
-   uint32_t appl_ready_delay_count;
-   bool appl_ready_wait;
-
-   uint32_t process_data_tick_counter;
-
-   app_mode_t mode;
-
-} app_data_t;
-
-static void app_plug_dap (app_data_t * app, uint16_t number_of_ports);
-static int app_set_initial_data_and_ioxs (app_data_t * app);
-static void app_cyclic_data_callback (app_subslot_t * subslot, void * tag);
-
-app_data_t app_state;
-
-pnet_t * app_get_pnet_instance (app_data_t * app)
-{
-   if (app != NULL)
-   {
-      return app->net;
-   }
-   return NULL;
-}
-
-app_data_t * app_init (pnet_cfg_t * pnet_cfg, const app_args_t * app_args)
-{
-   app_data_t * app = &app_state;
-
-   app->alarm_allowed = true;
-   app->main_api.arep = UINT32_MAX;
-   app->pnet_cfg = pnet_cfg;
-
-#if PNET_OPTION_DRIVER_LAN9662
-   app->mode = app_args->mode;
-   switch (app->mode)
-   {
-   case MODE_HW_OFFLOAD_CPU:
-      APP_LOG_INFO ("Application RTE mode \"cpu\"\n");
-      pnet_cfg->driver_enable = true;
-      break;
-   case MODE_HW_OFFLOAD_FULL:
-      APP_LOG_INFO ("Application RTE mode \"full\"\n");
-      pnet_cfg->driver_enable = true;
-      break;
-   case MODE_HW_OFFLOAD_NONE:
-      APP_LOG_INFO ("Application RTE mode \"none\"\n");
-      pnet_cfg->driver_enable = false;
-      break;
-   default:
-      APP_LOG_ERROR ("Application mode undefined\n");
-      pnet_cfg->driver_enable = false;
-      break;
-   }
-#else
-   app->mode = MODE_HW_OFFLOAD_NONE;
-#endif
-
-   app_data_init (app->mode);
-
-   app->net = pnet_init (app->pnet_cfg);
-
-   if (app->net == NULL)
-   {
-      return NULL;
-   }
-
-   return app;
-}
-
-static void main_timer_tick (os_timer_t * timer, void * arg)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   os_event_set (app->main_events, APP_EVENT_TIMER);
-}
-
-int app_start (app_data_t * app, app_run_in_separate_task_t task_config)
-{
-   if (app == NULL)
-   {
-      return -1;
-   }
-
-   app->main_events = os_event_create();
-   if (app->main_events == NULL)
-   {
-      return -1;
-   }
-
-   app->main_timer = os_timer_create (
-      APP_TICK_INTERVAL_US,
-      main_timer_tick,
-      (void *)app,
-      false);
-
-   if (app->main_timer == NULL)
-   {
-      os_event_destroy (app->main_events);
-      return -1;
-   }
-
-   if (task_config == RUN_IN_SEPARATE_THREAD)
-   {
-      os_thread_create (
-         "p-net_sample_app",
-         APP_MAIN_THREAD_PRIORITY,
-         APP_MAIN_THREAD_STACKSIZE,
-         app_loop_forever,
-         (void *)app);
-   }
-
-   os_timer_start (app->main_timer);
-
-   return 0;
-}
-
-static void app_set_outputs_default_value (void)
-{
-   // APP_LOG_DEBUG ("Setting outputs to default values.\n");
-   app_data_set_default_outputs();
-}
-
-/*********************************** Callbacks ********************************/
-
-static int app_connect_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG ("PLC connect indication. AREP: %u\n", arep);
-   /*
-    *  Handle the request on an application level.
-    *  This is a very simple application which does not need to handle anything.
-    *  All the needed information is in the AR data structure.
-    */
-
-   return 0;
-}
-
-static int app_release_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG ("PLC release (disconnect) indication. AREP: %u\n", arep);
-
-   app_set_outputs_default_value();
-
-   return 0;
-}
-
-static int app_dcontrol_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_control_command_t control_command,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG (
-      "PLC dcontrol message. AREP: %u  Command: %s\n",
-      arep,
-      app_utils_dcontrol_cmd_to_string (control_command));
-
-   return 0;
-}
-
-static int app_ccontrol_cnf (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG (
-      "PLC ccontrol message confirmation. AREP: %u  Status codes: %d "
-      "%d %d %d\n",
-      arep,
-      p_result->pnio_status.error_code,
-      p_result->pnio_status.error_decode,
-      p_result->pnio_status.error_code_1,
-      p_result->pnio_status.error_code_2);
-
-   return 0;
-}
-
-static int app_write_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint16_t idx,
-   uint16_t sequence_number,
-   uint16_t write_length,
-   const uint8_t * p_write_data,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG (
-      "PLC write record indication.\n"
-      "  AREP: %u API: %u Slot: %2u Subslot: %u Index: %u Sequence: %2u "
-      "Length: %u\n",
-      arep,
-      api,
-      slot_nbr,
-      subslot_nbr,
-      (unsigned)idx,
-      sequence_number,
-      write_length);
-
-   return 0;
-}
-
-static int app_read_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t api,
-   uint16_t slot_nbr,
-   uint16_t subslot_nbr,
-   uint16_t idx,
-   uint16_t sequence_number,
-   uint8_t ** pp_read_data,
-   uint16_t * p_read_length,
-   pnet_result_t * p_result)
-{
-   APP_LOG_DEBUG (
-      "PLC read record indication.\n"
-      "  AREP: %u API: %u Slot: %2u Subslot: %u Index: %u Sequence: %2u Max "
-      "length: %u\n",
-      arep,
-      api,
-      slot_nbr,
-      subslot_nbr,
-      (unsigned)idx,
-      sequence_number,
-      (unsigned)*p_read_length);
-
-   return 0;
-}
-
-static int app_state_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   pnet_event_values_t state)
-{
-   uint16_t err_cls = 0;  /* Error code 1 */
-   uint16_t err_code = 0; /* Error code 2 */
-   const char * error_class_description = "";
-   const char * error_code_description = "";
-
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "Event indication %s   AREP: %u\n",
-      app_utils_event_to_string (state),
-      arep);
-
-   if (state == PNET_EVENT_ABORT)
-   {
-      if (pnet_get_ar_error_codes (net, arep, &err_cls, &err_code) == 0)
-      {
-         app_utils_get_error_code_strings (
-            err_cls,
-            err_code,
-            &error_class_description,
-            &error_code_description);
-         APP_LOG_DEBUG (
-            "    Error class: 0x%02x %s \n"
-            "    Error code:  0x%02x %s \n",
-            (unsigned)err_cls,
-            error_class_description,
-            (unsigned)err_code,
-            error_code_description);
-      }
-      else
-      {
-         APP_LOG_DEBUG ("    No error status available\n");
-      }
-      /* Set output values */
-      app_set_outputs_default_value();
-
-      /* Only abort AR with correct session key */
-      os_event_set (app->main_events, APP_EVENT_ABORT);
-   }
-   else if (state == PNET_EVENT_PRMEND)
-   {
-      if (app->main_api.arep != UINT32_MAX)
-      {
-         APP_LOG_WARNING ("Warning - AREP out of sync\n");
-      }
-      app->main_api.arep = arep;
-
-      app_set_initial_data_and_ioxs (app);
-
-      (void)pnet_set_provider_state (net, true);
-
-      /* Send application ready at next tick
-         Do not call pnet_application_ready() here as it will affect
-         the internal stack states */
-      app->arep_for_appl_ready = arep;
-      os_event_set (app->main_events, APP_EVENT_READY_FOR_DATA);
-   }
-   else if (state == PNET_EVENT_DATA)
-   {
-      APP_LOG_DEBUG ("Cyclic data transmission started\n\n");
-   }
-
-   return 0;
-}
-
-static int app_reset_ind (
-   pnet_t * net,
-   void * arg,
-   bool should_reset_application,
-   uint16_t reset_mode)
-{
-   APP_LOG_DEBUG (
-      "PLC reset indication. Application reset mandatory: %u  Reset mode: %d\n",
-      should_reset_application,
-      reset_mode);
-
-   return 0;
-}
-
-static int app_signal_led_ind (pnet_t * net, void * arg, bool led_state)
-{
-   APP_LOG_INFO ("Profinet signal LED indication. New state: %u\n", led_state);
-
-   app_set_led (APP_PROFINET_SIGNAL_LED_ID, led_state);
-   return 0;
-}
-
-static int app_exp_module_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t api,
-   uint16_t slot,
-   uint32_t module_ident)
-{
-   int ret = -1;
-   int result = 0;
-   app_data_t * app = (app_data_t *)arg;
-   const char * module_name = "unknown";
-   const app_gsdml_module_t * module_config;
-
-   APP_LOG_DEBUG ("Module plug indication API %d\n");
-
-   if (slot >= PNET_MAX_SLOTS)
-   {
-      APP_LOG_ERROR (
-         "Unsupported slot number: %u  It should be less than %u\n",
-         slot,
-         PNET_MAX_SLOTS);
-      return -1;
-   }
-
-   module_config = app_gsdml_get_module_cfg (module_ident);
-   if (module_config == NULL)
-   {
-      APP_LOG_ERROR ("  Module ID %08x not found.\n", (unsigned)module_ident);
-      /*
-       * Needed to pass Behavior scenario 2
-       */
-      APP_LOG_DEBUG ("  Plug expected module anyway\n");
-   }
-   else
-   {
-      module_name = module_config->name;
-   }
-
-   APP_LOG_DEBUG ("  [%u] Pull old module\n", slot);
-   result = pnet_pull_module (net, api, slot);
-
-   if (result == 0)
-   {
-      app_utils_pull_module (&app->main_api, slot);
-   }
-
-   APP_LOG_DEBUG (
-      "  [%u] Plug module. Module ID: 0x%x \"%s\"\n",
-      slot,
-      (unsigned)module_ident,
-      module_name);
-
-   ret = pnet_plug_module (net, api, slot, module_ident);
-   if (ret == 0)
-   {
-      app_utils_plug_module (&app->main_api, slot, module_ident, module_name);
-   }
-   else
-   {
-      APP_LOG_ERROR (
-         "  [%u] Plug module failed. Ret: %u Module ID: 0x%x \" \"\n",
-         slot,
-         ret,
-         (unsigned)module_ident,
-         module_name);
-   }
-
-   return ret;
-}
-
-static int app_exp_submodule_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t api,
-   uint16_t slot,
-   uint16_t subslot,
-   uint32_t module_id,
-   uint32_t submodule_id,
-   const pnet_data_cfg_t * p_exp_data)
-{
-   int ret = -1;
-   int result = 0;
-   pnet_data_cfg_t data_cfg = {0};
-   app_data_t * app = (app_data_t *)arg;
-   const app_gsdml_submodule_t * submod_cfg;
-   const char * name = "Unsupported";
-   app_utils_cyclic_callback cyclic_data_callback = NULL;
-   app_subslot_t * p_subslot;
-
-   APP_LOG_DEBUG ("Submodule plug indication API %u\n", api);
-
-   submod_cfg = app_gsdml_get_submodule_cfg (submodule_id);
-   if (submod_cfg != NULL)
-   {
-      data_cfg.data_dir = submod_cfg->data_dir;
-      data_cfg.insize = submod_cfg->insize;
-      data_cfg.outsize = submod_cfg->outsize;
-      name = submod_cfg->name;
-
-      if (data_cfg.insize > 0 || data_cfg.outsize > 0)
-      {
-         cyclic_data_callback = app_cyclic_data_callback;
-      }
-   }
-   else
-   {
-      APP_LOG_WARNING (
-         "  [%u,%u] Submodule ID 0x%x in Module ID 0x%x not found \n",
-         slot,
-         subslot,
-         (unsigned)submodule_id,
-         (unsigned)module_id);
-
-      /*
-       * Needed for behavior scenario 2 to pass.
-       * Iops will be set to bad for this subslot
-       */
-      APP_LOG_WARNING (
-         "  [%u,%u] Plug expected submodule anyway\n",
-         slot,
-         subslot);
-
-      data_cfg.data_dir = p_exp_data->data_dir;
-      data_cfg.insize = p_exp_data->insize;
-      data_cfg.outsize = p_exp_data->outsize;
-   }
-
-   APP_LOG_DEBUG ("  [%u,%u] Pull old submodule.\n", slot, subslot);
-
-   result = pnet_pull_submodule (net, api, slot, subslot);
-   if (result == 0)
-   {
-      app_utils_pull_submodule (&app->main_api, slot, subslot);
-   }
-
-   APP_LOG_DEBUG (
-      "  [%u,%u] Plug submodule. Submodule ID: 0x%x Data Dir: %s In: %u Out: "
-      "%u \"%s\"\n",
-      slot,
-      subslot,
-      (unsigned)submodule_id,
-      app_utils_submod_dir_to_string (data_cfg.data_dir),
-      data_cfg.insize,
-      data_cfg.outsize,
-      name);
-
-   if (
-      data_cfg.data_dir != p_exp_data->data_dir ||
-      data_cfg.insize != p_exp_data->insize ||
-      data_cfg.outsize != p_exp_data->outsize)
-   {
-      APP_LOG_WARNING (
-         "  [%u,%u] Warning expected Data Dir: %s In: %u Out: %u\n",
-         slot,
-         subslot,
-         app_utils_submod_dir_to_string (p_exp_data->data_dir),
-         p_exp_data->insize,
-         p_exp_data->outsize);
-   }
-   ret = pnet_plug_submodule (
-      net,
-      api,
-      slot,
-      subslot,
-      module_id,
-      submodule_id,
-      data_cfg.data_dir,
-      data_cfg.insize,
-      data_cfg.outsize);
-
-   if (ret == 0)
-   {
-      p_subslot = app_utils_plug_submodule (
-         &app->main_api,
-         slot,
-         subslot,
-         submodule_id,
-         &data_cfg,
-         name,
-         cyclic_data_callback,
-         app);
-
-      /**
-       * Setup the RTE configuration for submodules data provided by the FPGA.
-       */
-
-      if (app->mode == MODE_HW_OFFLOAD_FULL)
-      {
-         const uint8_t * default_data;
-         uint16_t fpga_address;
-
-         if (
-            app_data_get_fpga_info_by_id (
-               submodule_id,
-               &fpga_address,
-               &default_data) == 0)
-         {
-            pnet_mera_rte_data_cfg_t rte_cfg = {
-               .type = PNET_MERA_DATA_TYPE_QSPI,
-               .address = fpga_address,
-               .default_data = default_data};
-
-            APP_LOG_INFO (
-               "  %-40s Set RTE QSPI address 0x%x\n",
-               app_utils_get_subslot_string (p_subslot),
-               rte_cfg.address);
-
-            if (data_cfg.insize > 0)
-            {
-               if (
-                  pnet_mera_input_set_rte_config (
-                     app->net,
-                     APP_GSDML_API,
-                     slot,
-                     subslot,
-                     &rte_cfg) != 0)
-               {
-                  APP_LOG_ERROR (
-                     "  %-40s RTE configuration failed\n",
-                     app_utils_get_subslot_string (p_subslot));
-               }
-            }
-            else
-            {
-               if (
-                  pnet_mera_output_set_rte_config (
-                     app->net,
-                     APP_GSDML_API,
-                     slot,
-                     subslot,
-                     &rte_cfg) != 0)
-               {
-                  APP_LOG_ERROR (
-                     "  %-40s RTE configuration failed\n",
-                     app_utils_get_subslot_string (p_subslot));
-               }
-            }
-         }
-      }
-   }
-   else
-   {
-      APP_LOG_ERROR (
-         "  [%u,%u] Plug submodule failed. Ret: %u\n",
-         slot,
-         subslot,
-         ret);
-   }
-
-   return ret;
-}
-
-static int app_new_data_status_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   uint32_t crep,
-   uint8_t changes,
-   uint8_t data_status)
-{
-   bool is_running = data_status & BIT (PNET_DATA_STATUS_BIT_PROVIDER_STATE);
-   bool is_valid = data_status & BIT (PNET_DATA_STATUS_BIT_DATA_VALID);
-
-   APP_LOG_DEBUG (
-      "Data status indication. AREP: %u  Data status changes: 0x%02x  "
-      "Data status: 0x%02x\n",
-      arep,
-      changes,
-      data_status);
-   APP_LOG_DEBUG (
-      "   %s, %s, %s, %s, %s\n",
-      is_running ? "Run" : "Stop",
-      is_valid ? "Valid" : "Invalid",
-      (data_status & BIT (PNET_DATA_STATUS_BIT_STATE)) ? "Primary" : "Backup",
-      (data_status & BIT (PNET_DATA_STATUS_BIT_STATION_PROBLEM_INDICATOR))
-         ? "Normal operation"
-         : "Problem",
-      (data_status & BIT (PNET_DATA_STATUS_BIT_IGNORE))
-         ? "Ignore data status"
-         : "Evaluate data status");
-
-   if (is_running == false || is_valid == false)
-   {
-      app_set_outputs_default_value();
-   }
-
-   return 0;
-}
-
-static int app_alarm_ind (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   const pnet_alarm_argument_t * p_alarm_arg,
-   uint16_t data_len,
-   uint16_t data_usi,
-   const uint8_t * p_data)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "Alarm indication. AREP: %u API: %d Slot: %d Subslot: %d "
-      "Type: %d Seq: %d Length: %d USI: %d\n",
-      arep,
-      p_alarm_arg->api_id,
-      p_alarm_arg->slot_nbr,
-      p_alarm_arg->subslot_nbr,
-      p_alarm_arg->alarm_type,
-      p_alarm_arg->sequence_number,
-      data_len,
-      data_usi);
-
-   app->alarm_arg = *p_alarm_arg;
-   os_event_set (app->main_events, APP_EVENT_ALARM);
-
-   return 0;
-}
-
-static int app_alarm_cnf (
-   pnet_t * net,
-   void * arg,
-   uint32_t arep,
-   const pnet_pnio_status_t * p_pnio_status)
-{
-   app_data_t * app = (app_data_t *)arg;
-
-   APP_LOG_DEBUG (
-      "PLC alarm confirmation. AREP: %u  Status code %u, "
-      "%u, %u, %u\n",
-      arep,
-      p_pnio_status->error_code,
-      p_pnio_status->error_decode,
-      p_pnio_status->error_code_1,
-      p_pnio_status->error_code_2);
-
-   app->alarm_allowed = true;
-
-   return 0;
-}
-
-static int app_alarm_ack_cnf (pnet_t * net, void * arg, uint32_t arep, int res)
-{
-   APP_LOG_DEBUG (
-      "PLC alarm ACK confirmation. AREP: %u  Result: "
-      "%d\n",
-      arep,
-      res);
-
-   return 0;
-}
-
-/**
- * Plug all DAP (sub)modules
- * Use existing callback functions to plug the (sub-)modules
- * @param app              InOut:   Application handle
- * @param number_of_ports  In:      Number of active ports
- */
-static void app_plug_dap (app_data_t * app, uint16_t number_of_ports)
-{
-   const pnet_data_cfg_t cfg_dap_data = {
-      .data_dir = PNET_DIR_NO_IO,
-      .insize = 0,
-      .outsize = 0,
-   };
-
-   APP_LOG_DEBUG ("Plug DAP module and its submodules\n");
-
-   app_exp_module_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_MOD_DAP_IDENT);
-
-   app_exp_submodule_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_SUBSLOT_DAP_IDENT,
-      PNET_MOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_IDENT,
-      &cfg_dap_data);
-
-   app_exp_submodule_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_SUBSLOT_DAP_INTERFACE_1_IDENT,
-      PNET_MOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_IDENT,
-      &cfg_dap_data);
-
-   app_exp_submodule_ind (
-      app->net,
-      app,
-      APP_GSDML_API,
-      PNET_SLOT_DAP_IDENT,
-      PNET_SUBSLOT_DAP_INTERFACE_1_PORT_1_IDENT,
-      PNET_MOD_DAP_IDENT,
-      PNET_SUBMOD_DAP_INTERFACE_1_PORT_1_IDENT,
-      &cfg_dap_data);
-
-   if (number_of_ports >= 2)
-   {
-      app_exp_submodule_ind (
-         app->net,
-         app,
-         APP_GSDML_API,
-         PNET_SLOT_DAP_IDENT,
-         PNET_SUBSLOT_DAP_INTERFACE_1_PORT_2_IDENT,
-         PNET_MOD_DAP_IDENT,
-         PNET_SUBMOD_DAP_INTERFACE_1_PORT_2_IDENT,
-         &cfg_dap_data);
-   }
-
-   if (number_of_ports >= 3)
-   {
-      app_exp_submodule_ind (
-         app->net,
-         app,
-         APP_GSDML_API,
-         PNET_SLOT_DAP_IDENT,
-         PNET_SUBSLOT_DAP_INTERFACE_1_PORT_3_IDENT,
-         PNET_MOD_DAP_IDENT,
-         PNET_SUBMOD_DAP_INTERFACE_1_PORT_3_IDENT,
-         &cfg_dap_data);
-   }
-
-   if (number_of_ports >= 4)
-   {
-      app_exp_submodule_ind (
-         app->net,
-         app,
-         APP_GSDML_API,
-         PNET_SLOT_DAP_IDENT,
-         PNET_SUBSLOT_DAP_INTERFACE_1_PORT_4_IDENT,
-         PNET_MOD_DAP_IDENT,
-         PNET_SUBMOD_DAP_INTERFACE_1_PORT_4_IDENT,
-         &cfg_dap_data);
-   }
-}
-
-/**
- * Send application ready to the PLC
- * @param net              InOut: p-net stack instance
- * @param arep             In:    Arep
- */
-static void app_handle_send_application_ready (pnet_t * net, uint32_t arep)
-{
-   int ret = -1;
-
-   APP_LOG_DEBUG (
-      "Application will signal that it is ready for data, for "
-      "AREP %u.\n",
-      arep);
-
-   ret = pnet_application_ready (net, arep);
-   if (ret != 0)
-   {
-      APP_LOG_ERROR (
-         "Error returned when application telling that it is ready for "
-         "data. Have you set IOCS or IOPS for all subslots?\n");
-   }
-
-   /* When the PLC sends a confirmation to this message, the
-      pnet_ccontrol_cnf() callback will be triggered.  */
-}
-
-/**
- * Send alarm ACK to the PLC
- *
- * @param net              InOut: p-net stack instance
- * @param arep             In:    Arep
- * @param p_alarm_arg      In:    Alarm argument (slot, subslot etc)
- */
-static void app_handle_send_alarm_ack (
-   pnet_t * net,
-   uint32_t arep,
-   const pnet_alarm_argument_t * p_alarm_arg)
-{
-   pnet_pnio_status_t pnio_status = {0, 0, 0, 0};
-   int ret;
-
-   ret = pnet_alarm_send_ack (net, arep, p_alarm_arg, &pnio_status);
-   if (ret != 0)
-   {
-      APP_LOG_DEBUG ("Error when sending alarm ACK. Error: %d\n", ret);
-   }
-   else
-   {
-      APP_LOG_DEBUG ("Alarm ACK sent\n");
-   }
-}
-
-/**
- * Handle cyclic data for all plugged submodules
- * Data is read from / written to the app_data file
- * which handles the data and update the physical
- * input /outputs.
- *
- * For subslots with mapped shared memory inputs, the
- * shared memory is read and the data is passed to the
- * stack.
- *
- * For subslots with mapped shared memory outputs, the
- * current output data is fetched from the stack and written to
- * mapped shared memory.
- *
- * @param subslot    In:   Subslot reference
- * @param tag        In:   Application handle
- */
-static void app_cyclic_data_callback (app_subslot_t * subslot, void * tag)
-{
-   app_data_t * app = (app_data_t *)tag;
-   uint8_t iops = PNET_IOXS_BAD;
-   uint8_t iocs = PNET_IOXS_BAD;
-   uint8_t * indata;
-   uint16_t indata_size;
-   bool outdata_updated;
-   uint16_t outdata_length;
-   uint8_t outdata_iops;
-   uint8_t * outdata;
-
-   if (app == NULL)
-   {
-      APP_LOG_ERROR ("Application tag not set in subslot?\n");
-      return;
-   }
-
-   if (subslot->data_cfg.insize > 0)
-   {
-      indata =
-         app_data_get_input_data (subslot->submodule_id, &indata_size, &iops);
-
-      if (indata != NULL)
-      {
-         iops = PNET_IOXS_GOOD;
-      }
-
-      (void)pnet_input_set_data_and_iops (
-         app->net,
-         APP_GSDML_API,
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         indata,
-         indata_size,
-         iops);
-
-      (void)pnet_input_get_iocs (
-         app->net,
-         APP_GSDML_API,
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         &iocs);
-
-      app_utils_print_ioxs_change (
-         subslot,
-         "Consumer Status (IOCS)",
-         subslot->indata_iocs,
-         iocs);
-      subslot->indata_iocs = iocs;
-   }
-
-   if (subslot->data_cfg.outsize > 0)
-   {
-      outdata = app_data_get_output_data_buffer (
-         subslot->submodule_id,
-         &outdata_length);
-
-      pnet_output_get_data_and_iops (
-         app->net,
-         APP_GSDML_API,
-         subslot->slot_nbr,
-         subslot->subslot_nbr,
-         &outdata_updated,
-         outdata,
-         &outdata_length,
-         &outdata_iops);
-
-      app_utils_print_ioxs_change (
-         subslot,
-         "Provider Status (IOPS)",
-         subslot->outdata_iops,
-         outdata_iops);
-      subslot->outdata_iops = outdata_iops;
-
-      if (outdata_length != subslot->data_cfg.outsize)
-      {
-         APP_LOG_ERROR (
-            "  %-40s Wrong outputdata length %u (%u)\n",
-            app_utils_get_subslot_string (subslot),
-            outdata_length,
-            subslot->data_cfg.outsize);
-         app_set_outputs_default_value();
-      }
-      else if (outdata_iops == PNET_IOXS_GOOD)
-      {
-         /* Set output data for submodule */
-         app_data_set_output_data (
-            subslot->submodule_id,
-            outdata,
-            outdata_length);
-      }
-      else
-      {
-         app_set_outputs_default_value();
-      }
-   }
-}
-
-/**
- * Set initial input data, provider and consumer status for a subslot.
- *
- * @param app              In:    Application handle
- */
-static int app_set_initial_data_and_ioxs (app_data_t * app)
-{
-   int ret;
-   uint8_t iops;
-   uint16_t slot;
-   uint16_t subslot;
-   const app_subslot_t * p_subslot;
-   uint8_t * indata;
-   uint16_t indata_size;
-
-   for (slot = 0; slot < PNET_MAX_SLOTS; slot++)
-   {
-      for (subslot = 0; subslot < PNET_MAX_SUBSLOTS; subslot++)
-      {
-         p_subslot = &app->main_api.slots[slot].subslots[subslot];
-         if (p_subslot->plugged)
-         {
-            iops = PNET_IOXS_GOOD;
-            if (
-               p_subslot->data_cfg.insize > 0 ||
-               p_subslot->data_cfg.data_dir == PNET_DIR_NO_IO)
-            {
-               indata = NULL;
-               indata_size = p_subslot->data_cfg.insize;
-
-               if (p_subslot->data_cfg.insize > 0)
-               {
-                  indata = app_data_get_input_data (
-                     p_subslot->submodule_id,
-                     &indata_size,
-                     &iops);
-               }
-
-               ret = pnet_input_set_data_and_iops (
-                  app->net,
-                  APP_GSDML_API,
-                  p_subslot->slot_nbr,
-                  p_subslot->subslot_nbr,
-                  indata,
-                  indata_size,
-                  iops);
-
-               /*
-                * If a submodule is still plugged but not used in current
-                * AR setting the data and iops will fail. This is not a
-                * problem. Log message below will only be printed for
-                * active submodules.
-                */
-               if (ret == 0)
-               {
-                  APP_LOG_DEBUG (
-                     "  %-40s Set input data and IOPS. Size: %d "
-                     "IOPS: %s\n",
-                     app_utils_get_subslot_string (p_subslot),
-                     p_subslot->data_cfg.insize,
-                     app_utils_ioxs_to_string (iops));
-               }
-            }
-
-            if (p_subslot->data_cfg.outsize > 0)
-            {
-               ret = pnet_output_set_iocs (
-                  app->net,
-                  APP_GSDML_API,
-                  p_subslot->slot_nbr,
-                  p_subslot->subslot_nbr,
-                  PNET_IOXS_GOOD);
-
-               if (ret == 0)
-               {
-                  APP_LOG_DEBUG (
-                     "  %-40s Set output IOCS: %s\n",
-                     app_utils_get_subslot_string (p_subslot),
-                     app_utils_ioxs_to_string (PNET_IOXS_GOOD));
-               }
-            }
-         }
-      }
-   }
-   return 0;
-}
-
-/**
- * Send and receive cyclic / process data
- *
- * Generate callback for all plugged submodules
- * the sample application handles all submodules
- * in the app_cyclic_data_callback() function.
- * A complex device may register separate callbacks
- * for each submodule.
- *
- * @param app        In:    Application handle
- */
-static void app_handle_cyclic_data (app_data_t * app)
-{
-   /* For the sample application cyclic data is updated
-    * with a period defined by APP_TICKS_UPDATE_DATA
-    */
-   app->process_data_tick_counter++;
-   if (app->process_data_tick_counter < APP_TICKS_UPDATE_DATA)
-   {
-      return;
-   }
-   app->process_data_tick_counter = 0;
-
-   app_utils_cyclic_data_poll (&app->main_api);
-}
-
-void app_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg)
-{
-   app_utils_pnet_cfg_init_default (pnet_cfg);
-
-   pnet_cfg->state_cb = app_state_ind;
-   pnet_cfg->connect_cb = app_connect_ind;
-   pnet_cfg->release_cb = app_release_ind;
-   pnet_cfg->dcontrol_cb = app_dcontrol_ind;
-   pnet_cfg->ccontrol_cb = app_ccontrol_cnf;
-   pnet_cfg->read_cb = app_read_ind;
-   pnet_cfg->write_cb = app_write_ind;
-   pnet_cfg->exp_module_cb = app_exp_module_ind;
-   pnet_cfg->exp_submodule_cb = app_exp_submodule_ind;
-   pnet_cfg->new_data_status_cb = app_new_data_status_ind;
-   pnet_cfg->alarm_ind_cb = app_alarm_ind;
-   pnet_cfg->alarm_cnf_cb = app_alarm_cnf;
-   pnet_cfg->alarm_ack_cnf_cb = app_alarm_ack_cnf;
-   pnet_cfg->reset_cb = app_reset_ind;
-   pnet_cfg->signal_led_cb = app_signal_led_ind;
-
-   pnet_cfg->cb_arg = (void *)&app_state;
-}
-
-void app_loop_forever (void * arg)
-{
-   app_data_t * app = (app_data_t *)arg;
-   uint32_t mask = APP_EVENT_READY_FOR_DATA | APP_EVENT_TIMER |
-                   APP_EVENT_ALARM | APP_EVENT_ABORT;
-   uint32_t flags = 0;
-
-   app->main_api.arep = UINT32_MAX;
-
-   app_set_led (APP_DATA_LED_ID, false);
-   app_plug_dap (app, app->pnet_cfg->num_physical_ports);
-   APP_LOG_INFO ("Waiting for PLC connect request\n\n");
-
-   /* Main event loop */
-   for (;;)
-   {
-      os_event_wait (app->main_events, mask, &flags, OS_WAIT_FOREVER);
-      if (flags & APP_EVENT_READY_FOR_DATA)
-      {
-         /* Delay the application ready event to
-          * allow the RTE to start sending frames.
-          */
-         app->appl_ready_delay_count = 256;
-         app->appl_ready_wait = true;
-         os_event_clr (app->main_events, APP_EVENT_READY_FOR_DATA);
-      }
-      else if (flags & APP_EVENT_ALARM)
-      {
-         os_event_clr (app->main_events, APP_EVENT_ALARM);
-
-         app_handle_send_alarm_ack (
-            app->net,
-            app->main_api.arep,
-            &app->alarm_arg);
-      }
-      else if (flags & APP_EVENT_TIMER)
-      {
-         os_event_clr (app->main_events, APP_EVENT_TIMER);
-
-         if (app->appl_ready_wait)
-         {
-            /* Delayed application ready event */
-            if (app->appl_ready_delay_count == 0)
-            {
-               app->appl_ready_wait = false;
-               app_handle_send_application_ready (
-                  app->net,
-                  app->arep_for_appl_ready);
-            }
-            else
-            {
-               app->appl_ready_delay_count--;
-            }
-         }
-
-         if (app->main_api.arep != UINT32_MAX)
-         {
-            /* Todo this operation should be split
-             * and inputs handled before pnet_handle_periodic is
-             * called and outputs after.*/
-            app_handle_cyclic_data (app);
-         }
-
-         /* Run p-net stack */
-         pnet_handle_periodic (app->net);
-      }
-      else if (flags & APP_EVENT_ABORT)
-      {
-         os_event_clr (app->main_events, APP_EVENT_ABORT);
-
-         app->main_api.arep = UINT32_MAX;
-         app->alarm_allowed = true;
-         APP_LOG_DEBUG ("Connection closed\n");
-         APP_LOG_DEBUG ("Waiting for PLC connect request\n\n");
-      }
-   }
-}

+ 0 - 148
samples/pn_dev_lan9662/sampleapp_common.h

@@ -1,148 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-#ifndef SAMPLEAPP_COMMON_H
-#define SAMPLEAPP_COMMON_H
-
-#include "osal.h"
-#include "pnal.h"
-#include <pnet_api.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define APP_TICK_INTERVAL_US 1000 /* 1 ms */
-
-/* Thread configuration for targets where sample
- * event loop is run in a separate thread (not main).
- * This applies for linux sample app implementation.
- */
-#define APP_MAIN_THREAD_PRIORITY  15
-#define APP_MAIN_THREAD_STACKSIZE 4096 /* bytes */
-
-#define APP_DATA_LED_ID            1
-#define APP_PROFINET_SIGNAL_LED_ID 2
-
-#define APP_TICKS_UPDATE_DATA 100
-
-typedef enum
-{
-   MODE_HW_OFFLOAD_NONE = 0,
-   MODE_HW_OFFLOAD_CPU,
-   MODE_HW_OFFLOAD_FULL,
-} app_mode_t;
-
-typedef struct app_args
-{
-   char path_button1[PNET_MAX_FILE_FULLPATH_SIZE]; /** Terminated string */
-   char path_button2[PNET_MAX_FILE_FULLPATH_SIZE]; /** Terminated string */
-   char path_storage_directory[PNET_MAX_DIRECTORYPATH_SIZE]; /** Terminated */
-   char station_name[PNET_STATION_NAME_MAX_SIZE]; /** Terminated string */
-   char eth_interfaces
-      [PNET_INTERFACE_NAME_MAX_SIZE * (PNET_MAX_PHYSICAL_PORTS + 1) +
-       PNET_MAX_PHYSICAL_PORTS]; /** Terminated string */
-   int verbosity;
-   int show;
-   bool factory_reset;
-   bool remove_files;
-   app_mode_t mode;
-} app_args_t;
-
-typedef enum
-{
-   RUN_IN_SEPARATE_THREAD,
-   RUN_IN_MAIN_THREAD
-} app_run_in_separate_task_t;
-
-typedef struct app_data_t app_data_t;
-
-void app_pnet_cfg_init_default (pnet_cfg_t * pnet_cfg);
-
-/**
- * Initialize application
- *
- * Initialize P-Net stack and application.
- * The pnet_cfg argument shall have been initialized using
- * app_pnet_cfg_init_default() before this function is
- * called.
- * @param pnet_cfg               In:    P-Net start configuration
- * @return Application handle, NULL on error
- */
-app_data_t * app_init (pnet_cfg_t * pnet_cfg, const app_args_t * app_args);
-
-/**
- * Start application
- *
- * Application must have been initialized using app_init() before
- * app_start() is called.
- * If task_config parameters is set to RUN_IN_SEPARATE_THREAD a
- * thread execution the app_loop_forever() function is started.
- * If task_config is set to RUN_IN_MAIN_THREAD no such thread is
- * started and the caller must call the app_loop_forever() after
- * calling this function.
- * RUN_IN_MAIN_THREAD is intended for rt-kernel targets.
- * RUN_IN_SEPARATE_THREAD is intended for linux targets.
- * @param app                 In:    Application handle
- * @param task_config         In:    Defines if stack and application
- *                                   is run in main or separate task.
- *
- * @return 0 on success, -1 on error
- */
-int app_start (app_data_t * app, app_run_in_separate_task_t task_config);
-
-/**
- * Application task definition. Handles events
- * in eternal loop.
- * @param arg                 In: Application handle
- * return Should not
- */
-void app_loop_forever (void * arg);
-
-/**
- * Get P-Net instance from application
- *
- * @param app                 In:    Application handle
- *
- * @return P-Net instance
- */
-pnet_t * app_get_pnet_instance (app_data_t * app);
-
-/**
- * Set LED state
- * Hardware specific. Implemented in sample app main file for
- * each supported platform.
- *
- * @param id               In:    LED number, starting from 0.
- * @param led_state        In:    LED state. Use true for on and false for off.
- */
-void app_set_led (uint16_t id, bool led_state);
-
-/**
- * Read button state
- *
- * Hardware specific. Implemented in sample app main file for
- * each supported platform.
- *
- * @param id               In:    Button number, starting from 0.
- * @return  true if button is pressed, false if not
- */
-bool app_get_button (uint16_t id);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* SAMPLEAPP_COMMON_H */

+ 0 - 77
samples/pn_dev_lan9662/switchdev-profinet-example.sh

@@ -1,77 +0,0 @@
-#!/bin/sh
-#
-# Start Profinet sample application
-# By default RTE mode is set to full / RTE-FGPA
-# The RTE mode can be selected by passing
-# "none", "cpu" or "full" to this script.
-#
-# Application RTE modes
-# none
-#  - LAN9662 RTE:      Disabled
-#  - I/O Data mapping: Shared Memory
-#  - P-Net data path:  P-Net default
-# cpu
-#  - LAN9662 RTE:      Enabled
-#  - I/O Data mapping: Shared Memory
-#  - P-Net data path:  RTE - SRAM
-# full
-#  - LAN9662 RTE:      Enabled
-#  - I/O Data mapping: iofpga
-#  - P-Net data path:  RTE - QSPI
-#
-# P-Net profinet requires a file system for
-# configuration storage. This example assumes
-# a rw file system mounted on /tmp/pn_data
-#
-
-echo "Starting switchdev-profinet-example"
-
-# Assume a valid partition on /dev/mmcblk0p2
-mkdir /tmp/pn_data
-mount -o sync /dev/mmcblk0p2 /tmp/pn_data
-
-# Configure bridge
-ip link add name br0 type bridge
-
-# Needed for bridge to work
-symreg ANA_PGID[61] 0x1ff
-
-ip link set br0 address 12:A9:2D:16:93:89
-ip link set br0 up
-sysctl -w net.ipv6.conf.br0.disable_ipv6=1
-
-ip link set eth0 up
-ip link set eth1 up
-
-ip link set eth0 master br0
-ip link set eth1 master br0
-
-# Enable forwarding to chip port 4 (RTE)
-symreg qsys_sw_port_mode[4] 0x45000
-
-# Start Profinet application
-if [[ $# -eq 0 ]] ; then
-    mode=full
-else
-    mode=$1
-fi
-
-echo "Starting LAN9662 Profinet sample application"
-echo "RTE mode: $mode"
-
-/usr/bin/pn_lan9662 -m "$mode" -vvvv -p /tmp/pn_data &
-
-# When enabling log level "DEBUG" for the P-Net stack
-# it may be useful to write log to file. The log file
-# can be uploaded from target using scp:
-# scp root@192.168.0.50:/tmp/pn_dev_log.txt pn_dev_log.txt
-
-#echo "Setup dropbear to support scp"
-#mkdir -p /var/run/dropbear/
-#dropbear -R -B
-
-# Enable to to write p-net log to file.
-#touch /tmp/pn_dev_log.txt
-#chmod a+w /tmp/pn_dev_log.txt
-#echo " Application log will be stored to /tmp/pn_dev_log.txt"
-#/usr/bin/pn_lan9662 -m "$mode" -vvvv -p /tmp/pn_data > /tmp/pn_dev_log.txt

+ 0 - 17
samples/pn_shm_tool/CMakeLists.txt

@@ -1,17 +0,0 @@
-#********************************************************************
-#        _       _         _
-#  _ __ | |_  _ | |  __ _ | |__   ___
-# | '__|| __|(_)| | / _` || '_ \ / __|
-# | |   | |_  _ | || (_| || |_) |\__ \
-# |_|    \__|(_)|_| \__,_||_.__/ |___/
-#
-# http://www.rt-labs.com
-# Copyright 2017 rt-labs AB, Sweden.
-# See LICENSE file in the project root for full license information.
-#*******************************************************************/
-
-target_include_directories(pn_shm_tool
-  PRIVATE
-  )
-
-install (TARGETS pn_shm_tool DESTINATION bin)

+ 0 - 509
samples/pn_shm_tool/pn_shm_tool.c

@@ -1,509 +0,0 @@
-/*********************************************************************
- *        _       _         _
- *  _ __ | |_  _ | |  __ _ | |__   ___
- * | '__|| __|(_)| | / _` || '_ \ / __|
- * | |   | |_  _ | || (_| || |_) |\__ \
- * |_|    \__|(_)|_| \__,_||_.__/ |___/
- *
- * www.rt-labs.com
- * Copyright 2021 rt-labs AB, Sweden.
- *
- * This software is dual-licensed under GPLv3 and a commercial
- * license. See the file LICENSE.md distributed with this software for
- * full license information.
- ********************************************************************/
-
-/* Linux application intended to be used
- * to read and write shared memory areas supported
- * by the lan9662 sample application.
- * See show_usage() for a functional description.
- */
-
-#include <getopt.h>
-#include <semaphore.h>
-#include <sys/mman.h>
-#include <sys/stat.h>
-
-#include <errno.h>
-#include <fcntl.h>
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#define MAX_FILE_NAME    200
-#define MAX_STDIO_BUFFER 10000
-
-#define DEBUG_LOG (1)
-#if DEBUG_LOG == 1
-#define LOG_ERR(...)                                                           \
-   fprintf (stderr, "Line:%d ", __LINE__);                                     \
-   fprintf (stderr, __VA_ARGS__);
-#else
-#define LOG_ERR(...)
-#endif
-
-typedef struct app
-{
-   enum
-   {
-      UNDEFINED = 0,
-      READ,
-      WRITE,
-      CREATE,
-      READ_BIT
-   } mode;
-
-   char name[MAX_FILE_NAME]; /* Shared memory file name*/
-   int fd;                   /* Shared memory file descriptor */
-   caddr_t mem_address;      /* Address of mapped shared memory */
-   sem_t * sem;              /* Named semaphore */
-   size_t shm_size;          /* The size of an existing shared memory area */
-   size_t create_size;       /* Size argument used when creating a shared memory
-                                area*/
-   uint32_t bitnumber;       /* Bit number to read */
-   uint8_t buffer[MAX_STDIO_BUFFER];
-} app_t;
-
-static void show_usage (void)
-{
-   printf ("\nTool for accessing shared memory files\n");
-   printf ("Intended to be used in combination with the \n"
-           "pn_lan9662 sample application. \n");
-   printf ("Arguments:\n");
-   printf ("   -h             Show help and exit\n");
-   printf (
-      "   -r <shm_name>  Read shared memory and write content to stdout \n");
-   printf ("   -w <shm_name>  Write content on stdin to shared memory \n");
-   printf ("   -c <shm_name>  Create shared memory area\n");
-   printf ("   -s <size>      Size of shared memory, only used with create\n");
-   printf ("   -b <shm_name>  Read bit from shared memory. Write '1' or '0' "
-           "to stdout\n");
-   printf (
-      "   -n <bitnumber> Bit number, only used with read bit. Defaults to\n");
-   printf (
-      "                  bit number 0 (least significant bit in first byte)\n");
-   printf (
-      "Partial write is allowed. Offsets are not supported. If write data\n");
-   printf ("is larger than shared memory, data is truncated.\n");
-
-   printf ("\nExample usage:\n");
-   printf ("Read slot and passing data to hexdump:\n");
-   printf ("pn_shm_tool -r pnet-in-1-1-digital_input_1x8 | hexdump -C\n");
-   printf ("Write slot:\n");
-   printf ("echo -n -e \"\\x02\" | pn_shm_tool -w "
-           "pnet-in-1-1-digital_input_1x8\n");
-   printf ("Create 4 bytes shared memory area (for testing this tool):\n");
-   printf ("pn_shm_tool -c test_shm -s 4\n");
-}
-
-/**
- * Open an existing shared memory area
- * figure out its size and map it.
- * @param   app      InOut: Application context
- * @return 0 on success, -1 on error
- */
-int open_shm (app_t * app)
-{
-   struct stat st;
-
-   if (app->mode == CREATE)
-   {
-      return -1;
-   }
-
-   app->fd = shm_open (app->name, O_RDWR, 0666);
-
-   if (app->fd < 0)
-   {
-      LOG_ERR ("\nFailed to open %s %s\n", app->name, strerror (errno));
-      return -1;
-   }
-
-   if (fstat (app->fd, &st))
-   {
-      LOG_ERR ("\nfstat error: [%s]\n", strerror (errno));
-      close (app->fd);
-      return -1;
-   }
-
-   app->shm_size = st.st_size;
-
-   if (ftruncate (app->fd, app->shm_size) != 0)
-   {
-      return -1;
-   }
-
-   app->mem_address =
-      mmap (NULL, app->shm_size, PROT_READ | PROT_WRITE, MAP_SHARED, app->fd, 0);
-
-   if (app->mem_address == MAP_FAILED)
-   {
-      LOG_ERR ("\nmmap error: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   app->sem = sem_open (app->name, 0, 0644, 1);
-
-   if (app->sem == NULL)
-   {
-      LOG_ERR ("\nFailed to open semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   return 0;
-}
-
-/**
- * Create a new shared memory area
- * @param   app      InOut: Application context
- * @return 0 on success, -1 on error
- */
-int create_shm (app_t * app)
-{
-   if (app->mode != CREATE)
-   {
-      return -1;
-   }
-
-   app->fd = shm_open (app->name, O_RDWR | O_CREAT, 0666);
-
-   if (app->fd < 0)
-   {
-      LOG_ERR ("\nFailed to create %s %s\n", app->name, strerror (errno));
-      return -1;
-   }
-
-   if (ftruncate (app->fd, app->create_size) != 0)
-   {
-      return -1;
-   }
-
-   app->mem_address = mmap (
-      NULL,
-      app->create_size,
-      PROT_READ | PROT_WRITE,
-      MAP_SHARED,
-      app->fd,
-      0);
-
-   if (app->mem_address == MAP_FAILED)
-   {
-      LOG_ERR ("\nmmap error: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   app->sem = sem_open (app->name, O_CREAT, 0644, 1);
-
-   if (app->sem == NULL)
-   {
-      LOG_ERR ("\nFailed to open semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   return 0;
-}
-
-/**
- * Close a shared memory area and its
- * open resources.
- * @param   app      InOut: Application context
- * @return 0 always
- */
-int close_shm (app_t * app)
-{
-   if (app->mem_address != 0)
-   {
-      munmap (app->mem_address, app->shm_size);
-      app->mem_address = 0;
-   }
-
-   if (app->fd >= 0)
-   {
-      close (app->fd);
-      app->fd = -1;
-   }
-
-   if (app->sem != NULL)
-   {
-      sem_close (app->sem);
-      app->sem = NULL;
-   }
-
-   return 0;
-}
-
-/**
- * Read a shared memory area and print its content
- * to STDOUT.
- * @param   app      InOut: Application context
- * @return 0 on success, -1 on error
- */
-int read_shm (app_t * app)
-{
-   int write_len;
-
-   if (sem_wait (app->sem) != 0)
-   {
-      LOG_ERR ("\nFailed to take semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   memcpy (app->buffer, app->mem_address, app->shm_size);
-
-   if (sem_post (app->sem) != 0)
-   {
-      LOG_ERR ("\nFailed to release semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   write_len = write (STDOUT_FILENO, app->buffer, app->shm_size);
-   if (write_len != (int)app->shm_size)
-   {
-      LOG_ERR ("\nFailed to write stdout\n");
-      return -1;
-   }
-
-   return 0;
-}
-
-/**
- * Read a bit from shared memory area and print "0" or "1" to STDOUT.
- * @param   app      InOut: Application context
- * @return 0 on success, -1 on error
- */
-int read_bit_shm (app_t * app)
-{
-   int write_len = 0;
-   uint32_t byte_number = 0;
-   uint8_t bitnumber_in_byte = 0;
-   uint8_t byte_value = 0;
-   uint8_t bit_value = 0;
-
-   if (app->shm_size == 0)
-   {
-      LOG_ERR ("\nShared memory size is zero\n");
-      return -1;
-   }
-
-   if (app->bitnumber >= MAX_STDIO_BUFFER * 8)
-   {
-      LOG_ERR (
-         "\nToo large bitnumber. Given: %u (Buffer size %u bytes)\n",
-         app->bitnumber,
-         MAX_STDIO_BUFFER);
-      return -1;
-   }
-
-   if (app->bitnumber >= app->shm_size * 8)
-   {
-      LOG_ERR (
-         "\nToo large bitnumber. Given: %u (Memory size %zu bytes)\n",
-         app->bitnumber,
-         app->shm_size);
-      return -1;
-   }
-
-   if (sem_wait (app->sem) != 0)
-   {
-      LOG_ERR ("\nFailed to take semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   memcpy (app->buffer, app->mem_address, app->shm_size);
-
-   if (sem_post (app->sem) != 0)
-   {
-      LOG_ERR ("\nFailed to release semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   byte_number = app->bitnumber / 8; /* byte_number 0 is first */
-   byte_value = app->buffer[byte_number];
-   bitnumber_in_byte = app->bitnumber % 8;
-   bit_value = (byte_value >> bitnumber_in_byte) & 0x01;
-
-   write_len = write (STDOUT_FILENO, bit_value ? "1\n" : "0\n", 2);
-   if (write_len != 2)
-   {
-      LOG_ERR ("\nFailed to write stdout\n");
-      return -1;
-   }
-
-   return 0;
-}
-
-/**
- * Read STDIN and copy the data to shared memory area.
- * @param   app      InOut: Application context
- * @return 0 on success, -1 on error
- */
-int write_shm (app_t * app)
-{
-   int len = read (STDIN_FILENO, app->buffer, app->shm_size);
-   if (len > (int)app->shm_size)
-   {
-      /* Truncate len of data to match shared memory */
-      len = app->shm_size;
-   }
-
-   if (len <= 0)
-   {
-      LOG_ERR ("\nFailed to read stdin: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   if (sem_wait (app->sem) != 0)
-   {
-      LOG_ERR ("\nFailed to take semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   memcpy (app->mem_address, app->buffer, len);
-
-   if (sem_post (app->sem) != 0)
-   {
-      LOG_ERR ("\nFailed to release semaphore: [%s]\n", strerror (errno));
-      return -1;
-   }
-
-   return 0;
-}
-
-/**
- * Execute a command given the configuration
- * set in the app variable.
- * Creation, read and write of shared memory regions
- * are supported.
- * @param   app      InOut: Application context
- * @return 0 on success, -1 on error
- */
-static int run (app_t * app)
-{
-   int error = 0;
-
-   if (app->mode == CREATE)
-   {
-      error = create_shm (app);
-      close_shm (app);
-      return error;
-   }
-
-   error = open_shm (app);
-   if (!error)
-   {
-      if (app->mode == READ)
-      {
-         error = read_shm (app);
-      }
-      else if (app->mode == READ_BIT)
-      {
-         error = read_bit_shm (app);
-      }
-      else if (app->mode == WRITE)
-      {
-         error = write_shm (app);
-      }
-      error |= close_shm (app);
-   }
-   return error;
-}
-
-/**
- * Parse command line arguments and execute selected command.
- * @param argc  In:  Number of args
- * @param argv  In:  Arguments
- * @return 0 on success, 1 on error
- */
-int main (int argc, char * argv[])
-{
-   int error = 0;
-   int option = 0;
-   app_t app = {0};
-
-   if (argc < 2)
-   {
-      show_usage();
-      exit (EXIT_FAILURE);
-   }
-
-   while ((option = getopt (argc, argv, "hw:r:c:s:b:n:")) != -1)
-   {
-      switch (option)
-      {
-      case 'r':
-         if (app.mode != UNDEFINED)
-         {
-            show_usage();
-            printf ("\nOnly one operation allowed\n");
-            exit (EXIT_FAILURE);
-         }
-         strncpy (app.name, optarg, MAX_FILE_NAME - 1);
-         app.mode = READ;
-         break;
-      case 'b':
-         if (app.mode != UNDEFINED)
-         {
-            show_usage();
-            printf ("\nOnly one operation allowed\n");
-            exit (EXIT_FAILURE);
-         }
-         strncpy (app.name, optarg, MAX_FILE_NAME - 1);
-         app.mode = READ_BIT;
-         break;
-      case 'w':
-         if (app.mode != UNDEFINED)
-         {
-            show_usage();
-            printf ("\nOnly one operation allowed\n");
-            exit (EXIT_FAILURE);
-         }
-         strncpy (app.name, optarg, MAX_FILE_NAME - 1);
-         app.mode = WRITE;
-         break;
-      case 'c':
-         if (app.mode != UNDEFINED)
-         {
-            show_usage();
-            printf ("\nOnly one operation allowed\n");
-            exit (EXIT_FAILURE);
-         }
-         strncpy (app.name, optarg, MAX_FILE_NAME - 1);
-         app.mode = CREATE;
-         break;
-      case 's':
-         app.create_size = atoi (optarg);
-         break;
-      case 'n':
-         app.bitnumber = atoi (optarg);
-         break;
-      case 'h':
-         show_usage();
-         exit (EXIT_SUCCESS);
-      default:
-         show_usage();
-         exit (EXIT_FAILURE);
-      }
-   }
-   if (app.mode == CREATE)
-   {
-      if (app.create_size <= 0 || app.create_size > MAX_STDIO_BUFFER)
-      {
-         show_usage();
-         printf ("\nSize must be set when creating shared mem area\n");
-         printf ("Min size 1, Max size %d\n", MAX_STDIO_BUFFER);
-         exit (EXIT_FAILURE);
-      }
-   }
-
-   error = run (&app);
-   if (error != 0)
-   {
-      fprintf (stderr, "Operation failed.\n");
-      exit (EXIT_FAILURE);
-   }
-
-   exit (EXIT_SUCCESS);
-}

+ 0 - 31
samples/pn_shm_tool/shm_LED_handler.sh

@@ -1,31 +0,0 @@
-#!/bin/sh
-#
-# Read shared memory and write to EVB-LAN9662 LED
-# Utility script using the pn_shm_tool. Intended to be
-# used for testing the pn_lan9662 application.
-#
-
-
-MEMORY_NAME="pnet-out-2-1-digital_output_1x8"
-BIT_NUMBER=7
-LED_NAME="twr1:yellow"
-
-echo "Starting LED handler for Profinet data LED"
-
-sleep 1
-
-while true
-do
-   sleep 0.1
-
-   led_state=$(pn_shm_tool -b "$MEMORY_NAME" -n "$BIT_NUMBER")
-   exitcode=$?
-
-   if [ $exitcode -ne 0 ]; then
-      echo "Failed to get LED state from shared memory"
-      exit 1
-   fi
-
-   echo ${led_state} > "/sys/class/leds/${LED_NAME}/brightness"
-
-done

+ 0 - 39
samples/pn_shm_tool/shm_button_handler.sh

@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# Read button on GPIO pin and write to shared memory
-# Utility script using the pn_shm_tool. Intended to be
-# used for testing the pn_lan9662 application.
-#
-
-MEMORY_NAME="pnet-in-1-1-digital_input_1x8"
-
-# Set up digital input on "Raspberry Pi"-type header
-# Button1, pin 7, use GND at pin 9
-GPIO_NUMBER=39
-
-echo "Starting button state monitor for GPIO $GPIO_NUMBER"
-
-echo "$GPIO_NUMBER" > /sys/class/gpio/export
-echo "1" > "/sys/class/gpio/gpio$GPIO_NUMBER/active_low"
-
-sleep 1
-
-while true
-do
-   sleep 0.1
-
-   button_state=$(cat "/sys/class/gpio/gpio$GPIO_NUMBER/value")
-   exitcode=$?
-
-   if [ $exitcode -ne 0 ]; then
-      echo "Failed to read button state"
-      exit 1
-   fi
-
-   if [ "$button_state" = "1" ]; then
-      echo -n -e '\x80' | pn_shm_tool -w "$MEMORY_NAME"
-   else
-      echo -n -e '\x00' | pn_shm_tool -w "$MEMORY_NAME"
-   fi
-
-done

+ 0 - 15
samples/pn_shm_tool/shm_echo_all.sh

@@ -1,15 +0,0 @@
-#!/bin/sh
-# Write shm outputs to inputs
-# For test running this command forever
-# may be handy:
-# while true; do /usr/bin/shm_echo_all.sh; done
-# Utility script using the pn_shm_tool. Intended to be
-# used for testing the pn_lan9662 application.
-#
-
-
-pn_shm_tool -r pnet-out-2-1-digital_output_1x8     | pn_shm_tool -w pnet-in-1-1-digital_input_1x8
-pn_shm_tool -r pnet-out-7-1-digital_out_1x64       | pn_shm_tool -w pnet-in-3-1-digital_input_1x64
-pn_shm_tool -r pnet-out-8-1-digital_output_2x32_a  | pn_shm_tool -w pnet-in-4-1-digital_input_2x32_a
-pn_shm_tool -r pnet-out-9-1-digital_output_2x32_b  | pn_shm_tool -w pnet-in-5-1-digital_input_2x32_b
-pn_shm_tool -r pnet-out-10-1-digital_output_1x800  | pn_shm_tool -w pnet-in-6-1-digital_input_1x800

+ 0 - 33
samples/pn_shm_tool/shm_read_all.sh

@@ -1,33 +0,0 @@
-#!/bin/sh
-# Utility script using the pn_shm_tool. Intended to be
-# used for testing the pn_lan9662 application.
-#
-# Dump the contents of all shared memory areas
-# supported by the lan9662 profinet sample application
-
-echo "Inputs"
-echo "------------------------------------------------------------------"
-echo "pnet-in-1-1-digital_input_1x8"
-pn_shm_tool -r pnet-in-1-1-digital_input_1x8 | hexdump -C
-echo "pnet-in-3-1-digital_input_1x64"
-pn_shm_tool -r pnet-in-3-1-digital_input_1x64 | hexdump -C
-echo "pnet-in-4-1-digital_input_2x32_a"
-pn_shm_tool -r pnet-in-4-1-digital_input_2x32_a | hexdump -C
-echo "pnet-in-5-1-digital_input_2x32_b"
-pn_shm_tool -r pnet-in-5-1-digital_input_2x32_b | hexdump -C
-echo "pnet-in-6-1-digital_input_1x800"
-pn_shm_tool -r pnet-in-6-1-digital_input_1x800 | hexdump -C
-
-echo ""
-echo "Outputs"
-echo "------------------------------------------------------------------"
-echo "pnet-out-2-1-digital_output_1x8"
-pn_shm_tool -r pnet-out-2-1-digital_output_1x8 | hexdump -C
-echo "pnet-out-7-1-digital_output_1x64"
-pn_shm_tool -r pnet-out-7-1-digital_output_1x64 | hexdump -C
-echo "pnet-out-8-1-digital_output_2x32_a"
-pn_shm_tool -r pnet-out-8-1-digital_output_2x32_a | hexdump -C
-echo "pnet-out-9-1-digital_output_2x32_b"
-pn_shm_tool -r pnet-out-9-1-digital_output_2x32_b | hexdump -C
-echo "pnet-out-10-1-digital_output_1x800"
-pn_shm_tool -r pnet-out-10-1-digital_output_1x800 | hexdump -C

+ 0 - 29
samples/pn_shm_tool/shm_write_all_inputs.sh

@@ -1,29 +0,0 @@
-#!/bin/sh
-# Utility script using the pn_shm_tool. Intended to be
-# used for testing the pn_lan9662 application.
-#
-# Write a character / byte to all shared memory inputs
-# supported by the lan9662 profinet sample application
-# Usage:
-#         shm_write_all_inputs.sh a
-#         shm_write_all_inputs.sh "\x02"
-
-echo -n -e "$1" | \
-pn_shm_tool -w pnet-in-1-1-digital_input_1x8
-
-echo -n -e "$1$1$1$1$1$1$1$1" | \
-pn_shm_tool -w pnet-in-3-1-digital_input_1x64
-
-echo -n -e "$1$1$1$1$1$1$1$1" | \
-pn_shm_tool -w pnet-in-4-1-digital_input_2x32_a
-
-echo -n -e "$1$1$1$1$1$1$1$1" | \
-pn_shm_tool -w pnet-in-5-1-digital_input_2x32_b
-
-data=''
-for i in `seq 1 100`;
-do
-data="${data}$1"
-done
-echo -n -e "$data" | \
-pn_shm_tool -w pnet-in-6-1-digital_input_1x800

+ 0 - 122
samples/pn_shm_tool/test.sh

@@ -1,122 +0,0 @@
-#!/bin/sh
-echo "Sanity test of pn_shm_tool."
-
-# Create a shared memory area for test
-f="shm_test_2"
-echo "Creating /dev/shm/$f for test"
-
-$(./pn_shm_tool -c "$f" -s 4)
-
-
-# 1 Verify correct size of data
-
-data_in="abcd"
-echo "Test data: $data_in"
-
-$(echo -n -e "$data_in" | ./pn_shm_tool -w "$f")
-data_out=$(./pn_shm_tool -r "$f")
-
-echo "Data out:  $data_out"
-
-if [ "$data_out" != "$data_in" ]; then
-  echo "Error"
-  exit 1
-fi
-
-
-# 2 Verify correct too small input data
-
-data_in="ABC"
-echo "Test data: $data_in"
-
-$(echo -n -e "$data_in" | ./pn_shm_tool -w "$f")
-data_out=$(./pn_shm_tool -r "$f")
-
-echo "Data out:  $data_out"
-
-# First three bytes changed. Last byte keeps value
-if [ "$data_out" != "ABCd" ]; then
-  echo "Error"
-  exit 1
-fi
-
-
-# 3 Verify correct too large input data
-
-data_in="123456"
-echo "Test data: $data_in"
-
-$(echo -n -e "$data_in" | ./pn_shm_tool -w "$f")
-data_out=$(./pn_shm_tool -r "$f")
-
-echo "Data out:  $data_out"
-
-# All bytes changed. Size unchanged
-if [ "$data_out" != "1234" ]; then
-  echo "Error"
-  exit 1
-fi
-
-
-# 4 faulty parameter
-
-echo "Testing invalid parameter:"
-show_cmd=$(./pn_shm_tool -d "$f")
-ret_val=$?
-echo " "
-
-if [ $ret_val -ne 1 ]; then
-  echo "Error"
-  exit 1
-fi
-
-# 5 Verify reading bit
-
-data_in="1234"
-echo "Test data: $data_in"
-echo "The stored data as ASCII: 0x31 0x32 0x33 0x34"
-
-$(echo -n -e "$data_in" | ./pn_shm_tool -w "$f")
-
-data_out=$(./pn_shm_tool -b "$f" -n 0)
-ret_val=$?
-if [ $ret_val -ne 0 ]; then
-  echo "Error when reading 0: Wrong exit code"
-  exit 1
-fi
-if [ "$data_out" != "1" ]; then
-  echo "Error reading bit 0: Wrong value"
-  exit 1
-fi
-
-data_out=$(./pn_shm_tool -b "$f" -n 1)
-if [ "$data_out" != "0" ]; then
-  echo "Error reading bit 1"
-  exit 1
-fi
-
-data_out=$(./pn_shm_tool -b "$f" -n 2)
-if [ "$data_out" != "0" ]; then
-  echo "Error reading bit 2"
-  exit 1
-fi
-
-data_out=$(./pn_shm_tool -b "$f" -n 3)
-if [ "$data_out" != "0" ]; then
-  echo "Error reading bit 3"
-  exit 1
-fi
-
-
-# 6 faulty parameter to read bit
-echo "Testing invalid parameter:"
-data_out=$(./pn_shm_tool -b "$f" -n 32)
-ret_val=$?
-echo " "
-
-if [ $ret_val -ne 1 ]; then
-  echo "Error"
-  exit 1
-fi
-
-echo "OK, test passed"

+ 0 - 61
tools/clean_no_alarm.sh

@@ -1,61 +0,0 @@
-number_of_arguments=$#
-directory=$1
-mode_argument=$2
-
-if [ "$number_of_arguments" -eq 0 ] || [ "$number_of_arguments" -gt 2 ]; then
-    echo "Usage: clean_no_alarm.sh directory [-a]"
-    echo
-    echo "Remove wireshark files that don't contain Profinet alarm frames."
-    echo
-    echo "By default this script will examine the next-newest file in the directory."
-    echo "Give the -a argument to scan all files in the directory."
-    echo
-    echo "Use the watch command to run this repeatedly:"
-    echo "  watch -n 10 ./clean_no_alarm.sh DIRECTORYNAME"
-    echo
-    echo "where the -n argument specifies the number of seconds between each invocation."
-    echo
-    echo "This tool uses the tshark program, which must be installed."
-    echo
-    echo "To record the files it is recommended to use the tcpdump utility to continuously"
-    echo "save data into 10 MByte files:"
-    echo "  sudo tcpdump -i INTERFACENAME -C 10 -w recordingfile -K -n"
-    echo "The directory that the files are saved into must have write permission for all:"
-    echo "  chmod o+w DIRECTORYNAME"
-
-    # Handling both sourced and executed script
-    return 1 2>/dev/null
-    exit 1
-fi
-
-# Delete a wireshark pcap file if it doesn't contain any Profinet alarm frames
-examine_file () {
-    full_path=$1
-    echo "Examining the file: ${full_path}"
-
-    file_description=`file ${full_path}`
-    case "$file_description" in
-    *capture*) ;;
-    *        ) echo "  Not a wireshark file"; return ;;
-    esac
-
-    # Check if the file contains the Profinet frame ID for ALARM_PRIO_LOW
-    number_of_alarm_frames=`tshark -r ${full_path} -T fields -e frame.number -Y "pn_rt.frame_id == 65025"  | wc -l`
-    if [ "$number_of_alarm_frames" -eq 0 ]; then
-        echo "  Deleting ${full_path} as it has no alarms"
-        rm "$full_path"
-    fi
-}
-
-if [ "$mode_argument" = "-a" ]
-then
-    # Examine all files in directory
-    for file in $directory/*
-    do
-        examine_file "$file"
-    done
-else
-    # Examine second newest file
-    filename=`ls -1t $directory | sed -n '2p'`
-    examine_file ${directory}/${filename}
-fi