Logo
UNICENS V2.3.0-4567
User Manual and API Reference
Supervisor Programming Mode

Introduction

When entering the Supervisor Programming Mode the Supervisor is responsible to run a certain sequence which allows to program the local INIC or remote INICs. The Supervisor supports the following information to be written to an INIC:

  • INIC Configuration String
  • INIC Identification String
  • INIC Patch String

Initialization

It is not possible to configure the Supervisor Programming Mode as initial Supervisor Mode. I.e. the application may set the Supervisor Inactive Mode as initial mode and may call Ucs_Supv_SetMode() to start the Supervisor Programming Mode. The application should assign the following callback functions which are dedicated to the Programming Mode:

  • supv.prog_event_fptr
    This callback function notifies certain events that can occur during local or remote programming. The events are necessary especially for remote programming.
  • supv.prog_local_fptr
    The application must assign this callback function to run the programming of the local INIC. The Network Supervisor invokes this callback function as the first one notifying the signature of the local INIC. The network is now in state "NotAvailable" and the application can trigger from within this callback function to program the local INIC. If this callback function is not assigned, the Supervisor immediately starts the procedure for remote programming.
  • supv.prog_signature_fptr
    After the Network Supervisor has started the network it will discover the remote INICs and notify the signatures of the remote INICs to the application. The application must gather enough information to determine which remote INICs must be programmed.

The following example shows how to configure the Network Supervisor to start in Supervisor Inactive Mode and assign callback functions required for the Supervisor Programming Mode.

void App_Initialize(void)
{
Ucs_InitData_t init_data;
Ucs_SetDefaultConfig(&init_data);
/* Network Events */
init_data.network.status.cb_fptr = &App_OnNetworkStatus;
/* Network Supervisor */
init_data.supv.report_mode_fptr = &App_OnSupvReportMode;
/* Normal Operation Mode */
init_data.supv.report_fptr = &App_OnSupvReport;
init_data.supv.nodes_list_ptr = &app_nodes[0];
init_data.supv.nodes_list_size = APP_NODES_NUM;
init_data.supv.routes_list_ptr = &app_routes[0];
init_data.supv.routes_list_size = APP_ROUTES_NUM;
/* Programming Mode */
init_data.supv.prog_event_fptr = &App_OnSupvProgReport;
init_data.supv.prog_local_fptr = &App_OnSupvProgLocalDiscover;
init_data.supv.prog_signature_fptr = &App_OnSupvProgRemoteDiscover;
/* ... further initialization ... */
Ucs_Init(&init_data, &App_OnInitResult);
}

Programming the local INIC

The above assigned callback function supv.prog_local_fptr is the entry point for programming the local INIC. When entering the Supervisor Programming Mode this function is invoked first notifying the signature of the local INIC. The application must decide within this callback function whether to program the local INIC or to skip the local programming and start the remote programming process. For the latter case the application must set none of the function parameters. For programming the local INIC the application must assign the following parameters which are implemented as pointers and hence returning the decision of the application:

  • program_pptr
    This parameter shall be used to specify the programming command which is applied to the local INIC. If this parameter is not written by the application (or set to NULL) the Supervisor starts with the remote programming procedure.
  • result_pfptr
    This parameter shall be used to assign a callback function which is invoked to notify the result of the local programming procedure.
