Commit 970b5281 authored by Marcus Nordenberg's avatar Marcus Nordenberg Committed by Esteban Blanc

profinet: propagate state on stack shutdown

(cherry picked from commit 9497f8a92eed8c75f9c90d459a91ec693939b21f)
parent e7b8508a
......@@ -301,7 +301,7 @@ static pwr_tStatus IoAgentWrite(io_tCtx ctx, io_sAgent* ap)
pack_write_req(&local->service_req_res,
local->device_data[ii]->device_ref, &sp->WriteReq);
sts = pnak_send_service_req_res(0, &local->service_req_res);
errh_Info("Profinet - Asynch write, dev: %d",
errh_Info("PROFINET: Async write, dev: %d",
local->device_data[ii]->device_ref);
break;
}
......@@ -329,48 +329,59 @@ static pwr_tStatus IoAgentClose(io_tCtx ctx, io_sAgent* ap)
io_sAgentLocal* local;
int *exitcodep;
int error;
pwr_tStatus sts = PB__NOTINIT;
local = (io_sAgentLocal*)ap->Local;
if (ctx->Node->EmergBreakTrue == 1)
errh_Fatal("Emergency break detected shutting down PROFINET");
/* Stop profistack */
// Stop the supervision thread before shutting down PROFINET.
local = (io_sAgentLocal*)ap->Local;
if (!local) return IO__SUCCESS;
if ((error = pthread_cancel(local->handle_events)))
errh_Warning("Unsuccessful cancelation of PROFINET supervision thread");
else
errh_Info("Canceled PROFINET supervision thread");
// Start taking the stack down. A PNAK_WAIT_OBJECT_CHANNEL_CLOSED event will
// be emitted and the supervision thread will exit
pnak_stop_stack(0);
// Wait for the thread to exit
if ((error = pthread_join(local->handle_events, (void**)&exitcodep)))
errh_Warning("Unable to wait for PROFINET thread! Might cause undefined behaviour...");
errh_Warning("PROFINET: Unable to wait for supervision thread!");
else
errh_Info("PROFINET supervision thread has exited. Stopping PROFINET...");
sts = pnak_stop_stack(0);
pnak_term();
errh_Info("PROFINET: Supervision thread has exited. PROFINET stopped...");
free(local);
local = NULL;
/* Clean data areas .... */
return sts;
return IO__SUCCESS;
}
static pwr_tStatus IoAgentSwap(io_tCtx ctx, io_sAgent* ap, io_eEvent event)
{
switch (event) {
switch (event)
{
// For now we just shut down regardless of what EmergBreakSelect says...safety
// first :)
case io_eEvent_EmergencyBreak:
case io_eEvent_IoCommEmergencyBreak:
errh_Fatal("PROFINET: Emergency break detected! Shutting down PROFINET!");
IoAgentClose(ctx, ap);
// TODO We need a complete overhaul of EmergencyBreakTrue / EmergBreakSelect
// / IOReadWriteFlag
// switch (ctx->Node->EmergBreakSelect)
// {
// case pwr_eEmergBreakSelectEnum_StopIO:
// case pwr_eEmergBreakSelectEnum_Reboot:
// errh_Fatal("PROFINET: Emergency break action (StopIO/Reboot) shutting
// down PROFINET"); IoAgentClose(ctx, ap); break;
// case pwr_eEmergBreakSelectEnum_NoAction:
// errh_Warning("PROFINET: Emergency break action (NoAction).
// Continuing..."); break;
// case pwr_eEmergBreakSelectEnum_FixedOutputValues:
// errh_Warning("PROFINET: Behaviour of FixedOutputValues should be
// configured on device level"); errh_Fatal("PROFINET: Emergency break
// action (Fixed Output Values)."); break;
// }
break;
case io_eEvent_IoCommEmergencyBreak:
break;
default:
break;
......
......@@ -64,7 +64,7 @@ static pwr_tStatus IoRackInit(io_tCtx ctx, io_sAgent* ap, io_sRack* rp)
pwr_sClass_ChanIo* chan_io;
sts = gdh_ObjidToName(rp->Objid, (char*)&name, sizeof(name), cdh_mNName);
errh_Info("Init of Profinet Device and Modules %s", name);
errh_Info("PROFINET: Init of device and modules %s", name);
op = (pwr_sClass_PnDevice*)rp->op;
local = (io_sPnRackLocal*)rp->Local;
......@@ -255,14 +255,17 @@ static pwr_tStatus IoRackRead(io_tCtx ctx, io_sAgent* ap, io_sRack* rp)
sp->ErrorCount++;
}
if (sp->ErrorCount == sp->ErrorHardLimit) {
errh_Error("IO Error hard limit reached on card '%s', stall action %d",
if (sp->ErrorCount == sp->ErrorHardLimit)
{
errh_Error("PROFINET: IO Error hard limit reached on device '%s', stall action %d",
rp->Name, sp->StallAction);
ctx->IOHandler->CardErrorHardLimit = 1;
ctx->IOHandler->ErrorHardLimitObject = cdh_ObjidToAref(rp->Objid);
sp->ErrorCount++;
} else if (sp->ErrorCount == sp->ErrorSoftLimit) {
errh_Error("IO Error soft limit reached on card '%s'", rp->Name);
}
else if (sp->ErrorCount == sp->ErrorSoftLimit)
{
errh_Error("PROFINET: IO Error soft limit reached on device '%s'", rp->Name);
ctx->IOHandler->CardErrorSoftLimit = 1;
ctx->IOHandler->ErrorSoftLimitObject = cdh_ObjidToAref(rp->Objid);
sp->ErrorCount++;
......@@ -297,14 +300,17 @@ static pwr_tStatus IoRackWrite(io_tCtx ctx, io_sAgent* ap, io_sRack* rp)
sp->ErrorCount++;
}
if (sp->ErrorCount == sp->ErrorHardLimit) {
errh_Error("IO Error hard limit reached on card '%s', stall action %d",
if (sp->ErrorCount == sp->ErrorHardLimit)
{
errh_Error("PROFINET: IO Error hard limit reached on device '%s', stall action %d",
rp->Name, sp->StallAction);
ctx->IOHandler->CardErrorHardLimit = 1;
ctx->IOHandler->ErrorHardLimitObject = cdh_ObjidToAref(rp->Objid);
sp->ErrorCount++;
} else if (sp->ErrorCount == sp->ErrorSoftLimit) {
errh_Error("IO Error soft limit reached on card '%s'", rp->Name);
}
else if (sp->ErrorCount == sp->ErrorSoftLimit)
{
errh_Error("PROFINET: IO Error soft limit reached on device '%s'", rp->Name);
ctx->IOHandler->CardErrorSoftLimit = 1;
ctx->IOHandler->ErrorSoftLimitObject = cdh_ObjidToAref(rp->Objid);
sp->ErrorCount++;
......
......@@ -1852,7 +1852,7 @@ void handle_device_state_changed(io_sAgentLocal* local, io_sAgent* ap)
else
dev->Status = PB__NOCONN;
errh_Info("Profinet - New device state, dev: %s, state: %d",
errh_Info("PROFINET: New device state, dev: %s, state: %d",
slave_list->Name, dev->State);
}
}
......@@ -1969,7 +1969,7 @@ void* handle_events(void* ptr)
/* Initialize interface */
errh_Info("Initializing interface for Profinet IO Master %s", ap->Name);
errh_Info("PROFINET: Initializing interface for controller %s", ap->Name);
/* Add master as a device */
......@@ -2092,7 +2092,7 @@ void* handle_events(void* ptr)
if (sts != PNAK_OK)
{
op->Status = PB__INITFAIL;
errh_Error("Starting profistack returned with error code: %d", sts);
errh_Error("PROFINET: Start of stack returned with error code: %d", sts);
// return IO__ERRINIDEVICE;
}
......@@ -2156,7 +2156,7 @@ void* handle_events(void* ptr)
}
else
{
errh_Error("Download of Profinet Device configuration failed for: %s",
errh_Error("PROFINET: Download of device configuration failed for: %s",
device_vect[ii]->device_name);
/* Setup a dummy i/o area. Depending on exisiting channels this area
* needs to exist */
......@@ -2221,7 +2221,7 @@ void* handle_events(void* ptr)
if (sts != PNAK_OK)
{
op->Status = PB__INITFAIL;
errh_Error("Profistack unable to go online, errcode: %d", sts);
errh_Error("PROFINET: Unable to go online, error code: %d", sts);
// return IO__ERRINIDEVICE;
}
......@@ -2242,7 +2242,7 @@ void* handle_events(void* ptr)
if (sts != PNAK_OK)
{
op->Status = PB__INITFAIL;
errh_Error("Profistack unable to set state online, errcode: %d", sts);
errh_Error("PROFINET: Unable to set state online, error code: %d", sts);
// return IO__ERRINIDEVICE;
}
}
......@@ -2267,7 +2267,7 @@ void* handle_events(void* ptr)
if (sts != PNAK_OK)
{
op->Status = PB__INITFAIL;
errh_Error("Profistack unable to activate devices, errcode: %d", sts);
errh_Error("PROFINET: Unable to activate devices, error code: %d", sts);
// return IO__ERRINIDEVICE;
}
......@@ -2290,83 +2290,83 @@ void* handle_events(void* ptr)
pthread_cond_signal(&local->cond);
pthread_mutex_unlock(&local->mutex);
/* Do forever ... */
/* Do until we close the channel and break out */
while (1)
{
// wait_object = PNAK_WAIT_OBJECTS_EVENT_IND | PNAK_WAIT_OBJECTS_OTHER
// | PNAK_WAIT_OBJECT_SERVICE_CON;
wait_object = PNAK_WAIT_OBJECTS_ALL &
~(PNAK_WAIT_OBJECT_PROVIDER_DATA_UPDATED |
PNAK_WAIT_OBJECT_CONSUMER_DATA_CHANGED);
/* Other states available:
PNAK_WAIT_OBJECT_ETHERNET_STATE_CHANGED
PNAK_WAIT_OBJECT_INTERRUPTED
PNAK_WAIT_OBJECTS_EVENT_IND
PNAK_WAIT_OBJECTS_OTHER
PNAK_WAIT_OBJECT_SERVICE_CON
*/
// pthread_mutex_lock(&local->mutex);
wait_object =
PNAK_WAIT_OBJECTS_ALL & ~(PNAK_WAIT_OBJECT_PROVIDER_DATA_UPDATED |
PNAK_WAIT_OBJECT_CONSUMER_DATA_CHANGED);
sts =
pnak_wait_for_multiple_objects(0, &wait_object, PNAK_INFINITE_TIMEOUT);
if (sts == PNAK_OK)
{
if (wait_object & PNAK_WAIT_OBJECT_EXCEPTION)
if (wait_object & PNAK_WAIT_OBJECT_CHANNEL_CLOSED)
{
errh_Info("PROFINET: Stack received channel closed event!");
// Iterate through all devices and propagate stopped state to all children
if (ap)
{
((pwr_sClass_PnControllerSoftingPNAK*)ap->op)->Status = PB__STOPPED;
io_sRack* device;
io_sCard* module;
pwr_sClass_PnDevice *dev;
pwr_sClass_PnModule *mod;
for (device = ap->racklist; device != NULL; device = device->next)
{
dev = (pwr_sClass_PnDevice*)device->op;
dev->Status = PB__STOPPED;
for (module = device->cardlist; module != NULL; module = module->next)
{
mod = (pwr_sClass_PnModule*)module->op;
mod->Status = PB__STOPPED;
}
}
}
break;
}
else if (wait_object & PNAK_WAIT_OBJECT_EXCEPTION)
{
// printf("Exception !!\n");
handle_exception(local);
}
else if (wait_object & PNAK_WAIT_OBJECT_STATE_CHANGED)
{
// printf("State changed !!\n");
handle_state_changed(local);
}
else if (wait_object & PNAK_WAIT_OBJECT_DEVICE_STATE_CHANGED)
{
// printf("Device state changed !!\n");
handle_device_state_changed(local, ap);
}
else if (wait_object & PNAK_WAIT_OBJECT_ALARM)
{
// printf("Alarm !!\n");
handle_alarm_indication(local, ap);
}
// else if (wait_object & PNAK_WAIT_OBJECT_CHANNEL_CLOSED) {
// // printf("Channel closed !!");
// // What to do if channel closes ???;
// }
// else if (wait_object & PNAK_WAIT_OBJECT_ETHERNET_STATE_CHANGED) {
// // printf("Ethernet state changed !!");
// // What to do if ethernet state changes ???;
// }
// else if (wait_object & PNAK_WAIT_OBJECT_INTERRUPTED) {
// // printf("Interrupted !!");
// // What to do if interrupted ???;
// }
else if (wait_object & PNAK_WAIT_OBJECT_SERVICE_CON)
{
// printf("Service con !!\n");
sts = handle_service_con(local, ap);
}
// else
// {
// printf("Unhandled status!! 0x%02X\n", wait_object);
// }
}
else if ((sts == PNAK_ERR_FATAL_ERROR) || (sts == PNAK_EXCEPTION_THROWN))
{
printf("Err Fatal / Exception !!\n");
// user_handle_exception (ChannelId);
}
else
{
printf("Running == NOT !!\n");
// pThisSmObject->Running = PN_FALSE;
errh_Fatal("PROFINET: Fatal exception occured. Stopping PROFINET!");
pnak_stop_stack(0);
}
// pthread_mutex_unlock(&local->mutex);
}
pnak_term();
return 0;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment