]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - examples/TestMasterSlave/TestMasterSlave.c
Implemented EMCY objects.
[CanFestival-3.git] / examples / TestMasterSlave / TestMasterSlave.c
1 /*
2 This file is part of CanFestival, a library implementing CanOpen Stack. 
3
4 Copyright (C): Edouard TISSERANT and Francis DUPIN
5
6 See COPYING file for copyrights details.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public
10 License as published by the Free Software Foundation; either
11 version 2.1 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public
19 License along with this library; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21 */
22
23 #if defined(WIN32) && !defined(__CYGWIN__)
24 #include <windows.h>
25 #include "getopt.h"
26 void pause(void)
27 {
28         system("PAUSE");
29 }
30 #else
31 #include <stdio.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <stdlib.h>
35 #include <signal.h>
36 #endif
37
38 #include "canfestival.h"
39 //#include <can_driver.h>
40 //#include <timers_driver.h>
41
42 #include "Master.h"
43 #include "Slave.h"
44 #include "TestMasterSlave.h"
45
46 UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
47 {
48         eprintf("OnSlaveMap1Update:%d\n", SlaveMap1);
49         return 0;
50 }
51
52 s_BOARD SlaveBoard = {"0", "125K"};
53 s_BOARD MasterBoard = {"1", "125K"};
54
55 #if !defined(WIN32) || defined(__CYGWIN__)
56 void catch_signal(int sig)
57 {
58   signal(SIGTERM, catch_signal);
59   signal(SIGINT, catch_signal);
60   eprintf("Got Signal %d\n",sig);
61 }
62 #endif
63
64 void help()
65 {
66   printf("**************************************************************\n");
67   printf("*  TestMasterSlave                                           *\n");
68   printf("*                                                            *\n");
69   printf("*  A simple example for PC. It does implement 2 CanOpen      *\n");
70   printf("*  nodes in the same process. A master and a slave. Both     *\n");
71   printf("*  communicate together, exchanging periodically NMT, SYNC,  *\n");
72   printf("*  SDO and PDO. Master configure heartbeat producer time     *\n");
73   printf("*  at 1000 ms for slave node-id 0x02 by concise DCF.         *\n");                                  
74   printf("*                                                            *\n");
75   printf("*   Usage:                                                   *\n");
76   printf("*   ./TestMasterSlave  [OPTIONS]                             *\n");
77   printf("*                                                            *\n");
78   printf("*   OPTIONS:                                                 *\n");
79   printf("*     -l : Can library [\"libcanfestival_can_virtual.so\"]     *\n");
80   printf("*                                                            *\n");
81   printf("*    Slave:                                                  *\n");
82   printf("*     -s : bus name [\"0\"]                                    *\n");
83   printf("*     -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
84   printf("*                                                            *\n");
85   printf("*    Master:                                                 *\n");
86   printf("*     -m : bus name [\"1\"]                                    *\n");
87   printf("*     -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
88   printf("*                                                            *\n");
89   printf("**************************************************************\n");
90 }
91
92 /***************************  INIT  *****************************************/
93 void InitNodes(CO_Data* d, UNS32 id)
94 {
95         /****************************** INITIALISATION SLAVE *******************************/
96         if(strcmp(SlaveBoard.baudrate, "none")) {
97                 /* Defining the node Id */
98                 setNodeId(&TestSlave_Data, 0x02);
99                 /* init */
100                 setState(&TestSlave_Data, Initialisation);
101         }
102
103         /****************************** INITIALISATION MASTER *******************************/
104         if(strcmp(MasterBoard.baudrate, "none")){
105                 RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update);
106                 
107                 /* Defining the node Id */
108                 setNodeId(&TestMaster_Data, 0x01);
109
110                 /* init */
111                 setState(&TestMaster_Data, Initialisation);
112                         
113         }
114 }
115
116 /****************************************************************************/
117 /***************************  MAIN  *****************************************/
118 /****************************************************************************/
119 int main(int argc,char **argv)
120 {
121
122   int c;
123   extern char *optarg;
124   char* LibraryPath="libcanfestival_can_virtual.so";
125
126   while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF)
127   {
128     switch(c)
129     {
130       case 's' :
131         if (optarg[0] == 0)
132         {
133           help();
134           exit(1);
135         }
136         SlaveBoard.busname = optarg;
137         break;
138       case 'm' :
139         if (optarg[0] == 0)
140         {
141           help();
142           exit(1);
143         }
144         MasterBoard.busname = optarg;
145         break;
146       case 'S' :
147         if (optarg[0] == 0)
148         {
149           help();
150           exit(1);
151         }
152         SlaveBoard.baudrate = optarg;
153         break;
154       case 'M' :
155         if (optarg[0] == 0)
156         {
157           help();
158           exit(1);
159         }
160         MasterBoard.baudrate = optarg;
161         break;
162       case 'l' :
163         if (optarg[0] == 0)
164         {
165           help();
166           exit(1);
167         }
168         LibraryPath = optarg;
169         break;
170       default:
171         help();
172         exit(1);
173     }
174   }
175
176 #if !defined(WIN32) || defined(__CYGWIN__)
177   /* install signal handler for manual break */
178         signal(SIGTERM, catch_signal);
179         signal(SIGINT, catch_signal);
180 #endif
181
182 #ifndef NOT_USE_DYNAMIC_LOADING
183         LoadCanDriver(LibraryPath);
184 #endif          
185         // Open CAN devices
186
187         if(strcmp(SlaveBoard.baudrate, "none")){
188                 
189                 TestSlave_Data.heartbeatError = TestSlave_heartbeatError;
190                 TestSlave_Data.initialisation = TestSlave_initialisation;
191                 TestSlave_Data.preOperational = TestSlave_preOperational;
192                 TestSlave_Data.operational = TestSlave_operational;
193                 TestSlave_Data.stopped = TestSlave_stopped;
194                 TestSlave_Data.post_sync = TestSlave_post_sync;
195                 TestSlave_Data.post_TPDO = TestSlave_post_TPDO;
196                 TestSlave_Data.storeODSubIndex = TestSlave_storeODSubIndex;
197                 TestSlave_Data.post_emcy = TestSlave_post_emcy;
198
199                 if(!canOpen(&SlaveBoard,&TestSlave_Data)){
200                         eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
201                         goto fail_slave;
202                 }
203         }
204         if(strcmp(MasterBoard.baudrate, "none")){
205                 
206                 TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
207                 TestMaster_Data.initialisation = TestMaster_initialisation;
208                 TestMaster_Data.preOperational = TestMaster_preOperational;
209                 TestMaster_Data.operational = TestMaster_operational;
210                 TestMaster_Data.stopped = TestMaster_stopped;
211                 TestMaster_Data.post_sync = TestMaster_post_sync;
212                 TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
213                 TestMaster_Data.post_emcy = TestMaster_post_emcy;
214                 
215                 if(!canOpen(&MasterBoard,&TestMaster_Data)){
216                         eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate);
217                         goto fail_master;
218                 }
219         }
220
221         // Start timer thread
222         StartTimerLoop(&InitNodes);
223
224         // wait Ctrl-C
225         
226         pause();
227
228         eprintf("Finishing.\n");
229     EnterMutex();
230         masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Reset_Node);
231     LeaveMutex();
232
233         eprintf("reset\n");
234         // Stop master
235     EnterMutex();
236         setState(&TestMaster_Data, Stopped);
237     LeaveMutex();
238         
239         // Stop timer thread
240         StopTimerLoop();
241         
242         // Close CAN devices (and can threads)
243         if(strcmp(SlaveBoard.baudrate, "none")) canClose(&TestSlave_Data);
244 fail_master:
245         if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data);    
246 fail_slave:
247         return 0;
248 }