diff --git a/adaptors/matlab/Makefile b/adaptors/matlab/Makefile
index 393415e9e28c90ed06d40fe9607dbe5b2d9e30dd..561bfd6da50cf58ee9fecd5e3cb29de9a65785bf 100644
--- a/adaptors/matlab/Makefile
+++ b/adaptors/matlab/Makefile
@@ -1,22 +1,9 @@
 LIBRARIES=libmoberg4simulink.so
-SFUNC=analogin analogout digitalin digitalout encoderin
-MATLAB_VERSION=
-MEX=MATLAB_VERSION=$(MATLAB_VERSION)  mex
-MEX_SUFFIX=$(shell $(MEX) -v -n analogin.c \
-	    | sed -e 's/^.*LDEXTENSION.*[.]\(mex.*\)/\1/p;d')
-
-CCFLAGS+=-Wall -Werror -I. -I../.. -g
+CCFLAGS+=-Wall -Werror -O3 -I. -I../.. -g
 
 all:	$(LIBRARIES:%=../../build/%)
 
-.PHONY: SFUNC
-SFUNC: $(SFUNC:%=../../build/%.$(MEX_SUFFIX))
-
 ../../build/libmoberg4simulink.so: moberg4simulink.c Makefile
 	$(CC) -o $@ $(CCFLAGS) -L../../build -shared -fPIC -lmoberg $<
 
 ../../build/libmoberg4simulink.so: ../../moberg.h
-
-../../build/%.$(MEX_SUFFIX): %.c Makefile
-	$(MEX) CFLAGS="$(CCFLAGS) -fPIC" \
-	       -outdir ../../build -L../../build -lmoberg4simulink $<
diff --git a/adaptors/matlab/Makefile.mex b/adaptors/matlab/Makefile.mex
new file mode 100644
index 0000000000000000000000000000000000000000..322bed350e3c0a2a193c886f1085559d82a4a03e
--- /dev/null
+++ b/adaptors/matlab/Makefile.mex
@@ -0,0 +1,26 @@
+MATLAB_VERSION=
+MEX=MATLAB_VERSION=$(MATLAB_VERSION) mex
+SUFFIX=$(shell $(MEX) -v -n analogin.c 2>&1 | \
+	       sed -e 's/^.*LDEXTENSION.*[.]\(mex.*\)/\1/p;d')
+TARGETS=realtimer \
+        analogin analogout \
+	digitalin digitalout \
+	encoderin 
+
+EXTRAFLAGS_realtimer=
+EXTRAFLAGS_analogin=-lmoberg4simulink
+EXTRAFLAGS_analogout=-lmoberg4simulink
+EXTRAFLAGS_digitalin=-lmoberg4simulink
+EXTRAFLAGS_digitalout=-lmoberg4simulink
+EXTRAFLAGS_encoderin=-lmoberg4simulink
+
+all:	$(TARGETS:%=%.$(SUFFIX))
+
+%.$(SUFFIX): %.c Makefile
+	$(MEX) CFLAGS='$$CFLAGS -Wall -Werror -I.' $< $(EXTRAFLAGS_$*)
+
+clean:
+	rm -f *~
+
+realclean: clean
+	rm -f $(TARGETS:%=%.mex*)
diff --git a/adaptors/matlab/realtimer.c b/adaptors/matlab/realtimer.c
new file mode 100644
index 0000000000000000000000000000000000000000..2f7b1e82ea5d6ec8781fe15bc428467131197b49
--- /dev/null
+++ b/adaptors/matlab/realtimer.c
@@ -0,0 +1,137 @@
+/*
+  realtimer.c, 
+  a MEX file for syncing elapsed Simulink time to elapsed wall time.
+  
+  Copyright (C) 1999-2005 Anders Blomdell <anders.blomdell@control.lth.se>
+  
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; either version 2 of the License, or
+  (at your option) any later version.
+  
+  This program 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 General Public License for more details.
+  
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#define S_FUNCTION_LEVEL 2
+#define S_FUNCTION_NAME realtimer
+
+#include "simstruc.h"
+#include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <time.h>
+
+static unsigned long long TIME2ULL(struct timeval t)
+{
+  unsigned long long result;
+  result = (unsigned long long)t.tv_sec * 1000000 + t.tv_usec;
+  return result;
+}
+
+#if 0
+static struct timeval ULL2TIME(unsigned long long t)
+{
+  struct timeval result;
+  result.tv_sec = t / 1000000;
+  result.tv_usec = t % 1000000;
+  return result;
+}
+#endif
+
+static struct timespec ULL2TIMESPEC(unsigned long long t)
+{
+  struct timespec result;
+  result.tv_sec = t / 1000000;
+  result.tv_nsec = (t % 1000000) * 1000;
+  return result;
+}
+
+static void mdlInitializeSizes(SimStruct *S)
+{
+  ssSetNumSFcnParams(S, 1);  /* Number of expected parameters */
+  if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) { return; }
+
+  ssSetNumContStates(S, 0);
+  ssSetNumDiscStates(S, 0);
+
+  if (!ssSetNumInputPorts(S, 0)) { return; }
+
+  if (!ssSetNumOutputPorts(S, 1)) { return; } 
+  ssSetOutputPortWidth(S, 0, 1);
+
+  ssSetNumSampleTimes(S, 1);
+
+  ssSetNumRWork(S, 0);
+  ssSetNumIWork(S, 6); /* 0,1: long long h 
+			  2,3: long long t 
+			  4,5: long long diff */
+  ssSetNumPWork(S, 0); 
+  ssSetNumModes(S, 0);
+
+  ssSetNumNonsampledZCs(S, 0);
+  
+  ssSetOptions(S, 0);
+}
+
+static void mdlInitializeSampleTimes(SimStruct *S)
+{
+  ssSetSampleTime(S, 0, mxGetScalar(ssGetSFcnParam(S, 0)));
+  ssSetOffsetTime(S, 0, 0.0);
+}
+
+#define MDL_START
+static void mdlStart(SimStruct *S)
+{
+  struct timeval now;
+  unsigned long long *work = (unsigned long long *)ssGetIWork(S);
+  gettimeofday(&now, 0); 
+  work[0] = mxGetScalar(ssGetSFcnParam(S, 0)) * 1000000;
+  work[1] = TIME2ULL(now);
+  work[2] = 0;
+}
+
+static void mdlOutputs(SimStruct *S, int_T tid)
+{
+  unsigned long long *work = (unsigned long long *)ssGetIWork(S);
+  real_T *y = ssGetOutputPortRealSignal(S,0);
+
+  *y = 1.0 - ((real_T)work[2] / (real_T)work[0]); 
+}
+
+#define MDL_UPDATE
+static void mdlUpdate(SimStruct *S, int_T tid)
+{
+  unsigned long long *work = (unsigned long long *)ssGetIWork(S);
+  long long diff;
+  struct timeval now;
+
+  work[1] += work[0];
+  gettimeofday(&now, 0);
+  diff = work[1] - TIME2ULL(now);
+  if ((diff) <= 0) {
+    diff = 0;
+    work[1] = TIME2ULL(now);
+  } else {
+    struct timespec delay = ULL2TIMESPEC(diff);
+    nanosleep(&delay, NULL);
+  }
+  work[2] = diff;
+}
+
+static void mdlTerminate(SimStruct *S)
+{
+}
+
+#ifdef  MATLAB_MEX_FILE    /* Is this file being compiled as a MEX-file? */
+#include "simulink.c"      /* MEX-file interface mechanism */
+#else
+#include "cg_sfun.h"       /* Code generation registration function */
+#endif
diff --git a/moberg.spec.template b/moberg.spec.template
index 3254e98832f2cfd672a9e670db2c6739d61b95a6..36e54381770aed0586f9e451dfbac82797eef6d7 100644
--- a/moberg.spec.template
+++ b/moberg.spec.template
@@ -58,26 +58,28 @@ mkdir -p ${RPM_BUILD_ROOT}%{_includedir}
 cp moberg.h ${RPM_BUILD_ROOT}%{_includedir}
 
 mkdir -p ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
