SDO callbacks.
authoretisserant
Fri, 16 Jun 2006 14:44:23 +0200
changeset 32 8afa33692372
parent 31 a82b70738e5c
child 33 c767eabbaaac
SDO callbacks.
Removed TimerLoop. Now call StartTimerLoop (non blocking) and StopTimerLoop
configure
drivers/timers_unix/timers_unix.c
drivers/timers_xeno/timers_xeno.c
examples/TestMasterSlave/TestMasterSlave.c
include/data.h
include/sdo.h
include/timers_driver.h
src/sdo.c
--- 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,