etisserant@0: /* etisserant@0: This file is part of CanFestival, a library implementing CanOpen Stack. etisserant@0: etisserant@0: Copyright (C): Edouard TISSERANT and Francis DUPIN etisserant@0: etisserant@0: See COPYING file for copyrights details. etisserant@0: etisserant@0: This library is free software; you can redistribute it and/or etisserant@0: modify it under the terms of the GNU Lesser General Public etisserant@0: License as published by the Free Software Foundation; either etisserant@0: version 2.1 of the License, or (at your option) any later version. etisserant@0: etisserant@0: This library is distributed in the hope that it will be useful, etisserant@0: but WITHOUT ANY WARRANTY; without even the implied warranty of etisserant@0: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU etisserant@0: Lesser General Public License for more details. etisserant@0: etisserant@0: You should have received a copy of the GNU Lesser General Public etisserant@0: License along with this library; if not, write to the Free Software etisserant@0: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA etisserant@0: */ etisserant@0: etisserant@145: #if defined(WIN32) && !defined(__CYGWIN__) etisserant@145: #include etisserant@145: #include "getopt.h" etisserant@145: void pause(void) etisserant@145: { etisserant@145: system("PAUSE"); etisserant@145: } etisserant@145: #else etisserant@0: #include etisserant@0: #include etisserant@169: #include etisserant@0: #include etisserant@0: #include etisserant@145: #endif etisserant@0: etisserant@156: #include "canfestival.h" etisserant@156: //#include etisserant@156: //#include etisserant@0: etisserant@0: #include "Master.h" etisserant@0: #include "Slave.h" etisserant@0: #include "TestMasterSlave.h" etisserant@0: etisserant@0: UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) etisserant@0: { greg@466: eprintf("OnMasterMap1Update:%d\n", MasterMap1); lbessard@31: return 0; etisserant@0: } etisserant@0: greg@179: s_BOARD SlaveBoard = {"0", "125K"}; greg@179: s_BOARD MasterBoard = {"1", "125K"}; etisserant@145: etisserant@145: #if !defined(WIN32) || defined(__CYGWIN__) etisserant@0: void catch_signal(int sig) etisserant@0: { etisserant@0: signal(SIGTERM, catch_signal); etisserant@0: signal(SIGINT, catch_signal); etisserant@32: eprintf("Got Signal %d\n",sig); etisserant@32: } etisserant@145: #endif etisserant@0: greg@454: void help(void) etisserant@0: { etisserant@0: printf("**************************************************************\n"); etisserant@0: printf("* TestMasterSlave *\n"); etisserant@0: printf("* *\n"); etisserant@0: printf("* A simple example for PC. It does implement 2 CanOpen *\n"); etisserant@0: printf("* nodes in the same process. A master and a slave. Both *\n"); etisserant@36: printf("* communicate together, exchanging periodically NMT, SYNC, *\n"); greg@179: printf("* SDO and PDO. Master configure heartbeat producer time *\n"); greg@179: printf("* at 1000 ms for slave node-id 0x02 by concise DCF. *\n"); etisserant@36: printf("* *\n"); etisserant@36: printf("* Usage: *\n"); etisserant@36: printf("* ./TestMasterSlave [OPTIONS] *\n"); etisserant@36: printf("* *\n"); etisserant@36: printf("* OPTIONS: *\n"); etisserant@145: printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n"); etisserant@145: printf("* *\n"); etisserant@36: printf("* Slave: *\n"); etisserant@36: printf("* -s : bus name [\"0\"] *\n"); etisserant@36: printf("* -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); etisserant@36: printf("* *\n"); etisserant@36: printf("* Master: *\n"); etisserant@36: printf("* -m : bus name [\"1\"] *\n"); etisserant@36: printf("* -M : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n"); etisserant@0: printf("* *\n"); etisserant@0: printf("**************************************************************\n"); etisserant@0: } etisserant@0: etisserant@36: /*************************** INIT *****************************************/ etisserant@36: void InitNodes(CO_Data* d, UNS32 id) etisserant@36: { etisserant@36: /****************************** INITIALISATION SLAVE *******************************/ greg@179: if(strcmp(SlaveBoard.baudrate, "none")) { etisserant@36: setNodeId(&TestSlave_Data, 0x02); etisserant@343: etisserant@36: /* init */ etisserant@36: setState(&TestSlave_Data, Initialisation); etisserant@36: } etisserant@36: etisserant@36: /****************************** INITIALISATION MASTER *******************************/ greg@179: if(strcmp(MasterBoard.baudrate, "none")){ etisserant@36: RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update); greg@179: etisserant@36: /* Defining the node Id */ etisserant@36: setNodeId(&TestMaster_Data, 0x01); etisserant@36: etisserant@36: /* init */ etisserant@36: setState(&TestMaster_Data, Initialisation); greg@179: etisserant@36: } etisserant@36: } etisserant@36: greg@454: /*************************** EXIT *****************************************/ greg@454: void Exit(CO_Data* d, UNS32 id) greg@454: { greg@465: if(strcmp(MasterBoard.baudrate, "none")){ greg@465: greg@465: masterSendNMTstateChange(&TestMaster_Data, 0x02, NMT_Reset_Node); greg@454: greg@465: //Stop master greg@465: setState(&TestMaster_Data, Stopped); greg@465: } greg@454: } greg@454: etisserant@0: /****************************************************************************/ etisserant@0: /*************************** MAIN *****************************************/ etisserant@0: /****************************************************************************/ etisserant@0: int main(int argc,char **argv) etisserant@0: { etisserant@0: etisserant@191: int c; etisserant@0: extern char *optarg; etisserant@343: char* LibraryPath="../../drivers/can_virtual/libcanfestival_can_virtual.so"; etisserant@145: etisserant@145: while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF) etisserant@0: { etisserant@0: switch(c) etisserant@0: { etisserant@0: case 's' : etisserant@0: if (optarg[0] == 0) etisserant@0: { etisserant@0: help(); etisserant@0: exit(1); etisserant@0: } etisserant@0: SlaveBoard.busname = optarg; etisserant@0: break; etisserant@0: case 'm' : etisserant@0: if (optarg[0] == 0) etisserant@0: { etisserant@0: help(); etisserant@0: exit(1); etisserant@0: } etisserant@0: MasterBoard.busname = optarg; etisserant@0: break; etisserant@36: case 'S' : etisserant@36: if (optarg[0] == 0) etisserant@36: { etisserant@36: help(); etisserant@36: exit(1); etisserant@36: } etisserant@145: SlaveBoard.baudrate = optarg; etisserant@36: break; etisserant@36: case 'M' : etisserant@36: if (optarg[0] == 0) etisserant@36: { etisserant@36: help(); etisserant@36: exit(1); etisserant@36: } etisserant@145: MasterBoard.baudrate = optarg; etisserant@145: break; etisserant@145: case 'l' : etisserant@145: if (optarg[0] == 0) etisserant@145: { etisserant@145: help(); etisserant@145: exit(1); etisserant@145: } etisserant@145: LibraryPath = optarg; etisserant@36: break; etisserant@0: default: etisserant@0: help(); etisserant@0: exit(1); etisserant@0: } etisserant@0: } etisserant@0: etisserant@145: #if !defined(WIN32) || defined(__CYGWIN__) etisserant@145: /* install signal handler for manual break */ etisserant@0: signal(SIGTERM, catch_signal); etisserant@0: signal(SIGINT, catch_signal); edouard@629: #endif edouard@629: // Also Windows needs to initialize the Timer! edouard@629: // Moving this line into the ifndef leads to a lethal crash! greg@454: TimerInit(); etisserant@145: etisserant@145: #ifndef NOT_USE_DYNAMIC_LOADING etisserant@331: if (LoadCanDriver(LibraryPath) == NULL) etisserant@331: printf("Unable to load library: %s\n",LibraryPath); etisserant@145: #endif etisserant@0: // Open CAN devices greg@179: greg@179: if(strcmp(SlaveBoard.baudrate, "none")){ etisserant@149: etisserant@149: TestSlave_Data.heartbeatError = TestSlave_heartbeatError; etisserant@149: TestSlave_Data.initialisation = TestSlave_initialisation; etisserant@149: TestSlave_Data.preOperational = TestSlave_preOperational; etisserant@149: TestSlave_Data.operational = TestSlave_operational; etisserant@149: TestSlave_Data.stopped = TestSlave_stopped; etisserant@149: TestSlave_Data.post_sync = TestSlave_post_sync; etisserant@149: TestSlave_Data.post_TPDO = TestSlave_post_TPDO; luis@284: TestSlave_Data.storeODSubIndex = TestSlave_storeODSubIndex; luis@284: TestSlave_Data.post_emcy = TestSlave_post_emcy; etisserant@149: etisserant@149: if(!canOpen(&SlaveBoard,&TestSlave_Data)){ etisserant@145: eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate); etisserant@145: goto fail_slave; etisserant@145: } etisserant@145: } greg@179: if(strcmp(MasterBoard.baudrate, "none")){ etisserant@149: etisserant@149: TestMaster_Data.heartbeatError = TestMaster_heartbeatError; etisserant@149: TestMaster_Data.initialisation = TestMaster_initialisation; etisserant@149: TestMaster_Data.preOperational = TestMaster_preOperational; etisserant@149: TestMaster_Data.operational = TestMaster_operational; etisserant@149: TestMaster_Data.stopped = TestMaster_stopped; etisserant@149: TestMaster_Data.post_sync = TestMaster_post_sync; etisserant@149: TestMaster_Data.post_TPDO = TestMaster_post_TPDO; luis@284: TestMaster_Data.post_emcy = TestMaster_post_emcy; etisserant@343: TestMaster_Data.post_SlaveBootup=TestMaster_post_SlaveBootup; etisserant@149: etisserant@149: if(!canOpen(&MasterBoard,&TestMaster_Data)){ greg@179: eprintf("Cannot open Master Board (%s,%s)\n",MasterBoard.busname, MasterBoard.baudrate); etisserant@145: goto fail_master; etisserant@145: } etisserant@145: } etisserant@194: etisserant@32: // Start timer thread etisserant@32: StartTimerLoop(&InitNodes); etisserant@32: etisserant@32: // wait Ctrl-C etisserant@32: pause(); etisserant@262: etisserant@32: // Stop timer thread greg@454: StopTimerLoop(&Exit); etisserant@32: etisserant@32: // Close CAN devices (and can threads) greg@454: if(strcmp(MasterBoard.baudrate, "none")) canClose(&TestMaster_Data); greg@454: fail_master: greg@179: if(strcmp(SlaveBoard.baudrate, "none")) canClose(&TestSlave_Data); etisserant@36: fail_slave: greg@454: TimerCleanup(); greg@179: return 0; greg@179: }