//--------------------------------------------------------------------------- // // Function: EplLinExit // // Description: Exit point of kernel module //// // // Parameters: N/A // // // Returns: Return code // //--------------------------------------------------------------------------- static void __exit EplLinExit (void) { tEplKernel EplRet; // halt the NMT state machine // so the processing of POWERLINK frames stops EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); // wait until NMT state machine is shut down wait_event_interruptible(WaitQueueShutdown_g, (atomic_read(&AtomicShutdown_g) == TRUE)); /* if ((iErr != 0) || (atomic_read(&AtomicShutdown_g) == EVENT_STATE_IOCTL)) { // waiting was interrupted by signal or application called wrong function EplRet = kEplShutdown; }*/ // Free resources used by the process image API EplRet = EplApiProcessImageFree(); // delete instance for all modules EplRet = EplApiShutdown(); PRINTF("EplApiShutdown(): 0x%X\n", EplRet); // deinitialize proc fs EplRet = EplLinProcFree(); PRINTF("EplLinProcFree(): 0x%X\n", EplRet); if (IS_FD_VALID(hAppFdTracingEnabled_g)) { close(hAppFdTracingEnabled_g); } }
static int EplLinRelease ( struct inode* pDeviceFile_p, // information about the device to open struct file* pInstance_p) // information about driver instance { tEplKernel EplRet = kEplSuccessful; int iRet; TRACE0("EPL: + EplLinRelease...\n"); if (uiEplState_g != EPL_STATE_NOTINIT) { // pass control to sync kernel thread, but signal termination atomic_set(&AtomicSyncState_g, EVENT_STATE_TERM); wake_up_interruptible(&WaitQueueCbSync_g); wake_up_interruptible(&WaitQueuePI_In_g); // pass control to event queue kernel thread atomic_set(&AtomicEventState_g, EVENT_STATE_TERM); wake_up_interruptible(&WaitQueueCbEvent_g); if (uiEplState_g == EPL_STATE_RUNNING) { // post NmtEventSwitchOff EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); if (EplRet == kEplSuccessful) { TRACE0("EPL: waiting for NMT_GS_OFF\n"); wait_event_interruptible(WaitQueueRelease_g, (uiEplState_g == EPL_STATE_SHUTDOWN)); // $$$ d.k.: What if waiting was interrupted by signal? } else { // post NmtEventSwitchOff failed TRACE0("EPL: event post failed\n"); } } TRACE0("EPL: call EplApiShutdown()\n"); // EPL stack can be safely shut down // delete instance for all EPL modules EplRet = EplApiShutdown(); printk("EplApiShutdown(): 0x%X\n", EplRet); } uiEplState_g = EPL_STATE_NOTOPEN; iRet = 0; MOD_DEC_USE_COUNT; TRACE1("EPL: - EplLinRelease (iRet=%d)\n", iRet); return (iRet); }
/** ******************************************************************************** \brief Destructor Destructs a POWERLINK object. *******************************************************************************/ EplApi::~EplApi() { tEplKernel EplRet; EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); pEplProcessThread->waitForNmtStateOff(); EplRet = EplApiProcessImageFree(); EplRet = EplApiShutdown(); }
//--------------------------------------------------------------------------- // // Function: openPowerlinkExit // // Description: // Shutdown and cleanup openPOWERLINK demo application // // Parameters: // none // // Returns: // void //--------------------------------------------------------------------------- void openPowerlinkExit (void) { tEplKernel EplRet; // halt the NMT state machine // so the processing of POWERLINK frames stops EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); // wait until NMT state machine is shut down taskDelay (sysClkRateGet()); fOpenPowerlinkIsRunning_g = FALSE; EplApiProcessImageFree(); // delete instance for all modules EplRet = EplApiShutdown(); PRINTF("EplApiShutdown(): 0x%X\n", EplRet); hrtimer_shutdown(); }
/*----------------------------------------------------------------------------*\ Close method for the Powerlink master \*----------------------------------------------------------------------------*/ static pwr_tStatus IoAgentClose( io_tCtx ctx, io_sAgent *ap) { tEplKernel EplRet = kEplSuccessful; io_sLocalEpl_MN *local = (io_sLocalEpl_MN *)ap->Local; io_sRack *rp; free(local); ap->Local = 0; for ( rp = ap->racklist; rp; rp = rp->next) free( (io_sLocalEpl_CN *)rp->Local); // halt the NMT state machine // so the processing of POWERLINK frames stops EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); // delete process image EplRet = EplApiProcessImageFree(); // delete instance for all modules EplRet = EplApiShutdown(); return IO__SUCCESS; }
//--------------------------------------------------------------------------- // // Function: main // // Description: main function of demo application // // Parameters: // // Returns: //--------------------------------------------------------------------------- int main (int argc, char **argv) { tEplKernel EplRet = kEplSuccessful; static tEplApiInitParam EplApiInitParam; char* sHostname = HOSTNAME; char cKey = 0; #ifdef CONFIG_POWERLINK_USERSTACK // variables for Pcap char sErr_Msg[ PCAP_ERRBUF_SIZE ]; char devName[128]; pcap_if_t * alldevs; pcap_if_t * seldev; int i = 0; int inum; #endif int opt; #if (TARGET_SYSTEM == _LINUX_) /* get command line parameters */ while ((opt = getopt(argc, argv, "c:l:")) != -1) { switch (opt) { case 'c': uiCycleLen_g = strtoul(optarg, NULL, 10); break; case 'l': pLogFile_g = optarg; break; default: /* '?' */ fprintf (stderr, "Usage: %s [-c CYCLE_TIME] [-l LOGFILE]\n", argv[0]); goto Exit; } } #endif #ifdef CONFIG_POWERLINK_USERSTACK #if (TARGET_SYSTEM == _LINUX_) struct sched_param schedParam; /* adjust process priority */ if (nice (-20) == -1) // push nice level in case we have no RTPreempt { EPL_DBGLVL_ERROR_TRACE("%s() couldn't set nice value! (%s)\n", __func__, strerror(errno)); } schedParam.__sched_priority = MAIN_THREAD_PRIORITY; if (pthread_setschedparam(pthread_self(), SCHED_RR, &schedParam) != 0) { EPL_DBGLVL_ERROR_TRACE("%s() couldn't set thread scheduling parameters! %d\n", __func__, schedParam.__sched_priority); } /* Initialize target specific stuff */ EplTgtInit(); #elif (TARGET_SYSTEM == _WIN32_) // activate realtime priority class SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); // lower the priority of this thread SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_IDLE); #endif // (TARGET_SYSTEM == _WIN32_) #endif // CONFIG_POWERLINK_USERSTACK #if (TARGET_SYSTEM == _LINUX_) #ifdef SET_CPU_AFFINITY { /* binds all openPOWERLINK threads to the second CPU core */ cpu_set_t affinity; CPU_ZERO(&affinity); CPU_SET(1, &affinity); sched_setaffinity(0, sizeof(cpu_set_t), &affinity); } #endif #endif /* Enabling ftrace for debugging */ FTRACE_OPEN(); FTRACE_ENABLE(TRUE); /* EPL_DBGLVL_ALWAYS_TRACE("%s(): Main Thread Id:%ld\n", __func__, syscall(SYS_gettid)); */ printf("----------------------------------------------------\n"); printf("openPOWERLINK console MN DEMO application\n"); printf("----------------------------------------------------\n"); EPL_MEMSET(&EplApiInitParam, 0, sizeof (EplApiInitParam)); EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam); #ifdef CONFIG_POWERLINK_USERSTACK /* Retrieve the device list on the local machine */ if (pcap_findalldevs(&alldevs, sErr_Msg) == -1) { fprintf(stderr, "Error in pcap_findalldevs: %s\n", sErr_Msg); EplRet = kEplNoResource; goto Exit; } PRINTF("--------------------------------------------------\n"); PRINTF("List of Ethernet Cards Found in this System: \n"); PRINTF("--------------------------------------------------\n"); /* Print the list */ for (seldev = alldevs; seldev != NULL; seldev = seldev->next) { PRINTF("%d. ", ++i); if (seldev->description) { PRINTF("%s\n %s\n", seldev->description, seldev->name); } else { PRINTF("%s\n", seldev->name); } } if (i == 0) { PRINTF("\nNo interfaces found! Make sure pcap library is installed.\n"); EplRet = kEplNoResource; goto Exit; } PRINTF("--------------------------------------------------\n"); PRINTF("Select the interface to be used for POWERLINK (1-%d):",i); if (scanf("%d", &inum) == EOF) { pcap_freealldevs(alldevs); EplRet = kEplNoResource; goto Exit; } PRINTF("--------------------------------------------------\n"); if ((inum < 1) || (inum > i)) { PRINTF("\nInterface number out of range.\n"); /* Free the device list */ pcap_freealldevs(alldevs); EplRet = kEplNoResource; goto Exit; } /* Jump to the selected adapter */ for (seldev = alldevs, i = 0; i < (inum - 1); seldev = seldev->next, i++) { // do nothing } strncpy(devName, seldev->name, 127); // pass selected device name to Edrv EplApiInitParam.m_HwParam.m_pszDevName = devName; #endif EplApiInitParam.m_uiNodeId = uiNodeId_g = NODEID; EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId; /* write 00:00:00:00:00:00 to MAC address, so that the driver uses the real hardware address */ EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress)); EplApiInitParam.m_fAsyncOnly = FALSE; EplApiInitParam.m_dwFeatureFlags = -1; EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection EplApiInitParam.m_uiIsochrTxMaxPayload = 256; // const EplApiInitParam.m_uiIsochrRxMaxPayload = 256; // const EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes) EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes) EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size EplApiInitParam.m_uiPrescaler = 2; // required for sync EplApiInitParam.m_dwLossOfFrameTolerance = 500000; EplApiInitParam.m_dwAsyncSlotTimeout = 3000000; EplApiInitParam.m_dwWaitSocPreq = 150000; EplApiInitParam.m_dwDeviceType = -1; // NMT_DeviceType_U32 EplApiInitParam.m_dwVendorId = -1; // NMT_IdentityObject_REC.VendorId_U32 EplApiInitParam.m_dwProductCode = -1; // NMT_IdentityObject_REC.ProductCode_U32 EplApiInitParam.m_dwRevisionNumber = -1; // NMT_IdentityObject_REC.RevisionNo_U32 EplApiInitParam.m_dwSerialNumber = -1; // NMT_IdentityObject_REC.SerialNo_U32 EplApiInitParam.m_dwSubnetMask = SUBNET_MASK; EplApiInitParam.m_dwDefaultGateway = 0; EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname)); EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA; EplApiInitParam.m_fSyncOnPrcNode = FALSE; // set callback functions EplApiInitParam.m_pfnCbEvent = AppCbEvent; #ifdef CONFIG_POWERLINK_USERSTACK EplApiInitParam.m_pfnObdInitRam = EplObdInitRam; EplApiInitParam.m_pfnCbSync = AppCbSync; #else EplApiInitParam.m_pfnCbSync = NULL; #endif printf("\n\nHello, I'm a Userspace POWERLINK node running as %s!\n (build: %s / %s)\n\n", (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"), __DATE__, __TIME__); // initialize POWERLINK stack printf ("Initializing openPOWERLINK stack...\n"); EplRet = EplApiInitialize(&EplApiInitParam); if(EplRet != kEplSuccessful) { printf("EplApiInitialize() failed (Error:0x%x!\n", EplRet); goto Exit; } // initialize application printf ("Initializing openPOWERLINK application...\n"); EplRet = AppInit(); if(EplRet != kEplSuccessful) { printf("ApiInit() failed!\n"); goto Exit; } #ifdef CONFIG_POWERLINK_USERSTACK /* At this point, we don't need any more the device list. Free it */ pcap_freealldevs(alldevs); EplRet = EplApiSetCdcFilename(pszCdcFilename_g); if(EplRet != kEplSuccessful) { goto Exit; } #else // create event thread if (pthread_create(&eventThreadId, NULL, &powerlinkEventThread, NULL) != 0) { goto Exit; } // create sync thread if (pthread_create(&syncThreadId, NULL, &powerlinkSyncThread, NULL) != 0) { goto Exit; } #endif printf("Initializing process image...\n"); printf("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g)); printf("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g)); AppProcessImageCopyJob_g.m_fNonBlocking = FALSE; AppProcessImageCopyJob_g.m_uiPriority = 0; AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g; AppProcessImageCopyJob_g.m_In.m_uiOffset = 0; AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g); AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g; AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0; AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g); EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g), sizeof (AppProcessImageOut_g), 2, 2); if (EplRet != kEplSuccessful) { goto Exit; } EplRet = EplApiProcessImageSetup(); if (EplRet != kEplSuccessful) { goto Exit; } // start processing EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); if (EplRet != kEplSuccessful) { goto ExitShutdown; } printf("\n-------------------------------\n"); printf("Press Esc to leave the program\n"); printf("Press r to reset the node\n"); printf("-------------------------------\n\n"); // wait for key hit while (cKey != 0x1B) { if( EplTgtKbhit() ) { cKey = (BYTE) EplTgtGetch(); switch (cKey) { case 'r': { EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); if (EplRet != kEplSuccessful) { goto ExitShutdown; } break; } case 'c': { EplRet = EplApiExecNmtCommand(kEplNmtEventNmtCycleError); if (EplRet != kEplSuccessful) { goto ExitShutdown; } break; } default: { break; } } } EplTgtMilliSleep( 1500 ); } FTRACE_ENABLE(FALSE); ExitShutdown: // halt the NMT state machine // so the processing of POWERLINK frames stops EplRet = EplApiExecNmtCommand(kEplNmtEventSwitchOff); // delete process image EplRet = EplApiProcessImageFree(); // delete instance for all modules EplRet = EplApiShutdown(); Exit: PRINTF("main(): returns 0x%X\n", EplRet); #if (TARGET_SYSTEM == _WIN32_) PRINTF("Press Enter to quit!\n"); EplTgtGetch(); #endif return EplRet; }
//--------------------------------------------------------------------------- // // Function: EplLinInit // // Description: Entry point of kernel module //// // // Parameters: N/A // // // Returns: Return code // //--------------------------------------------------------------------------- static int __init EplLinInit (void) { tEplKernel EplRet; static tEplApiInitParam EplApiInitParam = {0}; char* sHostname = HOSTNAME; BOOL fApiInit = FALSE; BOOL fLinProcInit =FALSE; atomic_set(&AtomicShutdown_g, TRUE); // open character device from debugfs to disable tracing when necessary hAppFdTracingEnabled_g = open("/sys/kernel/debug/tracing/tracing_enabled", O_WRONLY, 0666); // get node ID from insmod command line EplApiInitParam.m_uiNodeId = uiNodeId_g; if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { // invalid node ID set // set default node ID EplApiInitParam.m_uiNodeId = NODEID; } uiNodeId_g = EplApiInitParam.m_uiNodeId; // calculate IP address EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId; EplApiInitParam.m_fAsyncOnly = FALSE; EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam); EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress)); EplApiInitParam.m_dwFeatureFlags = (DWORD) ~0UL; EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes) EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes) EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size EplApiInitParam.m_uiPrescaler = 2; // required for sync EplApiInitParam.m_dwLossOfFrameTolerance = 500000; EplApiInitParam.m_dwAsyncSlotTimeout = 3000000; EplApiInitParam.m_dwWaitSocPreq = 150000; EplApiInitParam.m_dwDeviceType = (DWORD) ~0UL; // NMT_DeviceType_U32 EplApiInitParam.m_dwVendorId = (DWORD) ~0UL; // NMT_IdentityObject_REC.VendorId_U32 EplApiInitParam.m_dwProductCode = (DWORD) ~0UL; // NMT_IdentityObject_REC.ProductCode_U32 EplApiInitParam.m_dwRevisionNumber = (DWORD) ~0UL; // NMT_IdentityObject_REC.RevisionNo_U32 EplApiInitParam.m_dwSerialNumber = (DWORD) ~0UL; // NMT_IdentityObject_REC.SerialNo_U32 EplApiInitParam.m_dwSubnetMask = SUBNET_MASK; EplApiInitParam.m_dwDefaultGateway = 0; EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname)); EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA; EplApiInitParam.m_fSyncOnPrcNode = FALSE; // set callback functions EplApiInitParam.m_pfnCbEvent = AppCbEvent; EplApiInitParam.m_pfnCbSync = AppCbSync; EplApiInitParam.m_pfnObdInitRam = EplObdInitRam; printk("\n\n Hello, I'm a simple POWERLINK node running as %s!\n (build: %s / %s)\n\n", (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"), __DATE__, __TIME__); // initialize the Linux a wait queue for shutdown of this module init_waitqueue_head(&WaitQueueShutdown_g); // initialize the procfs device EplRet = EplLinProcInit(); if (EplRet != kEplSuccessful) { PRINTF("EplLinProcInit failed!\n"); goto Exit; } fLinProcInit = TRUE; // initialize POWERLINK stack EplRet = EplApiInitialize(&EplApiInitParam); if(EplRet != kEplSuccessful) { PRINTF("EplApiInitialize failed!\n"); goto Exit; } fApiInit = TRUE; EplRet = EplApiSetCdcFilename(pszCdcFilename_g); if(EplRet != kEplSuccessful) { goto Exit; } PRINTF("Initializing process image...\n"); PRINTF("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g)); PRINTF("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g)); AppProcessImageCopyJob_g.m_fNonBlocking = FALSE; AppProcessImageCopyJob_g.m_uiPriority = 0; AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g; AppProcessImageCopyJob_g.m_In.m_uiOffset = 0; AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g); AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g; AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0; AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g); EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g), sizeof (AppProcessImageOut_g), 2, 2); if (EplRet != kEplSuccessful) { goto Exit; } EplRet = EplApiProcessImageSetup(); if (EplRet != kEplSuccessful) { goto Exit; } // start the NMT state machine EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); atomic_set(&AtomicShutdown_g, FALSE); Exit: PRINTF("EplLinInit(): returns 0x%X\n", EplRet); if (EplRet != kEplSuccessful) { if (fApiInit != FALSE) { EplApiShutdown(); } if (fLinProcInit != FALSE) { EplLinProcFree(); } return -ENODEV; } else { return 0; } }
//--------------------------------------------------------------------------- // // Function: openPowerlinkInit // // Description: // Initialize and start the openPOWERLINK demo application // // Parameters: // pszEthName = pointer to string with name of network interface to use // // Returns: int // //--------------------------------------------------------------------------- int openPowerlinkInit (char *pszEthName, unsigned int uiDevNumber) { tEplKernel EplRet; static tEplApiInitParam EplApiInitParam = {0}; char* sHostname = HOSTNAME; BOOL fApiInit = FALSE; int tid; // Adjust task priorities of system tasks /* shell task is normally set to priority 1 which could disturb * openPOWERLINK if long-running commands are entered. Therefore * we lower the performance to 20 */ tid = taskIdSelf(); printf ("Task ID: %d\n", tid); taskPrioritySet(tid, 20); /* The priority of the network stack task has to be increased (default:50) * in order to get network packets in time! */ if ((tid = taskNameToId("tNet0")) != -1 ) { taskPrioritySet(tid, 5); } // Initialize high-resolution timer library hrtimer_init(EPL_TASK_PRIORITY_HRTIMER, EPL_TASK_STACK_SIZE); // get node ID from insmod command line EplApiInitParam.m_uiNodeId = uiNodeId_g; if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { // invalid node ID set // set default node ID EplApiInitParam.m_uiNodeId = NODEID; } uiNodeId_g = EplApiInitParam.m_uiNodeId; // calculate IP address EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId; EplApiInitParam.m_fAsyncOnly = FALSE; // store the specified device name EplApiInitParam.m_HwParam.m_pszDevName = pszEthName; EplApiInitParam.m_HwParam.m_uiDevNumber = uiDevNumber; EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam); EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof (EplApiInitParam.m_abMacAddress)); EplApiInitParam.m_dwFeatureFlags = (DWORD) ~0UL; EplApiInitParam.m_dwCycleLen = uiCycleLen_g; // required for error detection EplApiInitParam.m_uiIsochrTxMaxPayload = 100; // const EplApiInitParam.m_uiIsochrRxMaxPayload = 100; // const EplApiInitParam.m_dwPresMaxLatency = 50000; // const; only required for IdentRes EplApiInitParam.m_uiPreqActPayloadLimit = 36; // required for initialisation (+28 bytes) EplApiInitParam.m_uiPresActPayloadLimit = 36; // required for initialisation of Pres frame (+28 bytes) EplApiInitParam.m_dwAsndMaxLatency = 150000; // const; only required for IdentRes EplApiInitParam.m_uiMultiplCycleCnt = 0; // required for error detection EplApiInitParam.m_uiAsyncMtu = 1500; // required to set up max frame size EplApiInitParam.m_uiPrescaler = 2; // required for sync EplApiInitParam.m_dwLossOfFrameTolerance = 500000; EplApiInitParam.m_dwAsyncSlotTimeout = 3000000; EplApiInitParam.m_dwWaitSocPreq = 0; EplApiInitParam.m_dwDeviceType = (DWORD) ~0UL; // NMT_DeviceType_U32 EplApiInitParam.m_dwVendorId = (DWORD) ~0UL; // NMT_IdentityObject_REC.VendorId_U32 EplApiInitParam.m_dwProductCode = (DWORD) ~0UL; // NMT_IdentityObject_REC.ProductCode_U32 EplApiInitParam.m_dwRevisionNumber = (DWORD) ~0UL; // NMT_IdentityObject_REC.RevisionNo_U32 EplApiInitParam.m_dwSerialNumber = (DWORD) ~0UL; // NMT_IdentityObject_REC.SerialNo_U32 EplApiInitParam.m_dwSubnetMask = SUBNET_MASK; EplApiInitParam.m_dwDefaultGateway = 0; EPL_MEMCPY(EplApiInitParam.m_sHostname, sHostname, sizeof(EplApiInitParam.m_sHostname)); EplApiInitParam.m_uiSyncNodeId = EPL_C_ADR_SYNC_ON_SOA; // for fSyncOnPrcNode==TRUE, this means last PRC node EplApiInitParam.m_fSyncOnPrcNode = TRUE; // set callback functions EplApiInitParam.m_pfnCbEvent = AppCbEvent; EplApiInitParam.m_pfnCbSync = AppCbSync; EplApiInitParam.m_pfnObdInitRam = EplObdInitRam; printf("\n\n Hello, I'm a VxWorks POWERLINK node running as %s!\n" "(build: %s / %s)\n\n", (uiNodeId_g == EPL_C_ADR_MN_DEF_NODE_ID ? "Managing Node" : "Controlled Node"), __DATE__, __TIME__); // initialize POWERLINK stack EplRet = EplApiInitialize(&EplApiInitParam); if(EplRet != kEplSuccessful) { goto Exit; } fApiInit = TRUE; // set CDC filename EplRet = EplApiSetCdcFilename(pszCdcFilename_g); if(EplRet != kEplSuccessful) { printf ("Error set cdc filename!\n"); goto Exit; } // initialize application printf ("Initializing openPOWERLINK application...\n"); EplRet = AppInit(); if(EplRet != kEplSuccessful) { printf("ApiInit() failed!\n"); goto Exit; } // initialize process image printf("Initializing process image...\n"); printf("Size of input process image: %ld\n", sizeof(AppProcessImageIn_g)); printf("Size of output process image: %ld\n", sizeof (AppProcessImageOut_g)); AppProcessImageCopyJob_g.m_fNonBlocking = FALSE; AppProcessImageCopyJob_g.m_uiPriority = 0; AppProcessImageCopyJob_g.m_In.m_pPart = &AppProcessImageIn_g; AppProcessImageCopyJob_g.m_In.m_uiOffset = 0; AppProcessImageCopyJob_g.m_In.m_uiSize = sizeof (AppProcessImageIn_g); AppProcessImageCopyJob_g.m_Out.m_pPart = &AppProcessImageOut_g; AppProcessImageCopyJob_g.m_Out.m_uiOffset = 0; AppProcessImageCopyJob_g.m_Out.m_uiSize = sizeof (AppProcessImageOut_g); EplRet = EplApiProcessImageAlloc(sizeof (AppProcessImageIn_g), sizeof (AppProcessImageOut_g), 2, 2); if (EplRet != kEplSuccessful) { goto Exit; } EplRet = EplApiProcessImageSetup(); if (EplRet != kEplSuccessful) { goto Exit; } // start the NMT state machine EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); Exit: PRINTF("%s(): returns 0x%X\n", __func__, EplRet); if (EplRet != kEplSuccessful) { if (fApiInit != FALSE) { EplApiShutdown(); } // Shutdown high-resolution timer library hrtimer_shutdown(); fOpenPowerlinkIsRunning_g = FALSE; return -ENODEV; } else { fOpenPowerlinkIsRunning_g = TRUE; return 0; } }
int openPowerlink(void) { const BYTE abMacAddr[] = {MAC_ADDR}; static tEplApiInitParam EplApiInitParam = {0}; // needed for process var tEplObdSize ObdSize; tEplKernel EplRet; unsigned int uiVarEntries; fShutdown_l = FALSE; //////////////////////// // setup th EPL Stack // //////////////////////// // set EPL init parameters EplApiInitParam.m_uiSizeOfStruct = sizeof (EplApiInitParam); #ifdef NODESWITCH_SPI_BASE // read node-ID from hex switch on baseboard, which is connected via SPI shift register IOWR_ALTERA_AVALON_SPI_TXDATA(NODESWITCH_SPI_BASE, 0xFF); // generate pulse for latching inputs while ((IORD_ALTERA_AVALON_SPI_STATUS(NODESWITCH_SPI_BASE) & ALTERA_AVALON_SPI_STATUS_RRDY_MSK) == 0) { // wait } EplApiInitParam.m_uiNodeId = IORD_ALTERA_AVALON_SPI_RXDATA(NODESWITCH_SPI_BASE); #endif #ifdef NODESWITCH_PIO_BASE EplApiInitParam.m_uiNodeId = IORD_ALTERA_AVALON_PIO_DATA(NODESWITCH_PIO_BASE); #endif if (EplApiInitParam.m_uiNodeId == EPL_C_ADR_INVALID) { EplApiInitParam.m_uiNodeId = NODEID; // defined at the top of this file! } EPL_MEMCPY(EplApiInitParam.m_abMacAddress, abMacAddr, sizeof(EplApiInitParam.m_abMacAddress)); EplApiInitParam.m_abMacAddress[5] = (BYTE) EplApiInitParam.m_uiNodeId; // calculate IP address EplApiInitParam.m_dwIpAddress = (0xFFFFFF00 & IP_ADDR) | EplApiInitParam.m_uiNodeId; EplApiInitParam.m_uiIsochrTxMaxPayload = 256; EplApiInitParam.m_uiIsochrRxMaxPayload = 256; EplApiInitParam.m_dwPresMaxLatency = 2000; EplApiInitParam.m_dwAsndMaxLatency = 2000; EplApiInitParam.m_fAsyncOnly = FALSE; EplApiInitParam.m_dwFeatureFlags = -1; EplApiInitParam.m_dwCycleLen = CYCLE_LEN; EplApiInitParam.m_uiPreqActPayloadLimit = 36; EplApiInitParam.m_uiPresActPayloadLimit = 36; EplApiInitParam.m_uiMultiplCycleCnt = 0; EplApiInitParam.m_uiAsyncMtu = 1500; EplApiInitParam.m_uiPrescaler = 2; EplApiInitParam.m_dwLossOfFrameTolerance = 500000; EplApiInitParam.m_dwAsyncSlotTimeout = 3000000; EplApiInitParam.m_dwWaitSocPreq = 0; EplApiInitParam.m_dwDeviceType = -1; EplApiInitParam.m_dwVendorId = -1; EplApiInitParam.m_dwProductCode = -1; EplApiInitParam.m_dwRevisionNumber = -1; EplApiInitParam.m_dwSerialNumber = -1; EplApiInitParam.m_dwSubnetMask = SUBNET_MASK; EplApiInitParam.m_dwDefaultGateway = 0; EplApiInitParam.m_dwApplicationSwDate = 1; // PDL_LocVerApplSw_REC.ApplSwDate_U32 on programmable device or date portion of NMT_ManufactSwVers_VS on non-programmable device EplApiInitParam.m_pfnCbEvent = AppCbEvent; EplApiInitParam.m_pfnCbSync = AppCbSync; EplApiInitParam.m_pfnObdInitRam = EplObdInitRam; EplApiInitParam.m_dwSyncResLatency = EPL_C_DLL_T_IFG; // initialize EPL stack printf("init EPL Stack with node-ID 0x%02X:\n", EplApiInitParam.m_uiNodeId); EplRet = EplApiInitialize(&EplApiInitParam); if(EplRet != kEplSuccessful) { printf("init EPL Stack... error %X\n\n", EplRet); goto Exit; } printf("init EPL Stack...ok\n\n"); // link process variables used by CN to object dictionary printf("linking process vars:\n"); ObdSize = sizeof(bButtonInputs_l); uiVarEntries = 1; EplRet = EplApiLinkObject(0x6000, &bButtonInputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } ObdSize = sizeof(abVirtualInputs_l[0]); uiVarEntries = 17; EplRet = EplApiLinkObject(0x2000, abVirtualInputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } ObdSize = sizeof(adwVirtualInputs_l[0]); uiVarEntries = 8; EplRet = EplApiLinkObject(0x2001, adwVirtualInputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } ObdSize = sizeof(wDigitalOutputs_l); uiVarEntries = 1; EplRet = EplApiLinkObject(0x6300, &wDigitalOutputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } ObdSize = sizeof(bLedOutputs_l); uiVarEntries = 1; EplRet = EplApiLinkObject(0x6200, &bLedOutputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } ObdSize = sizeof(abVirtualOutputs_l[0]); uiVarEntries = 15; EplRet = EplApiLinkObject(0x2200, abVirtualOutputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } ObdSize = sizeof(adwVirtualOutputs_l[0]); uiVarEntries = 8; EplRet = EplApiLinkObject(0x2201, adwVirtualOutputs_l, &uiVarEntries, &ObdSize, 0x01); if (EplRet != kEplSuccessful) { printf("linking process vars... error\n\n"); goto ExitShutdown; } printf("linking process vars... ok\n\n"); // start the EPL stack printf("start EPL Stack...\n"); EplRet = EplApiExecNmtCommand(kEplNmtEventSwReset); if (EplRet != kEplSuccessful) { printf("start EPL Stack... error\n\n"); goto ExitShutdown; } printf("start EPL Stack... ok\n\n"); printf("NIOS II with openPowerlink is ready!\n\n"); #ifdef LED_PIO_BASE IOWR_ALTERA_AVALON_PIO_DATA(LED_PIO_BASE, 0xFF); #endif while(1) { EplApiProcess(); if (fShutdown_l == TRUE) break; } ExitShutdown: printf("Shutdown EPL Stack\n"); EplApiShutdown(); //shutdown node Exit: return EplRet; }