# HG changeset patch # User etisserant # Date 1150461863 -7200 # Node ID 8afa336923725fc9d47c120b10a427a189b87c54 # Parent a82b70738e5c16d118dc21dc137d98f5ec37e73f SDO callbacks. Removed TimerLoop. Now call StartTimerLoop (non blocking) and StopTimerLoop diff -r a82b70738e5c -r 8afa33692372 configure --- a/configure Fri Jun 16 14:24:59 2006 +0200 +++ b/configure Fri Jun 16 14:44:23 2006 +0200 @@ -453,7 +453,7 @@ if [ "$SUB_TIMERS_DRIVER" = "xeno" ]; then SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lrtdm fi - SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpcan + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpcan fi if [ "$SUB_CAN_DRIVER" = "none" ]; then @@ -463,7 +463,7 @@ #### TIMERS_DRIVER #### if [ "$SUB_TIMERS_DRIVER" = "unix" ]; then - SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpthread + SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpthread\ -lrt fi if [ "$SUB_TIMERS_DRIVER" = "xeno" ]; then diff -r a82b70738e5c -r 8afa33692372 drivers/timers_unix/timers_unix.c --- a/drivers/timers_unix/timers_unix.c Fri Jun 16 14:24:59 2006 +0200 +++ b/drivers/timers_unix/timers_unix.c Fri Jun 16 14:44:23 2006 +0200 @@ -1,8 +1,8 @@ #include #include +#include #include -#include #include "applicfg.h" #include "can_driver.h" @@ -10,31 +10,13 @@ pthread_mutex_t CanFestival_mutex = PTHREAD_MUTEX_INITIALIZER; +TASK_HANDLE TimerLoopThread; + TIMEVAL last_time_set = TIMEVAL_MAX; struct timeval last_sig; -char stop_timer=0; - -void sig(int val) -{ - signal( SIGALRM, sig); - gettimeofday(&last_sig,NULL); -// printf("getCurrentTime() return=%u\n", p.tv_usec); -} - -void initTimer(void) -{ - gettimeofday(&last_sig,NULL); - signal( SIGALRM, sig); - stop_timer = 0; -} - -void stopTimer(void) -{ - stop_timer = 1; - kill(0, SIGALRM); -} +timer_t timer; void EnterMutex(void) { @@ -46,17 +28,41 @@ pthread_mutex_unlock(&CanFestival_mutex); } -void TimerLoop(TimerCallback_t init_callback) +void timer_notify(int val) +{ + gettimeofday(&last_sig,NULL); + EnterMutex(); + TimeDispatch(); + LeaveMutex(); +// printf("getCurrentTime() return=%u\n", p.tv_usec); +} + +void initTimer(void) +{ + struct sigevent sigev; + + // Take first absolute time ref. + gettimeofday(&last_sig,NULL); + + memset (&sigev, 0, sizeof (struct sigevent)); + sigev.sigev_value.sival_int = 0; + sigev.sigev_notify = SIGEV_THREAD; + sigev.sigev_notify_attributes = NULL; + sigev.sigev_notify_function = timer_notify; + + timer_create (CLOCK_REALTIME, &sigev, &timer); +} + +void StopTimerLoop(void) +{ + timer_delete (timer); +} + +void StartTimerLoop(TimerCallback_t init_callback) { initTimer(); // At first, TimeDispatch will call init_callback. SetAlarm(NULL, 0, init_callback, 0, 0); - while (!stop_timer) { - EnterMutex(); - TimeDispatch(); - LeaveMutex(); - pause(); - } } void ReceiveLoop(void* arg) @@ -78,13 +84,16 @@ void setTimer(TIMEVAL value) { // printf("setTimer(TIMEVAL value=%d)\n", value); - struct itimerval timerValues; - struct itimerval timerV = {{0,0},{0,0}}; - timerValues.it_value.tv_sec = 0; - timerValues.it_value.tv_usec = max(value,1); + // TIMEVAL is us whereas setitimer wants ns... + long tv_nsec = 1000 * (max(value,1)%1000000); + time_t tv_sec = value/1000000; + struct itimerspec timerValues; + timerValues.it_value.tv_sec = tv_sec; + timerValues.it_value.tv_nsec = tv_nsec; timerValues.it_interval.tv_sec = 0; - timerValues.it_interval.tv_usec = 0; - setitimer(ITIMER_REAL, &timerValues, &timerV); + timerValues.it_interval.tv_nsec = 0; + + timer_settime (timer, 0, &timerValues, NULL); } TIMEVAL getElapsedTime(void) diff -r a82b70738e5c -r 8afa33692372 drivers/timers_xeno/timers_xeno.c --- a/drivers/timers_xeno/timers_xeno.c Fri Jun 16 14:24:59 2006 +0200 +++ b/drivers/timers_xeno/timers_xeno.c Fri Jun 16 14:44:23 2006 +0200 @@ -26,7 +26,7 @@ rt_task_delete(&timerloop_task); rt_alarm_delete(&timerloop_alarm); } -void stopTimer(void) +void StopTimerLoop(void) { stop_timer = 1; rt_task_unblock(&timerloop_task); @@ -57,7 +57,7 @@ printf("End of TimerLoop, code %d\n",ret); } -void TimerLoop(TimerCallback_t init_callback) +void StartTimerLoop(TimerCallback_t init_callback) { int ret; stop_timer = 0; @@ -86,8 +86,6 @@ goto error; } - // At first, TimeDispatch will call init_callback. - pause(); error: cleanup_all(); diff -r a82b70738e5c -r 8afa33692372 examples/TestMasterSlave/TestMasterSlave.c --- a/examples/TestMasterSlave/TestMasterSlave.c Fri Jun 16 14:24:59 2006 +0200 +++ b/examples/TestMasterSlave/TestMasterSlave.c Fri Jun 16 14:44:23 2006 +0200 @@ -117,10 +117,8 @@ { signal(SIGTERM, catch_signal); signal(SIGINT, catch_signal); - stopTimer(); - eprintf("Got Sigterm - Finishing.\n"); -} - + eprintf("Got Signal %d\n",sig); +} void help() { @@ -189,10 +187,17 @@ SlaveCanHandle = canOpen(&SlaveBoard); MasterCanHandle = canOpen(&MasterBoard); - // Will call InitNodes, and wait and handle next timer events. - TimerLoop(&InitNodes); - - // Close CAN devices + // Start timer thread + StartTimerLoop(&InitNodes); + + // wait Ctrl-C + pause(); + eprintf("Finishing.\n"); + + // Stop timer thread + StopTimerLoop(); + + // Close CAN devices (and can threads) canClose(SlaveCanHandle); canClose(MasterCanHandle); diff -r a82b70738e5c -r 8afa33692372 include/data.h --- a/include/data.h Fri Jun 16 14:24:59 2006 +0200 +++ b/include/data.h Fri Jun 16 14:44:23 2006 +0200 @@ -114,7 +114,8 @@ offset: 0,\ data: {0,},\ dataType: 0,\ - timer: -1},},\ + timer: -1,\ + Callback: NULL},},\ SDOtimeoutError: &NODE_PREFIX ## _SDOtimeoutError,\ \ /* State machine */\ diff -r a82b70738e5c -r 8afa33692372 include/sdo.h --- a/include/sdo.h Fri Jun 16 14:24:59 2006 +0200 +++ b/include/sdo.h Fri Jun 16 14:44:23 2006 +0200 @@ -28,6 +28,8 @@ #include "timer.h" +typedef void (*SDOCallback_t)(CO_Data* d, UNS8 nodeId); + /* The Transfer structure Used to store the different segments of - a SDO received before writing in the dictionary @@ -60,6 +62,7 @@ // the line state is in SDO_DOWNLOAD_IN_PROGRESS or // SDO_UPLOAD_IN_PROGRESS, and reseted to 0 // when the response SDO have been received. + SDOCallback_t Callback; // The user callback func to be called at SDO transaction end }; typedef struct struct_s_transfer s_transfer; diff -r a82b70738e5c -r 8afa33692372 include/timers_driver.h --- a/include/timers_driver.h Fri Jun 16 14:24:59 2006 +0200 +++ b/include/timers_driver.h Fri Jun 16 14:44:23 2006 +0200 @@ -30,10 +30,10 @@ void EnterMutex(void); void LeaveMutex(void); void WaitReceiveTaskEnd(TASK_HANDLE*); -void stopTimer(void); // For use from application -void TimerLoop(TimerCallback_t init_callback); +void StartTimerLoop(TimerCallback_t init_callback); +void StopTimerLoop(void); void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE *ReceiveLoop_task); #endif diff -r a82b70738e5c -r 8afa33692372 src/sdo.c --- a/src/sdo.c Fri Jun 16 14:24:59 2006 +0200 +++ b/src/sdo.c Fri Jun 16 14:44:23 2006 +0200 @@ -248,6 +248,7 @@ d->transfers[line].count = 0; d->transfers[line].offset = 0; d->transfers[line].dataType = 0; + d->transfers[line].Callback = NULL; return 0; } @@ -606,6 +607,8 @@ // The code is safe for the case e=s=0 in initiate frame. StopSDO_TIMER(line) d->transfers[line].state = SDO_FINISHED; + if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId); + MSG_WAR(0x3A77, "SDO. End of upload from node : ", nodeId); } else { // more segments to receive @@ -722,6 +725,7 @@ MSG_WAR(0x3A87, "SDO End download. segment response received. OK. from nodeId", nodeId); StopSDO_TIMER(line) d->transfers[line].state = SDO_FINISHED; + if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId); return 0x00; } // At least one transfer to send. @@ -861,6 +865,7 @@ StopSDO_TIMER(line) d->transfers[line].count = nbBytes; d->transfers[line].state = SDO_FINISHED; + if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId); return 0; } else { // So, if it is not an expedited transfert @@ -966,6 +971,7 @@ MSG_WAR(0x3AA6, "SDO End download expedited. Response received. from nodeId", nodeId); StopSDO_TIMER(line) d->transfers[line].state = SDO_FINISHED; + if(d->transfers[line].Callback) (*d->transfers[line].Callback)(d,nodeId); return 0x00; } if (nbBytes > 7) { @@ -1038,8 +1044,8 @@ } /*******************************************************************)******/ -UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, - UNS8 subIndex, UNS8 count, UNS8 dataType, void *data) +inline UNS8 _writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, + UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback) { UNS8 err; UNS8 SDOfound = 0; @@ -1141,14 +1147,25 @@ // release the line resetSDOline(d, line); return 0xFF; - } + } + d->transfers[line].Callback = Callback; return 0; } - - - -/***************************************************************************/ -UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType) +UNS8 writeNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, + UNS8 subIndex, UNS8 count, UNS8 dataType, void *data) +{ + return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, NULL); +} + +UNS8 writeNetworkDictCallBack (CO_Data* d, UNS8 nodeId, UNS16 index, + UNS8 subIndex, UNS8 count, UNS8 dataType, void *data, SDOCallback_t Callback) +{ + return _writeNetworkDict (d, nodeId, index, subIndex, count, dataType, data, Callback); +} + + +/***************************************************************************/ +UNS8 _readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback) { UNS8 err; UNS8 SDOfound = 0; @@ -1229,9 +1246,19 @@ resetSDOline(d, line); return 0xFF; } + d->transfers[line].Callback = Callback; return 0; } +UNS8 readNetworkDict (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType) +{ + return _readNetworkDict (d, nodeId, index, subIndex, dataType, NULL); +} + +UNS8 readNetworkDictCallback (CO_Data* d, UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, SDOCallback_t Callback) +{ + return _readNetworkDict (d, nodeId, index, subIndex, dataType, Callback); +} /***************************************************************************/ UNS8 getReadResultNetworkDict (CO_Data* d, UNS8 nodeId, void* data, UNS8 *size,