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 TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
104 void TgtDbgPostTraceValue(u32 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 //---------------------------------------------------------------------------
118 tShbInstance m_pShbKernelToUserInstance;
119 tShbInstance m_pShbUserToKernelInstance;
123 tEplSyncCb m_pfnCbSync;
124 unsigned int m_uiUserToKernelFullCount;
126 } tEplEventkInstance;
128 //---------------------------------------------------------------------------
129 // modul globale vars
130 //---------------------------------------------------------------------------
131 static tEplEventkInstance EplEventkInstance_g;
132 //---------------------------------------------------------------------------
133 // local function prototypes
134 //---------------------------------------------------------------------------
136 // callback function for incoming events
138 static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
139 unsigned long ulDataSize_p);
142 /***************************************************************************/
145 /* C L A S S <Epl-Kernelspace-Event> */
148 /***************************************************************************/
153 /***************************************************************************/
155 //=========================================================================//
157 // P U B L I C F U N C T I O N S //
159 //=========================================================================//
161 //---------------------------------------------------------------------------
163 // Function: EplEventkInit
165 // Description: function initializes the first instance
167 // Parameters: pfnCbSync_p = callback-function for sync event
169 // Returns: tEpKernel = errorcode
173 //---------------------------------------------------------------------------
175 tEplKernel EplEventkInit(tEplSyncCb pfnCbSync_p)
179 Ret = EplEventkAddInstance(pfnCbSync_p);
185 //---------------------------------------------------------------------------
187 // Function: EplEventkAddInstance
189 // Description: function adds one more instance
191 // Parameters: pfnCbSync_p = callback-function for sync event
193 // Returns: tEpKernel = errorcode
197 //---------------------------------------------------------------------------
199 tEplKernel EplEventkAddInstance(tEplSyncCb pfnCbSync_p)
204 unsigned int fShbNewCreated;
207 Ret = kEplSuccessful;
209 // init instance structure
210 EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
213 EplEventkInstance_g.m_pfnCbSync = pfnCbSync_p;
216 // init shared loop buffer
218 ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
219 EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
220 &EplEventkInstance_g.
221 m_pShbKernelToUserInstance,
223 if (ShbError != kShbOk) {
224 EPL_DBGLVL_EVENTK_TRACE1
225 ("EplEventkAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n",
227 Ret = kEplNoResource;
231 ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
232 EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
233 &EplEventkInstance_g.
234 m_pShbUserToKernelInstance,
236 if (ShbError != kShbOk) {
237 EPL_DBGLVL_EVENTK_TRACE1
238 ("EplEventkAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n",
240 Ret = kEplNoResource;
243 // register eventhandler
245 ShbCirSetSignalHandlerNewData(EplEventkInstance_g.
246 m_pShbUserToKernelInstance,
247 EplEventkRxSignalHandlerCb,
249 if (ShbError != kShbOk) {
250 EPL_DBGLVL_EVENTK_TRACE1
251 ("EplEventkAddInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n",
253 Ret = kEplNoResource;
264 //---------------------------------------------------------------------------
266 // Function: EplEventkDelInstance
268 // Description: function deletes instance and frees the buffers
272 // Returns: tEpKernel = errorcode
276 //---------------------------------------------------------------------------
278 tEplKernel EplEventkDelInstance(void)
285 Ret = kEplSuccessful;
288 // set eventhandler to NULL
290 ShbCirSetSignalHandlerNewData(EplEventkInstance_g.
291 m_pShbUserToKernelInstance, NULL,
293 if (ShbError != kShbOk) {
294 EPL_DBGLVL_EVENTK_TRACE1
295 ("EplEventkDelInstance(): ShbCirSetSignalHandlerNewData(U2K) -> 0x%X\n",
297 Ret = kEplNoResource;
299 // free buffer User -> Kernel
301 ShbCirReleaseBuffer(EplEventkInstance_g.m_pShbUserToKernelInstance);
302 if (ShbError != kShbOk) {
303 EPL_DBGLVL_EVENTK_TRACE1
304 ("EplEventkDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n",
306 Ret = kEplNoResource;
308 EplEventkInstance_g.m_pShbUserToKernelInstance = NULL;
311 // free buffer Kernel -> User
313 ShbCirReleaseBuffer(EplEventkInstance_g.m_pShbKernelToUserInstance);
314 if (ShbError != kShbOk) {
315 EPL_DBGLVL_EVENTK_TRACE1
316 ("EplEventkDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n",
318 Ret = kEplNoResource;
320 EplEventkInstance_g.m_pShbKernelToUserInstance = NULL;
328 //---------------------------------------------------------------------------
330 // Function: EplEventkProcess
332 // Description: Kernelthread that dispatches events in kernel part
334 // Parameters: pEvent_p = pointer to event-structure from buffer
336 // Returns: tEpKernel = errorcode
340 //---------------------------------------------------------------------------
342 tEplKernel EplEventkProcess(tEplEvent *pEvent_p)
345 tEplEventSource EventSource;
347 Ret = kEplSuccessful;
349 // error handling if event queue is full
350 if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0) { // 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
375 ShbCirResetBuffer(EplEventkInstance_g.
376 m_pShbUserToKernelInstance, 1000, NULL);
379 EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
380 TGT_DBG_SIGNAL_TRACE_POINT(22);
382 // also discard the current event (it doesn't matter if we lose another event)
386 switch (pEvent_p->m_EventSink) {
387 case kEplEventSinkSync:
389 if (EplEventkInstance_g.m_pfnCbSync != NULL) {
390 Ret = EplEventkInstance_g.m_pfnCbSync();
391 if (Ret == kEplSuccessful) {
392 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
393 // mark TPDOs as valid
394 Ret = EplPdokCalSetTpdosValid(TRUE);
396 } else if ((Ret != kEplReject)
397 && (Ret != kEplShutdown)) {
398 EventSource = kEplEventSourceSyncCb;
400 // Error event for API layer
402 (kEplEventSourceEventk, Ret,
403 sizeof(EventSource), &EventSource);
410 case kEplEventSinkNmtk:
412 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
413 Ret = EplNmtkProcess(pEvent_p);
414 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
415 EventSource = kEplEventSourceNmtk;
417 // Error event for API layer
418 EplEventkPostError(kEplEventSourceEventk,
424 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
425 if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent)
427 ((*((tEplNmtEvent *) pEvent_p->m_pArg) ==
428 kEplNmtEventDllCeSoa)
429 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
430 || (*((tEplNmtEvent *) pEvent_p->m_pArg) ==
431 kEplNmtEventDllMeSoaSent)
433 )) { // forward SoA event to error handler
434 Ret = EplErrorHandlerkProcess(pEvent_p);
435 if ((Ret != kEplSuccessful)
436 && (Ret != kEplShutdown)) {
437 EventSource = kEplEventSourceErrk;
439 // Error event for API layer
441 (kEplEventSourceEventk, Ret,
442 sizeof(EventSource), &EventSource);
444 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
445 // forward SoA event to PDO module
446 pEvent_p->m_EventType = kEplEventTypePdoSoa;
447 Ret = EplPdokProcess(pEvent_p);
448 if ((Ret != kEplSuccessful)
449 && (Ret != kEplShutdown)) {
450 EventSource = kEplEventSourcePdok;
452 // Error event for API layer
454 (kEplEventSourceEventk, Ret,
455 sizeof(EventSource), &EventSource);
464 // events for Dllk module
465 case kEplEventSinkDllk:
467 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
468 Ret = EplDllkProcess(pEvent_p);
469 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
470 EventSource = kEplEventSourceDllk;
472 // Error event for API layer
473 EplEventkPostError(kEplEventSourceEventk,
482 // events for DllkCal module
483 case kEplEventSinkDllkCal:
485 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
486 Ret = EplDllkCalProcess(pEvent_p);
487 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
488 EventSource = kEplEventSourceDllk;
490 // Error event for API layer
491 EplEventkPostError(kEplEventSourceEventk,
501 case kEplEventSinkPdok:
504 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
505 Ret = EplPdokProcess(pEvent_p);
506 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
507 EventSource = kEplEventSourcePdok;
509 // Error event for API layer
510 EplEventkPostError(kEplEventSourceEventk,
519 // events for Error handler module
520 case kEplEventSinkErrk:
522 // only call error handler if DLL is present
523 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
524 Ret = EplErrorHandlerkProcess(pEvent_p);
525 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
526 EventSource = kEplEventSourceErrk;
528 // Error event for API layer
529 EplEventkPostError(kEplEventSourceEventk,
541 Ret = kEplEventUnknownSink;
544 } // end of switch(pEvent_p->m_EventSink)
551 //---------------------------------------------------------------------------
553 // Function: EplEventkPost
555 // Description: post events from kernel part
557 // Parameters: pEvent_p = pointer to event-structure from buffer
559 // Returns: tEpKernel = errorcode
563 //---------------------------------------------------------------------------
565 tEplKernel EplEventkPost(tEplEvent *pEvent_p)
570 tShbCirChunk ShbCirChunk;
571 unsigned long ulDataSize;
572 unsigned int fBufferCompleted;
575 Ret = kEplSuccessful;
577 // the event must be posted by using the abBuffer
578 // it is neede because the Argument must by copied
579 // to the buffer too and not only the pointer
582 // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
585 ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
588 // decide in which buffer the event have to write
589 switch (pEvent_p->m_EventSink) {
590 // kernelspace modules
591 case kEplEventSinkSync:
592 case kEplEventSinkNmtk:
593 case kEplEventSinkDllk:
594 case kEplEventSinkDllkCal:
595 case kEplEventSinkPdok:
596 case kEplEventSinkErrk:
600 BENCHMARK_MOD_27_SET(2);
602 ShbCirAllocDataBlock(EplEventkInstance_g.
603 m_pShbUserToKernelInstance,
604 &ShbCirChunk, ulDataSize);
612 m_uiUserToKernelFullCount++;
613 Ret = kEplEventPostError;
619 EPL_DBGLVL_EVENTK_TRACE1
620 ("EplEventkPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n",
622 Ret = kEplEventPostError;
627 ShbCirWriteDataChunk(EplEventkInstance_g.
628 m_pShbUserToKernelInstance,
629 &ShbCirChunk, pEvent_p,
632 if (ShbError != kShbOk) {
633 EPL_DBGLVL_EVENTK_TRACE1
634 ("EplEventkPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n",
636 Ret = kEplEventPostError;
639 if (fBufferCompleted == FALSE) {
641 ShbCirWriteDataChunk(EplEventkInstance_g.
642 m_pShbUserToKernelInstance,
648 if ((ShbError != kShbOk)
649 || (fBufferCompleted == FALSE)) {
650 EPL_DBGLVL_EVENTK_TRACE1
651 ("EplEventkPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n",
653 Ret = kEplEventPostError;
657 BENCHMARK_MOD_27_RESET(2);
660 Ret = EplEventkProcess(pEvent_p);
667 case kEplEventSinkNmtu:
668 case kEplEventSinkNmtMnu:
669 case kEplEventSinkSdoAsySeq:
670 case kEplEventSinkApi:
671 case kEplEventSinkDlluCal:
672 case kEplEventSinkErru:
676 // BENCHMARK_MOD_27_SET(3); // 74 µs until reset
678 ShbCirAllocDataBlock(EplEventkInstance_g.
679 m_pShbKernelToUserInstance,
680 &ShbCirChunk, ulDataSize);
681 if (ShbError != kShbOk) {
682 EPL_DBGLVL_EVENTK_TRACE1
683 ("EplEventkPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n",
685 Ret = kEplEventPostError;
689 ShbCirWriteDataChunk(EplEventkInstance_g.
690 m_pShbKernelToUserInstance,
691 &ShbCirChunk, pEvent_p,
694 if (ShbError != kShbOk) {
695 EPL_DBGLVL_EVENTK_TRACE1
696 ("EplEventkPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n",
698 Ret = kEplEventPostError;
701 if (fBufferCompleted == FALSE) {
703 ShbCirWriteDataChunk(EplEventkInstance_g.
704 m_pShbKernelToUserInstance,
710 if ((ShbError != kShbOk)
711 || (fBufferCompleted == FALSE)) {
712 EPL_DBGLVL_EVENTK_TRACE1
713 ("EplEventkPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n",
715 Ret = kEplEventPostError;
719 // BENCHMARK_MOD_27_RESET(3); // 82 µs until ShbCirGetReadDataSize() in EplEventu
722 Ret = EplEventuProcess(pEvent_p);
730 Ret = kEplEventUnknownSink;
733 } // end of switch(pEvent_p->m_EventSink)
741 //---------------------------------------------------------------------------
743 // Function: EplEventkPostError
745 // Description: post error event from kernel part to API layer
747 // Parameters: EventSource_p = source-module of the error event
748 // EplError_p = code of occured error
749 // ArgSize_p = size of the argument
750 // pArg_p = pointer to the argument
752 // Returns: tEpKernel = errorcode
756 //---------------------------------------------------------------------------
758 tEplKernel EplEventkPostError(tEplEventSource EventSource_p,
759 tEplKernel EplError_p,
760 unsigned int uiArgSize_p, void *pArg_p)
763 u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
764 tEplEventError *pEventError = (tEplEventError *) abBuffer;
767 Ret = kEplSuccessful;
770 pEventError->m_EventSource = EventSource_p;
771 pEventError->m_EplError = EplError_p;
772 EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
775 EplEvent.m_EventType = kEplEventTypeError;
776 EplEvent.m_EventSink = kEplEventSinkApi;
777 EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
779 (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p);
780 EplEvent.m_pArg = &abBuffer[0];
783 Ret = EplEventkPost(&EplEvent);
788 //=========================================================================//
790 // P R I V A T E F U N C T I O N S //
792 //=========================================================================//
794 //---------------------------------------------------------------------------
796 // Function: EplEventkRxSignalHandlerCb()
798 // Description: Callback-function for events from user and kernel part
800 // Parameters: pShbRxInstance_p = Instance-pointer of buffer
801 // ulDataSize_p = size of data
807 //---------------------------------------------------------------------------
810 static void EplEventkRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
811 unsigned long ulDataSize_p)
813 tEplEvent *pEplEvent;
815 //unsigned long ulBlockCount;
816 //unsigned long ulDataSize;
817 u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
818 // d.k.: abDataBuffer contains the complete tEplEvent structure
819 // and behind this the argument
821 TGT_DBG_SIGNAL_TRACE_POINT(20);
823 BENCHMARK_MOD_27_RESET(0);
824 // copy data from event queue
825 ShbError = ShbCirReadDataBlock(pShbRxInstance_p,
827 sizeof(abDataBuffer), &ulDataSize_p);
828 if (ShbError != kShbOk) {
832 // resolve the pointer to the event structure
833 pEplEvent = (tEplEvent *) abDataBuffer;
835 pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
836 if (pEplEvent->m_uiSize > 0) {
837 // set pointer to argument
838 pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
840 //set pointer to NULL
841 pEplEvent->m_pArg = NULL;
844 BENCHMARK_MOD_27_SET(0);
845 // call processfunction
846 EplEventkProcess(pEplEvent);