Logo
UNICENS V2.1.0-3491
User Manual and API Reference
Node Scripting

Introduction

The idea behind the Node Scripting is to allow execution of custom scripts in remote Nodes. That is, user can specify scripts based on FBlock command syntax and run these on remote nodes by the use of Node Scripting module.
The module is designed and intended for the use of I2C and GPIO commands only. This means that using the Scripting module for any other FBlock INIC commands (MOST, MediaLB, USB, Streaming or Connection for example) is expressly prohibited.

A script is a structure data (see below) composed of:

  • The command based on INIC FBlock-Syntax to be transmitted
  • The expected result also based on INIC FBlock-Syntax.
  • The amount time [in milliseconds] to pause before sending the Tx command.
/*! \brief Structure of a node-script */
typedef struct Ucs_Ns_Script_
{
/*! \brief Specifies the pause which shall be set before sending
the Tx configuration message.
*/
uint16_t pause;
/*! \brief Send command to be transmitted. */
Ucs_Ns_ConfigMsg_t * send_cmd;
/*! \brief Expected result. */
Ucs_Ns_ConfigMsg_t * exp_result;

A Ucs_Ns_ConfigMsg_t message is based on INIC FBlock-Syntax and looks like this:

/*! \brief Structure of a ConfigMsg */
typedef struct Ucs_Ns_ConfigMsg_
{
/*! \brief FBlockId. */
uint8_t FBlockId;
/*! \brief InstId. */
uint8_t InstId;
/*! \brief FunktId. */
uint16_t FunktId;
/*! \brief OpCode. */
uint8_t OpCode;
/*! \brief Data length. */
uint8_t DataLen;
/*! \brief Reference to the Data */
uint8_t * DataPtr;

Operation

The user specifies the desired scripts, binds them to the target nodes and then call the function Ucs_Ns_Run() for processing. The result of the operation is reported via the result callback function Ucs_Ns_ResultCb_t, which is passed by user in the arguments list of Ucs_Ns_Run(). In addition to this callback function and the referred UCS instance the function requires a reference to the Node that contains the script(s).

The Ucs_Ns_Run() function starts the process to transmit the script(s) contained in the provided node and then checks for the expected results (specified by customer). The Node Scripting module will start a timer of 2600ms before sending the Tx command of each script. That is, if no incoming messages match the expected result of the script during this time the result code UCS_NS_RES_ERROR is returned via the Ucs_Ns_ResultCb_t user callback function. This error code is also get when the script module couldn't perform the device synchronization of the remote device (this can be read in the detailed error messages, if enabled. See below). Otherwise, if an incoming message matches the expected result, UCS_NS_RES_SUCCESS is returned.

The Ucs_Ns_Run() function will return UCS_RET_ERR_API_LOCKED when attempting to execute a script in a node that is currently busy with other(s) previous script(s). The Ucs_Ns_Run() function is namely locked for a Node when handling script(s) on this node and unlocked after reporting the result of the operation. However processing scripts can be executed on different nodes in parallel.

The detailed error messages can be read when enabling the error trace output in ucs_cfg.h file as shown below.

/* File: ucs_cfg.h */
/*------------------------------------------------------------------------------------------------*/
/* Tracing & Debugging */
/*------------------------------------------------------------------------------------------------*/
# define UCS_TR_ERROR App_TraceError
extern void App_TraceError(void *ucs_user_ptr, const char module_str[], const char entry_str[],
uint16_t vargs_cnt, ...);
/* File: app_trace.c */
void App_TraceError(void *ucs_user_ptr, const char module_str[], const char entry_str[],
uint16_t vargs_cnt, ...)
{
if (file_ != NULL)
{
char outbuf[256];
va_list argptr;
uint16_t timestamp = (uint16_t)timeGetTime() - startup_time;
va_start(argptr, vargs_cnt);
(void)vsprintf(outbuf, entry_str, argptr);
va_end(argptr);
(void)fprintf(file_, "%5u | [%u] | Error | %s | %s\n", timestamp, ucs_user_ptr, module_str, outbuf);
(void)fflush(file_);
}
}

Example

The example below outlines the execution of a script within a node with address 0x200. This example is inserted as a guide and may not contain all of the necessary details and information.

/* Flag that checks whether node with address 0x200 is discovered by Node Discovering */
static bool node200_discovered = false;
/* Forward declaration of result callback function */
static void App_OnScriptingResult(uint16_t node_address, Ucs_Ns_ResultCode_t result, void *user_ptr);
/* Configuration Msg specification */
static uint8_t tx_data [] = { 0x00, 0x40, 0x01, 0x01 };
static uint8_t rx_data [] = { 0x0F, 0x00 };
static Ucs_Ns_ConfigMsg_t tx_msg = { 0x00, 0x00, 0x6C1, 0x2, 4U, &tx_data };
static Ucs_Ns_ConfigMsg_t rx_msg = { 0x00, 0x01, 0x6C1, 0xC, 2U, &rx_data };
/* Scripts specification */
static Ucs_Ns_Script_t script_x = { 100U, &tx_msg, &rx_msg };
/* Signature specification */
Ucs_Signature_t sig_200 = { 200U };
/* Nodes objects Specification */
static Ucs_Rm_Node_t node_200 = { &sig_200, &script_x, 1U, 0U };
/* Main function */
void main(uint8_t argc, char *argv[])
{
/* ... */
if (node200_discovered)
{
(void)Ucs_Ns_Run(ucs_inst_ptr, &node_200, &App_OnScriptingResult);
}
/* ... */
}
/* The result callback function */
static void App_OnScriptingResult(Ucs_Rm_Node_t * node_ptr, Ucs_Ns_ResultCode_t result, void *user_ptr)
{
switch (result)
{
/* Node can be set to "Available" for example */
Ucs_Rm_SetNodeAvailable(ucs_inst_ptr, node_ptr, true);
break;
default:
/* Do whatever is necessary here */
break;
}
}