-cp adaptors/matlab/*.h  ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
-cp adaptors/matlab/*in.c  ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
-cp adaptors/matlab/*out.c  ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
-cp adaptors/matlab/Makefile  ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
+mkdir -p ${RPM_BUILD_ROOT}%{_includedir}
+cp adaptors/matlab/moberg4simulink.h ${RPM_BUILD_ROOT}%{_includedir}
+cp adaptors/matlab/realtimer.c ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
+cp adaptors/matlab/*in.c ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
+cp adaptors/matlab/*out.c ${RPM_BUILD_ROOT}/opt/matlab/src/moberg
+cp adaptors/matlab/Makefile.mex ${RPM_BUILD_ROOT}/opt/matlab/src/moberg/Makefile
 
 %files
 %defattr(-,root,root,-)
-%attr(04755,root,root) %{_libdir}/libmoberg.so
-%attr(04755,root,root) %{_libdir}/libmoberg_serial2002.so
+%{_libdir}/libmoberg.so
+%{_libdir}/libmoberg_serial2002.so
 
 %files comedi
 %defattr(-,root,root,-)
-%attr(04755,root,root) %{_libdir}/libmoberg_comedi.so
+%{_libdir}/libmoberg_comedi.so
 
 %files devel
 %defattr(-,root,root,-)
-%attr(04755,root,root) %{_includedir}/moberg.h
+%{_includedir}/moberg.h
 
 %files matlab
 %defattr(-,root,root,-)
-%attr(04755,root,root) %{_libdir}/libmoberg4simulink.so
-%attr(04755,root,root) /opt/matlab/src/moberg/*
-
+%{_libdir}/libmoberg4simulink.so
+/opt/matlab/src/moberg/*
+%{_includedir}/moberg4simulink.h
diff --git a/moberg_config.c b/moberg_config.c
index 6349bdeebca06c99a399a4c4016a38b4c73775a6..e4f467d708d8d0b5723b26731da38664272e6c47 100644
--- a/moberg_config.c
+++ b/moberg_config.c
@@ -24,14 +24,16 @@ struct moberg_config *moberg_config_new()
 
 void moberg_config_free(struct moberg_config *config)
 {
-  struct device_entry *entry = config->device_head;
-  while (entry) {
-    struct device_entry *tmp = entry;
-    entry = entry->next;
-    moberg_device_free(tmp->device);
-    free(tmp);
+  if (config) {
+    struct device_entry *entry = config->device_head;
+    while (entry) {
+      struct device_entry *tmp = entry;
+      entry = entry->next;
+      moberg_device_free(tmp->device);
+      free(tmp);
+    }
+    free(config);
   }
-  free(config);
 }
 
 int moberg_config_join(struct moberg_config *dest,