plugins/canfestival/cf_runtime.c
changeset 717 1c23952dbde1
parent 716 180e4a7d945c
child 718 5d4dc150b956
equal deleted inserted replaced
716:180e4a7d945c 717:1c23952dbde1
     1 
       
     2 #include "canfestival.h"
       
     3 
       
     4 /* CanFestival nodes generated OD headers*/
       
     5 %(nodes_includes)s
       
     6 
       
     7 #define BOARD_DECL(nodename, busname, baudrate)\
       
     8     s_BOARD nodename##Board = {busname, baudrate};
       
     9 
       
    10 /* CAN channels declaration */
       
    11 %(board_decls)s
       
    12 
       
    13 /* Keep track of init level to cleanup correctly */
       
    14 static int init_level=0;
       
    15 /* Retrieve PLC cycle time */
       
    16 extern int common_ticktime__;
       
    17 
       
    18 /* Called once all NetworkEdit declares slaves have booted*/
       
    19 static void Master_post_SlaveBootup(CO_Data* d, UNS8 nodeId)
       
    20 {
       
    21     /* Put the master in operational mode */
       
    22     setState(d, Operational);
       
    23 
       
    24     /* Ask slave node to go in operational mode */
       
    25     masterSendNMTstateChange (d, 0, NMT_Start_Node);
       
    26 }
       
    27 
       
    28 /* Per master node slavebootup callbacks. Checks that
       
    29  * every node have booted before calling Master_post_SlaveBootup */
       
    30 %(slavebootups)s
       
    31 
       
    32 /* One slave node post_sync callback.
       
    33  * Used to align PLC tick-time on CANopen SYNC
       
    34  */
       
    35 %(post_sync)s
       
    36 
       
    37 #define NODE_FORCE_SYNC(nodename) \
       
    38     /* Artificially force sync state to 1 so that it is not started */\
       
    39     nodename##_Data.CurrentCommunicationState.csSYNC = -1;\
       
    40     /* Force sync period to common_ticktime__ so that other node can read it*/\
       
    41     *nodename##_Data.COB_ID_Sync = 0x40000080;\
       
    42     *nodename##_Data.Sync_Cycle_Period = common_ticktime__ * 1000;
       
    43 
       
    44 #define NODE_INIT(nodename, nodeid) \
       
    45     /* Defining the node Id */\
       
    46     setNodeId(&nodename##_Data, nodeid);\
       
    47     /* init */\
       
    48     setState(&nodename##_Data, Initialisation);
       
    49 
       
    50 #define NODE_MASTER_INIT(nodename, nodeid) \
       
    51     NODE_FORCE_SYNC(nodename) \
       
    52     NODE_INIT(nodename, nodeid)
       
    53 
       
    54 #define NODE_SLAVE_INIT(nodename, nodeid) \
       
    55     NODE_INIT(nodename, nodeid)
       
    56 
       
    57 void InitNodes(CO_Data* d, UNS32 id)
       
    58 {
       
    59     %(slavebootup_register)s
       
    60     %(post_sync_register)s
       
    61     %(nodes_init)s
       
    62 }
       
    63 
       
    64 #define NODE_STOP(nodename) \
       
    65     if(init_level-- > 0)\
       
    66     {\
       
    67         masterSendNMTstateChange(&nodename##_Data, 0, NMT_Reset_Node);\
       
    68         setState(&nodename##_Data, Stopped);\
       
    69     }
       
    70 
       
    71 void Exit(CO_Data* d, UNS32 id)
       
    72 {
       
    73     %(nodes_stop)s
       
    74 }
       
    75 
       
    76 #define NODE_CLOSE(nodename) \
       
    77     if(init_level_c-- > 0)\
       
    78     {\
       
    79       canClose(&nodename##_Data);\
       
    80     }
       
    81 
       
    82 void __cleanup_%(locstr)s(void)
       
    83 {
       
    84     // Stop timer thread
       
    85     if(init_level-- > 0){
       
    86     int init_level_c = init_level;
       
    87         StopTimerLoop(&Exit);
       
    88         %(nodes_close)s
       
    89     }
       
    90 
       
    91     TimerCleanup();
       
    92 }
       
    93 
       
    94 #ifndef stderr
       
    95 #define fprintf(...)
       
    96 #define fflush(...)
       
    97 #endif
       
    98 
       
    99 #define NODE_OPEN(nodename)\
       
   100     if(!canOpen(&nodename##Board,&nodename##_Data)){\
       
   101         fprintf(stderr,"Cannot open CAN intefrace %%s at speed %%s\n for CANopen node \"" #nodename "\"",nodename##Board.busname, nodename##Board.baudrate);\
       
   102         fflush(stderr);\
       
   103         return -1;\
       
   104     }\
       
   105     init_level++;
       
   106 
       
   107 /***************************  INIT  *****************************************/
       
   108 int __init_%(locstr)s(int argc,char **argv)
       
   109 {
       
   110 #ifndef NOT_USE_DYNAMIC_LOADING
       
   111     if( !LoadCanDriver("%(candriver)s") ){
       
   112         fprintf(stderr, "Cannot load CAN interface library for CanFestival (%(candriver)s)\n");\
       
   113         fflush(stderr);\
       
   114         return -1;\
       
   115     }
       
   116 #endif
       
   117 
       
   118     TimerInit();
       
   119 
       
   120     %(nodes_open)s
       
   121 
       
   122     // Start timer thread
       
   123     StartTimerLoop(&InitNodes);
       
   124     init_level++;
       
   125     return 0;
       
   126 }
       
   127 
       
   128 #define NODE_SEND_SYNC(nodename)\
       
   129     sendSYNCMessage(&nodename##_Data);
       
   130 
       
   131 void __retrieve_%(locstr)s(void)
       
   132 {
       
   133     /* Locks the stack, so that no changes occurs while PLC access variables
       
   134      * TODO : implement buffers to avoid such a big lock
       
   135      *  */
       
   136     EnterMutex();
       
   137     /* Send Sync */
       
   138     %(nodes_send_sync)s
       
   139 }
       
   140 
       
   141 #define NODE_PROCEED_SYNC(nodename)\
       
   142     proceedSYNC(&nodename##_Data);
       
   143 
       
   144 void __publish_%(locstr)s(void)
       
   145 {
       
   146     /* Process sync event */
       
   147     %(nodes_proceed_sync)s
       
   148     LeaveMutex();
       
   149 }
       
   150