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

Retrieving an API Instance

UNICENS supports to access multiple instances within one process space. One UNICENS API instance is dedicated to one INIC the associated network. Hence, it is possible to deal with multiple networks within one process space. The maximum number of UNICENS API instances must be configured in ucs_cfg.h.

The following definition configures UNICENS to be used with 2 INICs.

/* Number of API instances which can be created by function Ucs_CreateInstance().
Valid range: 1..10. Default value: 1.
*/
#define UCS_NUM_INSTANCES 2

Accordingly UNICENS can provide 2 API instances that can be retrieved by calling Ucs_CreateInstance(). The retrieved instance remains valid until the process ends. There is no need to return or re-create an already retrieved instance. The following code shows how to retrieve one API instance.

/* create UNICENS API instance */
Ucs_Inst_t* inst_ptr = NULL;
inst_ptr = Ucs_CreateInstance();
if (inst_ptr == NULL)
{
/* UNICENS cannot any further API instance.
Check configuration MACRO UCS_NUM_INSTANCES.
*/
return;
}

Configuration Structure

The application has to prepare a configuration structure in order to initialize UNICENS. Therefore, it has to provide a Ucs_InitData_t variable. It is recommended to set the variable to default values by calling Ucs_SetDefaultConfig(). After that the application shall set specific attributes of the variable. The function Ucs_SetDefaultConfig() can be called at any time and is not bound up with a certain API instance.

Ucs_InitData_t init_data;

After the function returns, the application has to setup the configuration settings. The following section shows an example configuration.

init_data.user_ptr = &my_class;
/* General Section */
init_data.general.error_fptr = &App_OnGeneralError;
init_data.general.get_tick_count_fptr = &App_OnGetTickCount;
/* LLD Section */
init_data.lld.lld_user_ptr = &my_lld_class;
init_data.lld.start_fptr = &Lld_Start;
init_data.lld.stop_fptr = &Lld_Stop;
init_data.lld.tx_transmit_fptr = &Lld_TxTransmit;
init_data.lld.rx_available_fptr = &Lld_RxMsgAvailable;
/* Node Discovery Section */
init_data.nd.report_fptr = &App_OnNodeDiscoveryResult;
init_data.nd.eval_fptr = &App_OnNodeDiscoveryEval;

User References

By assigning init_data.user_ptr and init_data.lld.lld_user_ptr the application is able assign references of own objects to a certain UNICENS API instance. E.g., when driving 2 API instances the application can assign 2 different LLD objects. When UNICENS invokes LLD callback functions then one argument will provide the assigned lld_user_ptr. The application can simply forward the call to the actual LLD object.

void Lld_TxTransmit(Ucs_Lld_TxMsg_t *msg_ptr, void *lld_user_ptr)
{
CMyLldClass *my_lld = (CMyLldClass*)lld_user_ptr;
my_lld->Transmit(msg_ptr);
}

General Configuration

The callback general.error_fptr() is called if a general error occurs. The callback must adhere to function signature Ucs_ErrorCb_t. If a general error occurs the application must trigger a re-initialization of UNICENS. A simple example implementation is shown below.

Note
Ucs_Init() must not be called within general.error_fptr()!
void App_OnGeneralError(Ucs_Error_t error_code, void *user_ptr)
{
printf("General Error Occurred (Code: %u).\n\r", error_code);
App_TriggerReInit(); /* cleanup and re-initialize when leaving Ucs_Service() */
}

Timer Configuration

The UNICENS timer management requires a timer tick in milliseconds that is gathered via the callback general.get_tick_count_fptr(). The callback must adhere to function signature Ucs_GetTickCountCb_t. An example implementation for a Windows platform is shown below.

uint16_t App_OnGetTickCount(void *user_ptr)
{
DWORD tc = GetTickCount(); /* Get current tick count in milliseconds */
return (uint16_t)tc;
}

Initialization

The function Ucs_Init() must be called by the application to initialize one UNICENS API instance. library. The first argument is the reference to the API instance. The second argument is the reference to the initialization structure. The third argument is optional and can provide the reference to a result callback function. It is highly recommended to use the result callback to be able to handle possible errors during the initialization.

void App_Init(void)
{
...
if(Ucs_Init(inst_ptr, init_data, &App_OnInitResult) != UCS_RET_SUCCESS)
{
/* Handle synchronous initialization errors here... */
}
...
}
void App_OnInitResult(Ucs_InitResult_t result, void *user_ptr)
{
if(result != UCS_INIT_RES_SUCCESS)
{
/* Handle asynchronous initialization errors here... */
}
}