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@145: //#include etisserant@145: //#include etisserant@0: #include etisserant@0: #include etisserant@145: #endif etisserant@0: etisserant@0: #include etisserant@0: #include etisserant@0: #include etisserant@0: etisserant@0: #include "Master.h" etisserant@0: #include "Slave.h" etisserant@0: #include "TestMasterSlave.h" etisserant@0: etisserant@0: #define MyCase(fc) case fc: eprintf(#fc);break; etisserant@0: void print_message(Message *m) etisserant@0: { etisserant@0: int i; etisserant@0: switch(m->cob_id.w >> 7) etisserant@0: { etisserant@0: MyCase(SYNC) etisserant@0: MyCase(TIME_STAMP) etisserant@0: MyCase(PDO1tx) etisserant@0: MyCase(PDO1rx) etisserant@0: MyCase(PDO2tx) etisserant@0: MyCase(PDO2rx) etisserant@0: MyCase(PDO3tx) etisserant@0: MyCase(PDO3rx) etisserant@0: MyCase(PDO4tx) etisserant@0: MyCase(PDO4rx) etisserant@0: MyCase(SDOtx) etisserant@0: MyCase(SDOrx) etisserant@0: MyCase(NODE_GUARD) etisserant@0: MyCase(NMT) etisserant@0: } etisserant@0: eprintf(" rtr:%d", m->rtr); etisserant@0: eprintf(" len:%d", m->len); etisserant@0: for (i = 0 ; i < m->len ; i++) etisserant@0: eprintf(" %02x", m->data[i]); etisserant@0: eprintf("\n"); etisserant@0: } etisserant@0: etisserant@0: UNS32 OnMasterMap1Update(CO_Data* d, const indextable * unsused_indextable, UNS8 unsused_bSubindex) etisserant@0: { etisserant@0: eprintf("OnSlaveMap1Update:%d\n", SlaveMap1); lbessard@31: return 0; etisserant@0: } etisserant@0: etisserant@145: s_BOARD SlaveBoard = {"0", "500K"}; etisserant@145: s_BOARD MasterBoard = {"1", "500K"}; 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: etisserant@0: void help() 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"); etisserant@36: printf("* SDO and PDO. *\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 *******************************/ etisserant@36: if(SlaveBoard.baudrate) { etisserant@36: /* Defining the node Id */ etisserant@36: setNodeId(&TestSlave_Data, 0x02); etisserant@36: /* init */ etisserant@36: setState(&TestSlave_Data, Initialisation); etisserant@36: } etisserant@36: etisserant@36: /****************************** INITIALISATION MASTER *******************************/ etisserant@36: if(MasterBoard.baudrate){ etisserant@36: RegisterSetODentryCallBack(&TestMaster_Data, 0x2000, 0, &OnMasterMap1Update); etisserant@36: etisserant@36: /* Defining the node Id */ etisserant@36: setNodeId(&TestMaster_Data, 0x01); etisserant@36: etisserant@36: /* init */ etisserant@36: setState(&TestMaster_Data, Initialisation); etisserant@36: etisserant@36: /****************************** START *******************************/ etisserant@36: /* Put the master in operational mode */ etisserant@36: setState(&TestMaster_Data, Operational); etisserant@36: etisserant@36: /* Ask slave node to go in operational mode */ etisserant@36: masterSendNMTstateChange (&TestMaster_Data, 0x02, NMT_Start_Node); etisserant@36: } etisserant@36: } etisserant@36: etisserant@0: /****************************************************************************/ etisserant@0: /*************************** MAIN *****************************************/ etisserant@0: /****************************************************************************/ etisserant@0: int main(int argc,char **argv) etisserant@0: { etisserant@0: etisserant@0: char c; etisserant@0: extern char *optarg; etisserant@145: char* LibraryPath="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); etisserant@145: #endif etisserant@145: etisserant@145: #ifndef NOT_USE_DYNAMIC_LOADING etisserant@145: LoadCanDriver(LibraryPath); etisserant@145: #endif etisserant@0: // Open CAN devices etisserant@145: if(SlaveBoard.baudrate){ etisserant@149: etisserant@149: TestSlave_Data.heartbeatError = TestSlave_heartbeatError; etisserant@149: TestSlave_Data.SDOtimeoutError = TestSlave_SDOtimeoutError; 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; 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: } etisserant@145: etisserant@145: if(MasterBoard.baudrate){ etisserant@149: etisserant@149: TestMaster_Data.heartbeatError = TestMaster_heartbeatError; etisserant@149: TestMaster_Data.SDOtimeoutError = TestMaster_SDOtimeoutError; 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; etisserant@149: etisserant@149: if(!canOpen(&MasterBoard,&TestMaster_Data)){ etisserant@145: eprintf("Cannot open Master Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate); etisserant@145: goto fail_master; etisserant@145: } etisserant@145: } etisserant@0: etisserant@32: // Start timer thread etisserant@32: StartTimerLoop(&InitNodes); etisserant@32: etisserant@32: // wait Ctrl-C etisserant@32: pause(); etisserant@32: eprintf("Finishing.\n"); etisserant@32: etisserant@32: // Stop timer thread etisserant@32: StopTimerLoop(); etisserant@32: etisserant@32: // Close CAN devices (and can threads) etisserant@149: if(SlaveBoard.baudrate) canClose(&TestSlave_Data); etisserant@36: fail_master: etisserant@149: if(MasterBoard.baudrate) canClose(&TestMaster_Data); etisserant@36: fail_slave: etisserant@0: etisserant@0: etisserant@0: return 0; etisserant@0: }