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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ jobs:
config: ARM
build-mode: ${{ inputs.build_mode || 'Build' }}

- name: Build ARsim
uses: loupeteam/br-actions/build-as-project@v1
with:
exe-path: ${{ steps.find-as.outputs.exe-path }}
project: ${{ env.PROJECT }}
config: ARsim
build-mode: ${{ inputs.build_mode || 'Build' }}

- name: Upload build diagnostics
if: always()
uses: actions/upload-artifact@v4
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ ignored/

# Python
**/__pycache__/
example/UserPartition/*/result.csv
example/UserPartition/*/bitstring.csv
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,46 @@ For more documentation and examples, see https://loupeteam.github.io/LoupeDocs/l
# Installation
To install using the Loupe Package Manager (LPM), in an initialized Automation Studio project directory run `lpm install csvfilelib`. For more information about LPM, see https://loupeteam.github.io/LoupeDocs/tools/lpm.html

# Tests

The example project carries a self checking test suite for the bit string
(BYTE/WORD/DWORD) support, in `example/AsProject/Logical/Programs/Default`.
It runs automatically a few scans after boot, and can be re-run by setting
`runTest`.

The `ARsim` configuration exists so the suite can actually be executed; the
`Intel` and `ARM` configurations target hardware. CI compiles all three, but
does not run the suite - executing it is a manual step.

## Running it

The suite reads two hand written input files, `crafted.csv` and `badline.csv`,
from the USER file device. They live in `example/UserPartition/ARsim/` and
have to be present on the device before the suite runs, otherwise the file
phases cannot complete.

Either copy them onto the USER file device by hand, or let a tool that reads
`example/AsProject/.loupe/partition.json` place them for you. That file is the
Loupe VS Code PLC Toolkit / bnr-build partition mapping - it is not something
LPM or the Automation Studio build does on its own.

## Reading the result

The suite writes `result.csv` to the USER file device.

**`suiteOk` is the verdict.** It is TRUE only when there were no failures, the
full expected number of assertions actually ran, and the suite reached the
end. Checking `testFail` alone is not enough: a file operation that never
completes leaves `testFail` at 0, which would otherwise read as a pass.

`firstFail` names the first case that failed, if any. The remaining values in
the file are there to make a failure diagnosable - the data types PV_ninfo
reported, and the values read back from each input file.

Note that the PV_ninfo data type codes were measured on ARsim running
Automation Runtime 6.7.6. The configurations in this project pin 6.6.2, which
is what CI compiles against.

## Licensing

This project is licensed under the [MIT License](LICENSE).
6 changes: 6 additions & 0 deletions example/AsProject/.loupe/partition.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"version": 1,
"mappings": [
{ "configuration": "ARsim", "fileDevice": "USER", "localFolder": "../UserPartition/ARsim" }
]
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<Library xmlns="http://br-automation.co.at/AS/Library" Version="1.0.0" SubType="Binary">
<Library xmlns="http://br-automation.co.at/AS/Library" Version="1.1.0" SubType="Binary">
<Objects>
<Object Type="File" Description="Exported data types">StringExt.typ</Object>
<Object Type="File" Description="Exported constants">StringExt.var</Object>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Automation Studio generated header file */
/* Do not edit ! */
/* stringext 1.0.0 */
/* stringext 1.1.0 */

#ifndef _STRINGEXT_
#define _STRINGEXT_
Expand All @@ -9,7 +9,7 @@ extern "C"
{
#endif
#ifndef _stringext_VERSION
#define _stringext_VERSION 1.0.0
#define _stringext_VERSION 1.1.0
#endif

#include <bur/plctypes.h>
Expand All @@ -36,9 +36,19 @@ extern "C"

/* Datatypes and datatypes of function blocks */
typedef enum STREXT_ERR_enum
{ STREXT_ERR_INVALID_INPUT = -1
{ STREXT_ERR_BUFFER_TOO_SMALL = -4,
STREXT_ERR_RANGE = -3,
STREXT_ERR_INVALID_FORMAT = -2,
STREXT_ERR_INVALID_INPUT = -1
} STREXT_ERR_enum;

typedef enum STREXT_HEXPREFIX_enum
{ STREXT_HEXPREFIX_NONE = 0,
STREXT_HEXPREFIX_0X,
STREXT_HEXPREFIX_IEC,
STREXT_HEXPREFIX_DOLLAR
} STREXT_HEXPREFIX_enum;

typedef struct StrExtArgs_typ
{ float r[5];
unsigned long s[5];
Expand All @@ -55,6 +65,8 @@ _BUR_PUBLIC unsigned long atoui(unsigned long pString);
_BUR_PUBLIC unsigned long uitoa(unsigned long Value, unsigned long pString);
_BUR_PUBLIC unsigned long ByteToHexString(unsigned long pByte, unsigned long NumBytes, unsigned long pString);
_BUR_PUBLIC signed long HexStringToDINT(unsigned long pHexStr);
_BUR_PUBLIC signed long HexStringToUDINT(unsigned long pHexStr, unsigned long pValue);
_BUR_PUBLIC signed long UDINTToHexString(unsigned long Value, unsigned long pString, unsigned long Size, unsigned char NumDigits, unsigned char Prefix);
_BUR_PUBLIC unsigned short GenerateTimestampMS_1(unsigned long pDTStructure, unsigned long pTimestamp, unsigned long TimestampLength);
_BUR_PUBLIC unsigned short GenerateTimestampMS(unsigned long pDTStructure, unsigned long pTimestamp, unsigned long TimestampLength);
_BUR_PUBLIC unsigned short GenerateTimestamp(plcdt DT1, unsigned long pTimestamp, unsigned long TimestampLength);
Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Automation Studio generated header file */
/* Do not edit ! */
/* stringext 1.0.0 */
/* stringext 1.1.0 */

#ifndef _STRINGEXT_
#define _STRINGEXT_
Expand All @@ -9,7 +9,7 @@ extern "C"
{
#endif
#ifndef _stringext_VERSION
#define _stringext_VERSION 1.0.0
#define _stringext_VERSION 1.1.0
#endif

#include <bur/plctypes.h>
Expand All @@ -36,9 +36,19 @@ extern "C"

/* Datatypes and datatypes of function blocks */
typedef enum STREXT_ERR_enum
{ STREXT_ERR_INVALID_INPUT = -1
{ STREXT_ERR_BUFFER_TOO_SMALL = -4,
STREXT_ERR_RANGE = -3,
STREXT_ERR_INVALID_FORMAT = -2,
STREXT_ERR_INVALID_INPUT = -1
} STREXT_ERR_enum;

typedef enum STREXT_HEXPREFIX_enum
{ STREXT_HEXPREFIX_NONE = 0,
STREXT_HEXPREFIX_0X,
STREXT_HEXPREFIX_IEC,
STREXT_HEXPREFIX_DOLLAR
} STREXT_HEXPREFIX_enum;

typedef struct StrExtArgs_typ
{ float r[5];
unsigned long s[5];
Expand All @@ -55,6 +65,8 @@ _BUR_PUBLIC unsigned long atoui(unsigned long pString);
_BUR_PUBLIC unsigned long uitoa(unsigned long Value, unsigned long pString);
_BUR_PUBLIC unsigned long ByteToHexString(unsigned long pByte, unsigned long NumBytes, unsigned long pString);
_BUR_PUBLIC signed long HexStringToDINT(unsigned long pHexStr);
_BUR_PUBLIC signed long HexStringToUDINT(unsigned long pHexStr, unsigned long pValue);
_BUR_PUBLIC signed long UDINTToHexString(unsigned long Value, unsigned long pString, unsigned long Size, unsigned char NumDigits, unsigned char Prefix);
_BUR_PUBLIC unsigned short GenerateTimestampMS_1(unsigned long pDTStructure, unsigned long pTimestamp, unsigned long TimestampLength);
_BUR_PUBLIC unsigned short GenerateTimestampMS(unsigned long pDTStructure, unsigned long pTimestamp, unsigned long TimestampLength);
_BUR_PUBLIC unsigned short GenerateTimestamp(plcdt DT1, unsigned long pTimestamp, unsigned long TimestampLength);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/* Automation Studio generated header file */
/* Do not edit ! */
/* stringext 1.0.0 */
/* stringext 1.1.0 */

#ifndef _STRINGEXT_
#define _STRINGEXT_
Expand All @@ -9,7 +9,7 @@ extern "C"
{
#endif
#ifndef _stringext_VERSION
#define _stringext_VERSION 1.0.0
#define _stringext_VERSION 1.1.0
#endif

#include <bur/plctypes.h>
Expand All @@ -36,9 +36,19 @@ extern "C"

/* Datatypes and datatypes of function blocks */
typedef enum STREXT_ERR_enum
{ STREXT_ERR_INVALID_INPUT = -1
{ STREXT_ERR_BUFFER_TOO_SMALL = -4,
STREXT_ERR_RANGE = -3,
STREXT_ERR_INVALID_FORMAT = -2,
STREXT_ERR_INVALID_INPUT = -1
} STREXT_ERR_enum;

typedef enum STREXT_HEXPREFIX_enum
{ STREXT_HEXPREFIX_NONE = 0,
STREXT_HEXPREFIX_0X,
STREXT_HEXPREFIX_IEC,
STREXT_HEXPREFIX_DOLLAR
} STREXT_HEXPREFIX_enum;

typedef struct StrExtArgs_typ
{ float r[5];
unsigned long s[5];
Expand All @@ -55,6 +65,8 @@ _BUR_PUBLIC unsigned long atoui(unsigned long pString);
_BUR_PUBLIC unsigned long uitoa(unsigned long Value, unsigned long pString);
_BUR_PUBLIC unsigned long ByteToHexString(unsigned long pByte, unsigned long NumBytes, unsigned long pString);
_BUR_PUBLIC signed long HexStringToDINT(unsigned long pHexStr);
_BUR_PUBLIC signed long HexStringToUDINT(unsigned long pHexStr, unsigned long pValue);
_BUR_PUBLIC signed long UDINTToHexString(unsigned long Value, unsigned long pString, unsigned long Size, unsigned char NumDigits, unsigned char Prefix);
_BUR_PUBLIC unsigned short GenerateTimestampMS_1(unsigned long pDTStructure, unsigned long pTimestamp, unsigned long TimestampLength);
_BUR_PUBLIC unsigned short GenerateTimestampMS(unsigned long pDTStructure, unsigned long pTimestamp, unsigned long TimestampLength);
_BUR_PUBLIC unsigned short GenerateTimestamp(plcdt DT1, unsigned long pTimestamp, unsigned long TimestampLength);
Expand Down
17 changes: 17 additions & 0 deletions example/AsProject/Logical/Libraries/Loupe/stringext/StringExt.fun
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,23 @@ FUNCTION HexStringToDINT : DINT (*Converts a Hex String to a DINT*) (*$GROUP=Use
END_VAR
END_FUNCTION

FUNCTION HexStringToUDINT : DINT (*Parses a hex string with an optional 0x, 16# or $ prefix. Returns 0 on success or a STREXT_ERR_enum value; the parsed value is written through pValue*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*)
VAR_INPUT
pHexStr : UDINT; (*Pointer to the string to parse*)
pValue : UDINT; (*Pointer to the UDINT that receives the value*)
END_VAR
END_FUNCTION

FUNCTION UDINTToHexString : DINT (*Formats a UDINT as a hex string. Returns the string length or a STREXT_ERR_enum value*) (*$GROUP=User,$CAT=User,$GROUPICON=User.png,$CATICON=User.png*)
VAR_INPUT
Value : UDINT; (*Value to format*)
pString : UDINT; (*Pointer to the destination buffer*)
Size : UDINT; (*Size of the destination buffer, including the terminator*)
NumDigits : USINT; (*Zero pad to this many digits, 1..8. 0 for the shortest representation*)
Prefix : USINT; (*Notation to use, see STREXT_HEXPREFIX_enum*)
END_VAR
END_FUNCTION

FUNCTION GenerateTimestampMS_1 : UINT (*Generate a time stamp string from a DTStructure variable*)
VAR_INPUT
pDTStructure : UDINT;
Expand Down
10 changes: 10 additions & 0 deletions example/AsProject/Logical/Libraries/Loupe/stringext/StringExt.typ
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,18 @@
TYPE
STREXT_ERR_enum :
(
STREXT_ERR_BUFFER_TOO_SMALL := -4, (*Destination buffer is too small for the result*)
STREXT_ERR_RANGE := -3, (*Value does not fit in the destination type*)
STREXT_ERR_INVALID_FORMAT := -2, (*String is not a valid literal of the expected form*)
STREXT_ERR_INVALID_INPUT := -1
);
STREXT_HEXPREFIX_enum :
(
STREXT_HEXPREFIX_NONE := 0, (*FF*)
STREXT_HEXPREFIX_0X, (*0xFF*)
STREXT_HEXPREFIX_IEC, (*16#FF*)
STREXT_HEXPREFIX_DOLLAR (*$FF*)
);
StrExtArgs_typ : STRUCT (*Arguments for formatter*)
r : ARRAY[0..4]OF REAL; (*Reals*)
s : ARRAY[0..4]OF UDINT; (*Pointers to String*)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@loupeteam/stringext",
"version": "1.0.0",
"version": "1.1.0",
"description": "String manipulation functions for B&R Automation Studio (ANSIC library)",
"homepage": "https://loupeteam.github.io/LoupeDocs/libraries/stringext.html",
"scripts": {},
Expand Down
Loading
Loading