SDO callbacks.
Removed TimerLoop. Now call StartTimerLoop (non blocking) and StopTimerLoop
--- 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
--- 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 <stdlib.h>
#include <sys/time.h>
+#include <pthread.h>
#include <signal.h>
-#include <pthread.h>
#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)
--- 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();
--- 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);
--- 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 */\
--- 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;
--- 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
--- 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,