]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - examples/TestMasterSlave/TestMasterSlave.c
Master configure slave's heartbeat producer time by concise DCF.
[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   char 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
198                 if(!canOpen(&SlaveBoard,&TestSlave_Data)){
199                         eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
200                         goto fail_slave;
201                 }
202         }
203         if(strcmp(MasterBoard.baudrate, "none")){
204                 
205                 TestMaster_Data.heartbeatError = TestMaster_heartbeatError;
206                 TestMaster_Data.initialisation = TestMaster_initialisation;
207                 TestMaster_Data.preOperational = TestMaster_preOperational;
208                 TestMaster_Data.operational = TestMaster_operational;
209                 TestMaster_Data.stopped = TestMaster_stopped;
210                 TestMaster_Data.post_sync = TestMaster_post_sync;
211                 TestMaster_Data.post_TPDO = TestMaster_post_TPDO;
212                 
213                 if(!canOpen(&MasterBoard,&TestMaster_Data)){
214                         eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate);
215                         goto fail_master;
216                 }
217         }
218         sleep(2);
219         // Start timer thread
220         StartTimerLoop(&InitNodes);
221
222         // wait Ctrl-C
223         
224         pause();
225         eprintf("Finishing.\n");
226         
227         masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Reset_Node);
228         eprintf("reset\n");
229         // Stop master
230         setState(&TestMaster_Data, Stopped);
231         
232         // Stop timer thread
233         StopTimerLoop();
234         
235         // Close CAN devices (and can threads)
236         if(strcmp(SlaveBoard.baudrate, "none")) canClose(&TestSlave_Data);
237 fail_master:
238         if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data);    
239 fail_slave:
240         return 0;
241 }