groke6@381: /* groke6@381: This file is part of CanFestival, a library implementing CanOpen Stack. groke6@381: groke6@381: Copyright (C): Edouard TISSERANT and Francis DUPIN groke6@381: groke6@381: See COPYING file for copyrights details. groke6@381: groke6@381: This library is free software; you can redistribute it and/or groke6@381: modify it under the terms of the GNU Lesser General Public groke6@381: License as published by the Free Software Foundation; either groke6@381: version 2.1 of the License, or (at your option) any later version. groke6@381: groke6@381: This library is distributed in the hope that it will be useful, groke6@381: but WITHOUT ANY WARRANTY; without even the implied warranty of groke6@381: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU groke6@381: Lesser General Public License for more details. groke6@381: groke6@381: You should have received a copy of the GNU Lesser General Public groke6@381: License along with this library; if not, write to the Free Software groke6@381: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA groke6@381: */ groke6@381: groke6@381: #if defined(WIN32) && !defined(__CYGWIN__) groke6@381: #include groke6@381: #include "getopt.h" groke6@381: void pause(void) groke6@381: { groke6@381: system("PAUSE"); groke6@381: } groke6@381: #else groke6@381: #include groke6@381: #include groke6@381: #include groke6@381: #include groke6@381: #include groke6@381: #endif groke6@381: groke6@381: #include "canfestival.h" groke6@381: //#include groke6@381: //#include groke6@381: groke6@381: #include "Master.h" groke6@381: #include "SlaveA.h" groke6@381: #include "SlaveB.h" groke6@381: #include "TestMasterSlaveLSS.h" groke6@381: groke6@381: s_BOARD SlaveBoardA = {"0", "125K"}; groke6@381: s_BOARD SlaveBoardB = {"1", "125K"}; groke6@381: s_BOARD MasterBoard = {"2", "125K"}; groke6@381: groke6@381: #if !defined(WIN32) || defined(__CYGWIN__) groke6@381: void catch_signal(int sig) groke6@381: { groke6@381: signal(SIGTERM, catch_signal); groke6@381: signal(SIGINT, catch_signal); groke6@381: eprintf("Got Signal %d\n",sig); groke6@381: } groke6@381: #endif groke6@381: greg@454: void help(void) groke6@381: { groke6@381: printf("**************************************************************\n"); groke6@387: printf("* TestMasterSlaveLSS *\n"); groke6@387: printf("* *\n"); groke6@387: printf("* A LSS example for PC. It does implement 3 CanOpen *\n"); groke6@387: printf("* nodes in the same process. A master and 2 slaves. All *\n"); groke6@381: printf("* communicate together, exchanging periodically NMT, SYNC, *\n"); groke6@381: printf("* SDO and PDO. Master configure heartbeat producer time *\n"); groke6@517: printf("* at 1000 ms for the slaves by concise DCF. *\n"); groke6@381: printf("* *\n"); groke6@381: printf("* Usage: *\n"); groke6@387: printf("* ./TestMasterSlaveLSS [OPTIONS] *\n"); groke6@381: printf("* *\n"); groke6@381: printf("* OPTIONS: *\n"); groke6@517: printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n"); groke6@387: printf("* *\n"); groke6@387: printf("* SlaveA: *\n"); groke6@517: printf("* -a : bus name [\"0\"] *\n"); groke6@387: printf("* -A : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); groke6@387: printf("* *\n"); groke6@517: printf("* SlaveB: *\n"); groke6@517: printf("* -b : bus name [\"1\"] *\n"); groke6@387: printf("* -B : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); groke6@381: printf("* *\n"); groke6@381: printf("* Master: *\n"); groke6@517: printf("* -m : bus name [\"2\"] *\n"); groke6@381: printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); groke6@381: printf("* *\n"); groke6@381: printf("**************************************************************\n"); groke6@381: } groke6@381: groke6@381: /*************************** INIT *****************************************/ groke6@381: void InitNodes(CO_Data* d, UNS32 id) groke6@381: { groke6@381: /****************************** INITIALISATION SLAVE_A *******************************/ groke6@381: if(strcmp(SlaveBoardA.baudrate, "none")) { groke6@381: /* Set an invalid nodeID */ groke6@381: setNodeId(&TestSlaveA_Data, 0xFF); groke6@381: groke6@381: /* init */ groke6@381: setState(&TestSlaveA_Data, Initialisation); groke6@381: } groke6@381: groke6@381: /****************************** INITIALISATION SLAVE_B *******************************/ groke6@381: if(strcmp(SlaveBoardB.baudrate, "none")) { groke6@381: groke6@381: /* Set an invalid nodeID */ groke6@381: setNodeId(&TestSlaveB_Data, 0xFF); groke6@381: groke6@381: /* init */ groke6@381: setState(&TestSlaveB_Data, Initialisation); groke6@381: } groke6@381: groke6@381: /****************************** INITIALISATION MASTER *******************************/ groke6@381: if(strcmp(MasterBoard.baudrate, "none")){ groke6@381: groke6@381: /* Defining the node Id */ groke6@381: setNodeId(&TestMaster_Data, 0x01); groke6@381: groke6@381: /* init */ groke6@381: setState(&TestMaster_Data, Initialisation); groke6@381: } groke6@381: } groke6@381: greg@454: /*************************** EXIT *****************************************/ greg@454: void Exit(CO_Data* d, UNS32 id) greg@454: { greg@465: if(strcmp(MasterBoard.baudrate, "none")){ greg@454: eprintf("Finishing.\n"); greg@454: masterSendNMTstateChange (&TestMaster_Data, 0x00, NMT_Stop_Node); greg@454: greg@454: eprintf("reset\n"); greg@454: greg@454: // Stop master greg@454: setState(&TestMaster_Data, Stopped); greg@465: } greg@454: } greg@454: groke6@381: /****************************************************************************/ groke6@381: /*************************** MAIN *****************************************/ groke6@381: /****************************************************************************/ groke6@381: int main(int argc,char **argv) groke6@381: { groke6@381: groke6@381: int c; groke6@381: extern char *optarg; groke6@381: char* LibraryPath="../../drivers/can_virtual/libcanfestival_can_virtual.so"; groke6@381: groke6@387: while ((c = getopt(argc, argv, "-m:a:b:M:A:B:l:")) != EOF) groke6@381: { groke6@381: switch(c) groke6@381: { groke6@387: case 'a' : groke6@381: if (optarg[0] == 0) groke6@381: { groke6@381: help(); groke6@381: exit(1); groke6@381: } groke6@381: SlaveBoardA.busname = optarg; groke6@381: break; groke6@387: case 'b' : groke6@387: if (optarg[0] == 0) groke6@387: { groke6@387: help(); groke6@387: exit(1); groke6@387: } groke6@387: SlaveBoardB.busname = optarg; groke6@387: break; groke6@381: case 'm' : groke6@381: if (optarg[0] == 0) groke6@381: { groke6@381: help(); groke6@381: exit(1); groke6@381: } groke6@381: MasterBoard.busname = optarg; groke6@381: break; groke6@387: case 'A' : groke6@381: if (optarg[0] == 0) groke6@381: { groke6@381: help(); groke6@381: exit(1); groke6@381: } groke6@381: SlaveBoardA.baudrate = optarg; groke6@381: break; groke6@387: case 'B' : groke6@387: if (optarg[0] == 0) groke6@387: { groke6@387: help(); groke6@387: exit(1); groke6@387: } groke6@387: SlaveBoardB.baudrate = optarg; groke6@387: break; groke6@381: case 'M' : groke6@381: if (optarg[0] == 0) groke6@381: { groke6@381: help(); groke6@381: exit(1); groke6@381: } groke6@381: MasterBoard.baudrate = optarg; groke6@381: break; groke6@381: case 'l' : groke6@381: if (optarg[0] == 0) groke6@381: { groke6@381: help(); groke6@381: exit(1); groke6@381: } groke6@381: LibraryPath = optarg; groke6@381: break; groke6@381: default: groke6@381: help(); groke6@381: exit(1); groke6@381: } groke6@381: } groke6@381: groke6@381: #if !defined(WIN32) || defined(__CYGWIN__) groke6@381: /* install signal handler for manual break */ groke6@381: signal(SIGTERM, catch_signal); groke6@381: signal(SIGINT, catch_signal); greg@454: TimerInit(); groke6@381: #endif groke6@381: groke6@381: #ifndef NOT_USE_DYNAMIC_LOADING groke6@381: if (LoadCanDriver(LibraryPath) == NULL) groke6@381: printf("Unable to load library: %s\n",LibraryPath); groke6@381: #endif groke6@381: // Open CAN devices groke6@381: groke6@381: if(strcmp(SlaveBoardA.baudrate, "none")){ groke6@381: groke6@381: TestSlaveA_Data.heartbeatError = TestSlaveA_heartbeatError; groke6@381: TestSlaveA_Data.initialisation = TestSlaveA_initialisation; groke6@381: TestSlaveA_Data.preOperational = TestSlaveA_preOperational; groke6@381: TestSlaveA_Data.operational = TestSlaveA_operational; groke6@381: TestSlaveA_Data.stopped = TestSlaveA_stopped; groke6@381: TestSlaveA_Data.post_sync = TestSlaveA_post_sync; groke6@381: TestSlaveA_Data.post_TPDO = TestSlaveA_post_TPDO; groke6@381: TestSlaveA_Data.storeODSubIndex = TestSlaveA_storeODSubIndex; groke6@381: TestSlaveA_Data.post_emcy = TestSlaveA_post_emcy; groke6@517: /* in this example the slave doesn't implement NMT_Slave_Communications_Reset_Callback */ groke6@517: //TestSlaveA_Data.NMT_Slave_Communications_Reset_Callback = TestSlaveA_NMT_Slave_Communications_Reset_Callback; groke6@381: TestSlaveA_Data.lss_StoreConfiguration = TestSlaveA_StoreConfiguration; groke6@381: groke6@381: if(!canOpen(&SlaveBoardA,&TestSlaveA_Data)){ groke6@381: eprintf("Cannot open SlaveA Board (%s,%s)\n",SlaveBoardA.busname, SlaveBoardA.baudrate); groke6@381: goto fail_slaveA; groke6@381: } groke6@381: } groke6@381: groke6@381: if(strcmp(SlaveBoardB.baudrate, "none")){ groke6@381: groke6@381: TestSlaveB_Data.heartbeatError = TestSlaveB_heartbeatError; groke6@381: TestSlaveB_Data.initialisation = TestSlaveB_initialisation; groke6@381: TestSlaveB_Data.preOperational = TestSlaveB_preOperational; groke6@381: TestSlaveB_Data.operational = TestSlaveB_operational; groke6@381: TestSlaveB_Data.stopped = TestSlaveB_stopped; groke6@381: TestSlaveB_Data.post_sync = TestSlaveB_post_sync; groke6@381: TestSlaveB_Data.post_TPDO = TestSlaveB_post_TPDO; groke6@381: TestSlaveB_Data.storeODSubIndex = TestSlaveB_storeODSubIndex; groke6@381: TestSlaveB_Data.post_emcy = TestSlaveB_post_emcy; groke6@517: TestSlaveB_Data.NMT_Slave_Communications_Reset_Callback = TestSlaveB_NMT_Slave_Communications_Reset_Callback; groke6@381: TestSlaveB_Data.lss_StoreConfiguration = TestSlaveB_StoreConfiguration; groke6@381: groke6@381: if(!canOpen(&SlaveBoardB,&TestSlaveB_Data)){ groke6@381: eprintf("Cannot open SlaveB Board (%s,%s)\n",SlaveBoardB.busname, SlaveBoardB.baudrate); groke6@381: goto fail_slaveB; groke6@381: } groke6@381: } groke6@381: groke6@381: if(strcmp(MasterBoard.baudrate, "none")){ groke6@381: groke6@381: TestMaster_Data.heartbeatError = TestMaster_heartbeatError; groke6@381: TestMaster_Data.initialisation = TestMaster_initialisation; groke6@381: TestMaster_Data.preOperational = TestMaster_preOperational; groke6@381: TestMaster_Data.operational = TestMaster_operational; groke6@381: TestMaster_Data.stopped = TestMaster_stopped; groke6@381: TestMaster_Data.post_sync = TestMaster_post_sync; groke6@381: TestMaster_Data.post_TPDO = TestMaster_post_TPDO; groke6@381: TestMaster_Data.post_emcy = TestMaster_post_emcy; groke6@381: TestMaster_Data.post_SlaveBootup=TestMaster_post_SlaveBootup; groke6@381: groke6@381: if(!canOpen(&MasterBoard,&TestMaster_Data)){ groke6@381: eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate); groke6@381: goto fail_master; groke6@381: } groke6@381: } groke6@381: groke6@381: // Start timer thread groke6@381: StartTimerLoop(&InitNodes); groke6@381: groke6@381: // wait Ctrl-C groke6@381: groke6@381: pause(); groke6@381: groke6@381: // Stop timer thread greg@454: StopTimerLoop(&Exit); groke6@381: groke6@381: // Close CAN devices (and can threads) groke6@381: if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data); groke6@381: fail_master: groke6@381: if(strcmp(SlaveBoardB.baudrate, "none")) canClose(&TestSlaveB_Data); groke6@381: fail_slaveB: groke6@381: if(strcmp(SlaveBoardA.baudrate, "none")) canClose(&TestSlaveA_Data); groke6@381: fail_slaveA: greg@454: TimerCleanup(); groke6@381: return 0; groke6@381: }