How to enable a callback for cyclic IO - data
Caution: using that callback routine can have a massiv influence to the realtime behavior of the stack!
This feature is unavailable for multicore projects until GOAL v2.23.0.
The example below shows the use of the callback function:
create the following local prototype and variables
Add the callback function to the callback handler
/****************************************************************************/
/* Local Prototypes */
/****************************************************************************/
static GOAL_STATUS_T appl_pnioCb(
GOAL_PNIO_T *pHdlPnio, /**< PROFINET instance */
GOAL_PNIO_CB_ID_T id, /**< callback id */
GOAL_PNIO_CB_DATA_T *pCb /**< callback parameters */
);
/****************************************************************************/
/* Local Variables */
/****************************************************************************/
static GOAL_BOOL_T flgAppReady = GOAL_FALSE; /**< app ready flag */
static GOAL_PNIO_AR_ID_T idAr = 0; /**< AR ID */
static GOAL_PNIO_T *pPnio; /**< PROFINET instance */
static char targetData[APPL_MOD_SIZE]; /**< dummy where data is copied to */
/****************************************************************************/
/** Profinet Callback Handler
*
* This function collects all callbacks from the stack and decides if the
* callback must be handled.
*/
static GOAL_STATUS_T appl_pnioCb(
GOAL_PNIO_T *pHdlPnio, /**< PROFINET instance */
GOAL_PNIO_CB_ID_T id, /**< callback id */
GOAL_PNIO_CB_DATA_T *pCb /**< callback parameters */
)
{
GOAL_STATUS_T res = GOAL_OK; /* return value */
UNUSEDARG(pHdlPnio);
/* handle callback IDs */
switch (id) {
case GOAL_PNIO_CB_ID_APPL_READY:
/* application ready was confirmed, start data handling if not
* already running */
if (GOAL_TRUE != flgAppReady) {
flgAppReady = GOAL_TRUE;
idAr = pCb->data[0].idAr;
}
break;
case GOAL_PNIO_CB_ID_RELEASE_AR:
/* AR was released, stop data handling if it was the first AR */
if (idAr == pCb->data[0].idAr) {
flgAppReady = GOAL_FALSE;
idAr = 0;
}
break;
case GOAL_PNIO_CB_ID_BLINK:
goal_targetSetLeds((pCb->data[1].stateDcpLight) ? UINT32_MAX : 0);
break;
case GOAL_PNIO_CB_ID_NEW_IO_DATA:
/* New I/O data received.
* Be careful: this call will block the PNIO stack
* so just do the copying here and nothing else.
* If not fast enough, just set a flag and retrieve the data
* later in appl_loop if required.
**/
memcpy(targetData, pCb->data[2].pCu8, pCb->data[1].u16);
break;
default:
break;
}
return res;
}
To use the cb function GOAL_PNIO_CB_ID_NEW_IO_DATA
the following functions have to be called exactly in the order described below before and after function goal_pnioNew(...)
:
goal_pnioCfgNewIoDataCbSet(GOAL_TRUE);
→ configure stack to feature the GOAL_PNIO_CB_ID_NEW_IO_DATA callbackgoal_pnioCyclicCtrl(pPnio,GOAL_TRUE);
→ enable GOAL_PNIO_CB_ID_NEW_IO_DATA callback for each arrived cyclic frame
/****************************************************************************/
/** Application Setup
*
* Setup the application.
*/
GOAL_STATUS_T appl_setup(
void
)
{
GOAL_STATUS_T res; /* result */
/* configure stack to feature the GOAL_PNIO_CB_ID_NEW_IO_DATA callback */
goal_pnioCfgNewIoDataCbSet(GOAL_TRUE);
/* create new PROFINET instance */
res = goal_pnioNew(&pPnio, APPL_PNIO_ID, appl_pnioCb);
if (GOAL_RES_ERR(res)) {
goal_logErr("failed to create a new PROFINET instance");
return res;
}
/* enable GOAL_PNIO_CB_ID_NEW_IO_DATA callback for each arrived cyclic frame */
goal_pnioCyclicCtrl(pPnio,GOAL_TRUE);
goal_logInfo("Initializing device structure");
/* from here create the device configuration */
...
/* PROFINET configuration succesful */
goal_logInfo("PROFINET ready");
return GOAL_OK;
}