//------------------------------------------------------------------------------ void SdoDialog::userDefEvent(void* pUserArg_p) { tSdoComConHdl SdoComConHdl; tObdSize obdSize; tOplkError ret; obdSize = data.size(); if (pUserArg_p == readButton) { ret = oplk_readObject(&SdoComConHdl, targetNodeId, targetIndex, targetSubindex, data.data(), &obdSize, (tSdoType) sdoType, NULL); if (ret == kErrorApiTaskDeferred) { // SDO transfer started return; } else if (ret == kErrorOk) { // local OD access data.resize(obdSize); emit sigUpdateData("Successfully read from local OD"); } else { data.resize(0); emit sigUpdateData(QString("Error 0x%1: %2") .arg(ret, 0, 16) .arg(debugstr_getRetValStr(ret))); } } else if (pUserArg_p == writeButton) { ret = oplk_writeObject(&SdoComConHdl, targetNodeId, targetIndex, targetSubindex, data.data(), obdSize, (tSdoType) sdoType, NULL); if (ret == kErrorApiTaskDeferred) { // SDO transfer started return; } else if (ret == kErrorOk) { // local OD access data.resize(obdSize); emit sigUpdateData("Successfully written to local OD"); } else { data.resize(0); emit sigUpdateData(QString("Error 0x%1: %2") .arg(ret, 0, 16) .arg(debugstr_getRetValStr(ret))); } } }
//------------------------------------------------------------------------------ static tOplkError processErrorWarningEvent(tOplkApiEventType EventType_p, tOplkApiEventArg* pEventArg_p, void* pUserArg_p) { // error or warning occurred within the stack or the application // on error the API layer stops the NMT state machine tEventError* pInternalError = &pEventArg_p->internalError; UNUSED_PARAMETER(EventType_p); UNUSED_PARAMETER(pUserArg_p); PRINTF("Err/Warn: Source = %s (%02X) OplkError = %s (0x%03X)\n", debugstr_getEventSourceStr(pInternalError->eventSource), pInternalError->eventSource, debugstr_getRetValStr(pInternalError->oplkError), pInternalError->oplkError); PRINTF("Err/Warn: Source = %s (%02X) OplkError = %s (0x%03X)\n", debugstr_getEventSourceStr(pInternalError->eventSource), pInternalError->eventSource, debugstr_getRetValStr(pInternalError->oplkError), pInternalError->oplkError); // check additional argument switch (pInternalError->eventSource) { case kEventSourceEventk: case kEventSourceEventu: // error occurred within event processing // either in kernel or in user part PRINTF(" OrgSource = %s %02X\n", debugstr_getEventSourceStr(pInternalError->errorArg.eventSource), pInternalError->errorArg.eventSource); PRINTF(" OrgSource = %s %02X\n", debugstr_getEventSourceStr(pInternalError->errorArg.eventSource), pInternalError->errorArg.eventSource); break; case kEventSourceDllk: // error occurred within the data link layer (e.g. interrupt processing) // the DWORD argument contains the DLL state and the NMT event PRINTF(" val = %X\n", pInternalError->errorArg.uintArg); PRINTF(" val = %X\n", pInternalError->errorArg.uintArg); break; default: PRINTF("\n"); break; } return kErrorOk; }
//------------------------------------------------------------------------------ static tOplkError initProcessImage(void) { tOplkError ret = kErrorOk; UINT varEntries; tObdSize obdSize; /* Allocate process image */ PRINTF("Initializing process image...\n"); PRINTF("Size of input process image: %d\n", (UINT32)sizeof(PI_IN)); PRINTF("Size of output process image: %d\n", (UINT32)sizeof (PI_OUT)); ret = oplk_allocProcessImage(sizeof(PI_IN), sizeof(PI_OUT)); if (ret != kErrorOk) { return ret; } pProcessImageIn_l = oplk_getProcessImageIn(); pProcessImageOut_l = oplk_getProcessImageOut(); /* link process variables used by CN to object dictionary */ PRINTF("Linking process image vars:\n"); obdSize = sizeof(pProcessImageIn_l->digitalIn[0]); varEntries = 4; ret = oplk_linkProcessImageObject(0x6000, 0x01, offsetof(PI_IN, digitalIn), FALSE, obdSize, &varEntries); if (ret != kErrorOk) { PRINTF("linking process vars ... error %04x\n\"%s\"\n\n", ret, debugstr_getRetValStr(ret)); return ret; } obdSize = sizeof(pProcessImageOut_l->digitalOut[0]); varEntries = 4; ret = oplk_linkProcessImageObject(0x6200, 0x01, offsetof(PI_OUT, digitalOut), TRUE, obdSize, &varEntries); if (ret != kErrorOk) { PRINTF("linking process vars ... error %04x\n\"%s\"\n\n", ret, debugstr_getRetValStr(ret)); return ret; } PRINTF("Linking process vars... ok\n\n"); return kErrorOk; }
//------------------------------------------------------------------------------ tOplkError pdok_deAllocChannelMem(void) { tOplkError Ret = kErrorOk; #if NMT_MAX_NODE_ID > 0 tDllNodeOpParam NodeOpParam; NodeOpParam.opNodeType = kDllNodeOpTypeFilterPdo; NodeOpParam.nodeId = C_ADR_BROADCAST; Ret = dllk_deleteNode(&NodeOpParam); if (Ret != kErrorOk) { DEBUG_LVL_PDO_TRACE("%s() dllk_deleteNode failed (%s)\n", __func__, debugstr_getRetValStr(Ret)); return Ret; } #endif // NMT_MAX_NODE_ID > 0 // de-allocate mem for RX PDO channels if (pdokInstance_g.pdoChannels.allocation.rxPdoChannelCount != 0) { pdokInstance_g.pdoChannels.allocation.rxPdoChannelCount = 0; if (pdokInstance_g.pdoChannels.pRxPdoChannel != NULL) { OPLK_FREE(pdokInstance_g.pdoChannels.pRxPdoChannel); pdokInstance_g.pdoChannels.pRxPdoChannel = NULL; } } // de-allocate mem for TX PDO channels if (pdokInstance_g.pdoChannels.allocation.txPdoChannelCount != 0) { pdokInstance_g.pdoChannels.allocation.txPdoChannelCount = 0; if (pdokInstance_g.pdoChannels.pTxPdoChannel != NULL) { OPLK_FREE(pdokInstance_g.pdoChannels.pTxPdoChannel); pdokInstance_g.pdoChannels.pTxPdoChannel = NULL; } } return Ret; }
//------------------------------------------------------------------------------ tOplkError ProcessThread::processPdoChangeEvent(tOplkApiEventType eventType_p, tOplkApiEventArg* pEventArg_p, void* pUserArg_p) { tOplkApiEventPdoChange* pPdoChange = &pEventArg_p->pdoChange; UINT subIndex; UINT64 mappObject; tOplkError ret; UINT varLen; UNUSED_PARAMETER(eventType_p); UNUSED_PARAMETER(pUserArg_p); sigPrintLog(QString("PDO change event: (%1PDO = 0x%2 to node 0x%3 with %4 objects %5)") .arg(pPdoChange->fTx ? "T" : "R") .arg(pPdoChange->mappParamIndex, 4, 16, QLatin1Char('0')) .arg(pPdoChange->nodeId, 2, 16, QLatin1Char('0')) .arg(pPdoChange->mappObjectCount) .arg(pPdoChange->fActivated ? "activated" : "deleted")); for (subIndex = 1; subIndex <= pPdoChange->mappObjectCount; subIndex++) { varLen = sizeof(mappObject); ret = oplk_readLocalObject(pPdoChange->mappParamIndex, subIndex, &mappObject, &varLen); if (ret != kErrorOk) { sigPrintLog(QString(" Reading 0x%1/%2 failed with 0x%3\n\"4\"") .arg(pPdoChange->mappParamIndex, 4, 16, QLatin1Char('0')) .arg(subIndex) .arg(ret, 4, 16, QLatin1Char('0')) .arg(debugstr_getRetValStr(ret))); continue; } sigPrintLog(QString(" %1. mapped object 0x%2/%3") .arg(subIndex) .arg(mappObject & 0x00FFFFULL, 4, 16, QLatin1Char('0')) .arg((mappObject & 0xFF0000ULL) >> 16, 4, 16, QLatin1Char('0'))); } return kErrorOk; }
//------------------------------------------------------------------------------ tOplkError ProcessThread::processErrorWarningEvent(tOplkApiEventType eventType_p, tOplkApiEventArg* pEventArg_p, void* pUserArg_p) { tEventError* pInternalError = &pEventArg_p->internalError; UNUSED_PARAMETER(eventType_p); UNUSED_PARAMETER(pUserArg_p); sigPrintLog(QString("Err/Warn: Source = %1 (0x%2) OplkError = %3 (0x%4)") .arg(debugstr_getEventSourceStr(pInternalError->eventSource)) .arg(pInternalError->eventSource, 2, 16, QLatin1Char('0')) .arg(debugstr_getRetValStr(pInternalError->oplkError)) .arg(pInternalError->oplkError, 3, 16, QLatin1Char('0'))); switch (pInternalError->eventSource) { case kEventSourceEventk: case kEventSourceEventu: // error occurred within event processing // either in kernel or in user part sigPrintLog(QString(" OrgSource = %1 %2") .arg(debugstr_getEventSourceStr(pInternalError->errorArg.eventSource)) .arg(pInternalError->errorArg.eventSource, 2, 16, QLatin1Char('0'))); break; case kEventSourceObdu: case kEventSourceDllk: // error occurred within the data link layer (e.g. interrupt processing) // the DWORD argument contains the DLL state and the NMT event sigPrintLog(QString(" val = %1").arg(pInternalError->errorArg.uintArg, 0, 16)); break; default: //sigPrintLog(QString("\n")); break; } return kErrorOk; }
//------------------------------------------------------------------------------ static tOplkError processPdoChangeEvent(const tOplkApiEventPdoChange* pPdoChange_p, void* pUserArg_p) { UINT subIndex; UINT64 mappObject; tOplkError ret; size_t varLen; UNUSED_PARAMETER(pUserArg_p); eventlog_printPdoEvent(pPdoChange_p); for (subIndex = 1; subIndex <= pPdoChange_p->mappObjectCount; subIndex++) { varLen = sizeof(mappObject); ret = oplk_readLocalObject(pPdoChange_p->mappParamIndex, subIndex, &mappObject, &varLen); if (ret != kErrorOk) { eventlog_printMessage(kEventlogLevelError, kEventlogCategoryObjectDictionary, "Reading 0x%X/%d failed with %s(0x%X)", pPdoChange_p->mappParamIndex, subIndex, debugstr_getRetValStr(ret), ret); continue; } eventlog_printPdoMap(pPdoChange_p->mappParamIndex, subIndex, mappObject); } return kErrorOk; }
//------------------------------------------------------------------------------ static tOplkError initPowerlink(UINT32 cycleLen_p, char* pszCdcFileName_p, const BYTE* macAddr_p) { tOplkError ret = kErrorOk; static tOplkApiInitParam initParam; static char devName[128]; printf("Initializing openPOWERLINK stack...\n"); #if defined(CONFIG_USE_PCAP) if (selectPcapDevice(devName) < 0) return kErrorIllegalInstance; #elif defined(__COBALT__) if (selectDevice(devName) < 0) return kErrorIllegalInstance; #endif memset(&initParam, 0, sizeof(initParam)); initParam.sizeOfInitParam = sizeof(initParam); // pass selected device name to Edrv initParam.hwParam.pDevName = devName; initParam.nodeId = NODEID; initParam.ipAddress = (0xFFFFFF00 & IP_ADDR) | initParam.nodeId; /* write 00:00:00:00:00:00 to MAC address, so that the driver uses the real hardware address */ memcpy(initParam.aMacAddress, macAddr_p, sizeof(initParam.aMacAddress)); initParam.fAsyncOnly = FALSE; initParam.featureFlags = UINT_MAX; initParam.cycleLen = cycleLen_p; // required for error detection initParam.isochrTxMaxPayload = 256; // const initParam.isochrRxMaxPayload = 256; // const initParam.presMaxLatency = 50000; // const; only required for IdentRes initParam.preqActPayloadLimit = 36; // required for initialisation (+28 bytes) initParam.presActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes) initParam.asndMaxLatency = 150000; // const; only required for IdentRes initParam.multiplCylceCnt = 0; // required for error detection initParam.asyncMtu = 1500; // required to set up max frame size initParam.prescaler = 2; // required for sync initParam.lossOfFrameTolerance = 500000; initParam.asyncSlotTimeout = 3000000; initParam.waitSocPreq = 1000; initParam.deviceType = UINT_MAX; // NMT_DeviceType_U32 initParam.vendorId = UINT_MAX; // NMT_IdentityObject_REC.VendorId_U32 initParam.productCode = UINT_MAX; // NMT_IdentityObject_REC.ProductCode_U32 initParam.revisionNumber = UINT_MAX; // NMT_IdentityObject_REC.RevisionNo_U32 initParam.serialNumber = UINT_MAX; // NMT_IdentityObject_REC.SerialNo_U32 initParam.subnetMask = SUBNET_MASK; initParam.defaultGateway = DEFAULT_GATEWAY; sprintf((char*)initParam.sHostname, "%02x-%08x", initParam.nodeId, initParam.vendorId); initParam.syncNodeId = C_ADR_SYNC_ON_SOA; initParam.fSyncOnPrcNode = FALSE; // set callback functions initParam.pfnCbEvent = processEvents; #if defined(CONFIG_KERNELSTACK_DIRECTLINK) initParam.pfnCbSync = processSync; #else initParam.pfnCbSync = NULL; #endif // initialize POWERLINK stack ret = oplk_init(&initParam); if (ret != kErrorOk) { fprintf(stderr, "oplk_init() failed with \"%s\" (0x%04x)\n", debugstr_getRetValStr(ret), ret); return ret; } ret = oplk_setCdcFilename(pszCdcFileName_p); if (ret != kErrorOk) { fprintf(stderr, "oplk_setCdcFilename() failed with \"%s\" (0x%04x)\n", debugstr_getRetValStr(ret), ret); return ret; } return kErrorOk; }
//------------------------------------------------------------------------------ static tOplkError initPowerlink(tInstance* pInstance_p) { tOplkError ret = kErrorOk; static tOplkApiInitParam initParam; PRINTF("Initializing openPOWERLINK stack...\n"); memset(&initParam, 0, sizeof(initParam)); initParam.sizeOfInitParam = sizeof(initParam); initParam.nodeId = pInstance_p->nodeId; initParam.ipAddress = (0xFFFFFF00 & IP_ADDR) | initParam.nodeId; memcpy(initParam.aMacAddress, pInstance_p->aMacAddr, sizeof(initParam.aMacAddress)); initParam.fAsyncOnly = FALSE; initParam.featureFlags = -1; initParam.cycleLen = pInstance_p->cycleLen; // required for error detection initParam.isochrTxMaxPayload = 36; // const initParam.isochrRxMaxPayload = 36; // const initParam.presMaxLatency = 2000; // const; only required for IdentRes initParam.asndMaxLatency = 2000; // const; only required for IdentRes initParam.preqActPayloadLimit = 36; // required for initialization (+28 bytes) initParam.presActPayloadLimit = 36; // required for initialization of Pres frame (+28 bytes) initParam.multiplCylceCnt = 0; // required for error detection initParam.asyncMtu = 300; // required to set up max frame size initParam.prescaler = 2; // required for sync initParam.lossOfFrameTolerance = 100000; initParam.asyncSlotTimeout = 3000000; initParam.waitSocPreq = 0; initParam.deviceType = -1; // NMT_DeviceType_U32 initParam.vendorId = -1; // NMT_IdentityObject_REC.VendorId_U32 initParam.productCode = -1; // NMT_IdentityObject_REC.ProductCode_U32 initParam.revisionNumber = -1; // NMT_IdentityObject_REC.RevisionNo_U32 initParam.serialNumber = -1; // NMT_IdentityObject_REC.SerialNo_U32 initParam.applicationSwDate = 0; initParam.applicationSwTime = 0; initParam.subnetMask = SUBNET_MASK; initParam.defaultGateway = DEFAULT_GATEWAY; sprintf((char*)initParam.sHostname, "%02x-%08x", initParam.nodeId, initParam.vendorId); initParam.syncNodeId = C_ADR_SYNC_ON_SOC; initParam.fSyncOnPrcNode = FALSE; // set callback functions initParam.pfnCbEvent = processEvents; initParam.pfnCbSync = processSync; // initialize POWERLINK stack ret = oplk_init(&initParam); if (ret != kErrorOk) { PRINTF("oplk_init() failed with \"%s\"\n(Error:0x%x!)\n", debugstr_getRetValStr(ret), ret); return ret; } // Set real MAC address to ARP module oplk_getEthMacAddr(initParam.aMacAddress); arp_setMacAddr(initParam.aMacAddress); // Set IP address to ARP module arp_setIpAddr(initParam.ipAddress); // Set default gateway to ARP module arp_setDefGateway(initParam.defaultGateway); return kErrorOk; }
//------------------------------------------------------------------------------ Api::Api(MainWindow* pMainWindow_p, UINT nodeId_p, const QString& rDevName_p) : pCdcFilename("mnobd.cdc") { tOplkError ret; State* pState; Output* pOutput; Input* pInput; CnState* pCnState; pState = pMainWindow_p->getStateWidget(); pOutput = pMainWindow_p->getOutputWidget(); pInput = pMainWindow_p->getInputWidget(); pCnState = pMainWindow_p->getCnStateWidget(); pProcessThread = new ProcessThread(pMainWindow_p); QObject::connect(pProcessThread, SIGNAL(oplkStatusChanged(int)), pState, SLOT(setStatusLed(int))); QObject::connect(pProcessThread, SIGNAL(nmtStateChanged(const QString&)), pState, SLOT(setNmtStateText(const QString&))); QObject::connect(pProcessThread, SIGNAL(nodeAppeared(int)), pInput, SLOT(addNode(int))); QObject::connect(pProcessThread, SIGNAL(allNodesRemoved()), pInput, SLOT(removeAllNodes())); QObject::connect(pProcessThread, SIGNAL(nodeDisappeared(int)), pInput, SLOT(removeNode(int))); QObject::connect(pProcessThread, SIGNAL(nodeAppeared(int)), pOutput, SLOT(addNode(int))); QObject::connect(pProcessThread, SIGNAL(nodeDisappeared(int)), pOutput, SLOT(removeNode(int))); QObject::connect(pProcessThread, SIGNAL(allNodesRemoved()), pOutput, SLOT(removeAllNodes())); QObject::connect(pProcessThread, SIGNAL(nodeAppeared(int)), pCnState, SLOT(addNode(int))); QObject::connect(pProcessThread, SIGNAL(nodeDisappeared(int)), pCnState, SLOT(removeNode(int))); QObject::connect(pProcessThread, SIGNAL(allNodesRemoved()), pCnState, SLOT(removeAllNodes())); QObject::connect(pProcessThread, SIGNAL(nodeStatusChanged(int, int)), pCnState, SLOT(setState(int, int))); QObject::connect(pProcessThread, SIGNAL(printLog(const QString&)), pMainWindow_p, SLOT(printlog(const QString&))); QObject::connect(pProcessThread, SIGNAL(userDefEvent(void*)), this, SIGNAL(userDefEvent(void*)), Qt::DirectConnection); QObject::connect(pProcessThread, SIGNAL(sdoFinished(tSdoComFinished)), this, SIGNAL(sdoFinished(tSdoComFinished))); pDataInOutThread = new DataInOutThread; QObject::connect(pDataInOutThread, SIGNAL(processImageOutChanged(int, int)), pOutput, SLOT(setValue(int, int))); QObject::connect(pDataInOutThread, SIGNAL(processImageInChanged(int, int)), pInput, SLOT(setLeds(int, int))); QObject::connect(pDataInOutThread, SIGNAL(disableOutputs(int)), pOutput, SLOT(disable(int))); QObject::connect(pProcessThread, SIGNAL(isMnActive(bool)), pDataInOutThread, SLOT(setMnActiveFlag(bool))); memset(&initParam, 0, sizeof(initParam)); initParam.sizeOfInitParam = sizeof(initParam); initParam.nodeId = nodeId_p; initParam.ipAddress = (IP_ADDR & 0xFFFFFF00) | initParam.nodeId; initParam.fAsyncOnly = FALSE; initParam.featureFlags = UINT_MAX; initParam.cycleLen = CYCLE_LEN; // required for error detection initParam.isochrTxMaxPayload = 256; // const initParam.isochrRxMaxPayload = 1490; // const initParam.presMaxLatency = 50000; // const; only required for IdentRes initParam.preqActPayloadLimit = 36; // required for initialization (+28 bytes) initParam.presActPayloadLimit = 36; // required for initialization of Pres frame (+28 bytes) initParam.asndMaxLatency = 150000; // const; only required for IdentRes initParam.multiplCylceCnt = 0; // required for error detection initParam.asyncMtu = 1500; // required to set up max frame size initParam.prescaler = 2; // required for sync initParam.lossOfFrameTolerance = 500000; initParam.asyncSlotTimeout = 3000000; initParam.waitSocPreq = 1000; initParam.deviceType = UINT_MAX; // NMT_DeviceType_U32 initParam.vendorId = UINT_MAX; // NMT_IdentityObject_REC.VendorId_U32 initParam.productCode = UINT_MAX; // NMT_IdentityObject_REC.ProductCode_U32 initParam.revisionNumber = UINT_MAX; // NMT_IdentityObject_REC.RevisionNo_U32 initParam.serialNumber = UINT_MAX; // NMT_IdentityObject_REC.SerialNo_U32 initParam.subnetMask = SUBNET_MASK; initParam.defaultGateway = DEFAULT_GATEWAY; sprintf((char*)initParam.sHostname, "%02x-%08x", initParam.nodeId, initParam.vendorId); initParam.syncNodeId = C_ADR_SYNC_ON_SOA; initParam.fSyncOnPrcNode = FALSE; // set callback functions initParam.pfnCbEvent = pProcessThread->getEventCbFunc(); /* write 00:00:00:00:00:00 to MAC address, so that the driver uses the real hardware address */ memcpy(initParam.aMacAddress, aMacAddr_l, sizeof(initParam.aMacAddress)); // Copy the selected interface string to a local variable strcpy(devName_l, rDevName_p.toStdString().c_str()); initParam.hwParam.pDevName = devName_l; #if defined(CONFIG_KERNELSTACK_DIRECTLINK) initParam.pfnCbSync = pDataInOutThread->getSyncCbFunc(); #else initParam.pfnCbSync = NULL; #endif // Initialize object dictionary ret = obdcreate_initObd(&initParam.obdInitParam); if (ret != kErrorOk) { QMessageBox::critical(0, "POWERLINK demo", QString("Initialization of openPOWERLINK stack failed.\n") + "Error code: 0x" + QString::number(ret, 16) + "\n" + "\"" + debugstr_getRetValStr(ret) + "\"\n" + "For further information please consult the manual."); goto Exit; } // init POWERLINK ret = oplk_initialize(); if (ret != kErrorOk) { QMessageBox::critical(0, "POWERLINK demo", QString("Initialization of openPOWERLINK stack failed.\n") + "Error code: 0x"+ QString::number(ret, 16) + "\n" + "\"" + debugstr_getRetValStr(ret) + "\"\n" + "For further information please consult the manual."); goto Exit; } ret = oplk_create(&initParam); if (ret != kErrorOk) { QMessageBox::critical(0, "POWERLINK demo", QString("Creation of openPOWERLINK stack failed.\n") + "Error code: 0x"+ QString::number(ret, 16) + "\n" + "\"" + debugstr_getRetValStr(ret) + "\"\n" + "The most common error source are an unsupported Ethernet controller or the kernel module is not loaded.\n" + "For further information please consult the manual."); goto Exit; } ret = oplk_setCdcFilename(Api::pCdcFilename); if (ret != kErrorOk) { QMessageBox::critical(0, "POWERLINK demo", QString("oplk_setCdcFilename() failed.\n") + "Error code: 0x"+ QString::number(ret, 16) + "\n" + "\"" + debugstr_getRetValStr(ret) + "\""); goto Exit; } ret = pDataInOutThread->setupProcessImage(); if (ret != kErrorOk) { QMessageBox::critical(0, "POWERLINK demo", QString("setupProcessImage() failed.\n") + "Error code: 0x"+ QString::number(ret, 16) + "\n" + "\"" + debugstr_getRetValStr(ret) + "\""); goto Exit; } // start the openPOWERLINK stack ret = oplk_execNmtCommand(kNmtEventSwReset); if (ret != kErrorOk) { QMessageBox::critical(0, "POWERLINK demo", QString("oplk_execNmtCommand() failed.\n") + "Error code: 0x"+ QString::number(ret, 16) + "\n" + "\"" + debugstr_getRetValStr(ret) + "\""); goto Exit; } // start process thread pProcessThread->start(); #if !defined(CONFIG_KERNELSTACK_DIRECTLINK) // start data in out thread pDataInOutThread->start(); #endif Exit: return; }
//------------------------------------------------------------------------------ int main(void) { tOplkError ret = kErrorOk; const UINT8 aMacAddr[] = {MAC_ADDR}; UINT8 nodeid; // Initialize helper modules gpio_init(); lcd_init(); // get node ID from input nodeid = gpio_getNodeid(); // initialize instance memset(&instance_l, 0, sizeof(instance_l)); instance_l.cycleLen = CYCLE_LEN; instance_l.nodeId = (nodeid != 0) ? nodeid : NODEID; instance_l.fShutdown = FALSE; instance_l.fGsOff = FALSE; // set mac address (last byte is set to node ID) memcpy(instance_l.aMacAddr, aMacAddr, sizeof(aMacAddr)); instance_l.aMacAddr[5] = instance_l.nodeId; initEvents(&eventCbPowerlink); arp_init((UINT8)instance_l.nodeId); PRINTF("----------------------------------------------------\n"); PRINTF("openPOWERLINK embedded CN DEMO application\n"); PRINTF("using openPOWERLINK Stack: %s\n", oplk_getVersionString()); PRINTF("----------------------------------------------------\n"); PRINTF("NODEID=0x%02X\n", instance_l.nodeId); lcd_printNodeId(instance_l.nodeId); if ((ret = initPowerlink(&instance_l)) != kErrorOk) goto Exit; if ((ret = initApp()) != kErrorOk) goto Exit; if ((ret = oplk_setNonPlkForward(TRUE)) != kErrorOk) { PRINTF("WARNING: oplk_setNonPlkForward() failed with \"%s\"\n(Error:0x%x!)\n", debugstr_getRetValStr(ret), ret); } loopMain(&instance_l); Exit: arp_exit(); shutdownApp(); shutdownPowerlink(&instance_l); // Shutdown helper modules lcd_exit(); gpio_exit(); return 0; }
//------------------------------------------------------------------------------ tOplkError ProcessThread::processStateChangeEvent(tOplkApiEventType eventType_p, tOplkApiEventArg* pEventArg_p, void* pUserArg_p) { tOplkError ret = kErrorOk; tEventNmtStateChange* pNmtStateChange = &pEventArg_p->nmtStateChange; #if !defined(CONFIG_INCLUDE_CFM) UINT varLen; #endif QString str; UNUSED_PARAMETER(eventType_p); UNUSED_PARAMETER(pUserArg_p); sigNmtState(pNmtStateChange->newNmtState); sigPrintLog(QString("StateChangeEvent %1: %2 -> %3") .arg(debugstr_getNmtEventStr(pNmtStateChange->nmtEvent)) .arg(debugstr_getNmtStateStr(pNmtStateChange->oldNmtState)) .arg(debugstr_getNmtStateStr(pNmtStateChange->newNmtState))); switch (pNmtStateChange->newNmtState) { case kNmtGsOff: pProcessThread_g->sigOplkStatus(0); // NMT state machine was shut down, // because of user signal (CTRL-C) or critical POWERLINK stack error // -> also shut down oplk_process() ret = kErrorShutdown; // and unblock DataInDataOutThread oplk_freeProcessImage(); //jba do we need it here? reachedNmtStateOff(); break; case kNmtGsResetCommunication: #if !defined(CONFIG_INCLUDE_CFM) ret = setDefaultNodeAssignment(); #endif pProcessThread_g->sigOplkStatus(1); break; case kNmtGsResetConfiguration: #if !defined(CONFIG_INCLUDE_CFM) // Configuration Manager is not available, // so fetch object 0x1006 NMT_CycleLen_U32 from local OD // (in little endian byte order) // for configuration of remote CN varLen = sizeof(UINT32); ret = oplk_readObject(NULL, 0, 0x1006, 0x00, &cycleLen_g, &varLen, kSdoTypeAsnd, NULL); if (ret != kErrorOk) { sigPrintLog(QString(" oplk_readObject() failed with 0x%1\n\"2\"") .arg(ret) .arg(debugstr_getRetValStr(ret))); break; } #endif sigOplkStatus(1); break; case kNmtCsNotActive: case kNmtMsNotActive: case kNmtRmsNotActive: case kNmtGsInitialising: case kNmtGsResetApplication: case kNmtCsPreOperational1: case kNmtMsPreOperational1: case kNmtCsPreOperational2: case kNmtMsPreOperational2: case kNmtCsReadyToOperate: case kNmtMsReadyToOperate: case kNmtCsBasicEthernet: case kNmtMsBasicEthernet: sigOplkStatus(1); break; case kNmtCsOperational: case kNmtMsOperational: sigOplkStatus(2); break; default: sigOplkStatus(-1); break; } return ret; }