From c8ad48b0e8b63ba1d0a0638d614a0dd847feb62b Mon Sep 17 00:00:00 2001 From: "Albrecht Johannes (DC-AE/ESW1)" Date: Mon, 27 May 2024 16:32:18 +0200 Subject: [PATCH] Fix: Fixed broken links --- doc/about.md | 2 +- doc/changelog.md | 11 +- .../TEMPLATE.diagnostics.en-US.json | 33 -- .../TEMPLATE.diagnostics.h | 24 - .../diagnosis_templates/readme.md | 97 ---- doc/datalayer.md | 476 ---------------- doc/dotnet.md | 518 +++++++++--------- doc/fbs2plc.md | 100 ---- doc/images/flatbuffer_compiler.png | Bin 12463 -> 0 bytes doc/samples.md | 94 ---- doc/storage-extension.md | 2 +- 11 files changed, 271 insertions(+), 1086 deletions(-) delete mode 100644 doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.en-US.json delete mode 100644 doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.h delete mode 100644 doc/common.log.diagnosis/diagnosis_templates/readme.md delete mode 100644 doc/datalayer.md delete mode 100644 doc/fbs2plc.md delete mode 100644 doc/images/flatbuffer_compiler.png delete mode 100644 doc/samples.md diff --git a/doc/about.md b/doc/about.md index 6d28c1482..2c3da80ed 100644 --- a/doc/about.md +++ b/doc/about.md @@ -1,4 +1,4 @@ -Copyright © 2020-2023 Bosch Rexroth AG. All rights reserved. +Copyright © 2020-2024 Bosch Rexroth AG. All rights reserved. Please note that any trademarks, logos and pictures contained or linked to in this Software are owned by or copyright © Bosch Rexroth AG 2023 and not licensed under the Software's license terms. diff --git a/doc/changelog.md b/doc/changelog.md index d38da059a..e14bb07a2 100644 --- a/doc/changelog.md +++ b/doc/changelog.md @@ -1,5 +1,14 @@ ## Software Development Kit for ctrlX AUTOMATION +### Version 2.6.0 May, 2024 + +* Docu: Improve documentation +* Moved angular sample to node samples +* C#: Upgrade to .NET 8 +* Go: Use package `ctrlx-datalayer-golang/v2` +* Node: Use node version 20.12.0 +* ctrlX Data Layer: Use version 2.6.1 + ### Version 2.4.0 November, 2023 * Fix: Some internal Bugfixes @@ -30,7 +39,7 @@ * Revisions regarding Virtual Box and Native Ubuntu 20.04 * Deploy fbs only in namepaces -See also [Changes of the App Build Environment ](app_builder_env_changes.md) +See also [Changes of the App Build Environment](app_builder_env_changes.md) ### Version 1.14.0 March 15, 2022 diff --git a/doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.en-US.json b/doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.en-US.json deleted file mode 100644 index 2fc5e2852..000000000 --- a/doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.en-US.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "product": "", - "mainDiagnostics": { - "": { - "text": "", - "version": , - "detailedDiagnostics": { - "": { - "text": "", - "version": - }, - "": { - "text": "", - "version": - } - } - }, - "": { - "text": "", - "version": , - "detailedDiagnostics": { - "": { - "text": "", - "version": - } - } - }, - "": { - "text": "", - "version": - } - } -} diff --git a/doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.h b/doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.h deleted file mode 100644 index 4490e1bcf..000000000 --- a/doc/common.log.diagnosis/diagnosis_templates/TEMPLATE.diagnostics.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -//! @file your_component_diagnostics.h -//! @brief This C++ header contains the diagnostics declarations of component 'your_component' in case of en-US used as default language. - -namespace your -{ - namespace component - { - constexpr char LIBRARY_DIAGNOSTICS_FILE_NAME[] = "your_component_diagnostics_en-US.json"; //!< File name with diagnostics used in this library. - - // -------------------- - // Main diagnostics - // -------------------- - constexpr std::uint32_t MAIN_DIAG_ = 0x; //!< - constexpr std::uint32_t MAIN_DIAG_ = 0x; //!< - - // -------------------- - // Detailed diagnostics - // -------------------- - constexpr std::uint32_t DETAILED_DIAG_ = 0x; //!< - constexpr std::uint32_t DETAILED_DIAG_ = 0x; //!< - } -} diff --git a/doc/common.log.diagnosis/diagnosis_templates/readme.md b/doc/common.log.diagnosis/diagnosis_templates/readme.md deleted file mode 100644 index 8d45a4468..000000000 --- a/doc/common.log.diagnosis/diagnosis_templates/readme.md +++ /dev/null @@ -1,97 +0,0 @@ -How to use, create, add and change diagnostics for the diagnosis system {#publicdocu} -======================================================================= - -This documentation is intended for Bosch developers of ctrlX CORE and in many parts also for OEMs, partners and customers. - -@copyright (C) 2019-20xx Bosch Rexroth AG - -The reproduction, distribution and utilization of this file as well as the communication of its contents to others -without express authorization is prohibited. Offenders will be held liable for the payment of damages. -All rights reserved in the event of the grant of a patent, utility model or design. - -# Introduction - -## Deprecated interfaces -The interfaced IRegistration, IRegistration2 and IRegistration3 are deprecated and should not be used! Use interface IRegistration4 instead! -Cause: The deprecated interfaces does not comply with C++20 and VS2022. Variable arguments are no longer transferred. This may lead to faulty texts in journald and logbook. - -## Some definitions -For the structure (definition of the individual bits) of the main and detailed diagnostic numbers, please see https://inside-docupedia.bosch.com/confluence/display/EDCA/DIA_Control_Diagnosenummer or the officially provided documentation of the diagnosis system https://docs.automation.boschrexroth.com/welcome/. -* Main diagnostic number: - * Must always be unambiguous. - * Whole number = 0 is reserved and cannot be used as a valid number. - * Valid source types (bits 24-29): 08-10 and 30-37, all others are invalid. - * Valid diagnostic classes in combination with priorities (bits 11-19): A0, E0, F0, F2, F6, F8, F9, all others are invalid. - * Disappeared bit (bit 20) is handled by diagnosis system -> always use 0. -* Detailed diagnostic number: - * May be ambiguous. - * Whole number = 0 is reserved and cannot be used as a valid number. -* The combination of main and detailed diagnostics must again be unambiguous. - -## Prepare a component the first time for the usage of diagnostic numbers - -### Get diagnostics bundle interfaces -* Add component "common.log.diagnosis" to your component. - -### Handle JSON File for un-/registration of diagnostics -* The file contains all main and detailed diagnostic numbers and texts for the default language (which will also always appear in journald). -* Create a JSON file for the diagnostics you want to use: - * For Bosch developers: - * For Bosch projects/components it is mandatory to use English texts for the default language. - * Use the export mechanism of the common database. Details see https://inside-docupedia.bosch.com/confluence/x/dY4ucw. - * It is necessary to provide the exported JSON file within your bundle. Therefore adapt your bundle CMakeLists.txt: - - celix_bundle_files(${BUNDLEX_NAME} - ${DIAGNOSTICS_FILES_DEPENDENCY_DIR}/public/src/common_log_diagnosis_diagnostics_en-US.json - DESTINATION "resources/diagnostics" - ) - * The path to the JSON file which is needed for un-/registration of the diagnostics is composed of the bundle path (gotten from Celix) and your chosen file location in your provided bundle and your chosen file name, e.g. matching the above definition: - - std::string pathToJsonFile = m_bundlePath + "/resources/diagnostics/" + "_diagnostics_en-US.json"; - * For OEMs, partners and customers: - * It is recommended to use English texts for the default language. - * The common.log.diagnosis component provides the file `public/src/diagnosis_templates/TEMPLATE.diagnostics.en-US.json` which can be used as a template for your diagnostics. - * The key "product" is optional. - * Recommendation for file location in your component: ./private/src/impl/resources/diagnostics/ - * It is necessary to provide the JSON file within your bundle. Therefore adapt your bundle CMakeLists.txt: - - celix_bundle_files(${BUNDLEX_NAME} - ${CMAKE_SOURCE_DIR}/private/src/impl/resources - DESTINATION "" - ) - * Hints: - * Keep in mind: special characters in your json text strings (like backslash or double quotes) have to be escaped by an additional backslash in front of the special character. - * The language identifier has to be part of the file name, e.g. `\.en-US.json`. Definitions see https://en.wikipedia.org/wiki/Language_localisation#Language_tags_and_codes. - * Recommendation for file name: `\_diagnostics_\.json`, e.g. `your_component.diagnostics.en-US.json`. - * The path to the JSON file which is needed for un-/registration of the diagnostics is composed of the bundle path (gotten from Celix) and your chosen file location in your provided bundle and your chosen file name, e.g. matching the above definition: - - std::string pathToJsonFile = m_bundlePath + "/resources/diagnostics/" + ".diagnostics.en-US.json"; - -### Handle declaration of diagnostics in C++ header file -* For sending logs to the diagnosis system, it is necessary to use the main and detailed diagnostic numbers. Therefore, it is recommended to create a header file with the declaration of symbolic constants of all your numbers in it. - * For Bosch developers: use the header file of the export mechanism of the common database. Details see https://inside-docupedia.bosch.com/confluence/x/dY4ucw. - * For OEMs, partners and customers: the common.log.diagnosis component provides the file `public/src/diagnosis_templates/TEMPLATE.diagnostics.h` which can be used as a template for your diagnostics. - -# Adding or changing a diagnostics - -## For Bosch developers of ctrlX CORE - -## General steps when adding or changing a diagnostics -In general, when adding/changing a diagnostics the following steps have always to be done. -1. Think about the diagnosis text and do the review therefor - * see https://inside-docupedia.bosch.com/confluence/x/cB_GPQ -2. Insert a new diagnostic in the common database - * see https://inside-docupedia.bosch.com/confluence/x/u7_yZg -3. Use the export mechanism of the database to get the json file for your component - * https://inside-docupedia.bosch.com/confluence/x/dY4ucw -4. Add/edit the related diagnostics documentation - * see https://inside-docupedia.bosch.com/confluence/x/br8jSg - -## Change a main diagnostics -ToDo - -## Change a detailed diagnostics -ToDo - -# For OEMs, partners and customers -ToDo diff --git a/doc/datalayer.md b/doc/datalayer.md deleted file mode 100644 index 52b93fe5f..000000000 --- a/doc/datalayer.md +++ /dev/null @@ -1,476 +0,0 @@ -# Documentation - -* [naming conventions](#namingConventions) -* [provider](#provider) -* [Routing of requests](#routing) -* [Provider Interface functions](#providerInterface) -* [Usage of Variant](#variant) -* [Usage of flatbuffers](#flatbuffers) -* [Metadata](#metadata) -* [Typetree](#typetree) -* [Usage of client](#client) - -## Node names - -Each value is addressed by a path. A path creates of a set of nodes. When nodes are -named, an API is intuitive and easy to use. If done poorly, that same API can -feel difficult to use and to understand. - -A **node can be a singleton or a collection**. For Example ```customers``` is a -collection node and ```customer``` is a singleton resource (in a banking -domain). We can identify ```customers``` collection resource using the path -```/customers```. We can identify a single ```customer``` resource using -the path ```/customers/{customerID}```. - -A **node may contain sub-collection resources** also. For example, sub-collection -resource ```accounts``` of a particular ```customer``` can be identified -using the path ```/customers/{customerId}/accounts``` (in a banking domain). -Similarly, a singleton resource ```account``` inside the sub-collection -resource ```accounts``` can be identified as -follows: ```/customers/{customerId}/accounts/{accountId}```. - -## Provider - -A provider is responsible for nodes. One provider can handle an unlimited amount -of nodes. All requests to one provider are serialized: It's guarantied that if -you are in one of the interface functions of a node (onRead, onWrite, ...) no -other interface function of a node handled by the same provider is called. So -you don't have to handle mutual exclusion to data handled by one provider. - -### Register of nodes - -To register a path you have to specify which ProviderNode is responsible for this node. - -Example: -Registration for ethercat/version: whenever a request for "ethercat/version" is send, this request will be routed to this particular node. - -If a provider is responsible for multiple nodes or the subnodes are unknown at the moment of registration, its possible to register with wildcards. - -### Single wildcard "\*" - -A single wildcard is the sign "\*". "\*" stands for a any string on a hierarchy level. You can use multiple wildcards at different levels. - -Examples: - -* provider1: test/\* -* provider2: test/foo/\*/bar -* provider3: test/\*/foo -* provider4: test/\*/\* -* provider5: test/bar/bar - -### Double wildcard "\*\*" - -A double wildcard is the string "\*\*". "\*\*" stands for any string on any hierarchy level. Such a wildcard is only allowed as last characters at your registration string. - -Example: - -* provider6: test/\** -* provider7: test/bar/** - -## Routing of requests - -All requests except browse requests are routed to the provider the address matches best to the registered path. -So on each level a registration with a specific path matches before a registration with a wildcard. -A single wildcard matches before a double wildcard. -An address matches always the best registered provider (see example). -Only provider with a wildcard at end of it's registered address will get browse requests. - -### Behavior of '/' - -Any '/' at begin or end at the request address will be removed. A provider will -never get an address with a leading or tailing '/'. Routing of addresses will be -done without a leading or tailing '/'. - -### Example for routing of requests: - -| address | destination for browse | destination for read | -| -------------------- | ---------------------- | -------------------- | -| "" | nobody | nobody | -| "test" | provider1 | nobody | -| "test/1" | provider4 | provider1 | -| "test/1/foo" | provider6 | provider3 | -| "test/1/bar" | provider6 | provider4 | -| "test/foo" | provider4 | provider1 | -| "test/bar" | provider7 | provider1 | -| "test/bar/bar" | provider7 | provider5 | -| "test/bar/foo" | provider7 | provider7 | -| "test/bar/bar/foo" | provider7 | provider7 | -| "test/bar/foo/foo" | provider7 | provider7 | -| "test/foo/foo" | provider6 | provider3 | -| "test/foo/foo/bar" | provider6 | provider2 | -| "test/foo/foo/foo" | provider6 | provider6 | -| "test/1/bar" | provider6 | provider4 | -| "test/1/bar/1" | provider6 | provider6 | - -### Browse - -Whenever a node is browsed, the result is a list of strings with contains the names of the subnodes of this nodes. In general datalayer wants to answer this kind of requests at its own. Only if someone has registered with a wildcard ("*") for this particular node this provider will be asked to give for subnodes. The result of this request will be merged with the nodes datalayer knows for its own. So a provider does not need to return values on a browse request it has already registered with a more specific path. - -| address | result of browse | -| -------------------- | ------------------------------------ | -| "" | "test" | -| "test" | "foo", "bar" + return from provider1 | -| "test/1" | "foo" + return from provider4 | -| "test/1/foo" | return from provider6 | -| "test/1/bar" | return from provider6 | -| "test/foo" | "foo" + return from provider4 | -| "test/bar" | "foo" + "bar"+ return from provider7 | -| "test/bar/bar" | return from provider7 | -| "test/bar/foo" | return from provider7 | -| "test/bar/bar/foo" | return from provider7 | -| "test/bar/foo/foo" | return from provider7 | -| "test/foo/foo" | "bar" + return from provider6 | -| "test/foo/foo/bar" | return from provider6 | -| "test/foo/foo/foo" | return from provider6 | -| "test/1/bar" | return from provider6 | -| "test/1/bar/1" | return from provider6 | - -## Provider Interface functions - -Properties: - -* idempotent, i.e. operation will have the same effect on the servers state if - executed once or multiple times (note: this does not necessarily mean returning - the same response or status code) -* safe, i.e. must not have side effects such as state changes -* Input data -* Output data - -| function | description | safe | idempotent | Input | Output | -| ---------- | ------------------------ | :--: | :--------: | :---: | :-----: | -| onCreate | Creates an object | no | no | yes | yes | -| onRemove | Removes an object | no | yes | no | no | -| onBrowse | Browse childs of a node | yes | yes | no | yes | -| onRead | Reads value of a node | yes | yes | yes | yes | -| onWrite | Writes value to a node | no | yes | yes | yes | -| onMetadata | Reads metadata of a node | yes | yes | no | no | - -Requests are Stateless: Your node/application is not allowed to store anything -about latest request. Handle each and every request as new. No session, no -history. Design your interface in a way that each request contains all the -information necessary to service the request. - -``` Text -No Client context shall be stored on the server between requests. -The client is responsible for managing the state of the application. -``` - -### onCreate - -This function should be used to create a new object. This function is not -idempotent. So two calls of onCreate will not have the same result. As input -all data should be provided to create the object. As output data the location -(path) of of the new object should be returned. - -Examples: - -* Creating an order in an online shop -* Creating an axis -* Creating a Motion Command - -### onRemove - -This function removes an object. No input and output data are allowed. - -Examples: - -* Removing an axis - -### onBrowse - -This function returns child nodes of this node. The result must be an -array of strings with the names of the child nodes. - -### onRead - -This function reads the value of a node. To specify the read operation the onRead -function may have input data. This function is idempotent and safe. So two equal -subsequent calls will have the same result and will not change the state. - -### onWrite - -This function changes the value of an already existing node. The new value is -provided as input data. As output data you can return the new node value or -nothing. This function is idempotent. So if you send a request multiple -times, that should be equivalent to a single request modification. - -### onMetadata - -This function returns the metadata of this note. You have to return a -metadata.fbs flatbuffer. See [metadata](#metadata). - -## Usage of Variant - -A variant holds data of different types. Following basic types are defined: - -| type | description | -| ----------------- | ---------------------------------------------------: | -| UNKNOWN | unknown datatype | -| BOOL8 | bool 8 bit | -| INT8 | signed int 8 bit | -| UINT8 | unsigned int 8 bit | -| INT16 | signed int 16 bit | -| UINT16 | unsigned int 16 bit | -| INT32 | signed int 32 bit | -| UINT32 | unsigned int 32 bit | -| INT64 | signed int 64 bit | -| UINT64 | unsigned int 64 bit | -| FLOAT32 | float 32 bit | -| FLOAT64 | float 64 bit | -| STRING | string (UTF-8) | -| ARRAY_OF_BOOL8 | array of bool 8 bit | -| ARRAY_OF_INT8 | array of signed int 8 bit | -| ARRAY_OF_UINT8 | array of unsigned int 8 bit | -| ARRAY_OF_INT16 | array of signed int 16 bit | -| ARRAY_OF_UINT16 | array of unsigned int 16 bit | -| ARRAY_OF_INT32 | array of signed int 32 bit | -| ARRAY_OF_UINT32 | array of unsigned int 32 bit | -| ARRAY_OF_INT64 | array of signed int 64 bit | -| ARRAY_OF_UINT64 | array of unsigned int 64 bit | -| ARRAY_OF_FLOAT32 | array of float 32 bit | -| ARRAY_OF_FLOAT64 | array of float 64 bit | -| ARRAY_OF_STRING | array of string (UTF-8) | -| RAW | raw bytes | -| FLATBUFFERS | bytes as a complex data type encoded as a flatbuffer | - -### Set a value of a variant - -To set a value to a variant, you can use one of the following functions: - -* setValue(\ value) - * value is a C data type: type of the variant will be identified **automatically** by its type (including string) - * value is a vector/set: - * array type of the variant will be identified **automatically** - * values will be copied -* setValue(\\* values, size_t count) - * value is array of c data type (including array of string) - * array type of variant will be identified **automatically** by its type (including string) - * values will be copied -* shareValue(\\* values, size_t count) - * In some cases it is not necessary to copy the value to a variant. A reference to the particular data is sufficient. - * type of variant will be identified automatically - * only a pointer to data will be stored - * this function is faster than the copy functions -* copyFlatbuffers() - * copyFlatbuffer from flatbuffer builder object -* shareFlatbuffers - * same as copyFlatbuffers() but data will not be copied. - * Only pointer to data will be stored -* setSharedPointer(type, data, size) - * set a variant to **type** with **data** and **size** - * data will not be copied, only a pointer will be stored -* setType(type, size) + copyRaw(data, size) - * set a variant with a specific **type** and **size** with **data** - * data will be copied - -### Get a value of a variant - -To access data you can assign a variant to a basic data type. If the type of the variant match the basic data type, -the value will be copied to the variable. If the type did not match, 0 or NULL will be returned. - -#### Example access scalar values - -``` Text - Variant variant; - uint32_t value1 = 4711; - variant.setValue(value1); - uint32_t value2 = variant; // value2 is 4711 - uint16_t value3 = variant; // value3 is 0 -``` - -To get the type of a variant use **getType()** - -#### Accessing values of an Array - -You can assign a variant to an C array type. If the type of the variant match the basic data type. - -#### Example access array values - -``` Text - Variant data; // data containing an array of string - const char** strArray = data; - for (size_t i = 0; i < data.getCount(); i++) - printf("%s", strArray[i]); -``` - -You can also use this kind of access for non-array values. getCount() returns 1 for nonArray values and cast to const pointer returns address of data. - -#### Access flatbuffers - -A variant can hold a flatbuffer. To check whether a variant has a specific flatbuffer type you can use the verifier of the flatbuffer. -This check contains check for right data type (FLATBUFFERS) and check against flatbuffer verifier. - -``` Text - Variant data; // data with a flatbuffer - if (STATUS_SUCCEEDED(data.verifyFlatbuffers(VerifyAxisBuffer))); // VerifyAxisBuffer is generated out of .fbs file - { - auto axis = GetAxis(data->getData()); // GetAxis is generated out of .fbs file - } -``` - -## Usage of flatbuffers - -Flatbuffers is used for complex data types. Documentation is available at [here](https://google.github.io/flatbuffers/). - -Base of a complex data type is type defined in a [.fbs](https://google.github.io/flatbuffers/flatbuffers_guide_writing_schema.html) file. -Out of a .fbs file you have to generate different files: - -![Flatbuffer Compiler](./images/flatbuffer_compiler.png) - -* type_generated.h - * File to include in your source code. This header enables you to access a existing flatbuffer or create a new one. -* type.bfbs - * binary representation of the type. This file is used for generic access to a flatbuffer. It enables the datalayer to - convert between flatbuffer and JSON. - * If you use flatbuffers as a data, you have to return the content of this file as metadata (see [metadata](#metadata)) - -### Automatic Build using CMake - -To build your `.fbs` files using CMake include following lines in your CMakeLists.txt. - -To use the right flatbuffer compiler use these lines: - -``` CMake -# set flatbuffer root folder -set(FLATBUFFER_ROOT ${DEPENDENCIES_ROOT}/appflatbuffers) - -# expand binary search path for flatbuffer compiler -if (WIN32) - set(CMAKE_PROGRAM_PATH ${CMAKE_PROGRAM_PATH} ${FLATBUFFER_ROOT}/public/bin/win-msvc-x86/release) -else() - set(CMAKE_PROGRAM_PATH ${CMAKE_PROGRAM_PATH} ${FLATBUFFER_ROOT}/public/bin/linux-gcc-x64/release) - - # set executable attributes for flatbuffer compiler - execute_process(COMMAND chmod +x ${FLATBUFFER_ROOT}/public/bin/linux-gcc-x64/debug/flatc) - execute_process(COMMAND chmod +x ${FLATBUFFER_ROOT}/public/bin/linux-gcc-x64/release/flatc) -endif() - -# include flatbuffer cmake functions -include(${FLATBUFFER_ROOT}/public/CMake/FindFlatBuffers.cmake) -``` - -To compile your `.fbs` files, use these lines: - -``` CMake -set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} ${FLATBUFFER_ROOT}/public/include ) -include(${FLATBUFFER_ROOT}/public/CMake/FindFlatBuffers.cmake) - -SET ( IDL_FILES ${IDL_FILES} - ${CMAKE_CURRENT_LIST_DIR}/mockups/Interpolator.fbs - ${CMAKE_CURRENT_LIST_DIR}/mockups/AllDataTypes.fbs - ${CMAKE_CURRENT_LIST_DIR}/motion/axis.fbs -) - -build_flatbuffers( "${IDL_FILES}" "" BuildFlatbuffers "" "${CMAKE_CURRENT_BINARY_DIR}" "${CMAKE_CURRENT_BINARY_DIR}" "") -``` - -This will generate an additional buildtarget `BuildFlatbuffers`. You can add this build target to your dependencies. - -### Tips and Tricks - -1. Force Defaults / IsField Present - * Tables fields are only stored if they are set and are different from its default values. To ensure that all values are set in your - flatbuffer, you can enable force_default in flatbuffer builder object: - ``` C++ - flatbuffers::FlatBufferBuilder builder; - builder.ForceDefaults(true); - ``` -2. Access of array values - * assume .fbs file - ``` C++ - table myTable { - myVecDouble:[double]; - } - root_type MyTable; - ``` - * access as flatbuffer vector - ``` C++ - auto myTable = GetMyTable(value.getData()); - auto myVecDouble = myTable->myVecDouble(); - for (size_t i = 0; i < myVecDouble->size(); i++) - double value = myVecDouble[i]; - ``` - * access as C array - ``` C++ - auto myTable = GetMyTable(value.getData()); - const double* myVecDouble = myTable->myVecDouble()->data(); - for (size_t i = 0; i < myVecDouble->size(); i++) - double value = myVecDouble[i]; - ``` - * access as plane uint_8* memory (little endian) - ``` C++ - auto myTable = GetMyTable(value.getData()); - const uint_8* myVecDouble = myTable->myVecDouble()->Data(); - ``` - -## Metadata - -Metadata contains additional information about a node. This information can be -read using the metadata function. -Definition of metadata can be found [here](../../private/src/impl/metadata.fbs). - -| field | comment | -| ------------------ | --------| -| nodeClass | Resource: node is a resource
Method: node is a command
Type: node represents a type | -| operations | contains allowed operations | -| description | Short description in markdown format | -| descriptionUrl | URL to detailed description | -| displayName | Name to be displayed instead of node address | -| displayFormat | Auto: display in standard type format
Bin: display as binary
Oct: display octal
Dec: display Decimal
Hex: display hexadecimal | -| unit | unit of value | -| extensions | user defined extensions (key/value pair) | -| references | references to other nodes (key/value pair) | - -### References to other nodes in metadata - -Metadata of nodes can reference other nodes. A reference contains of a type and -a targetAddress. -There are some predefined types of references - -| type | comment | -| ------------ | ------- | -| readType | type when reading a value | -| writeType | type when writing a value | -| createType | type when creating a value | - -The target of a reference is a address in the datalayer tree. - -## Typetree - -All types are included as nodes in the datalayer tree. Types are located under -"types/". Types can be references in metadata as a reference. - -## Usage Of Client - -### Creation - -To create a client use factory function ```createClient(addr)```. -For ```addr``` you have following possibilities - -| connection scheme | comment | -| ----------------- | ------- | -| INPROC | Use empty address string to use in process communication. This works only if your client is in same address space (process) like datalayer application. | -| IPC | Only available in Linux. Use this communication kind in same device between processes. | -| TCP | Communication between devices | - -| addr | comment | -| ---------------------- | ------- | -| "" | INPROC communication (default) | -| DL_IPC_AUTO | Automatic choice of IPC port. It uses \<$HOME\>/.datalayer/frontend/2069 as IPC communication port. You can also use this define for communication between snaps with same user | -| "ipc://\ | IPC communication with specific path. You have to run a broker with this IPC path. | -| "tcp://\:\ | TCP communication with specific device. Standard port of TCP is 2069. | - -## Celix Bundle - -This components includes a Celix bundle. You can use it in your own Celix -framework. Be careful that on your target exists only one broker. So if you -use datalayer in multiple Celix framework only one broker has to be started. To -control start of broker you can use following entry in config.properties in your -Celix preferences. - -``` C++ -datalayer.broker.enable=false -``` - -The default value of this switch is true. So you have to set it explicit to -false to disable startup of broker in your system. diff --git a/doc/dotnet.md b/doc/dotnet.md index 7e728462f..13bb10389 100644 --- a/doc/dotnet.md +++ b/doc/dotnet.md @@ -1,260 +1,260 @@ -# README .NET Apps @ ctrlX - -![.NET](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a3/.NET_Logo.svg/120px-.NET_Logo.svg.png) - -## Introduction - -This document describes how to setup up your development environment for building __self-contained ctrlX Apps based on Microsoft .NET runtime__. - -__Self-contained__ means, your App contains an already matching and optimized .NET runtime for your target architecture, so there's no need to install any additional .NET runtime. - -All samples generate Apps (snaps) for the targets - -+ ctrlX COREvirtual (amd64) -+ ctrlX CORE (arm64) - -## Prerequisites - -In this chapter we describe how to install the necessary components on a development environment based on a QEMU VM. - -How you can create and run a QEMU VM is described [here](setup_qemu_ubuntu.md). - -### Installation of .NET SDK on the QEMU VM - -Start a SSH session and login into the VM with boschrexroth/boschrexroth: - - ssh -p 10022 boschrexroth@localhost - -Start the script to install .NET as snap on your VM: - - ./install-dotnet-sdk.sh - -When installation is finished you can check your installed SDKs: - - dotnet --list-sdks - -The output should show the installed version and the path of ths dotnet-sdk. - -Check your Runtime: - - dotnet --list-runtimes - - -### Install the Visual Studio Code Extension from Marketplace - -We recommend to use __Microsoft Visual Studio Code__ on your host computer as IDE - [see here](vscode.md). - -To develop and test .NET application for the ctrlX we have to install the C# extension in the VM. - -* Start Visual Studio Code and connect it with the QEMU VM. -* Select the extension icon in the left side bar and enter c# -* Select this extension and click 'Install in SSH' - -![C# extension](images/csharpextension.png) - -### Prepare NuGet on the QEMU VM - -.NET projects can use NuGet packages. Therefor we have to provide some prerequisites on the VM. - -If you're behing a corporate proxy, you have to configure the __NuGet Proxy__ in configuration file: - - /home/${USER}/.nuget/NuGet/NuGet.Config - -Edit the NuGet configuration file with your preferred editor or with Visual Studio Code and add a _config_ section containing the __http_proxy__ and __https_proxy__ inside the _configuration_ section like shown below. - -__Example:__ - -The following sample uses the [Px Proxy](https://pypi.org/project/px-proxy) running on the host computer. From the VM's point of view, this proxy can be reached with the URL http://10.0.2.2:3128. - - - - - - - ... - - - -## Building a .NET Sample Project -Each .NET sample provides a rich set of tasks for your convenience. - -![Tasks](images/tasks.png) - -+ Click on Terminal -> __Run Task__. -+ Choose your preferred task to run. - -### Build (compile) your code - -+ Click on Terminal -> __Run Task__. -+ Choose Task __build__. - -### Clean your code - -+ Click on Terminal -> __Run Task__. -+ Choose Task __clean__. - -### Publish your (self-contained) application - -+ Click on Terminal -> __Run Task__. -+ Choose any Task __publish *__ matching your architecture and mode. - -### make snap - -+ Click on Terminal -> __Run Task__. -+ Choose any Task __make snap *__ matching your architecture and mode. - -## Debugging - -### Debug on QEMU VM - -Just press __F5__ or - -+ Click on the __Run__ from the menu. -+ Choose Run -> __.NET Core Launch (console)__. -+ Press the green __Play__ button. - -### Debug snap on ctrlX COREvirtual - -+ Click on Terminal -> __Run Task__. -+ Choose any Task __make snap amd64__. -+ Install snap on ctrlX COREvirtual via ctrlX web interface -+ For debugging snaps see [here](https://snapcraft.io/docs/debug-snaps) - -### Debug snap on ctrlX CORE - -+ Click on Terminal -> __Run Task__. -+ Choose any Task __make snap arm64__. -+ Install snap on ctrlX CORE via ctrlX web interface -+ For debugging snaps see [here](https://snapcraft.io/docs/debug-snaps) - -Now you're ready to code .NET on ctrlX! - -## Best Practise - -### Provider Concepts - -There different concepts to write a ctrlX Data Layer provider: - -#### Create and register nodes with individual node handlers - -Create a provider, which creates and registers _all_ nodes with an _individual_ node handler - - n x CreateNode - n x Register - Node : Handler = 1:1 - -__Recommendation:__ - -+ Use for a _small/medium_ of nodes with _individual_ node handling. -+ Use for a logical grouping and managing of nodes. - -__Pros:__ - -+ The ctrlX Data Layer is managaging your node hierarchy: No implementation of _OnBrowse()_ required (return DL_UNSUPPORTED or DL_OK with an empty list). - -__Contras:__ - -+ Not efficent for a large/very large set of nodes to handle. - -__Samples:__ - -+ datalayer.provider - -#### Create and register nodes with same node handler - -Create a provider, which creates _individual_ nodes and registers all nodes individually with _same_ node handler. - - n x CreateNode - n x Register - Node : Handler = n:1 - -__Recommendation:__ - -+ Use for a _small/medium_ of nodes with _common_ node handling -+ Use for a logical grouping and managing of nodes. - -__Pros:__ - -+ The ctrlX Data Layer is managaging your node hierarchy: No Implementation of _OnBrowse()_ required (return DL_UNSUPPORTED or DL_OK with an empty list). - -__Contras:__ - -+ Not efficent for a large/very large set of nodes to handle. - -__Samples:__ - -+ datalayer.provider.alldata - -#### Virtual provider (lightweight): Register on wildcard and manage virtual nodes - -Create just _one_ node with a single node handler, registered to a _wildcard_ address (e.g. myroot/**) and managing the nodes for your own. This _lightweight_ handler returns _virtual_ nodes in _OnBrowse()_ method. -See ctrlX Data Layer documentation for details. - - 1 x CreateNode - 1 x Register - Node : Handler = n:1 - -__Recommendation:__ - -+ Use for a _large/very large_ or _dynamic_ set of nodes (big data provider). -+ Use if you want to manage the nodes in your application code. - -__Pros:__ - -+ Very efficient. - -__Contras:__ - -+ The ctrlX Data Layer is _not_ managaging your node hierarchy: You have to return the valid data in _OnBrowse()_. - -__Samples:__ - -+ datalayer.provider.virtual - -## Pitfalls - -### Arithmetic operators of different integral or foating point types - -The following operators perform arithmetic operations with operands of numeric types: - -+ __Unary__: ++ (increment), -- (decrement), + (plus), and - (minus) operators -+ __Binary__: * (multiplication), / (division), % (remainder), + (addition), and - (subtraction) operators - -Those operators are supported by all integral and floating-point numeric types. - -In the case of integral types, those operators (except the ++ and -- operators) are defined for the __int__, __uint__, __long__, and __ulong__ types. - -When operands are of other integral types (__sbyte__, __byte__, __short__, __ushort__, or __char__), their values are __converted to the int type__, which is also the __result type__ of an operation. - -When operands are of __different integral or floating-point__ types, their values are __converted to the closest containing type__, if such a type exists. For more information, see the Numeric promotions section of the C# language specification. - -The ++ and -- operators are defined for all integral and floating-point numeric types and the char type. - -__Example__: - -Let' say we just wan't to increment a __sbyte__ Variant value by keeping the data type, we have cast the result after performing the arithmetic operation: - - sbyte value = 42; - var oldVariant = new Variant(value) - var newVariant = new Variant((sbyte)(oldVariant.ToSByte() + 1)); - -+ Please see [here](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators) for more informations. - -## Support - -### Developer Community - -Please join the [Developer Community](https://developer.community.boschrexroth.com/) - -### SDK Forum - -Please visit the [SDK Forum](https://developer.community.boschrexroth.com/t5/ctrlX-AUTOMATION/ct-p/dcdev_community-bunit-dcae/) - -### Issues - -If you've found an error in these sample, please [file an issue](https://github.com/boschrexroth) - -## License - -SPDX-FileCopyrightText: Bosch Rexroth AG +# README .NET Apps @ ctrlX + +![.NET](https://upload.wikimedia.org/wikipedia/commons/thumb/a/a3/.NET_Logo.svg/120px-.NET_Logo.svg.png) + +## Introduction + +This document describes how to setup up your development environment for building __self-contained ctrlX Apps based on Microsoft .NET runtime__. + +__Self-contained__ means, your App contains an already matching and optimized .NET runtime for your target architecture, so there's no need to install any additional .NET runtime. + +All samples generate Apps (snaps) for the targets + ++ ctrlX CORE^virtual^ (amd64) ++ ctrlX CORE (arm64) + +## Prerequisites + +In this chapter we describe how to install the necessary components on a development environment based on a QEMU VM. + +How you can create and run a QEMU VM is described [here](setup_qemu_ubuntu.md). + +### Installation of .NET SDK on the QEMU VM + +Start a SSH session and login into the VM with boschrexroth/boschrexroth: + + ssh -p 10022 boschrexroth@localhost + +Start the script to install .NET as snap on your VM: + + ./install-dotnet-sdk.sh + +When installation is finished you can check your installed SDKs: + + dotnet --list-sdks + +The output should show the installed version and the path of ths dotnet-sdk. + +Check your Runtime: + + dotnet --list-runtimes + + +### Install the Visual Studio Code Extension from Marketplace + +We recommend to use __Microsoft Visual Studio Code__ on your host computer as IDE - [see here](vscode.md). + +To develop and test .NET application for the ctrlX we have to install the C# extension in the VM. + +* Start Visual Studio Code and connect it with the QEMU VM. +* Select the extension icon in the left side bar and enter c# +* Select this extension and click 'Install in SSH' + +![C# extension](images/csharpextension.png) + +### Prepare NuGet on the QEMU VM + +.NET projects can use NuGet packages. Therefor we have to provide some prerequisites on the VM. + +If you're behing a corporate proxy, you have to configure the __NuGet Proxy__ in configuration file: + + /home/${USER}/.nuget/NuGet/NuGet.Config + +Edit the NuGet configuration file with your preferred editor or with Visual Studio Code and add a _config_ section containing the __http_proxy__ and __https_proxy__ inside the _configuration_ section like shown below. + +__Example:__ + +The following sample uses the [Px Proxy](https://pypi.org/project/px-proxy) running on the host computer. From the VM's point of view, this proxy can be reached with the URL http://10.0.2.2:3128. + + + + + + + ... + + + +## Building a .NET Sample Project +Each .NET sample provides a rich set of tasks for your convenience. + +![Tasks](images/tasks.png) + ++ Click on Terminal -> __Run Task__. ++ Choose your preferred task to run. + +### Build (compile) your code + ++ Click on Terminal -> __Run Task__. ++ Choose Task __build__. + +### Clean your code + ++ Click on Terminal -> __Run Task__. ++ Choose Task __clean__. + +### Publish your (self-contained) application + ++ Click on Terminal -> __Run Task__. ++ Choose any Task __publish *__ matching your architecture and mode. + +### make snap + ++ Click on Terminal -> __Run Task__. ++ Choose any Task __make snap *__ matching your architecture and mode. + +## Debugging + +### Debug on QEMU VM + +Just press __F5__ or + ++ Click on the __Run__ from the menu. ++ Choose Run -> __.NET Core Launch (console)__. ++ Press the green __Play__ button. + +### Debug snap on ctrlX CORE^virtual^ + ++ Click on Terminal -> __Run Task__. ++ Choose any Task __make snap amd64__. ++ Install snap on ctrlX CORE^virtual^ via ctrlX web interface ++ For debugging snaps see [here](https://snapcraft.io/docs/debug-snaps) + +### Debug snap on ctrlX CORE + ++ Click on Terminal -> __Run Task__. ++ Choose any Task __make snap arm64__. ++ Install snap on ctrlX CORE via ctrlX web interface ++ For debugging snaps see [here](https://snapcraft.io/docs/debug-snaps) + +Now you're ready to code .NET on ctrlX! + +## Best Practise + +### Provider Concepts + +There different concepts to write a ctrlX Data Layer provider: + +#### Create and register nodes with individual node handlers + +Create a provider, which creates and registers _all_ nodes with an _individual_ node handler + + n x CreateNode + n x Register + Node : Handler = 1:1 + +__Recommendation:__ + ++ Use for a _small/medium_ of nodes with _individual_ node handling. ++ Use for a logical grouping and managing of nodes. + +__Pros:__ + ++ The ctrlX Data Layer is managaging your node hierarchy: No implementation of _OnBrowse()_ required (return DL_UNSUPPORTED or DL_OK with an empty list). + +__Contras:__ + ++ Not efficent for a large/very large set of nodes to handle. + +__Samples:__ + ++ datalayer.provider + +#### Create and register nodes with same node handler + +Create a provider, which creates _individual_ nodes and registers all nodes individually with _same_ node handler. + + n x CreateNode + n x Register + Node : Handler = n:1 + +__Recommendation:__ + ++ Use for a _small/medium_ of nodes with _common_ node handling ++ Use for a logical grouping and managing of nodes. + +__Pros:__ + ++ The ctrlX Data Layer is managaging your node hierarchy: No Implementation of _OnBrowse()_ required (return DL_UNSUPPORTED or DL_OK with an empty list). + +__Contras:__ + ++ Not efficent for a large/very large set of nodes to handle. + +__Samples:__ + ++ datalayer.provider.alldata + +#### Virtual provider (lightweight): Register on wildcard and manage virtual nodes + +Create just _one_ node with a single node handler, registered to a _wildcard_ address (e.g. myroot/**) and managing the nodes for your own. This _lightweight_ handler returns _virtual_ nodes in _OnBrowse()_ method. +See ctrlX Data Layer documentation for details. + + 1 x CreateNode + 1 x Register + Node : Handler = n:1 + +__Recommendation:__ + ++ Use for a _large/very large_ or _dynamic_ set of nodes (big data provider). ++ Use if you want to manage the nodes in your application code. + +__Pros:__ + ++ Very efficient. + +__Contras:__ + ++ The ctrlX Data Layer is _not_ managaging your node hierarchy: You have to return the valid data in _OnBrowse()_. + +__Samples:__ + ++ datalayer.provider.virtual + +## Pitfalls + +### Arithmetic operators of different integral or foating point types + +The following operators perform arithmetic operations with operands of numeric types: + ++ __Unary__: ++ (increment), -- (decrement), + (plus), and - (minus) operators ++ __Binary__: * (multiplication), / (division), % (remainder), + (addition), and - (subtraction) operators + +Those operators are supported by all integral and floating-point numeric types. + +In the case of integral types, those operators (except the ++ and -- operators) are defined for the __int__, __uint__, __long__, and __ulong__ types. + +When operands are of other integral types (__sbyte__, __byte__, __short__, __ushort__, or __char__), their values are __converted to the int type__, which is also the __result type__ of an operation. + +When operands are of __different integral or floating-point__ types, their values are __converted to the closest containing type__, if such a type exists. For more information, see the Numeric promotions section of the C# language specification. + +The ++ and -- operators are defined for all integral and floating-point numeric types and the char type. + +__Example__: + +Let' say we just wan't to increment a __sbyte__ Variant value by keeping the data type, we have cast the result after performing the arithmetic operation: + + sbyte value = 42; + var oldVariant = new Variant(value) + var newVariant = new Variant((sbyte)(oldVariant.ToSByte() + 1)); + ++ Please see [here](https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/arithmetic-operators) for more informations. + +## Support + +### Developer Community + +Please join the [Developer Community](https://developer.community.boschrexroth.com/) + +### SDK Forum + +Please visit the [SDK Forum](https://developer.community.boschrexroth.com/t5/ctrlX-AUTOMATION/ct-p/dcdev_community-bunit-dcae/) + +### Issues + +If you've found an error in these sample, please [file an issue](https://github.com/boschrexroth) + +## License + +SPDX-FileCopyrightText: Bosch Rexroth AG SPDX-License-Identifier: MIT \ No newline at end of file diff --git a/doc/fbs2plc.md b/doc/fbs2plc.md deleted file mode 100644 index c7270aba6..000000000 --- a/doc/fbs2plc.md +++ /dev/null @@ -1,100 +0,0 @@ -# fbs2plc.exe - Use Flatbuffers in your PLC project - -A lot of ctrlX Data Layer nodes contain structured data stored in the [Flatbuffers](https://google.github.io/flatbuffers/) format. - -The data structure is defined in a schema file (.fbs file). The FlatBuffers compiler [flatc](https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html) is able to compile such a .fbs file into code for several programming languages including IEC 61131-3 Structured Text (ST). - -This guide describes how one or more fbs files can be compiled into IEC 61131-3 ST code and how this code can be imported and used in your IEC 61131-3 project to handle Flatbuffers. - -The described workflow and the tools are currently running __only under Windows 10__. - -## Prerequisites - -### ctrlX WORKS - -Install ctrlX WORKS >= 1.20 with the function 'ctrlX PLC Engineering' and 'App Build Environment'. - -We recommend to use __"C:\Program Files\Rexroth\ctrlX WORKS"__ as installation path. -In this case the path to ctrlX PLC Engineering is __"C:\Program Files\Rexroth\ctrlX WORKS\Studio\Common\ctrlX-PLC-Engineering.exe"__ - -#### ctrlX CORE - -* Create a ctrlX COREvirtual with __Port Forwarding__ and start it. -* Install the PLC snap. - -### ctrlX AUTOMATION SDK - -#### On your Windows host - -Download the [ctrlX AUTOMATION SDK](https://github.com/boschrexroth/ctrlx-automation-sdk/releases) and extract it to __c:\ctrlx-automation-sdk__ - -Now two executables are available: - -* c:\ctrlx-automation-sdk\bin\oss.flatbuffers\win-msvc-x64\release\flatc.exe -* c:\ctrlx-automation-sdk\bin\fbs2plc\win-x64\fbs2plc.exe - -#### On your App Build Environment - -* From ctrlX WORKS, create and start an App Build Environment. -* Login into your App Build Environment: ssh -p 10022 boschrexroth@127.0.0.1 -* Password is boschrexroth -* Install the ctrlX AUTOMATION SDK - - $ ~/scripts/install-sdk.sh - -* Build a required snap (here amd64) and install it on the ctrlX COREvirtual - - $ cd ~/ctrlx-automation-sdk/samples-cpp/datalayer.provider.all-data - $ ../../scripts/build-upload-log-snap.sh -PF - -* Open a web browser, login into your ctrlX COREvirtual. A Data Layer node __sdk-cpp-alldata/dynamic/fbs__ should exist. - -This node later can be read, changed and written by our IEC 61131-3 PLC code. - -## Reading and writing a flatbuffers ctrlX Data Layer node in your PLC project - -The basic steps are: - -1. Create a PLC library which contains the IEC61131 ST code to handle a Flatbuffers variable -2. Create a new PLC project -3. Import the created PLC library and provided sample code into your project -4. Compile the project and log into your ctrl COREvirtual - -### Create a PLC library - -Start cmd.exe and enter these commands: - - c: - cd \ctrlx-automation-sdk\samples-fbs2plc\sampleSchema - start.bat - -Result: -* The file c:\ctrlx-automation-sdk\samples-cpp\datalayer.provider.all-data\sampleSchema.fbs was compiled into IEC61131 code. -* A new PLC library __fbs-sampleSchema__ was created, using c:\ctrlx-automation-sdk\plc\CXA_fbs_Template.library as template. -* All required standard libraries were imported. -* ctrlX PLC Engineering now has the new library opened. - -Store the new library so that you can use it in your PLC project: - -* Select File - Save project and install into library repository -* Close the libray -* Keep ctrlX PLC Engineering running - -### Create a PLC project - -* In ctrlX PLC Engineering create a new PLC project use 'ctrlX CORE x64 Project' as template. -* Select the node Application and delete it. -* Select the node PLC Logic -* Select menu item Project - PLCopenXML import..., select c:\ctrlx-automation-sdk\samples-fbs2plc\sampleSchema\fbs-read-write.xml -* Double click the node library manager -* Add the library CXA_DATALAYER to your project. -* Connect the device of ypur PLC project with the ctrlX COREvirtual -* Login into your ctrlX COREvirtual - -### Check the Flatbuffer Access - -* From a web browser login into your ctrlX COREvirtual Web UI -* Select Settings - Data Layer -* Expand the Data Layer tree: sdk-cpp-alldata/dynamic/fbs - -The values of the x, y, z variables should be changed by our PLC program. diff --git a/doc/images/flatbuffer_compiler.png b/doc/images/flatbuffer_compiler.png deleted file mode 100644 index df306d7fd1e47943f89b68b2a1f1cfebd63cf245..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12463 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 VwukHo{1E~4Ra6FCCj8C!e*m4e7HR+h diff --git a/doc/samples.md b/doc/samples.md deleted file mode 100644 index bc2ec8e9f..000000000 --- a/doc/samples.md +++ /dev/null @@ -1,94 +0,0 @@ - -## Sample Projects - -Applications (snaps) for ctrlX CORE targets can be written in several programming language or even as shell scripts. - -For creating your own applications, the ctrlX AUTOMATION SDK offers sample projects that can be used as source of code snippets as templates. The sample projects are saved in sub folders according to their programming language or their type. - -Here an overview of the sample project types and their subfolders. - -!!! important - Run the install script listet in column three once before you are working with one or more sample projects. - These scripts are located in __/home/boschrexroth/scripts__. See also [install-scripts](install-scripts.md). - -| Sample Project Type | Link to Projects | Install Script -| :------------------ | :------------------------------------------------------ | :------------------------ | -| __C/C++__ | [samples-cpp/README.md](samples-cpp/README.md) | ~/scripts/install-cpp-aarch64-libs.sh -| __Go__ | [samples-go/README.md](samples-go/README.md) | ~/scripts/install-go.sh -| __Python__ | [samples-python/README.md](samples-python/README.md) | -| __.NET__ | [samples-net/README.md](samples-net/README.md) | ~/scripts/install-dotnet-sdk.sh -| __Node.js__ | [samples-node/README.md](samples-node/README.md) | ~/scripts/install-nodejs-npm.sh | -| __Snap__ | [samples-snap/README.md](samples-snap/README.md) | -| __IEC 61131-3__ | [samples-iec61131/README.md](samples-iec61131/README.md)| - - -## Building Snaps - -!!! important - All project folders are containing these scripts to build snaps: - -* __build-snap-amd64.sh__: Build an amd64 snap for a ctrlX COREvirtual. -* __build-snap-arm64.sh__: Build an arm64 (aarch64) snap for a ctrlX CORE. - -You can call these scripts from the command line: - - ./build-snap-amd64.sh - ./build-snap-arm64.sh - - or from Visual Studio Code: - - * Select main menu item Terminal --> Run Build Task - * Select `build snap amd64` for building a snap for a ctrlX COREvirtual - * Select `build snap arm64` for building a snap for a ctrlX CORE. - -At the end of the build process the snap file should be available in the root folder of your project. - -See below for further Run Build Task items. - -## Installing a Snap Manually - -Right click the snap file in the Visual Studio Code EXPLORER and select 'Download'. Visual Studio Code stores it in your home directory on your host computer. For Windows 10 this is %USERPROFILE%, in Linux this is: ~/ - -Start a Web browser, login into your ctrlX CORE: - -* Select Settings - Apps -* Switch to Service Mode -* Click Install from file -* Select the downloaded file -* Switch to Operation Mode - -## Building and Installing a Snap Automated by Script - -Using the bash script __build-upload-log-snap.sh__ in the ctrlX AUTOMATION SDK folder scripts/ -You can create a snap file, upload it, install it on a ctrlX CORE and view the log output. - -The script can be started either from the command line or with the additional Run Build Task items of the Visual Studio Code IDE. - -### Starting Script from the Command Line - -Change into a sample project folder (e.g. samples-cpp/datalayer.client) and enter - - ../../scripts/build-upload-log-snap.sh -help - -All parameters and their default values are listed. - -E.g. to build and install a snap for a ctrlX COREvirtual with Network Adapter enter - - ../../scripts/build-upload-log-snap.sh -NA - -But we recommend calling this script from Visual Studio Code. See next chapter. - -### Starting Script as Visual Studio Build Task - -Additional to the two Build Tasks mentioned above there are further tasks: - -* __Build upload snap - ctrlX COREvirtual Network Adapter__ -* __Build upload snap - ctrlX COREvirtual Port Forwarding__ -* __Build upload log snap - ctrlX CORE 192.168.1.1__ -* __Build upload snap__ - -The first three tasks are calling the script with the parameter set needed for the according destination. There is sno need to select further parameters. - -If you are choosing the last item each parameter is prompted. - -Feel free to add more tasks or adapt the existing ones. diff --git a/doc/storage-extension.md b/doc/storage-extension.md index 2eb053237..279b0cee0 100644 --- a/doc/storage-extension.md +++ b/doc/storage-extension.md @@ -148,7 +148,7 @@ This will be done by adding a "part" in your snapcraft.yaml and add a snapshots. # Sample app -This sample app ( [storage-extension-sample](./samples-go/storage-extension)) is the minimum set to use storage extension. +This sample app ( [storage-extension-sample](./samples-snap/storage-extension/README.md) ) is the minimum set to use storage extension. Feel free to add the content to your app. # Use storage extension