Note
If the application does not assign the callback function supv.prog_local_fptr in the initialization structure, the Network Supervisor automatically skips the local programming phase, starts the network and continues with the remote scanning phase.
typedef enum App_ProgTask_
{
APP_PRGT_NONE = 0x00U, /* nothing to do */
APP_PRGT_CS = 0x01U, /* program configuration string */
APP_PRGT_IS = 0x02U /* program identification string */
} App_ProgTask_t;
extern void App_OnSupvProgLocalDiscover(Ucs_Signature_t *signature_ptr,
Ucs_Prg_Command_t **program_pptr,
Ucs_Prg_ReportCb_t *result_pfptr,
void *user_ptr)
{
App_ProgTask_t task = APP_PRGT_NONE;
printf("App_OnSupvProgLocalDiscover(): position=0x%04X, node=0x%04X, diag_id=0x%04X\n",
signature_ptr->node_pos_addr, signature_ptr->node_address, signature_ptr->diagnosis_id);
task = App_CheckSignature(signature_ptr); /* find out what to do... */
switch (task)
{
case APP_PRGT_CS:
*program_pptr = &app_identstr_cmd; /* assign to programming command */
*result_pfptr = &App_OnSupvProgResult; /* assign callback function */
printf("App_OnSupvProgLocalDiscover(): initiate CS programming\n");
break;
case APP_PRGT_IS:
*program_pptr = &app_configstr_cmd; /* assign to programming command */
*result_pfptr = &App_OnSupvProgResult; /* assign callback function */
printf("App_OnSupvProgLocalDiscover(): initiate IS programming\n");
break;
case APP_PRGT_NONE:
default:
/* do not assign programming command and callback function */
/* -> continue with remote programming */
printf("App_OnSupvProgLocalDiscover(): programming not necessary\n");
break;
}
}

Programming remote INICs

If the application decides not to program the local INIC, the Network Supervisor automatically starts the network and continues with the remote programming process. The following issues are important for the remote programming process:

  • The Network Supervisor calls supv.prog_signature_fptr to notify discovered remote nodes. There is a cyclic recovery mechanism trigged every 5 seconds. Nodes discovered in a previous cycle may also be discovered in a following cycle. Due to specific network events it may be possible that the notified node position address within the signature may change. It is important that the application gathers enough information from all remote nodes to have a clear picture of all nodes and their actual position in the network.
  • If a node needs to be programmed the application shall call Ucs_Supv_ProgramNode(). The Network Supervisor will leave the remote scanning phase and program the node.
  • After programming a remote node, the Network Supervisor will notify the programming result to the application. The Network Supervisor then starts a new remote scanning phase announced by UCS_SUPV_PROG_INFO_SCAN_NEW. The application shall discard previously announced signatures and start to gather new information about the discovered remote nodes. When the application has again enough information it may trigger another programming task.
  • If there is no (more) programming task required the application shall call Ucs_Supv_ProgramExit(). The Network supervisor will automatically shutdown the network and return to the Supervisor Inactive Mode.
  • If an error occurs while the Supervisor Programming Mode is active, the Network Supervisor will invoke the callback function supv.prog_event_fptr notifying an appropriate error code. The Network Supervisor will automatically return to the Supervisor Inactive Mode.

The following example code shows a simple example how to discover 2 expected nodes on node position address 0x401 and 0x402 and how it is possible to store the signature for a subsequent programming task.

Note
It is highly recommended to use further criteria besides the node position address to securely identify a node. The EUI48 address, Diagnosis ID or INIC Configuration String version might be helpful to identify remote nodes.
extern void App_OnSupvProgRemoteDiscover(Ucs_Signature_t *signature_ptr, void *user_ptr)
{
if ((signature_ptr->node_pos_addr == 0x401U) && ((signature_ptr->node_address == 0x240U) || (signature_ptr->node_address == 0xFFFFU)))
{
app_401_found = true;
app_401_signature = *signature_ptr;
printf("App_OnSupvProgRemoteDiscover(): recognized position=0x%04X, node=0x%04X, diag=0x%04X\n", signature_ptr->node_pos_addr, signature_ptr->node_address, signature_ptr->diagnosis_id);
}
else if ((signature_ptr->node_pos_addr == 0x402U) && ((signature_ptr->node_address == 0x241U) || (signature_ptr->node_address == 0xFFFFU)) )
{
app_402_found = true;
app_402_signature = *signature_ptr;
printf("App_OnSupvProgRemoteDiscover(): recognized position=0x%04X, node=0x%04X, diag=0x%04X\n", signature_ptr->node_pos_addr, signature_ptr->node_address, signature_ptr->diagnosis_id);
}
else
{
(void)printf("App_OnSupvProgRemoteDiscover(): found unknown position=0x%04X, node=0x%04X, diag=0x%04X\n", signature_ptr->node_pos_addr, signature_ptr->node_address, signature_ptr->diagnosis_id);
}
}