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 TgtDbgSignalTracePoint(u8 bTracePointNumber_p);
100 void TgtDbgPostTraceValue(u32 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 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 EplEventuAddInstance(tEplProcessEventCb pfnApiProcessEventCb_p)
207 unsigned int fShbNewCreated;
210 Ret = kEplSuccessful;
212 // init instance variables
213 EplEventuInstance_g.m_pfnApiProcessEventCb = pfnApiProcessEventCb_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 &EplEventuInstance_g.
221 m_pShbKernelToUserInstance,
223 if (ShbError != kShbOk) {
224 EPL_DBGLVL_EVENTK_TRACE1
225 ("EplEventuAddInstance(): ShbCirAllocBuffer(K2U) -> 0x%X\n",
227 Ret = kEplNoResource;
232 ShbError = ShbCirAllocBuffer(EPL_EVENT_SIZE_SHB_USER_TO_KERNEL,
233 EPL_EVENT_NAME_SHB_USER_TO_KERNEL,
234 &EplEventuInstance_g.
235 m_pShbUserToKernelInstance,
237 if (ShbError != kShbOk) {
238 EPL_DBGLVL_EVENTK_TRACE1
239 ("EplEventuAddInstance(): ShbCirAllocBuffer(U2K) -> 0x%X\n",
241 Ret = kEplNoResource;
244 // register eventhandler
246 ShbCirSetSignalHandlerNewData(EplEventuInstance_g.
247 m_pShbKernelToUserInstance,
248 EplEventuRxSignalHandlerCb,
250 if (ShbError != kShbOk) {
251 EPL_DBGLVL_EVENTK_TRACE1
252 ("EplEventuAddInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n",
254 Ret = kEplNoResource;
265 //---------------------------------------------------------------------------
267 // Function: EplEventuDelInstance
269 // Description: function delete instance an free the bufferstructure
276 // Returns: tEpKernel = errorcode
281 //---------------------------------------------------------------------------
282 tEplKernel EplEventuDelInstance(void)
289 Ret = kEplSuccessful;
292 // set eventhandler to NULL
294 ShbCirSetSignalHandlerNewData(EplEventuInstance_g.
295 m_pShbKernelToUserInstance, NULL,
297 if (ShbError != kShbOk) {
298 EPL_DBGLVL_EVENTK_TRACE1
299 ("EplEventuDelInstance(): ShbCirSetSignalHandlerNewData(K2U) -> 0x%X\n",
301 Ret = kEplNoResource;
303 // free buffer User -> Kernel
305 ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbUserToKernelInstance);
306 if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) {
307 EPL_DBGLVL_EVENTK_TRACE1
308 ("EplEventuDelInstance(): ShbCirReleaseBuffer(U2K) -> 0x%X\n",
310 Ret = kEplNoResource;
312 EplEventuInstance_g.m_pShbUserToKernelInstance = NULL;
315 // free buffer Kernel -> User
317 ShbCirReleaseBuffer(EplEventuInstance_g.m_pShbKernelToUserInstance);
318 if ((ShbError != kShbOk) && (ShbError != kShbMemUsedByOtherProcs)) {
319 EPL_DBGLVL_EVENTK_TRACE1
320 ("EplEventuDelInstance(): ShbCirReleaseBuffer(K2U) -> 0x%X\n",
322 Ret = kEplNoResource;
324 EplEventuInstance_g.m_pShbKernelToUserInstance = NULL;
333 //---------------------------------------------------------------------------
335 // Function: EplEventuProcess
337 // Description: Kernelthread that dispatches events in kernelspace
341 // Parameters: pEvent_p = pointer to event-structur from buffer
344 // Returns: tEpKernel = errorcode
349 //---------------------------------------------------------------------------
350 tEplKernel EplEventuProcess(tEplEvent *pEvent_p)
353 tEplEventSource EventSource;
355 Ret = kEplSuccessful;
358 switch (pEvent_p->m_EventSink) {
360 case kEplEventSinkNmtu:
362 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
363 Ret = EplNmtuProcessEvent(pEvent_p);
364 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
365 EventSource = kEplEventSourceNmtu;
367 // Error event for API layer
368 EplEventuPostError(kEplEventSourceEventu,
377 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
378 // NMT-MN-User-Module
379 case kEplEventSinkNmtMnu:
381 Ret = EplNmtMnuProcessEvent(pEvent_p);
382 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
383 EventSource = kEplEventSourceNmtMnu;
385 // Error event for API layer
386 EplEventuPostError(kEplEventSourceEventu,
395 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0) \
396 || (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0))
397 // events for asynchronus SDO Sequence Layer
398 case kEplEventSinkSdoAsySeq:
400 Ret = EplSdoAsySeqProcessEvent(pEvent_p);
401 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
402 EventSource = kEplEventSourceSdoAsySeq;
404 // Error event for API layer
405 EplEventuPostError(kEplEventSourceEventu,
414 // LED user part module
415 case kEplEventSinkLedu:
417 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
418 Ret = EplLeduProcessEvent(pEvent_p);
419 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
420 EventSource = kEplEventSourceLedu;
422 // Error event for API layer
423 EplEventuPostError(kEplEventSourceEventu,
433 case kEplEventSinkApi:
435 if (EplEventuInstance_g.m_pfnApiProcessEventCb != NULL) {
438 m_pfnApiProcessEventCb(pEvent_p);
439 if ((Ret != kEplSuccessful)
440 && (Ret != kEplShutdown)) {
441 EventSource = kEplEventSourceEplApi;
443 // Error event for API layer
445 (kEplEventSourceEventu, Ret,
446 sizeof(EventSource), &EventSource);
453 case kEplEventSinkDlluCal:
455 Ret = EplDlluCalProcess(pEvent_p);
456 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
457 EventSource = kEplEventSourceDllu;
459 // Error event for API layer
460 EplEventuPostError(kEplEventSourceEventu,
469 case kEplEventSinkErru:
472 Ret = EplErruProcess(pEvent_p);
473 if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
475 EventSource = kEplEventSourceErru;
477 // Error event for API layer
478 EplEventuPostError(kEplEventSourceEventu,
491 Ret = kEplEventUnknownSink;
494 } // end of switch(pEvent_p->m_EventSink)
500 //---------------------------------------------------------------------------
502 // Function: EplEventuPost
504 // Description: post events from userspace
508 // Parameters: pEvent_p = pointer to event-structur from buffer
511 // Returns: tEpKernel = errorcode
516 //---------------------------------------------------------------------------
517 tEplKernel EplEventuPost(tEplEvent *pEvent_p)
522 tShbCirChunk ShbCirChunk;
523 unsigned long ulDataSize;
524 unsigned int fBufferCompleted;
527 Ret = kEplSuccessful;
530 // 2006/08/03 d.k.: Event and argument are posted as separate chunks to the event queue.
533 ((pEvent_p->m_pArg != NULL) ? pEvent_p->m_uiSize : 0);
536 // decide in which buffer the event have to write
537 switch (pEvent_p->m_EventSink) {
538 // kernelspace modules
539 case kEplEventSinkSync:
540 case kEplEventSinkNmtk:
541 case kEplEventSinkDllk:
542 case kEplEventSinkDllkCal:
543 case kEplEventSinkPdok:
544 case kEplEventSinkErrk:
549 ShbCirAllocDataBlock(EplEventuInstance_g.
550 m_pShbUserToKernelInstance,
551 &ShbCirChunk, ulDataSize);
552 if (ShbError != kShbOk) {
553 EPL_DBGLVL_EVENTK_TRACE1
554 ("EplEventuPost(): ShbCirAllocDataBlock(U2K) -> 0x%X\n",
556 Ret = kEplEventPostError;
560 ShbCirWriteDataChunk(EplEventuInstance_g.
561 m_pShbUserToKernelInstance,
562 &ShbCirChunk, pEvent_p,
565 if (ShbError != kShbOk) {
566 EPL_DBGLVL_EVENTK_TRACE1
567 ("EplEventuPost(): ShbCirWriteDataChunk(U2K) -> 0x%X\n",
569 Ret = kEplEventPostError;
572 if (fBufferCompleted == FALSE) {
574 ShbCirWriteDataChunk(EplEventuInstance_g.
575 m_pShbUserToKernelInstance,
581 if ((ShbError != kShbOk)
582 || (fBufferCompleted == FALSE)) {
583 EPL_DBGLVL_EVENTK_TRACE1
584 ("EplEventuPost(): ShbCirWriteDataChunk2(U2K) -> 0x%X\n",
586 Ret = kEplEventPostError;
591 Ret = EplEventkProcess(pEvent_p);
598 case kEplEventSinkNmtMnu:
599 case kEplEventSinkNmtu:
600 case kEplEventSinkSdoAsySeq:
601 case kEplEventSinkApi:
602 case kEplEventSinkDlluCal:
603 case kEplEventSinkErru:
604 case kEplEventSinkLedu:
609 ShbCirAllocDataBlock(EplEventuInstance_g.
610 m_pShbKernelToUserInstance,
611 &ShbCirChunk, ulDataSize);
612 if (ShbError != kShbOk) {
613 EPL_DBGLVL_EVENTK_TRACE1
614 ("EplEventuPost(): ShbCirAllocDataBlock(K2U) -> 0x%X\n",
616 Ret = kEplEventPostError;
620 ShbCirWriteDataChunk(EplEventuInstance_g.
621 m_pShbKernelToUserInstance,
622 &ShbCirChunk, pEvent_p,
625 if (ShbError != kShbOk) {
626 EPL_DBGLVL_EVENTK_TRACE1
627 ("EplEventuPost(): ShbCirWriteDataChunk(K2U) -> 0x%X\n",
629 Ret = kEplEventPostError;
632 if (fBufferCompleted == FALSE) {
634 ShbCirWriteDataChunk(EplEventuInstance_g.
635 m_pShbKernelToUserInstance,
641 if ((ShbError != kShbOk)
642 || (fBufferCompleted == FALSE)) {
643 EPL_DBGLVL_EVENTK_TRACE1
644 ("EplEventuPost(): ShbCirWriteDataChunk2(K2U) -> 0x%X\n",
646 Ret = kEplEventPostError;
651 Ret = EplEventuProcess(pEvent_p);
659 Ret = kEplEventUnknownSink;
662 } // end of switch(pEvent_p->m_EventSink)
671 //---------------------------------------------------------------------------
673 // Function: EplEventuPostError
675 // Description: post errorevent from userspace
679 // Parameters: EventSource_p = source-module of the errorevent
680 // EplError_p = code of occured error
681 // uiArgSize_p = size of the argument
682 // pArg_p = pointer to the argument
685 // Returns: tEpKernel = errorcode
690 //---------------------------------------------------------------------------
691 tEplKernel EplEventuPostError(tEplEventSource EventSource_p,
692 tEplKernel EplError_p,
693 unsigned int uiArgSize_p, void *pArg_p)
696 u8 abBuffer[EPL_MAX_EVENT_ARG_SIZE];
697 tEplEventError *pEventError = (tEplEventError *) abBuffer;
700 Ret = kEplSuccessful;
703 pEventError->m_EventSource = EventSource_p;
704 pEventError->m_EplError = EplError_p;
705 EPL_MEMCPY(&pEventError->m_Arg, pArg_p, uiArgSize_p);
708 EplEvent.m_EventType = kEplEventTypeError;
709 EplEvent.m_EventSink = kEplEventSinkApi;
710 EPL_MEMSET(&EplEvent.m_NetTime, 0x00, sizeof(EplEvent.m_NetTime));
712 (sizeof(EventSource_p) + sizeof(EplError_p) + uiArgSize_p);
713 EplEvent.m_pArg = &abBuffer[0];
716 Ret = EplEventuPost(&EplEvent);
721 //=========================================================================//
723 // P R I V A T E F U N C T I O N S //
725 //=========================================================================//
727 //---------------------------------------------------------------------------
729 // Function: EplEventuRxSignalHandlerCb()
731 // Description: Callback-function for evets from kernelspace
735 // Parameters: pShbRxInstance_p = Instance-pointer for buffer
736 // ulDataSize_p = size of data
744 //---------------------------------------------------------------------------
746 static void EplEventuRxSignalHandlerCb(tShbInstance pShbRxInstance_p,
747 unsigned long ulDataSize_p)
749 tEplEvent *pEplEvent;
751 //unsigned long ulBlockCount;
752 //unsigned long ulDataSize;
753 u8 abDataBuffer[sizeof(tEplEvent) + EPL_MAX_EVENT_ARG_SIZE];
754 // d.k.: abDataBuffer contains the complete tEplEvent structure
755 // and behind this the argument
757 TGT_DBG_SIGNAL_TRACE_POINT(21);
759 // d.k. not needed because it is already done in SharedBuff
762 BENCHMARK_MOD_28_SET(1); // 4 µs until reset
764 ShbError = ShbCirGetReadDataSize (pShbRxInstance_p, &ulDataSize);
765 if(ShbError != kShbOk)
771 BENCHMARK_MOD_28_RESET(1); // 14 µs until set
773 // copy data from event queue
774 ShbError = ShbCirReadDataBlock(pShbRxInstance_p,
776 sizeof(abDataBuffer), &ulDataSize_p);
777 if (ShbError != kShbOk) {
781 // resolve the pointer to the event structure
782 pEplEvent = (tEplEvent *) abDataBuffer;
784 pEplEvent->m_uiSize = (ulDataSize_p - sizeof(tEplEvent));
785 if (pEplEvent->m_uiSize > 0) {
786 // set pointer to argument
787 pEplEvent->m_pArg = &abDataBuffer[sizeof(tEplEvent)];
789 //set pointer to NULL
790 pEplEvent->m_pArg = NULL;
793 BENCHMARK_MOD_28_SET(1);
794 // call processfunction
795 EplEventuProcess(pEplEvent);
797 BENCHMARK_MOD_28_RESET(1);
798 // read number of left messages to process
799 // d.k. not needed because it is already done in SharedBuff
800 /* ShbError = ShbCirGetReadBlockCount (pShbRxInstance_p, &ulBlockCount);
801 if (ShbError != kShbOk)
806 } while (ulBlockCount > 0);