# HG changeset patch # User etisserant # Date 1150836217 -7200 # Node ID 9b5bb1dcb4f514c16d4aca2188b953e8e7f25084 # Parent c6ff23a48232f189786f1ae465c055d14fd1cae8 Cygwin port. Still untested. Compiles and link. diff -r c6ff23a48232 -r 9b5bb1dcb4f5 configure --- a/configure Tue Jun 20 19:02:43 2006 +0200 +++ b/configure Tue Jun 20 22:43:37 2006 +0200 @@ -345,8 +345,8 @@ # If target not specified, try to gess one if [ "$SUB_TARGET" = "" ]; then if [ "$SUB_OS_NAME" = "CYGWIN" ]; then - echo "Choosing win32 target" - SUB_TARGET=win32 + echo "Choosing unix (cygwin) target" + SUB_TARGET=unix else echo "Choosing unix target" SUB_TARGET=unix @@ -456,6 +456,17 @@ SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpcan fi +if [ "$SUB_CAN_DRIVER" = "peak_win32" ]; then + if [ "PCAN_HEADER" = "" -o "PCAN_LIB" = "" ]; then + echo "!!! ERROR !!! Please set PCAN_LIB PCAN_HEADER [PCAN_INCLUDE] to appropriate paths ! " + fi + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ \'$PCAN_LIB\' + if [ "$PCAN_INCLUDE" != "" ]; then + SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -I$PCAN_INCLUDE + fi + SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ \'-DPCAN_HEADER_=\"$PCAN_HEADER\"\' +fi + if [ "$SUB_CAN_DRIVER" = "none" ]; then SUB_CAN_DRIVER= fi @@ -463,7 +474,9 @@ #### TIMERS_DRIVER #### if [ "$SUB_TIMERS_DRIVER" = "unix" ]; then - SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpthread\ -lrt + if [ "$SUB_OS_NAME" != "CYGWIN" ]; then + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpthread\ -lrt + fi fi if [ "$SUB_TIMERS_DRIVER" = "xeno" ]; then diff -r c6ff23a48232 -r 9b5bb1dcb4f5 drivers/can_peak_win32/.cvsignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_peak_win32/.cvsignore Tue Jun 20 22:43:37 2006 +0200 @@ -0,0 +1,1 @@ +Makefile diff -r c6ff23a48232 -r 9b5bb1dcb4f5 drivers/can_peak_win32/Makefile.in --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_peak_win32/Makefile.in Tue Jun 20 22:43:37 2006 +0200 @@ -0,0 +1,59 @@ +#! gmake + +# +# Copyright (C) 2006 Laurent Bessard +# +# This file is part of canfestival, a library implementing the canopen +# stack +# +# This library is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +CC = SUB_CC +OPT_CFLAGS = -O2 +CFLAGS = SUB_OPT_CFLAGS +PROG_CFLAGS = SUB_PROG_CFLAGS +PREFIX = SUB_PREFIX +TARGET = SUB_TARGET +CAN_DRIVER = SUB_CAN_DRIVER +TIMERS_DRIVER = SUB_TIMERS_DRIVER +BINUTILS_PREFIX = SUB_BINUTILS_PREFIX + +INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER) + +OBJS = $(CAN_DRIVER).o + +SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h + +TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h + +all: driver + +driver: $(OBJS) + +%o: %c + $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $< + +install: + mkdir -p $(PREFIX)/include/canfestival + cp $(SRC_HFILES) $(PREFIX)/include/canfestival + +uninstall: + rm -f $(TARGET_HFILES) + +clean: + -\rm $(OBJS) + +mrproper: clean diff -r c6ff23a48232 -r 9b5bb1dcb4f5 drivers/can_peak_win32/can_peak_win32.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/drivers/can_peak_win32/can_peak_win32.c Tue Jun 20 22:43:37 2006 +0200 @@ -0,0 +1,166 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include +#include +#include +#include +#include /* for NULL */ +#include +#include +#include +#include +#include + +/* driver pcan pci for Peak board */ +//#include "libpcan.h" +//#include "pcan.h" + +#include +#include "timer.h" +#include "can_driver.h" +#include "timers_driver.h" + +#define MAX_NB_CAN_PORTS 1 + +typedef struct { + char used; + TASK_HANDLE receiveTask; + CO_Data* d; +} CANPort; + +CANPort canports[MAX_NB_CAN_PORTS] = {{0,},}; + +// Define for rtr CAN message +#define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR + +/*********functions which permit to communicate with the board****************/ +UNS8 canReceive(CAN_HANDLE fd0, Message *m) +{ + UNS8 data; + TPCANMsg peakMsg; + if ((errno = CAN_Read(& peakMsg))) { // Blocks until no new message or error. + perror("!!! Peak board : error of reading. (from f_can_receive function) \n"); + return 1; + } + m->cob_id.w = peakMsg.ID; + if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_*/ + m->rtr = 0; + else + m->rtr = 1; + m->len = peakMsg.LEN; /* count of data bytes (0..8) */ + for(data = 0 ; data < peakMsg.LEN ; data++) + m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */ + + return 0; +} + +void canReceiveLoop(CAN_HANDLE fd0) +{ + CO_Data* d = ((CANPort*)fd0)->d; + Message m; + while (1) { + if(!canReceive(fd0, &m)) + { + EnterMutex(); + canDispatch(d, &m); + LeaveMutex(); + }else{ +// printf("canReceive returned error\n"); + break; + } + } +} + +/***************************************************************************/ +UNS8 canSend(CAN_HANDLE fd0, Message *m) +{ + UNS8 data; + TPCANMsg peakMsg; + peakMsg.ID=m -> cob_id.w; /* 11/29 bit code */ + if(m->rtr == 0) + peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_*/ + else { + peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_*/ + } + peakMsg.LEN = m->len; + /* count of data bytes (0..8) */ + for(data = 0 ; data < m->len; data ++) + peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */ + + if((errno = CAN_Write(& peakMsg))) { + perror("!!! Peak board : error of writing. (from canSend function) \n"); + return 1; + } + return 0; + +} + +/***************************************************************************/ +CAN_HANDLE canOpen(s_BOARD *board) +{ + HANDLE fd0 = NULL; + char busname[64]; + char* pEnd; + int i; + + for(i=0; i < MAX_NB_CAN_PORTS; i++) + { + if(!canports[i].used) + break; + } + if(canports[i].used) + { + perror("can_peak_win32.c: no more can port available with this pcan library\n"); + perror("can_peak_win32.c: please link another executable with another pcan lib\n"); + return NULL; + } +// if(strtol(board->busname, &pEnd,0) >= 0) +// { +// sprintf(busname,"/dev/pcan%s",board->busname); +// fd0 = LINUX_CAN_Open(busname, O_RDWR); +// } + + if (i==MAX_NB_CAN_PORTS || fd0 == NULL) + { + fprintf (stderr, "Open failed.\n"); + return (CAN_HANDLE)NULL; + } + + CAN_Init(board->baudrate, CAN_INIT_TYPE_ST); + + canports[i].used = 1; + + canports[i].d = board->d; + CreateReceiveTask((CANPort*) &canports[i], &canports[i].receiveTask); + + return (CANPort*) &canports[i]; +} + +/***************************************************************************/ +int canClose(CAN_HANDLE fd0) +{ + CAN_Close(); + ((CANPort*)fd0)->used = 0; + WaitReceiveTaskEnd(&((CANPort*)fd0)->receiveTask); + return 0; +} diff -r c6ff23a48232 -r 9b5bb1dcb4f5 drivers/timers_unix/timers_unix.c --- a/drivers/timers_unix/timers_unix.c Tue Jun 20 19:02:43 2006 +0200 +++ b/drivers/timers_unix/timers_unix.c Tue Jun 20 22:43:37 2006 +0200 @@ -81,12 +81,12 @@ pthread_join(*Thread, NULL); } -#define max(a,b) a>b?a:b +#define maxval(a,b) a>b?a:b void setTimer(TIMEVAL value) { // printf("setTimer(TIMEVAL value=%d)\n", value); // TIMEVAL is us whereas setitimer wants ns... - long tv_nsec = 1000 * (max(value,1)%1000000); + long tv_nsec = 1000 * (maxval(value,1)%1000000); time_t tv_sec = value/1000000; struct itimerspec timerValues; timerValues.it_value.tv_sec = tv_sec; diff -r c6ff23a48232 -r 9b5bb1dcb4f5 examples/TestMasterSlave/.cvsignore --- a/examples/TestMasterSlave/.cvsignore Tue Jun 20 19:02:43 2006 +0200 +++ b/examples/TestMasterSlave/.cvsignore Tue Jun 20 22:43:37 2006 +0200 @@ -1,3 +1,4 @@ Makefile TestMasterSlave result.txt +TestMasterSlave.exe diff -r c6ff23a48232 -r 9b5bb1dcb4f5 include/can_peak_win32/cancfg.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/can_peak_win32/cancfg.h Tue Jun 20 22:43:37 2006 +0200 @@ -0,0 +1,31 @@ +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#ifndef __CANCFG_H__ +#define __CANCFG_H__ + +#include +//#include "Pcan_usb.h" +#include PCAN_HEADER_ +#define CAN_HANDLE void* + +#endif diff -r c6ff23a48232 -r 9b5bb1dcb4f5 include/timers_unix/timerscfg.h --- a/include/timers_unix/timerscfg.h Tue Jun 20 19:02:43 2006 +0200 +++ b/include/timers_unix/timerscfg.h Tue Jun 20 22:43:37 2006 +0200 @@ -28,7 +28,7 @@ // Time unit : us // Time resolution : 64bit (~584942 years) #define TIMEVAL unsigned long long -#define TIMEVAL_MAX 0xffffffffffffffff +#define TIMEVAL_MAX ~(TIMEVAL)0 #define MS_TO_TIMEVAL(ms) ms*1000 #define US_TO_TIMEVAL(us) us diff -r c6ff23a48232 -r 9b5bb1dcb4f5 src/timer.c --- a/src/timer.c Tue Jun 20 19:02:43 2006 +0200 +++ b/src/timer.c Tue Jun 20 22:43:37 2006 +0200 @@ -1,164 +1,163 @@ -/* -This file is part of CanFestival, a library implementing CanOpen Stack. - -Copyright (C): Edouard TISSERANT and Francis DUPIN - -See COPYING file for copyrights details. - -This library is free software; you can redistribute it and/or -modify it under the terms of the GNU Lesser General Public -License as published by the Free Software Foundation; either -version 2.1 of the License, or (at your option) any later version. - -This library is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -Lesser General Public License for more details. - -You should have received a copy of the GNU Lesser General Public -License along with this library; if not, write to the Free Software -Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -*/ - -//#define DEBUG_WAR_CONSOLE_ON -//#define DEBUG_ERR_CONSOLE_ON - -#include -#include "timer.h" - -// --------- The timer table --------- -s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},}; -// -TIMEVAL total_sleep_time = TIMEVAL_MAX; -TIMER_HANDLE last_timer_raw = -1; - -#define max(a,b) a>b?a:b -#define min(a,b) astate == TIMER_FREE) // and empty row - { // just store - row->callback = callback; - row->d = d; - row->id = id; - row->val = value; - row->interval = period; - row->state = TIMER_ARMED; - row_number = i; - break; - } - } - - if (row_number != TIMER_NONE) // if successfull - { - if (row_number == last_timer_raw + 1) last_timer_raw++; - - // set next wakeup alarm if new entry is sooner than others, or if it is alone - TIMEVAL real_timer_value = min(value, TIMEVAL_MAX); - TIMEVAL elapsed_time = getElapsedTime(); - - //printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); - if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) - { - total_sleep_time = elapsed_time + real_timer_value; - setTimer(real_timer_value); - } - //printf("SetAlarm() return %d\n", row_number); - return row_number; - } - return TIMER_NONE; -} - -// --------- Use this to remove an alarm --------- -TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) -{ - // Quick and dirty. system timer will continue to be trigged, but no action will be preformed. - MSG_WAR(0x3320, "DelAlarm. handle = ", handle); - if(handle != TIMER_NONE) - { - if(handle == last_timer_raw) - last_timer_raw--; - timers[handle].state = TIMER_FREE; - } - else { - } - return TIMER_NONE; -} - - -// --------- TimeDispatch is called on each timer expiration --------- -void TimeDispatch() -{ - TIMER_HANDLE i; - TIMEVAL next_wakeup = TIMEVAL_MAX; // used to compute when should normaly occur next wakeup - // First run : change timer state depending on time - // Get time since timer signal - TIMEVAL overrun = getElapsedTime(); - - TIMEVAL real_total_sleep_time = total_sleep_time + overrun; - //printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); - - for(i=0; i <= last_timer_raw; i++) - { - s_timer_entry *row = (timers+i); - - if (row->state & TIMER_ARMED) // if row is active - { - if (row->val <= real_total_sleep_time) // to be trigged - { - //printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); - if (!row->interval) // if simply outdated - { - row->state = TIMER_TRIG; // ask for trig - } - else // or period have expired - { - // set val as interval, with overrun correction - row->val = row->interval - (overrun % row->interval); - row->state = TIMER_TRIG_PERIOD; // ask for trig, periodic - // Check if this new timer value is the soonest - next_wakeup = min(row->val,next_wakeup); - } - } - else - { - // Each armed timer value in decremented. - row->val -= real_total_sleep_time; - - // Check if this new timer value is the soonest - next_wakeup = min(row->val,next_wakeup); - } - } - } - - // Remember how much time we should sleep. - total_sleep_time = next_wakeup; - - // Set timer to soonest occurence - setTimer(next_wakeup); - - // Then trig them or not. - for(i=0; i<=last_timer_raw; i++) - { - s_timer_entry *row = (timers+i); - - if (row->state & TIMER_TRIG) - { - row->state &= ~TIMER_TRIG; // reset trig state (will be free if not periodic) - (*row->callback)(row->d, row->id); // trig ! - } - } -} - +/* +This file is part of CanFestival, a library implementing CanOpen Stack. + +Copyright (C): Edouard TISSERANT and Francis DUPIN + +See COPYING file for copyrights details. + +This library is free software; you can redistribute it and/or +modify it under the terms of the GNU Lesser General Public +License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. + +This library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public +License along with this library; if not, write to the Free Software +Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +//#define DEBUG_WAR_CONSOLE_ON +//#define DEBUG_ERR_CONSOLE_ON + +#include +#include "timer.h" + +// --------- The timer table --------- +s_timer_entry timers[MAX_NB_TIMER] = {{TIMER_FREE, NULL, NULL, 0, 0, 0},}; +// +TIMEVAL total_sleep_time = TIMEVAL_MAX; +TIMER_HANDLE last_timer_raw = -1; + +#define minval(a,b) astate == TIMER_FREE) // and empty row + { // just store + row->callback = callback; + row->d = d; + row->id = id; + row->val = value; + row->interval = period; + row->state = TIMER_ARMED; + row_number = i; + break; + } + } + + if (row_number != TIMER_NONE) // if successfull + { + if (row_number == last_timer_raw + 1) last_timer_raw++; + + // set next wakeup alarm if new entry is sooner than others, or if it is alone + TIMEVAL real_timer_value = minval(value, TIMEVAL_MAX); + TIMEVAL elapsed_time = getElapsedTime(); + + //printf("elapsed_time=%d real_timer_value=%d total_sleep_time=%d\n", elapsed_time, real_timer_value, total_sleep_time); + if (total_sleep_time > elapsed_time && total_sleep_time - elapsed_time > real_timer_value) + { + total_sleep_time = elapsed_time + real_timer_value; + setTimer(real_timer_value); + } + //printf("SetAlarm() return %d\n", row_number); + return row_number; + } + return TIMER_NONE; +} + +// --------- Use this to remove an alarm --------- +TIMER_HANDLE DelAlarm(TIMER_HANDLE handle) +{ + // Quick and dirty. system timer will continue to be trigged, but no action will be preformed. + MSG_WAR(0x3320, "DelAlarm. handle = ", handle); + if(handle != TIMER_NONE) + { + if(handle == last_timer_raw) + last_timer_raw--; + timers[handle].state = TIMER_FREE; + } + else { + } + return TIMER_NONE; +} + + +// --------- TimeDispatch is called on each timer expiration --------- +void TimeDispatch() +{ + TIMER_HANDLE i; + TIMEVAL next_wakeup = TIMEVAL_MAX; // used to compute when should normaly occur next wakeup + // First run : change timer state depending on time + // Get time since timer signal + TIMEVAL overrun = getElapsedTime(); + + TIMEVAL real_total_sleep_time = total_sleep_time + overrun; + //printf("total_sleep_time %d + overrun %d\n", total_sleep_time , overrun); + + for(i=0; i <= last_timer_raw; i++) + { + s_timer_entry *row = (timers+i); + + if (row->state & TIMER_ARMED) // if row is active + { + if (row->val <= real_total_sleep_time) // to be trigged + { + //printf("row->val(%d) <= (%d)real_total_sleep_time\n", row->val, real_total_sleep_time); + if (!row->interval) // if simply outdated + { + row->state = TIMER_TRIG; // ask for trig + } + else // or period have expired + { + // set val as interval, with overrun correction + row->val = row->interval - (overrun % row->interval); + row->state = TIMER_TRIG_PERIOD; // ask for trig, periodic + // Check if this new timer value is the soonest + next_wakeup = minval(row->val,next_wakeup); + } + } + else + { + // Each armed timer value in decremented. + row->val -= real_total_sleep_time; + + // Check if this new timer value is the soonest + next_wakeup = minval(row->val,next_wakeup); + } + } + } + + // Remember how much time we should sleep. + total_sleep_time = next_wakeup; + + // Set timer to soonest occurence + setTimer(next_wakeup); + + // Then trig them or not. + for(i=0; i<=last_timer_raw; i++) + { + s_timer_entry *row = (timers+i); + + if (row->state & TIMER_TRIG) + { + row->state &= ~TIMER_TRIG; // reset trig state (will be free if not periodic) + (*row->callback)(row->d, row->id); // trig ! + } + } +} +