nico@215: nico@215:
nico@215:00001 /* nico@215: 00002 This file is part of CanFestival, a library implementing CanOpen Stack. nico@215: 00003 nico@215: 00004 Copyright (C): Edouard TISSERANT and Francis DUPIN nico@215: 00005 nico@215: 00006 See COPYING file for copyrights details. nico@215: 00007 nico@215: 00008 This library is free software; you can redistribute it and/or nico@215: 00009 modify it under the terms of the GNU Lesser General Public nico@215: 00010 License as published by the Free Software Foundation; either nico@215: 00011 version 2.1 of the License, or (at your option) any later version. nico@215: 00012 nico@215: 00013 This library is distributed in the hope that it will be useful, nico@215: 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of nico@215: 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU nico@215: 00016 Lesser General Public License for more details. nico@215: 00017 nico@215: 00018 You should have received a copy of the GNU Lesser General Public nico@215: 00019 License along with this library; if not, write to the Free Software nico@215: 00020 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA nico@215: 00021 */ nico@215: 00022 nico@215: 00023 #if defined(WIN32) && !defined(__CYGWIN__) nico@215: 00024 #include <windows.h> nico@215: 00025 #include "getopt.h" nico@215: 00026 void pause(void) nico@215: 00027 { nico@215: 00028 system("PAUSE"); nico@215: 00029 } nico@215: 00030 #else nico@215: 00031 #include <stdio.h> nico@215: 00032 #include <string.h> nico@215: 00033 #include <unistd.h> nico@215: 00034 #include <stdlib.h> nico@215: 00035 #include <signal.h> nico@215: 00036 #endif nico@215: 00037 nico@215: 00038 #include "canfestival.h" nico@215: 00039 //#include <can_driver.h> nico@215: 00040 //#include <timers_driver.h> nico@215: 00041 nico@215: 00042 #include "Master.h" nico@215: 00043 #include "Slave.h" nico@215: 00044 #include "TestMasterSlave.h" nico@215: 00045 nico@215: 00046 UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) nico@215: 00047 { nico@215: 00048 eprintf("OnSlaveMap1Update:%d\n", SlaveMap1); nico@215: 00049 return 0; nico@215: 00050 } nico@215: 00051 nico@215: 00052 s_BOARD SlaveBoard = {"0", "125K"}; nico@215: 00053 s_BOARD MasterBoard = {"1", "125K"}; nico@215: 00054 nico@215: 00055 #if !defined(WIN32) || defined(__CYGWIN__) nico@215: 00056 void catch_signal(int sig) nico@215: 00057 { nico@215: 00058 signal(SIGTERM, catch_signal); nico@215: 00059 signal(SIGINT, catch_signal); nico@215: 00060 eprintf("Got Signal %d\n",sig); nico@215: 00061 } nico@215: 00062 #endif nico@215: 00063 nico@215: 00064 void help() nico@215: 00065 { nico@215: 00066 printf("**************************************************************\n"); nico@215: 00067 printf("* TestMasterSlave *\n"); nico@215: 00068 printf("* *\n"); nico@215: 00069 printf("* A simple example for PC. It does implement 2 CanOpen *\n"); nico@215: 00070 printf("* nodes in the same process. A master and a slave. Both *\n"); nico@215: 00071 printf("* communicate together, exchanging periodically NMT, SYNC, *\n"); nico@215: 00072 printf("* SDO and PDO. Master configure heartbeat producer time *\n"); nico@215: 00073 printf("* at 1000 ms for slave node-id 0x02 by concise DCF. *\n"); nico@215: 00074 printf("* *\n"); nico@215: 00075 printf("* Usage: *\n"); nico@215: 00076 printf("* ./TestMasterSlave [OPTIONS] *\n"); nico@215: 00077 printf("* *\n"); nico@215: 00078 printf("* OPTIONS: *\n"); nico@215: 00079 printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n"); nico@215: 00080 printf("* *\n"); nico@215: 00081 printf("* Slave: *\n"); nico@215: 00082 printf("* -s : bus name [\"0\"] *\n"); nico@215: 00083 printf("* -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); nico@215: 00084 printf("* *\n"); nico@215: 00085 printf("* Master: *\n"); nico@215: 00086 printf("* -m : bus name [\"1\"] *\n"); nico@215: 00087 printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); nico@215: 00088 printf("* *\n"); nico@215: 00089 printf("**************************************************************\n"); nico@215: 00090 } nico@215: 00091 nico@215: 00092 /*************************** INIT *****************************************/ nico@215: 00093 void InitNodes(CO_Data* d, UNS32 id) nico@215: 00094 { nico@215: 00095 /****************************** INITIALISATION SLAVE *******************************/ nico@215: 00096 if(strcmp(SlaveBoard.baudrate, "none")) { nico@215: 00097 /* Defining the node Id */ nico@215: 00098 setNodeId(&TestSlave_Data, 0x02); nico@215: 00099 /* init */ nico@215: 00100 setState(&TestSlave_Data, Initialisation); nico@215: 00101 } nico@215: 00102 nico@215: 00103 /****************************** INITIALISATION MASTER *******************************/ nico@215: 00104 if(strcmp(MasterBoard.baudrate, "none")){ nico@215: 00105 RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update); nico@215: 00106 nico@215: 00107 /* Defining the node Id */ nico@215: 00108 setNodeId(&TestMaster_Data, 0x01); nico@215: 00109 nico@215: 00110 /* init */ nico@215: 00111 setState(&TestMaster_Data, Initialisation); nico@215: 00112 nico@215: 00113 } nico@215: 00114 } nico@215: 00115 nico@215: 00116 /****************************************************************************/ nico@215: 00117 /*************************** MAIN *****************************************/ nico@215: 00118 /****************************************************************************/ nico@215: 00119 int main(int argc,char **argv) nico@215: 00120 { nico@215: 00121 nico@215: 00122 int c; nico@215: 00123 extern char *optarg; nico@215: 00124 char* LibraryPath="libcanfestival_can_virtual.so"; nico@215: 00125 nico@215: 00126 while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF) nico@215: 00127 { nico@215: 00128 switch(c) nico@215: 00129 { nico@215: 00130 case 's' : nico@215: 00131 if (optarg[0] == 0) nico@215: 00132 { nico@215: 00133 help(); nico@215: 00134 exit(1); nico@215: 00135 } nico@215: 00136 SlaveBoard.busname = optarg; nico@215: 00137 break; nico@215: 00138 case 'm' : nico@215: 00139 if (optarg[0] == 0) nico@215: 00140 { nico@215: 00141 help(); nico@215: 00142 exit(1); nico@215: 00143 } nico@215: 00144 MasterBoard.busname = optarg; nico@215: 00145 break; nico@215: 00146 case 'S' : nico@215: 00147 if (optarg[0] == 0) nico@215: 00148 { nico@215: 00149 help(); nico@215: 00150 exit(1); nico@215: 00151 } nico@215: 00152 SlaveBoard.baudrate = optarg; nico@215: 00153 break; nico@215: 00154 case 'M' : nico@215: 00155 if (optarg[0] == 0) nico@215: 00156 { nico@215: 00157 help(); nico@215: 00158 exit(1); nico@215: 00159 } nico@215: 00160 MasterBoard.baudrate = optarg; nico@215: 00161 break; nico@215: 00162 case 'l' : nico@215: 00163 if (optarg[0] == 0) nico@215: 00164 { nico@215: 00165 help(); nico@215: 00166 exit(1); nico@215: 00167 } nico@215: 00168 LibraryPath = optarg; nico@215: 00169 break; nico@215: 00170 default: nico@215: 00171 help(); nico@215: 00172 exit(1); nico@215: 00173 } nico@215: 00174 } nico@215: 00175 nico@215: 00176 #if !defined(WIN32) || defined(__CYGWIN__) nico@215: 00177 /* install signal handler for manual break */ nico@215: 00178 signal(SIGTERM, catch_signal); nico@215: 00179 signal(SIGINT, catch_signal); nico@215: 00180 #endif nico@215: 00181 nico@215: 00182 #ifndef NOT_USE_DYNAMIC_LOADING nico@215: 00183 LoadCanDriver(LibraryPath); nico@215: 00184 #endif nico@215: 00185 // Open CAN devices nico@215: 00186 nico@215: 00187 if(strcmp(SlaveBoard.baudrate, "none")){ nico@215: 00188 nico@215: 00189 TestSlave_Data.heartbeatError = TestSlave_heartbeatError; nico@215: 00190 TestSlave_Data.initialisation = TestSlave_initialisation; nico@215: 00191 TestSlave_Data.preOperational = TestSlave_preOperational; nico@215: 00192 TestSlave_Data.operational = TestSlave_operational; nico@215: 00193 TestSlave_Data.stopped = TestSlave_stopped; nico@215: 00194 TestSlave_Data.post_sync = TestSlave_post_sync; nico@215: 00195 TestSlave_Data.post_TPDO = TestSlave_post_TPDO; nico@215: 00196 TestSlave_Data.storeODSubIndex = TestSlave_storeODSubIndex; nico@215: 00197 nico@215: 00198 if(!canOpen(&SlaveBoard,&TestSlave_Data)){ nico@215: 00199 eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate); nico@215: 00200 goto fail_slave; nico@215: 00201 } nico@215: 00202 } nico@215: 00203 if(strcmp(MasterBoard.baudrate, "none")){ nico@215: 00204 nico@215: 00205 TestMaster_Data.heartbeatError = TestMaster_heartbeatError; nico@215: 00206 TestMaster_Data.initialisation = TestMaster_initialisation; nico@215: 00207 TestMaster_Data.preOperational = TestMaster_preOperational; nico@215: 00208 TestMaster_Data.operational = TestMaster_operational; nico@215: 00209 TestMaster_Data.stopped = TestMaster_stopped; nico@215: 00210 TestMaster_Data.post_sync = TestMaster_post_sync; nico@215: 00211 TestMaster_Data.post_TPDO = TestMaster_post_TPDO; nico@215: 00212 nico@215: 00213 if(!canOpen(&MasterBoard,&TestMaster_Data)){ nico@215: 00214 eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate); nico@215: 00215 goto fail_master; nico@215: 00216 } nico@215: 00217 } nico@215: 00218 nico@215: 00219 // Start timer thread nico@215: 00220 StartTimerLoop(&InitNodes); nico@215: 00221 nico@215: 00222 // wait Ctrl-C nico@215: 00223 nico@215: 00224 pause(); nico@215: 00225 eprintf("Finishing.\n"); nico@215: 00226 nico@215: 00227 masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Reset_Node); nico@215: 00228 eprintf("reset\n"); nico@215: 00229 // Stop master nico@215: 00230 setState(&TestMaster_Data, Stopped); nico@215: 00231 nico@215: 00232 // Stop timer thread nico@215: 00233 StopTimerLoop(); nico@215: 00234 nico@215: 00235 // Close CAN devices (and can threads) nico@215: 00236 if(strcmp(SlaveBoard.baudrate, "none")) canClose(&TestSlave_Data); nico@215: 00237 fail_master: nico@215: 00238 if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data); nico@215: 00239 fail_slave: nico@215: 00240 return 0; nico@215: 00241 } nico@215: