1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for Epl-Kernelspace-Event-Modul
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
50 -------------------------------------------------------------------------
52 $RCSfile: EplEventk.c,v $
56 $Revision: 1.9 $ $Date: 2008/10/17 15:32:32 $
63 -------------------------------------------------------------------------
67 2006/06/20 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "kernel/EplEventk.h"
72 #include "kernel/EplNmtk.h"
73 #include "kernel/EplDllk.h"
74 #include "kernel/EplDllkCal.h"
75 #include "kernel/EplErrorHandlerk.h"
76 #include "Benchmark.h"
78 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
79 #include "kernel/EplPdok.h"
80 #include "kernel/EplPdokCal.h"
84 #include "user/EplEventu.h"
86 #include "SharedBuff.h"
89 /***************************************************************************/
92 /* G L O B A L D E F I N I T I O N S */
95 /***************************************************************************/
97 //---------------------------------------------------------------------------
99 //---------------------------------------------------------------------------
101 // TracePoint support for realtime-debugging
102 #ifdef _DBG_TRACE_POINTS_
103 void PUBLIC TgtDbgSignalTracePoint (BYTE bTracePointNumber_p);
104 void PUBLIC TgtDbgPostTraceValue (DWORD dwTraceValue_p);
105 #define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
106 #define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
108 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
109 #define TGT_DBG_POST_TRACE_VALUE(v)
112 //---------------------------------------------------------------------------
114 //---------------------------------------------------------------------------
119 tShbInstance m_pShbKernelToUserInstance;
120 tShbInstance m_pShbUserToKernelInstance;
124 tEplSyncCb m_pfnCbSync;
125 unsigned int m_uiUserToKernelFullCount;
127 } tEplEventkInstance;
129 //---------------------------------------------------------------------------
130 // modul globale vars
131 //---------------------------------------------------------------------------
132 static tEplEventkInstance EplEventkInstance_g;
133 //---------------------------------------------------------------------------
134 // local function prototypes
135 //---------------------------------------------------------------------------
137 // callback function for incoming events
139 static void EplEventkRxSignalHandlerCb (
140 tShbInstance pShbRxInstance_p,
141 unsigned long ulDataSize_p);
144 /***************************************************************************/
147 /* C L A S S <Epl-Kernelspace-Event> */
150 /***************************************************************************/
155 /***************************************************************************/
157 //=========================================================================//
159 // P U B L I C F U N C T I O N S //
161 //=========================================================================//
163 //---------------------------------------------------------------------------
165 // Function: EplEventkInit
167 // Description: function initializes the first instance
169 // Parameters: pfnCbSync_p = callback-function for sync event
171 // Returns: tEpKernel = errorcode
175 //---------------------------------------------------------------------------
177 tEplKernel PUBLIC EplEventkInit(tEplSyncCb pfnCbSync_p)
181 Ret = EplEventkAddInstance(pfnCbSync_p);
188 //---------------------------------------------------------------------------
190 // Function: EplEventkAddInstance
192 // Description: function adds one more instance
194 // Parameters: pfnCbSync_p = callback-function for sync event
196 // Returns: tEpKernel = errorcode
200 //---------------------------------------------------------------------------
202 tEplKernel PUBLIC EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
207 unsigned int fShbNewCreated;
210 Ret = kEplSuccessful;
212 // init instance structure
213 EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
216 EplEventkInstance_g.m_pfnCbSync = pfnCbSync_p;
219 // init shared loop buffer
221 ShbError = ShbCirAllocBuffer (EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
222 EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
223 &EplEventkInstance_g.m_pShbKernelToUserInstance,
225 if(ShbError != kShbOk)
227 EPL_DBGLVL_EVENTK_TRACE1("EplEventkAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n", ShbError);
228 Ret = kEplNoResource;
233 ShbError = ShbCirAllocBuffer (EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
234 EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
235 &EplEventkInstance_g.m_pShbUserToKernelInstance,
237 if(ShbError != kShbOk)
239 EPL_DBGLVL_EVENTK_TRACE1("EplEventkAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n", ShbError);
240 Ret = kEplNoResource;
244 // register eventhandler
245 ShbError = ShbCirSetSignalHandlerNewData (EplEventkInstance_g.m_pShbUserToKernelInstance,
246 EplEventkRxSignalHandlerCb,
248 if(ShbError != kShbOk)
250 EPL_DBGLVL_EVENTK_TRACE1("EplEventkAddInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n", ShbError);
251 Ret = kEplNoResource;
263 //---------------------------------------------------------------------------
265 // Function: EplEventkDelInstance
267 // Description: function deletes instance and frees the buffers
271 // Returns: tEpKernel = errorcode
275 //---------------------------------------------------------------------------
277 tEplKernel PUBLIC EplEventkDelInstance()
284 Ret = kEplSuccessful;
287 // set eventhandler to NULL
288 ShbError = ShbCirSetSignalHandlerNewData (EplEventkInstance_g.m_pShbUserToKernelInstance,
291 if(ShbError != kShbOk)
293 EPL_DBGLVL_EVENTK_TRACE1("EplEventkDelInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n", ShbError);
294 Ret = kEplNoResource;
297 // free buffer User -> Kernel
298 ShbError = ShbCirReleaseBuffer (EplEventkInstance_g.m_pShbUserToKernelInstance);
299 if(ShbError != kShbOk)
301 EPL_DBGLVL_EVENTK_TRACE1("EplEventkDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n", ShbError);
302 Ret = kEplNoResource;
306 EplEventkInstance_g.m_pShbUserToKernelInstance = NULL;
309 // free buffer Kernel -> User
310 ShbError = ShbCirReleaseBuffer (EplEventkInstance_g.m_pShbKernelToUserInstance);
311 if(ShbError != kShbOk)
313 EPL_DBGLVL_EVENTK_TRACE1("EplEventkDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n", ShbError);
314 Ret = kEplNoResource;
318 EplEventkInstance_g.m_pShbKernelToUserInstance = NULL;
327 //---------------------------------------------------------------------------
329 // Function: EplEventkProcess
331 // Description: Kernelthread that dispatches events in kernel part
333 // Parameters: pEvent_p = pointer to event-structure from buffer
335 // Returns: tEpKernel = errorcode
339 //---------------------------------------------------------------------------
341 tEplKernel PUBLIC EplEventkProcess(tEplEvent* pEvent_p)
344 tEplEventSource EventSource;
346 Ret = kEplSuccessful;
348 // error handling if event queue is full
349 if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0)
350 { // UserToKernel event queue has run out of space -> kEplNmtEventInternComError
351 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
353 tEplNmtEvent NmtEvent;
359 // directly call NMTk process function, because event queue is full
360 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
361 NmtEvent = kEplNmtEventInternComError;
362 Event.m_EventSink = kEplEventSinkNmtk;
363 Event.m_NetTime.m_dwNanoSec = 0;
364 Event.m_NetTime.m_dwSec = 0;
365 Event.m_EventType = kEplEventTypeNmtEvent;
366 Event.m_pArg = &NmtEvent;
367 Event.m_uiSize = sizeof(NmtEvent);
368 Ret = EplNmtkProcess(&Event);
371 // NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION)
372 // now, it is safe to reset the counter and empty the event queue
374 ShbError = ShbCirResetBuffer (EplEventkInstance_g.m_pShbUserToKernelInstance, 1000, NULL);
377 EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
378 TGT_DBG_SIGNAL_TRACE_POINT(22);
380 // also discard the current event (it doesn't matter if we lose another event)
385 switch(pEvent_p->m_EventSink)
387 case kEplEventSinkSync:
389 if (EplEventkInstance_g.m_pfnCbSync != NULL)
391 Ret = EplEventkInstance_g.m_pfnCbSync();
392 if (Ret == kEplSuccessful)
394 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
395 // mark TPDOs as valid
396 Ret = EplPdokCalSetTpdosValid(TRUE);
399 else if ((Ret != kEplReject) && (Ret != kEplShutdown))
401 EventSource = kEplEventSourceSyncCb;
403 // Error event for API layer
404 EplEventkPostError(kEplEventSourceEventk,
414 case kEplEventSinkNmtk:
416 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
417 Ret = EplNmtkProcess(pEvent_p);
418 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
420 EventSource = kEplEventSourceNmtk;
422 // Error event for API layer
423 EplEventkPostError(kEplEventSourceEventk,
429 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
430 if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent)
431 && ((*((tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa)
432 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
433 || (*((tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllMeSoaSent)
436 { // forward SoA event to error handler
437 Ret = EplErrorHandlerkProcess(pEvent_p);
438 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
440 EventSource = kEplEventSourceErrk;
442 // Error event for API layer
443 EplEventkPostError(kEplEventSourceEventk,
449 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
450 // forward SoA event to PDO module
451 pEvent_p->m_EventType = kEplEventTypePdoSoa;
452 Ret = EplPdokProcess(pEvent_p);
453 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
455 EventSource = kEplEventSourcePdok;
457 // Error event for API layer
458 EplEventkPostError(kEplEventSourceEventk,
470 // events for Dllk module
471 case kEplEventSinkDllk:
473 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
474 Ret = EplDllkProcess(pEvent_p);
475 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
477 EventSource = kEplEventSourceDllk;
479 // Error event for API layer
480 EplEventkPostError(kEplEventSourceEventk,
489 // events for DllkCal module
490 case kEplEventSinkDllkCal:
492 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
493 Ret = EplDllkCalProcess(pEvent_p);
494 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
496 EventSource = kEplEventSourceDllk;
498 // Error event for API layer
499 EplEventkPostError(kEplEventSourceEventk,
509 case kEplEventSinkPdok:
512 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
513 Ret = EplPdokProcess(pEvent_p);
514 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
516 EventSource = kEplEventSourcePdok;
518 // Error event for API layer
519 EplEventkPostError(kEplEventSourceEventk,
528 // events for Error handler module
529 case kEplEventSinkErrk:
531 // only call error handler if DLL is present
532 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
533 Ret = EplErrorHandlerkProcess(pEvent_p);
534 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
536 EventSource = kEplEventSourceErrk;
538 // Error event for API layer
539 EplEventkPostError(kEplEventSourceEventk,
551 Ret = kEplEventUnknownSink;
554 } // end of switch(pEvent_p->m_EventSink)
562 //---------------------------------------------------------------------------
564 // Function: EplEventkPost
566 // Description: post events from kernel part
568 // Parameters: pEvent_p = pointer to event-structure from buffer
570 // Returns: tEpKernel = errorcode
574 //---------------------------------------------------------------------------
576 tEplKernel PUBLIC EplEventkPost(tEplEvent * pEvent_p)
581 tShbCirChunk ShbCirChunk;
582 unsigned long ulDataSize;
583 unsigned int fBufferCompleted;
586 Ret = kEplSuccessful;
589 // the event must be posted by using the abBuffer
590 // it is neede because the Argument must by copied
591 // to the buffer too and not only the pointer
594 // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
595 ulDataSize = sizeof(tEplEvent) + ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
598 // decide in which buffer the event have to write
599 switch(pEvent_p->m_EventSink)
601 // kernelspace modules
602 case kEplEventSinkSync:
603 case kEplEventSinkNmtk:
604 case kEplEventSinkDllk:
605 case kEplEventSinkDllkCal:
606 case kEplEventSinkPdok:
607 case kEplEventSinkErrk:
611 BENCHMARK_MOD_27_SET(2);
612 ShbError = ShbCirAllocDataBlock (EplEventkInstance_g.m_pShbUserToKernelInstance,
622 EplEventkInstance_g.m_uiUserToKernelFullCount++;
623 Ret = kEplEventPostError;
629 EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n", ShbError);
630 Ret = kEplEventPostError;
634 ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbUserToKernelInstance,
639 if (ShbError != kShbOk)
641 EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n", ShbError);
642 Ret = kEplEventPostError;
645 if (fBufferCompleted == FALSE)
647 ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbUserToKernelInstance,
650 (unsigned long) pEvent_p->m_uiSize,
652 if ((ShbError != kShbOk) || (fBufferCompleted == FALSE))
654 EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n", ShbError);
655 Ret = kEplEventPostError;
659 BENCHMARK_MOD_27_RESET(2);
662 Ret = EplEventkProcess(pEvent_p);
669 case kEplEventSinkNmtu:
670 case kEplEventSinkNmtMnu:
671 case kEplEventSinkSdoAsySeq:
672 case kEplEventSinkApi:
673 case kEplEventSinkDlluCal:
674 case kEplEventSinkErru:
678 // BENCHMARK_MOD_27_SET(3); // 74 µs until reset
679 ShbError = ShbCirAllocDataBlock (EplEventkInstance_g.m_pShbKernelToUserInstance,
682 if(ShbError != kShbOk)
684 EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n", ShbError);
685 Ret = kEplEventPostError;
688 ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbKernelToUserInstance,
693 if(ShbError != kShbOk)
695 EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n", ShbError);
696 Ret = kEplEventPostError;
699 if (fBufferCompleted == FALSE)
701 ShbError = ShbCirWriteDataChunk (EplEventkInstance_g.m_pShbKernelToUserInstance,
704 (unsigned long) pEvent_p->m_uiSize,
706 if ((ShbError != kShbOk) || (fBufferCompleted == FALSE))
708 EPL_DBGLVL_EVENTK_TRACE1("EplEventkPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n", ShbError);
709 Ret = kEplEventPostError;
713 // BENCHMARK_MOD_27_RESET(3); // 82 µs until ShbCirGetReadDataSize() in EplEventu
716 Ret = EplEventuProcess(pEvent_p);
724 Ret = kEplEventUnknownSink;
728 }// end of switch(pEvent_p->m_EventSink)
737 //---------------------------------------------------------------------------
739 // Function: EplEventkPostError
741 // Description: post error event from kernel part to API layer
743 // Parameters: EventSource_p = source-module of the error event
744 // EplError_p = code of occured error
745 // ArgSize_p = size of the argument
746 // pArg_p = pointer to the argument
748 // Returns: tEpKernel = errorcode
752 //---------------------------------------------------------------------------
754 tEplKernel PUBLIC EplEventkPostError(tEplEventSource EventSource_p,
755 tEplKernel EplError_p,
756 unsigned int uiArgSize_p,
760 BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
761 tEplEventError* pEventError = (tEplEventError*) abBuffer;
764 Ret = kEplSuccessful;
767 pEventError->m_EventSource = EventSource_p;
768 pEventError->m_EplError = EplError_p;
769 EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
772 EplEvent.m_EventType = kEplEventTypeError;
773 EplEvent.m_EventSink = kEplEventSinkApi;
774 EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
775 EplEvent.m_uiSize = (sizeof(EventSource_p)+ sizeof(EplError_p)+ uiArgSize_p);
776 EplEvent.m_pArg = &abBuffer[0];
779 Ret = EplEventkPost(&EplEvent);
785 //=========================================================================//
787 // P R I V A T E F U N C T I O N S //
789 //=========================================================================//
791 //---------------------------------------------------------------------------
793 // Function: EplEventkRxSignalHandlerCb()
795 // Description: Callback-function for events from user and kernel part
797 // Parameters: pShbRxInstance_p = Instance-pointer of buffer
798 // ulDataSize_p = size of data
804 //---------------------------------------------------------------------------
807 static void EplEventkRxSignalHandlerCb (
808 tShbInstance pShbRxInstance_p,
809 unsigned long ulDataSize_p)
811 tEplEvent *pEplEvent;
813 //unsigned long ulBlockCount;
814 //unsigned long ulDataSize;
815 BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
816 // d.k.: abDataBuffer contains the complete tEplEvent structure
817 // and behind this the argument
819 TGT_DBG_SIGNAL_TRACE_POINT(20);
821 BENCHMARK_MOD_27_RESET(0);
822 // copy data from event queue
823 ShbError = ShbCirReadDataBlock (pShbRxInstance_p,
825 sizeof(abDataBuffer),
827 if(ShbError != kShbOk)
833 // resolve the pointer to the event structure
834 pEplEvent = (tEplEvent *) abDataBuffer;
836 pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
837 if(pEplEvent->m_uiSize > 0)
839 // set pointer to argument
840 pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
844 //set pointer to NULL
845 pEplEvent->m_pArg = NULL;
848 BENCHMARK_MOD_27_SET(0);
849 // call processfunction
850 EplEventkProcess(pEplEvent);