Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /****************************************************************************
  2 
  3   (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
  4       www.systec-electronic.com
  5 
  6   Project:      openPOWERLINK
  7 
  8   Description:  source file for NMT-Userspace-Module
  9 
 10   License:
 11 
 12     Redistribution and use in source and binary forms, with or without
 13     modification, are permitted provided that the following conditions
 14     are met:
 15 
 16     1. Redistributions of source code must retain the above copyright
 17        notice, this list of conditions and the following disclaimer.
 18 
 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.
 22 
 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.
 27 
 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.
 40 
 41     Severability Clause:
 42 
 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.
 49 
 50   -------------------------------------------------------------------------
 51 
 52                 $RCSfile: EplNmtu.c,v $
 53 
 54                 $Author: D.Krueger $
 55 
 56                 $Revision: 1.8 $  $Date: 2008/11/10 17:17:42 $
 57 
 58                 $State: Exp $
 59 
 60                 Build Environment:
 61                     GCC V3.4
 62 
 63   -------------------------------------------------------------------------
 64 
 65   Revision History:
 66 
 67   2006/06/09 k.t.:   start of the implementation
 68 
 69 ****************************************************************************/
 70 
 71 #include "EplInc.h"
 72 #include "user/EplNmtu.h"
 73 #include "user/EplObdu.h"
 74 #include "user/EplTimeru.h"
 75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
 76 #include "kernel/EplNmtk.h"
 77 #endif
 78 
 79 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
 80 /***************************************************************************/
 81 /*                                                                         */
 82 /*                                                                         */
 83 /*          G L O B A L   D E F I N I T I O N S                            */
 84 /*                                                                         */
 85 /*                                                                         */
 86 /***************************************************************************/
 87 
 88 //---------------------------------------------------------------------------
 89 // const defines
 90 //---------------------------------------------------------------------------
 91 
 92 //---------------------------------------------------------------------------
 93 // local types
 94 //---------------------------------------------------------------------------
 95 
 96 typedef struct {
 97         tEplNmtuStateChangeCallback m_pfnNmtChangeCb;
 98         tEplTimerHdl m_TimerHdl;
 99 
100 } tEplNmtuInstance;
101 
102 //---------------------------------------------------------------------------
103 // modul globale vars
104 //---------------------------------------------------------------------------
105 
106 static tEplNmtuInstance EplNmtuInstance_g;
107 
108 //---------------------------------------------------------------------------
109 // local function prototypes
110 //---------------------------------------------------------------------------
111 
112 //=========================================================================//
113 //                                                                         //
114 //          P U B L I C   F U N C T I O N S                                //
115 //                                                                         //
116 //=========================================================================//
117 
118 //---------------------------------------------------------------------------
119 //
120 // Function:    EplNmtuInit
121 //
122 // Description: init first instance of the module
123 //
124 //
125 //
126 // Parameters:
127 //
128 //
129 // Returns:     tEplKernel  = errorcode
130 //
131 //
132 // State:
133 //
134 //---------------------------------------------------------------------------
135 tEplKernel EplNmtuInit(void)
136 {
137         tEplKernel Ret;
138 
139         Ret = EplNmtuAddInstance();
140 
141         return Ret;
142 }
143 
144 //---------------------------------------------------------------------------
145 //
146 // Function:    EplNmtuAddInstance
147 //
148 // Description: init other instances of the module
149 //
150 //
151 //
152 // Parameters:
153 //
154 //
155 // Returns:     tEplKernel  = errorcode
156 //
157 //
158 // State:
159 //
160 //---------------------------------------------------------------------------
161 tEplKernel EplNmtuAddInstance(void)
162 {
163         tEplKernel Ret;
164 
165         Ret = kEplSuccessful;
166 
167         EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
168 
169         return Ret;
170 
171 }
172 
173 //---------------------------------------------------------------------------
174 //
175 // Function:    EplNmtuDelInstance
176 //
177 // Description: delete instance
178 //
179 //
180 //
181 // Parameters:
182 //
183 //
184 // Returns:     tEplKernel  = errorcode
185 //
186 //
187 // State:
188 //
189 //---------------------------------------------------------------------------
190 tEplKernel EplNmtuDelInstance(void)
191 {
192         tEplKernel Ret;
193 
194         Ret = kEplSuccessful;
195 
196         EplNmtuInstance_g.m_pfnNmtChangeCb = NULL;
197 
198         // delete timer
199         Ret = EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
200 
201         return Ret;
202 
203 }
204 
205 //---------------------------------------------------------------------------
206 //
207 // Function:    EplNmtuNmtEvent
208 //
209 // Description: sends the NMT-Event to the NMT-State-Maschine
210 //
211 //
212 //
213 // Parameters:  NmtEvent_p  = NMT-Event to send
214 //
215 //
216 // Returns:     tEplKernel  = errorcode
217 //
218 //
219 // State:
220 //
221 //---------------------------------------------------------------------------
222 tEplKernel EplNmtuNmtEvent(tEplNmtEvent NmtEvent_p)
223 {
224         tEplKernel Ret;
225         tEplEvent Event;
226 
227         Event.m_EventSink = kEplEventSinkNmtk;
228         Event.m_NetTime.m_dwNanoSec = 0;
229         Event.m_NetTime.m_dwSec = 0;
230         Event.m_EventType = kEplEventTypeNmtEvent;
231         Event.m_pArg = &NmtEvent_p;
232         Event.m_uiSize = sizeof(NmtEvent_p);
233 
234         Ret = EplEventuPost(&Event);
235 
236         return Ret;
237 }
238 
239 //---------------------------------------------------------------------------
240 //
241 // Function:    EplNmtuGetNmtState
242 //
243 // Description: returns the actuell NMT-State
244 //
245 //
246 //
247 // Parameters:
248 //
249 //
250 // Returns:     tEplNmtState  = NMT-State
251 //
252 //
253 // State:
254 //
255 //---------------------------------------------------------------------------
256 tEplNmtState EplNmtuGetNmtState(void)
257 {
258         tEplNmtState NmtState;
259 
260         // $$$ call function of communication abstraction layer
261 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
262         NmtState = EplNmtkGetNmtState();
263 #else
264         NmtState = 0;
265 #endif
266 
267         return NmtState;
268 }
269 
270 //---------------------------------------------------------------------------
271 //
272 // Function:    EplNmtuProcessEvent
273 //
274 // Description: processes events from event queue
275 //
276 //
277 //
278 // Parameters:  pEplEvent_p =   pointer to event
279 //
280 //
281 // Returns:     tEplKernel  = errorcode
282 //
283 //
284 // State:
285 //
286 //---------------------------------------------------------------------------
287 tEplKernel EplNmtuProcessEvent(tEplEvent *pEplEvent_p)
288 {
289         tEplKernel Ret;
290 
291         Ret = kEplSuccessful;
292 
293         // process event
294         switch (pEplEvent_p->m_EventType) {
295                 // state change of NMT-Module
296         case kEplEventTypeNmtStateChange:
297                 {
298                         tEplEventNmtStateChange *pNmtStateChange;
299 
300                         // delete timer
301                         Ret =
302                             EplTimeruDeleteTimer(&EplNmtuInstance_g.m_TimerHdl);
303 
304                         pNmtStateChange =
305                             (tEplEventNmtStateChange *) pEplEvent_p->m_pArg;
306 
307                         // call cb-functions to inform higher layer
308                         if (EplNmtuInstance_g.m_pfnNmtChangeCb != NULL) {
309                                 Ret =
310                                     EplNmtuInstance_g.
311                                     m_pfnNmtChangeCb(*pNmtStateChange);
312                         }
313 
314                         if (Ret == kEplSuccessful) {    // everything is OK, so switch to next state if necessary
315                                 switch (pNmtStateChange->m_NewNmtState) {
316                                         // EPL stack is not running
317                                 case kEplNmtGsOff:
318                                         break;
319 
320                                         // first init of the hardware
321                                 case kEplNmtGsInitialising:
322                                         {
323                                                 Ret =
324                                                     EplNmtuNmtEvent
325                                                     (kEplNmtEventEnterResetApp);
326                                                 break;
327                                         }
328 
329                                         // init of the manufacturer-specific profile area and the
330                                         // standardised device profile area
331                                 case kEplNmtGsResetApplication:
332                                         {
333                                                 Ret =
334                                                     EplNmtuNmtEvent
335                                                     (kEplNmtEventEnterResetCom);
336                                                 break;
337                                         }
338 
339                                         // init of the communication profile area
340                                 case kEplNmtGsResetCommunication:
341                                         {
342                                                 Ret =
343                                                     EplNmtuNmtEvent
344                                                     (kEplNmtEventEnterResetConfig);
345                                                 break;
346                                         }
347 
348                                         // build the configuration with infos from OD
349                                 case kEplNmtGsResetConfiguration:
350                                         {
351                                                 unsigned int uiNodeId;
352 
353                                                 // get node ID from OD
354 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
355                                                 uiNodeId =
356                                                     EplObduGetNodeId
357                                                     (EPL_MCO_PTR_INSTANCE_PTR);
358 #else
359                                                 uiNodeId = 0;
360 #endif
361                                                 //check node ID if not should be master or slave
362                                                 if (uiNodeId == EPL_C_ADR_MN_DEF_NODE_ID) {     // node shall be MN
363 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
364                                                         Ret =
365                                                             EplNmtuNmtEvent
366                                                             (kEplNmtEventEnterMsNotActive);
367 #else
368                                                         TRACE0
369                                                             ("EplNmtuProcess(): no MN functionality implemented\n");
370 #endif
371                                                 } else {        // node shall be CN
372                                                         Ret =
373                                                             EplNmtuNmtEvent
374                                                             (kEplNmtEventEnterCsNotActive);
375                                                 }
376                                                 break;
377                                         }
378 
379                                         //-----------------------------------------------------------
380                                         // CN part of the state machine
381 
382                                         // node listens for EPL-Frames and check timeout
383                                 case kEplNmtCsNotActive:
384                                         {
385                                                 u32 dwBuffer;
386                                                 tEplObdSize ObdSize;
387                                                 tEplTimerArg TimerArg;
388 
389                                                 // create timer to switch automatically to BasicEthernet if no MN available in network
390 
391                                                 // read NMT_CNBasicEthernetTimerout_U32 from OD
392                                                 ObdSize = sizeof(dwBuffer);
393 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
394                                                 Ret =
395                                                     EplObduReadEntry
396                                                     (EPL_MCO_PTR_INSTANCE_PTR_
397                                                      0x1F99, 0x00, &dwBuffer,
398                                                      &ObdSize);
399 #else
400                                                 Ret = kEplObdIndexNotExist;
401 #endif
402                                                 if (Ret != kEplSuccessful) {
403                                                         break;
404                                                 }
405                                                 if (dwBuffer != 0) {    // BasicEthernet is enabled
406                                                         // convert us into ms
407                                                         dwBuffer =
408                                                             dwBuffer / 1000;
409                                                         if (dwBuffer == 0) {    // timer was below one ms
410                                                                 // set one ms
411                                                                 dwBuffer = 1;
412                                                         }
413                                                         TimerArg.m_EventSink =
414                                                             kEplEventSinkNmtk;
415                                                         TimerArg.m_ulArg =
416                                                             (unsigned long)
417                                                             kEplNmtEventTimerBasicEthernet;
418                                                         Ret =
419                                                             EplTimeruModifyTimerMs
420                                                             (&EplNmtuInstance_g.
421                                                              m_TimerHdl,
422                                                              (unsigned long)
423                                                              dwBuffer,
424                                                              TimerArg);
425                                                         // potential error is forwarded to event queue which generates error event
426                                                 }
427                                                 break;
428                                         }
429 
430                                         // node processes only async frames
431                                 case kEplNmtCsPreOperational1:
432                                         {
433                                                 break;
434                                         }
435 
436                                         // node processes isochronous and asynchronous frames
437                                 case kEplNmtCsPreOperational2:
438                                         {
439                                                 Ret =
440                                                     EplNmtuNmtEvent
441                                                     (kEplNmtEventEnterReadyToOperate);
442                                                 break;
443                                         }
444 
445                                         // node should be configured und application is ready
446                                 case kEplNmtCsReadyToOperate:
447                                         {
448                                                 break;
449                                         }
450 
451                                         // normal work state
452                                 case kEplNmtCsOperational:
453                                         {
454                                                 break;
455                                         }
456 
457                                         // node stopped by MN
458                                         // -> only process asynchronous frames
459                                 case kEplNmtCsStopped:
460                                         {
461                                                 break;
462                                         }
463 
464                                         // no EPL cycle
465                                         // -> normal ethernet communication
466                                 case kEplNmtCsBasicEthernet:
467                                         {
468                                                 break;
469                                         }
470 
471                                         //-----------------------------------------------------------
472                                         // MN part of the state machine
473 
474 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
475                                         // node listens for EPL-Frames and check timeout
476                                 case kEplNmtMsNotActive:
477                                         {
478                                                 u32 dwBuffer;
479                                                 tEplObdSize ObdSize;
480                                                 tEplTimerArg TimerArg;
481 
482                                                 // create timer to switch automatically to BasicEthernet/PreOp1 if no other MN active in network
483 
484                                                 // check NMT_StartUp_U32.Bit13
485                                                 // read NMT_StartUp_U32 from OD
486                                                 ObdSize = sizeof(dwBuffer);
487 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
488                                                 Ret =
489                                                     EplObduReadEntry
490                                                     (EPL_MCO_PTR_INSTANCE_PTR_
491                                                      0x1F80, 0x00, &dwBuffer,
492                                                      &ObdSize);
493 #else
494                                                 Ret = kEplObdIndexNotExist;
495 #endif
496                                                 if (Ret != kEplSuccessful) {
497                                                         break;
498                                                 }
499 
500                                                 if ((dwBuffer & EPL_NMTST_BASICETHERNET) == 0) {        // NMT_StartUp_U32.Bit13 == 0
501                                                         // new state PreOperational1
502                                                         TimerArg.m_ulArg =
503                                                             (unsigned long)
504                                                             kEplNmtEventTimerMsPreOp1;
505                                                 } else {        // NMT_StartUp_U32.Bit13 == 1
506                                                         // new state BasicEthernet
507                                                         TimerArg.m_ulArg =
508                                                             (unsigned long)
509                                                             kEplNmtEventTimerBasicEthernet;
510                                                 }
511 
512                                                 // read NMT_BootTime_REC.MNWaitNotAct_U32 from OD
513                                                 ObdSize = sizeof(dwBuffer);
514 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
515                                                 Ret =
516                                                     EplObduReadEntry
517                                                     (EPL_MCO_PTR_INSTANCE_PTR_
518                                                      0x1F89, 0x01, &dwBuffer,
519                                                      &ObdSize);
520 #else
521                                                 Ret = kEplObdIndexNotExist;
522 #endif
523                                                 if (Ret != kEplSuccessful) {
524                                                         break;
525                                                 }
526                                                 // convert us into ms
527                                                 dwBuffer = dwBuffer / 1000;
528                                                 if (dwBuffer == 0) {    // timer was below one ms
529                                                         // set one ms
530                                                         dwBuffer = 1;
531                                                 }
532                                                 TimerArg.m_EventSink =
533                                                     kEplEventSinkNmtk;
534                                                 Ret =
535                                                     EplTimeruModifyTimerMs
536                                                     (&EplNmtuInstance_g.
537                                                      m_TimerHdl,
538                                                      (unsigned long)dwBuffer,
539                                                      TimerArg);
540                                                 // potential error is forwarded to event queue which generates error event
541                                                 break;
542                                         }
543 
544                                         // node processes only async frames
545                                 case kEplNmtMsPreOperational1:
546                                         {
547                                                 u32 dwBuffer = 0;
548                                                 tEplObdSize ObdSize;
549                                                 tEplTimerArg TimerArg;
550 
551                                                 // create timer to switch automatically to PreOp2 if MN identified all mandatory CNs
552 
553                                                 // read NMT_BootTime_REC.MNWaitPreOp1_U32 from OD
554                                                 ObdSize = sizeof(dwBuffer);
555 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) != 0) || (EPL_OBD_USE_KERNEL != FALSE)
556                                                 Ret =
557                                                     EplObduReadEntry
558                                                     (EPL_MCO_PTR_INSTANCE_PTR_
559                                                      0x1F89, 0x03, &dwBuffer,
560                                                      &ObdSize);
561                                                 if (Ret != kEplSuccessful) {
562                                                         // ignore error, because this timeout is optional
563                                                         dwBuffer = 0;
564                                                 }
565 #endif
566                                                 if (dwBuffer == 0) {    // delay is deactivated
567                                                         // immediately post timer event
568                                                         Ret =
569                                                             EplNmtuNmtEvent
570                                                             (kEplNmtEventTimerMsPreOp2);
571                                                         break;
572                                                 }
573                                                 // convert us into ms
574                                                 dwBuffer = dwBuffer / 1000;
575                                                 if (dwBuffer == 0) {    // timer was below one ms
576                                                         // set one ms
577                                                         dwBuffer = 1;
578                                                 }
579                                                 TimerArg.m_EventSink =
580                                                     kEplEventSinkNmtk;
581                                                 TimerArg.m_ulArg =
582                                                     (unsigned long)
583                                                     kEplNmtEventTimerMsPreOp2;
584                                                 Ret =
585                                                     EplTimeruModifyTimerMs
586                                                     (&EplNmtuInstance_g.
587                                                      m_TimerHdl,
588                                                      (unsigned long)dwBuffer,
589                                                      TimerArg);
590                                                 // potential error is forwarded to event queue which generates error event
591                                                 break;
592                                         }
593 
594                                         // node processes isochronous and asynchronous frames
595                                 case kEplNmtMsPreOperational2:
596                                         {
597                                                 break;
598                                         }
599 
600                                         // node should be configured und application is ready
601                                 case kEplNmtMsReadyToOperate:
602                                         {
603                                                 break;
604                                         }
605 
606                                         // normal work state
607                                 case kEplNmtMsOperational:
608                                         {
609                                                 break;
610                                         }
611 
612                                         // no EPL cycle
613                                         // -> normal ethernet communication
614                                 case kEplNmtMsBasicEthernet:
615                                         {
616                                                 break;
617                                         }
618 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
619 
620                                 default:
621                                         {
622                                                 TRACE1
623                                                     ("EplNmtuProcess(): unhandled NMT state 0x%X\n",
624                                                      pNmtStateChange->
625                                                      m_NewNmtState);
626                                         }
627                                 }
628                         } else if (Ret == kEplReject) { // application wants to change NMT state itself
629                                 // it's OK
630                                 Ret = kEplSuccessful;
631                         }
632 
633                         EPL_DBGLVL_NMTU_TRACE0
634                             ("EplNmtuProcessEvent(): NMT-State-Maschine announce change of NMT State\n");
635                         break;
636                 }
637 
638         default:
639                 {
640                         Ret = kEplNmtInvalidEvent;
641                 }
642 
643         }
644 
645 //Exit:
646         return Ret;
647 }
648 
649 //---------------------------------------------------------------------------
650 //
651 // Function:    EplNmtuRegisterStateChangeCb
652 //
653 // Description: register Callback-function go get informed about a
654 //              NMT-Change-State-Event
655 //
656 //
657 //
658 // Parameters:  pfnEplNmtStateChangeCb_p = functionpointer
659 //
660 //
661 // Returns:     tEplKernel  = errorcode
662 //
663 //
664 // State:
665 //
666 //---------------------------------------------------------------------------
667 tEplKernel EplNmtuRegisterStateChangeCb(tEplNmtuStateChangeCallback pfnEplNmtStateChangeCb_p)
668 {
669         tEplKernel Ret;
670 
671         Ret = kEplSuccessful;
672 
673         // save callback-function in modul global var
674         EplNmtuInstance_g.m_pfnNmtChangeCb = pfnEplNmtStateChangeCb_p;
675 
676         return Ret;
677 
678 }
679 
680 //=========================================================================//
681 //                                                                         //
682 //          P R I V A T E   F U N C T I O N S                              //
683 //                                                                         //
684 //=========================================================================//
685 
686 //---------------------------------------------------------------------------
687 //
688 // Function:
689 //
690 // Description:
691 //
692 //
693 //
694 // Parameters:
695 //
696 //
697 // Returns:
698 //
699 //
700 // State:
701 //
702 //---------------------------------------------------------------------------
703 
704 #endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
705 
706 // EOF
707 
  This page was automatically generated by the LXR engine.