]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - examples/TestMasterSlaveLSS/TestMasterSlaveLSS.c
added TestMasterSlaveLSS. LSS protocol revised.
[CanFestival-3.git] / examples / TestMasterSlaveLSS / TestMasterSlaveLSS.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 "SlaveA.h"
44 #include "SlaveB.h"
45 #include "TestMasterSlaveLSS.h"
46
47 s_BOARD SlaveBoardA = {"0", "125K"};
48 s_BOARD SlaveBoardB = {"1", "125K"};
49 s_BOARD MasterBoard = {"2", "125K"};
50
51 #if !defined(WIN32) || defined(__CYGWIN__)
52 void catch_signal(int sig)
53 {
54   signal(SIGTERM, catch_signal);
55   signal(SIGINT, catch_signal);
56   eprintf("Got Signal %d\n",sig);
57 }
58 #endif
59
60 void help()
61 {
62   printf("**************************************************************\n");
63   printf("*  TestMasterSlaveLSS                                           *\n");
64   printf("*                                                            *\n");
65   printf("*  A LSS example for PC. It does implement 3 CanOpen      *\n");
66   printf("*  nodes in the same process. A master and 2 slaves. Both     *\n");
67   printf("*  communicate together, exchanging periodically NMT, SYNC,  *\n");
68   printf("*  SDO and PDO. Master configure heartbeat producer time     *\n");
69   printf("*  at 1000 ms for slave node-id 0x02 by concise DCF.         *\n");                                  
70   printf("*                                                            *\n");
71   printf("*   Usage:                                                   *\n");
72   printf("*   ./TestMasterSlaveLSS  [OPTIONS]                             *\n");
73   printf("*                                                            *\n");
74   printf("*   OPTIONS:                                                 *\n");
75   printf("*     -l : Can library [\"libcanfestival_can_virtual.so\"]     *\n");
76   printf("*                                                            *\n");
77   printf("*    SlaveA:                                                  *\n");
78   printf("*     -s : bus name [\"0\"]                                    *\n");
79   printf("*     -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
80   printf("*                                                            *\n");
81   printf("*    Master:                                                 *\n");
82   printf("*     -m : bus name [\"1\"]                                    *\n");
83   printf("*     -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
84   printf("*                                                            *\n");
85   printf("**************************************************************\n");
86 }
87
88 /***************************  INIT  *****************************************/
89 void InitNodes(CO_Data* d, UNS32 id)
90 {
91         /****************************** INITIALISATION SLAVE_A *******************************/
92         if(strcmp(SlaveBoardA.baudrate, "none")) {
93                 /* Set an invalid nodeID */
94                 setNodeId(&TestSlaveA_Data, 0xFF);
95
96                 /* init */
97                 setState(&TestSlaveA_Data, Initialisation);
98         }
99         
100         /****************************** INITIALISATION SLAVE_B *******************************/
101         if(strcmp(SlaveBoardB.baudrate, "none")) {
102
103                 /* Set an invalid nodeID */
104                 setNodeId(&TestSlaveB_Data, 0xFF);
105
106                 /* init */
107                 setState(&TestSlaveB_Data, Initialisation);
108         }
109
110         /****************************** INITIALISATION MASTER *******************************/
111         if(strcmp(MasterBoard.baudrate, "none")){
112                 
113                 /* Defining the node Id */
114                 setNodeId(&TestMaster_Data, 0x01);
115
116                 /* init */
117                 setState(&TestMaster_Data, Initialisation);             
118         }
119 }
120
121 /****************************************************************************/
122 /***************************  MAIN  *****************************************/
123 /****************************************************************************/
124 int main(int argc,char **argv)
125 {
126
127   int c;
128   extern char *optarg;
129   char* LibraryPath="../../drivers/can_virtual/libcanfestival_can_virtual.so";
130
131   while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF)
132   {
133     switch(c)
134     {
135       case 's' :
136         if (optarg[0] == 0)
137         {
138           help();
139           exit(1);
140         }
141         SlaveBoardA.busname = optarg;
142         break;
143       case 'm' :
144         if (optarg[0] == 0)
145         {
146           help();
147           exit(1);
148         }
149         MasterBoard.busname = optarg;
150         break;
151       case 'S' :
152         if (optarg[0] == 0)
153         {
154           help();
155           exit(1);
156         }
157         SlaveBoardA.baudrate = optarg;
158         break;
159       case 'M' :
160         if (optarg[0] == 0)
161         {
162           help();
163           exit(1);
164         }
165         MasterBoard.baudrate = optarg;
166         break;
167       case 'l' :
168         if (optarg[0] == 0)
169         {
170           help();
171           exit(1);
172         }
173         LibraryPath = optarg;
174         break;
175       default:
176         help();
177         exit(1);
178     }
179   }
180
181 #if !defined(WIN32) || defined(__CYGWIN__)
182   /* install signal handler for manual break */
183         signal(SIGTERM, catch_signal);
184         signal(SIGINT, catch_signal);
185 #endif
186
187 #ifndef NOT_USE_DYNAMIC_LOADING
188         if (LoadCanDriver(LibraryPath) == NULL)
189             printf("Unable to load library: %s\n",LibraryPath);
190 #endif          
191         // Open CAN devices
192
193         if(strcmp(SlaveBoardA.baudrate, "none")){
194                 
195                 TestSlaveA_Data.heartbeatError = TestSlaveA_heartbeatError;
196                 TestSlaveA_Data.initialisation = TestSlaveA_initialisation;
197                 TestSlaveA_Data.preOperational = TestSlaveA_preOperational;
198                 TestSlaveA_Data.operational = TestSlaveA_operational;
199                 TestSlaveA_Data.stopped = TestSlaveA_stopped;
200                 TestSlaveA_Data.post_sync = TestSlaveA_post_sync;
201                 TestSlaveA_Data.post_TPDO = TestSlaveA_post_TPDO;
202                 TestSlaveA_Data.storeODSubIndex = TestSlaveA_storeODSubIndex;
203                 TestSlaveA_Data.post_emcy = TestSlaveA_post_emcy;
204                 /* in this example the slave doesn't support Store configuration*/
205                 TestSlaveA_Data.lss_StoreConfiguration = TestSlaveA_StoreConfiguration;
206                 TestSlaveA_Data.lss_ChangeBaudRate=TestSlaveA_ChangeBaudRate;
207
208                 if(!canOpen(&SlaveBoardA,&TestSlaveA_Data)){
209                         eprintf("Cannot open SlaveA Board (%s,%s)\n",SlaveBoardA.busname, SlaveBoardA.baudrate);
210                         goto fail_slaveA;
211                 }
212         }
213         
214         if(strcmp(SlaveBoardB.baudrate, "none")){
215                 
216                 TestSlaveB_Data.heartbeatError = TestSlaveB_heartbeatError;
217                 TestSlaveB_Data.initialisation = TestSlaveB_initialisation;
218                 TestSlaveB_Data.preOperational = TestSlaveB_preOperational;
219                 TestSlaveB_Data.operational = TestSlaveB_operational;
220                 TestSlaveB_Data.stopped = TestSlaveB_stopped;
221                 TestSlaveB_Data.post_sync = TestSlaveB_post_sync;
222                 TestSlaveB_Data.post_TPDO = TestSlaveB_post_TPDO;
223                 TestSlaveB_Data.storeODSubIndex = TestSlaveB_storeODSubIndex;
224                 TestSlaveB_Data.post_emcy = TestSlaveB_post_emcy;
225                 TestSlaveB_Data.lss_StoreConfiguration = TestSlaveB_StoreConfiguration;
226                 TestSlaveB_Data.lss_ChangeBaudRate=TestSlaveB_ChangeBaudRate;
227
228
229                 if(!canOpen(&SlaveBoardB,&TestSlaveB_Data)){
230                         eprintf("Cannot open SlaveB Board (%s,%s)\n",SlaveBoardB.busname, SlaveBoardB.baudrate);
231                         goto fail_slaveB;
232                 }
233         }
234         
235         if(strcmp(MasterBoard.baudrate, "none")){
236                 
237                 TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
238                 TestMaster_Data.initialisation = TestMaster_initialisation;
239                 TestMaster_Data.preOperational = TestMaster_preOperational;
240                 TestMaster_Data.operational = TestMaster_operational;
241                 TestMaster_Data.stopped = TestMaster_stopped;
242                 TestMaster_Data.post_sync = TestMaster_post_sync;
243                 TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
244                 TestMaster_Data.post_emcy = TestMaster_post_emcy;
245                 TestMaster_Data.post_SlaveBootup=TestMaster_post_SlaveBootup;
246                 TestMaster_Data.lss_ChangeBaudRate=TestMaster_ChangeBaudRate;
247                 
248                 if(!canOpen(&MasterBoard,&TestMaster_Data)){
249                         eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate);
250                         goto fail_master;
251                 }
252         }
253
254         // Start timer thread
255         StartTimerLoop(&InitNodes);
256
257         // wait Ctrl-C
258         
259         pause();
260
261         eprintf("Finishing.\n");
262     EnterMutex();
263         masterSendNMTstateChange (&TestMaster_Data, 0x00, NMT_Stop_Node);
264     LeaveMutex();
265
266         eprintf("reset\n");
267         // Stop master
268     EnterMutex();
269         setState(&TestMaster_Data, Stopped);
270     LeaveMutex();
271         
272         // Stop timer thread
273         StopTimerLoop();
274         
275         // Close CAN devices (and can threads)
276         if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data);    
277 fail_master:
278         if(strcmp(SlaveBoardB.baudrate, "none")) canClose(&TestSlaveB_Data);
279 fail_slaveB:
280         if(strcmp(SlaveBoardA.baudrate, "none")) canClose(&TestSlaveA_Data);
281 fail_slaveA:
282         return 0;
283 }