1 /****************************************************************************
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
8 Description: source file for Epl-Userspace-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: EplEventu.c,v $
56 $Revision: 1.8 $ $Date: 2008/11/17 16:40:39 $
63 -------------------------------------------------------------------------
67 2006/06/20 k.t.: start of the implementation
69 ****************************************************************************/
71 #include "user/EplEventu.h"
72 #include "user/EplNmtu.h"
73 #include "user/EplNmtMnu.h"
74 #include "user/EplSdoAsySequ.h"
75 #include "user/EplDlluCal.h"
76 #include "user/EplLedu.h"
77 #include "Benchmark.h"
80 #include "kernel/EplEventk.h"
82 #include "SharedBuff.h"
85 /***************************************************************************/
88 /* G L O B A L D E F I N I T I O N S */
91 /***************************************************************************/
93 //---------------------------------------------------------------------------
95 //---------------------------------------------------------------------------
97 // TracePoint support for realtime-debugging
98 #ifdef _DBG_TRACE_POINTS_
99 void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
100 void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
101 #define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
102 #define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
104 #define TGT_DBG_SIGNAL_TRACE_POINT(p)
105 #define TGT_DBG_POST_TRACE_VALUE(v)
108 //---------------------------------------------------------------------------
110 //---------------------------------------------------------------------------
114 tShbInstance m_pShbKernelToUserInstance;
115 tShbInstance m_pShbUserToKernelInstance;
117 tEplProcessEventCb m_pfnApiProcessEventCb;
119 } tEplEventuInstance;
121 //---------------------------------------------------------------------------
122 // modul globale vars
123 //---------------------------------------------------------------------------
125 //#ifndef EPL_NO_FIFO
126 static tEplEventuInstance EplEventuInstance_g;
129 //---------------------------------------------------------------------------
130 // local function prototypes
131 //---------------------------------------------------------------------------
134 // callback function for incomming events
135 static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
136 unsigned long ulDataSize_p);
139 /***************************************************************************/
142 /* C L A S S <Epl-User-Event> */
145 /***************************************************************************/
150 /***************************************************************************/
152 //=========================================================================//
154 // P U B L I C F U N C T I O N S //
156 //=========================================================================//
158 //---------------------------------------------------------------------------
160 // Function: EplEventuInit
162 // Description: function initialize the first instance
166 // Parameters: pfnApiProcessEventCb_p = function pointer for API event callback
169 // Returns: tEpKernel = errorcode
174 //---------------------------------------------------------------------------
175 tEplKernel PUBLIC EplEventuInit(tEplProcessEventCb pfnApiProcessEventCb_p)
179 Ret = EplEventuAddInstance(pfnApiProcessEventCb_p);
185 //---------------------------------------------------------------------------
187 // Function: EplEventuAddInstance
189 // Description: function add one more instance
193 // Parameters: pfnApiProcessEventCb_p = function pointer for API event callback
196 // Returns: tEpKernel = errorcode
201 //---------------------------------------------------------------------------
202 tEplKernel PUBLIC EplEventuAddInstance(tEplProcessEventCb
203 pfnApiProcessEventCb_p)
208 unsigned int fShbNewCreated;
211 Ret = kEplSuccessful;
213 // init instance variables
214 EplEventuInstance_g.m_pfnApiProcessEventCb = pfnApiProcessEventCb_p;
217 // init shared loop buffer
219 ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_KERNEL_TO_USER,
220 EPL_EVENT_NAME_SHB_KERNEL_TO_USER,
221 &EplEventuInstance_g.
222 m_pShbKernelToUserInstance,
224 if (ShbError != kShbOk) {
225 EPL_DBGLVL_EVENTK_TRACE1
226 ("EplEventuAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n",
228 Ret = kEplNoResource;
233 ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
234 EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
235 &EplEventuInstance_g.
236 m_pShbUserToKernelInstance,
238 if (ShbError != kShbOk) {
239 EPL_DBGLVL_EVENTK_TRACE1
240 ("EplEventuAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n",
242 Ret = kEplNoResource;
245 // register eventhandler
247 ShbCirSetSignalHandlerNewData(EplEventuInstance_g.
248 m_pShbKernelToUserInstance,
249 EplEventuRxSignalHandlerCb,
251 if (ShbError != kShbOk) {
252 EPL_DBGLVL_EVENTK_TRACE1
253 ("EplEventuAddInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n",
255 Ret = kEplNoResource;
266 //---------------------------------------------------------------------------
268 // Function: EplEventuDelInstance
270 // Description: function delete instance an free the bufferstructure
277 // Returns: tEpKernel = errorcode
282 //---------------------------------------------------------------------------
283 tEplKernel PUBLIC EplEventuDelInstance()
290 Ret = kEplSuccessful;
293 // set eventhandler to NULL
295 ShbCirSetSignalHandlerNewData(EplEventuInstance_g.
296 m_pShbKernelToUserInstance, NULL,
298 if (ShbError != kShbOk) {
299 EPL_DBGLVL_EVENTK_TRACE1
300 ("EplEventuDelInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n",
302 Ret = kEplNoResource;
304 // free buffer User -> Kernel
306 ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbUserToKernelInstance);
307 if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) {
308 EPL_DBGLVL_EVENTK_TRACE1
309 ("EplEventuDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n",
311 Ret = kEplNoResource;
313 EplEventuInstance_g.m_pShbUserToKernelInstance = NULL;
316 // free buffer Kernel -> User
318 ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbKernelToUserInstance);
319 if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) {
320 EPL_DBGLVL_EVENTK_TRACE1
321 ("EplEventuDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n",
323 Ret = kEplNoResource;
325 EplEventuInstance_g.m_pShbKernelToUserInstance = NULL;
334 //---------------------------------------------------------------------------
336 // Function: EplEventuProcess
338 // Description: Kernelthread that dispatches events in kernelspace
342 // Parameters: pEvent_p = pointer to event-structur from buffer
345 // Returns: tEpKernel = errorcode
350 //---------------------------------------------------------------------------
351 tEplKernel PUBLIC EplEventuProcess(tEplEvent * pEvent_p)
354 tEplEventSource EventSource;
356 Ret = kEplSuccessful;
359 switch (pEvent_p->m_EventSink) {
361 case kEplEventSinkNmtu:
363 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
364 Ret = EplNmtuProcessEvent(pEvent_p);
365 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
366 EventSource = kEplEventSourceNmtu;
368 // Error event for API layer
369 EplEventuPostError(kEplEventSourceEventu,
378 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
379 // NMT-MN-User-Module
380 case kEplEventSinkNmtMnu:
382 Ret = EplNmtMnuProcessEvent(pEvent_p);
383 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
384 EventSource = kEplEventSourceNmtMnu;
386 // Error event for API layer
387 EplEventuPostError(kEplEventSourceEventu,
396 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) \
397 || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0))
398 // events for asynchronus SDO Sequence Layer
399 case kEplEventSinkSdoAsySeq:
401 Ret = EplSdoAsySeqProcessEvent(pEvent_p);
402 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
403 EventSource = kEplEventSourceSdoAsySeq;
405 // Error event for API layer
406 EplEventuPostError(kEplEventSourceEventu,
415 // LED user part module
416 case kEplEventSinkLedu:
418 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
419 Ret = EplLeduProcessEvent(pEvent_p);
420 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
421 EventSource = kEplEventSourceLedu;
423 // Error event for API layer
424 EplEventuPostError(kEplEventSourceEventu,
434 case kEplEventSinkApi:
436 if (EplEventuInstance_g.m_pfnApiProcessEventCb != NULL) {
439 m_pfnApiProcessEventCb(pEvent_p);
440 if ((Ret != kEplSuccessful)
441 && (Ret != kEplShutdown)) {
442 EventSource = kEplEventSourceEplApi;
444 // Error event for API layer
446 (kEplEventSourceEventu, Ret,
447 sizeof(EventSource), &EventSource);
454 case kEplEventSinkDlluCal:
456 Ret = EplDlluCalProcess(pEvent_p);
457 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
458 EventSource = kEplEventSourceDllu;
460 // Error event for API layer
461 EplEventuPostError(kEplEventSourceEventu,
470 case kEplEventSinkErru:
473 Ret = EplErruProcess(pEvent_p);
474 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
476 EventSource = kEplEventSourceErru;
478 // Error event for API layer
479 EplEventuPostError(kEplEventSourceEventu,
492 Ret = kEplEventUnknownSink;
495 } // end of switch(pEvent_p->m_EventSink)
501 //---------------------------------------------------------------------------
503 // Function: EplEventuPost
505 // Description: post events from userspace
509 // Parameters: pEvent_p = pointer to event-structur from buffer
512 // Returns: tEpKernel = errorcode
517 //---------------------------------------------------------------------------
518 tEplKernel PUBLIC EplEventuPost(tEplEvent * pEvent_p)
523 tShbCirChunk ShbCirChunk;
524 unsigned long ulDataSize;
525 unsigned int fBufferCompleted;
528 Ret = kEplSuccessful;
531 // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
534 ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
537 // decide in which buffer the event have to write
538 switch (pEvent_p->m_EventSink) {
539 // kernelspace modules
540 case kEplEventSinkSync:
541 case kEplEventSinkNmtk:
542 case kEplEventSinkDllk:
543 case kEplEventSinkDllkCal:
544 case kEplEventSinkPdok:
545 case kEplEventSinkErrk:
550 ShbCirAllocDataBlock(EplEventuInstance_g.
551 m_pShbUserToKernelInstance,
552 &ShbCirChunk, ulDataSize);
553 if (ShbError != kShbOk) {
554 EPL_DBGLVL_EVENTK_TRACE1
555 ("EplEventuPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n",
557 Ret = kEplEventPostError;
561 ShbCirWriteDataChunk(EplEventuInstance_g.
562 m_pShbUserToKernelInstance,
563 &ShbCirChunk, pEvent_p,
566 if (ShbError != kShbOk) {
567 EPL_DBGLVL_EVENTK_TRACE1
568 ("EplEventuPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n",
570 Ret = kEplEventPostError;
573 if (fBufferCompleted == FALSE) {
575 ShbCirWriteDataChunk(EplEventuInstance_g.
576 m_pShbUserToKernelInstance,
582 if ((ShbError != kShbOk)
583 || (fBufferCompleted == FALSE)) {
584 EPL_DBGLVL_EVENTK_TRACE1
585 ("EplEventuPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n",
587 Ret = kEplEventPostError;
592 Ret = EplEventkProcess(pEvent_p);
599 case kEplEventSinkNmtMnu:
600 case kEplEventSinkNmtu:
601 case kEplEventSinkSdoAsySeq:
602 case kEplEventSinkApi:
603 case kEplEventSinkDlluCal:
604 case kEplEventSinkErru:
605 case kEplEventSinkLedu:
610 ShbCirAllocDataBlock(EplEventuInstance_g.
611 m_pShbKernelToUserInstance,
612 &ShbCirChunk, ulDataSize);
613 if (ShbError != kShbOk) {
614 EPL_DBGLVL_EVENTK_TRACE1
615 ("EplEventuPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n",
617 Ret = kEplEventPostError;
621 ShbCirWriteDataChunk(EplEventuInstance_g.
622 m_pShbKernelToUserInstance,
623 &ShbCirChunk, pEvent_p,
626 if (ShbError != kShbOk) {
627 EPL_DBGLVL_EVENTK_TRACE1
628 ("EplEventuPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n",
630 Ret = kEplEventPostError;
633 if (fBufferCompleted == FALSE) {
635 ShbCirWriteDataChunk(EplEventuInstance_g.
636 m_pShbKernelToUserInstance,
642 if ((ShbError != kShbOk)
643 || (fBufferCompleted == FALSE)) {
644 EPL_DBGLVL_EVENTK_TRACE1
645 ("EplEventuPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n",
647 Ret = kEplEventPostError;
652 Ret = EplEventuProcess(pEvent_p);
660 Ret = kEplEventUnknownSink;
663 } // end of switch(pEvent_p->m_EventSink)
672 //---------------------------------------------------------------------------
674 // Function: EplEventuPostError
676 // Description: post errorevent from userspace
680 // Parameters: EventSource_p = source-module of the errorevent
681 // EplError_p = code of occured error
682 // uiArgSize_p = size of the argument
683 // pArg_p = pointer to the argument
686 // Returns: tEpKernel = errorcode
691 //---------------------------------------------------------------------------
692 tEplKernel PUBLIC EplEventuPostError(tEplEventSource EventSource_p,
693 tEplKernel EplError_p,
694 unsigned int uiArgSize_p, void *pArg_p)
697 BYTE abBuffer[EPL_MAX_EVENT_ARG_SIZE];
698 tEplEventError *pEventError = (tEplEventError *) abBuffer;
701 Ret = kEplSuccessful;
704 pEventError->m_EventSource = EventSource_p;
705 pEventError->m_EplError = EplError_p;
706 EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
709 EplEvent.m_EventType = kEplEventTypeError;
710 EplEvent.m_EventSink = kEplEventSinkApi;
711 EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
713 (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p);
714 EplEvent.m_pArg = &abBuffer[0];
717 Ret = EplEventuPost(&EplEvent);
722 //=========================================================================//
724 // P R I V A T E F U N C T I O N S //
726 //=========================================================================//
728 //---------------------------------------------------------------------------
730 // Function: EplEventuRxSignalHandlerCb()
732 // Description: Callback-function for evets from kernelspace
736 // Parameters: pShbRxInstance_p = Instance-pointer for buffer
737 // ulDataSize_p = size of data
745 //---------------------------------------------------------------------------
747 static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
748 unsigned long ulDataSize_p)
750 tEplEvent *pEplEvent;
752 //unsigned long ulBlockCount;
753 //unsigned long ulDataSize;
754 BYTE abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
755 // d.k.: abDataBuffer contains the complete tEplEvent structure
756 // and behind this the argument
758 TGT_DBG_SIGNAL_TRACE_POINT(21);
760 // d.k. not needed because it is already done in SharedBuff
763 BENCHMARK_MOD_28_SET(1); // 4 µs until reset
765 ShbError = ShbCirGetReadDataSize (pShbRxInstance_p, &ulDataSize);
766 if(ShbError != kShbOk)
772 BENCHMARK_MOD_28_RESET(1); // 14 µs until set
774 // copy data from event queue
775 ShbError = ShbCirReadDataBlock(pShbRxInstance_p,
777 sizeof(abDataBuffer), &ulDataSize_p);
778 if (ShbError != kShbOk) {
782 // resolve the pointer to the event structure
783 pEplEvent = (tEplEvent *) abDataBuffer;
785 pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
786 if (pEplEvent->m_uiSize > 0) {
787 // set pointer to argument
788 pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
790 //set pointer to NULL
791 pEplEvent->m_pArg = NULL;
794 BENCHMARK_MOD_28_SET(1);
795 // call processfunction
796 EplEventuProcess(pEplEvent);
798 BENCHMARK_MOD_28_RESET(1);
799 // read number of left messages to process
800 // d.k. not needed because it is already done in SharedBuff
801 /* ShbError = ShbCirGetReadBlockCount (pShbRxInstance_p, &ulBlockCount);
802 if (ShbError != kShbOk)
807 } while (ulBlockCount > 0);