]> rtime.felk.cvut.cz Git - CanFestival-3.git/blob - examples/TestMasterSlave/TestMasterSlave.c
Win32 Native support and dynamicaly loaded CAN drivers for Linux, Cygwin and Win32.
[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 <sys/time.h>
34 //#include <unistd.h>
35 #include <stdlib.h>
36 #include <signal.h>
37 #endif
38
39 #include <applicfg.h>
40 #include <can_driver.h>
41 #include <timers_driver.h>
42
43 #include "Master.h"
44 #include "Slave.h"
45 #include "TestMasterSlave.h"
46
47 #define MyCase(fc) case fc: eprintf(#fc);break;
48 void print_message(Message *m)
49 {
50         int i;
51         switch(m->cob_id.w >> 7)
52         {
53                 MyCase(SYNC)
54                 MyCase(TIME_STAMP)
55                 MyCase(PDO1tx)
56                 MyCase(PDO1rx)
57                 MyCase(PDO2tx)
58                 MyCase(PDO2rx)
59                 MyCase(PDO3tx)
60                 MyCase(PDO3rx)
61                 MyCase(PDO4tx)
62                 MyCase(PDO4rx)
63                 MyCase(SDOtx)
64                 MyCase(SDOrx)
65                 MyCase(NODE_GUARD)
66                 MyCase(NMT)
67         }
68         eprintf(" rtr:%d", m->rtr);
69         eprintf(" len:%d", m->len);
70         for (i = 0 ; i < m->len ; i++)
71                 eprintf(" %02x", m->data[i]);
72         eprintf("\n");
73 }
74
75 UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex)
76 {
77         eprintf("OnSlaveMap1Update:%d\n", SlaveMap1);
78         return 0;
79 }
80
81 CAN_PORT SlaveCanHandle;
82 CAN_PORT MasterCanHandle;
83
84 s_BOARD SlaveBoard = {"0", "500K"};
85 s_BOARD MasterBoard = {"1", "500K"};
86
87 #if !defined(WIN32) || defined(__CYGWIN__)
88 void catch_signal(int sig)
89 {
90   signal(SIGTERM, catch_signal);
91   signal(SIGINT, catch_signal);
92   eprintf("Got Signal %d\n",sig);
93 }
94 #endif
95
96 void help()
97 {
98   printf("**************************************************************\n");
99   printf("*  TestMasterSlave                                           *\n");
100   printf("*                                                            *\n");
101   printf("*  A simple example for PC. It does implement 2 CanOpen      *\n");
102   printf("*  nodes in the same process. A master and a slave. Both     *\n");
103   printf("*  communicate together, exchanging periodically NMT, SYNC,  *\n");
104   printf("*  SDO and PDO.                                              *\n");
105   printf("*                                                            *\n");
106   printf("*   Usage:                                                   *\n");
107   printf("*   ./TestMasterSlave  [OPTIONS]                             *\n");
108   printf("*                                                            *\n");
109   printf("*   OPTIONS:                                                 *\n");
110   printf("*     -l : Can library [\"libcanfestival_can_virtual.so\"]     *\n");
111   printf("*                                                            *\n");
112   printf("*    Slave:                                                  *\n");
113   printf("*     -s : bus name [\"0\"]                                    *\n");
114   printf("*     -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
115   printf("*                                                            *\n");
116   printf("*    Master:                                                 *\n");
117   printf("*     -m : bus name [\"1\"]                                    *\n");
118   printf("*     -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable)  *\n");
119   printf("*                                                            *\n");
120   printf("**************************************************************\n");
121 }
122
123 /***************************  INIT  *****************************************/
124 void InitNodes(CO_Data* d, UNS32 id)
125 {
126         /****************************** INITIALISATION SLAVE *******************************/
127         if(SlaveBoard.baudrate) {
128                 /* Defining the node Id */
129                 setNodeId(&TestSlave_Data, 0x02);
130                 /* init */
131                 setState(&TestSlave_Data, Initialisation);
132         }
133
134         /****************************** INITIALISATION MASTER *******************************/
135         if(MasterBoard.baudrate){
136                 RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update);
137
138                 /* Defining the node Id */
139                 setNodeId(&TestMaster_Data, 0x01);
140
141                 /* init */
142                 setState(&TestMaster_Data, Initialisation);
143
144                 /****************************** START *******************************/
145                 /* Put the master in operational mode */
146                 setState(&TestMaster_Data, Operational);
147   
148                 /* Ask slave node to go in operational mode */
149                 masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Start_Node);
150         }
151 }
152
153 /****************************************************************************/
154 /***************************  MAIN  *****************************************/
155 /****************************************************************************/
156 int main(int argc,char **argv)
157 {
158
159   char c;
160   extern char *optarg;
161   char* LibraryPath="libcanfestival_can_virtual.so";
162
163   while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF)
164   {
165     switch(c)
166     {
167       case 's' :
168         if (optarg[0] == 0)
169         {
170           help();
171           exit(1);
172         }
173         SlaveBoard.busname = optarg;
174         break;
175       case 'm' :
176         if (optarg[0] == 0)
177         {
178           help();
179           exit(1);
180         }
181         MasterBoard.busname = optarg;
182         break;
183       case 'S' :
184         if (optarg[0] == 0)
185         {
186           help();
187           exit(1);
188         }
189         SlaveBoard.baudrate = optarg;
190         break;
191       case 'M' :
192         if (optarg[0] == 0)
193         {
194           help();
195           exit(1);
196         }
197         MasterBoard.baudrate = optarg;
198         break;
199       case 'l' :
200         if (optarg[0] == 0)
201         {
202           help();
203           exit(1);
204         }
205         LibraryPath = optarg;
206         break;
207       default:
208         help();
209         exit(1);
210     }
211   }
212
213 #if !defined(WIN32) || defined(__CYGWIN__)
214   /* install signal handler for manual break */
215         signal(SIGTERM, catch_signal);
216         signal(SIGINT, catch_signal);
217 #endif
218
219 #ifndef NOT_USE_DYNAMIC_LOADING
220         LoadCanDriver(LibraryPath);
221 #endif          
222         // Open CAN devices
223         if(SlaveBoard.baudrate){
224                 SlaveCanHandle = canOpen(&SlaveBoard,&TestSlave_Data);
225                 if(SlaveCanHandle == NULL){
226                         eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
227                         goto fail_slave;
228                 }
229         }
230
231         if(MasterBoard.baudrate){
232                 MasterCanHandle = canOpen(&MasterBoard,&TestMaster_Data);
233                 if(MasterCanHandle == NULL){
234                         eprintf("Cannot open Master Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
235                         goto fail_master;
236                 }
237         }
238         
239         // Start timer thread
240         StartTimerLoop(&InitNodes);
241
242         // wait Ctrl-C
243         pause();
244         eprintf("Finishing.\n");
245         
246         // Stop timer thread
247         StopTimerLoop();
248         
249         // Close CAN devices (and can threads)
250         if(SlaveBoard.baudrate) canClose(SlaveCanHandle);
251 fail_master:
252         if(MasterBoard.baudrate) canClose(MasterCanHandle);     
253 fail_slave:
254         
255
256   return 0;
257 }