From d6d799ed48f8193bee286187132221f831726a07 Mon Sep 17 00:00:00 2001
From: gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4>
Date: Sat, 6 Oct 2007 08:58:52 +0000
Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@39
 35acf78f-673a-0410-8e92-d51de3d6d3f4

---
 demos/ARM7-LPC214x-GCC/Makefile | 10 +++---
 demos/ARM7-LPC214x-GCC/chcore.h |  2 +-
 demos/ARM7-LPC214x-GCC/main.c   | 10 +++---
 demos/AVR-AT90CANx-GCC/chcore.h |  4 +--
 readme.txt                      |  8 ++++-
 src/include/ch.h                |  8 ++++-
 src/include/delta.h             | 13 +++++---
 src/include/events.h            | 22 ++++++++-----
 src/include/lists.h             | 18 ++++++++---
 src/include/messages.h          | 22 ++++++++-----
 src/include/queues.h            | 64 ++++++++++++++++++++++----------------
 src/include/scheduler.h         | 22 ++++++++-----
 src/include/semaphores.h        | 34 ++++++++++++---------
 src/include/serial.h            | 38 +++++++++++++++--------
 src/include/sleep.h             | 17 ++++++-----
 src/include/threads.h           | 30 +++++++++---------
 src/lib/evtimer.c               | 68 +++++++++++++++++++++++++++++++++++++++++
 src/lib/evtimer.h               | 65 +++++++++++++++++++++++++++++++++++++++
 test/test.c                     |  2 +-
 19 files changed, 334 insertions(+), 123 deletions(-)
 create mode 100644 src/lib/evtimer.c
 create mode 100644 src/lib/evtimer.h

diff --git a/demos/ARM7-LPC214x-GCC/Makefile b/demos/ARM7-LPC214x-GCC/Makefile
index 8400d8f82..b69ae8780 100644
--- a/demos/ARM7-LPC214x-GCC/Makefile
+++ b/demos/ARM7-LPC214x-GCC/Makefile
@@ -62,7 +62,7 @@ UDEFS =
 UADEFS =
 
 # List ARM-mode C source files here
-ASRC = chcore.c main.c buzzer.c \
+ASRC = chcore.c main.c buzzer.c ../../src/lib/evtimer.c \
        ../../test/test.c ../../ports/ARM7-LPC214x/GCC/lpc214x_serial.c  \
        ../../src/chinit.c ../../src/chlists.c ../../src/chdelta.c ../../src/chschd.c \
        ../../src/chthreads.c ../../src/chsem.c ../../src/chevents.c ../../src/chmsg.c \
@@ -92,8 +92,6 @@ AOPT =
 TOPT = -mthumb -D THUMB
 
 # Common options here
-# NOTE: -mthumb-interwork increases the code size, remove it if you dont have
-#       Thumb code anywhere in the project.
 # NOTE: -ffixed-f7 is only needed if you enabled CH_CURRP_REGISTER_CACHE in chconf.h.
 OPT = -O2 -ggdb -fomit-frame-pointer -fno-strict-aliasing
 #OPT += -ffixed-f7
@@ -117,7 +115,7 @@ LIBS    = $(DLIBS) $(ULIBS)
 MCFLAGS = -mcpu=$(MCU)
 
 ASFLAGS = $(MCFLAGS) -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
-CPFLAGS = $(MCFLAGS) $(OPT) $(WARN) -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
+CPFLAGS = $(MCFLAGS) $(OPT) $(WARN) -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
 LDFLAGS = $(MCFLAGS) -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(PROJECT).map,--cref,--no-warn-mismatch $(LIBDIR)
 ODFLAGS	= -x --syms
 
@@ -137,15 +135,19 @@ CPFLAGS += -MD -MP -MF .dep/$(@F).d
 all: $(OBJS) $(PROJECT).elf $(PROJECT).hex $(PROJECT).bin $(PROJECT).dmp
 
 $(AOBJS) : %.o : %.c
+	@echo
 	$(CC) -c $(CPFLAGS) $(AOPT) -I . $(INCDIR) $< -o $@
 
 $(TOBJS) : %.o : %.c
+	@echo
 	$(CC) -c $(CPFLAGS) $(TOPT) -I . $(INCDIR) $< -o $@
 
 $(ASMOBJS) : %.o : %.s
+	@echo
 	$(AS) -c $(ASFLAGS) $< -o $@
 
 %elf: $(OBJS)
+	@echo
 	$(CC) $(ASMOBJS) $(AOBJS) $(TOBJS) $(LDFLAGS) $(LIBS) -o $@
 
 %hex: %elf
diff --git a/demos/ARM7-LPC214x-GCC/chcore.h b/demos/ARM7-LPC214x-GCC/chcore.h
index b2091b686..9c583c2ac 100644
--- a/demos/ARM7-LPC214x-GCC/chcore.h
+++ b/demos/ARM7-LPC214x-GCC/chcore.h
@@ -98,7 +98,7 @@ extern void chSysUnlock(void);
                           sizeof(struct stackregs) + (n) + (INT_REQUIRED_STACK))
 
 void chSysHalt(void) __attribute__((noreturn));
-void chSysPause(void);
+void chSysPause(void)  __attribute__((noreturn));
 void chSysSwitchI(Context *oldp, Context *newp);
 void threadstart(void);
 void DefFiqHandler(void);
diff --git a/demos/ARM7-LPC214x-GCC/main.c b/demos/ARM7-LPC214x-GCC/main.c
index 0183b276b..5db6815fb 100644
--- a/demos/ARM7-LPC214x-GCC/main.c
+++ b/demos/ARM7-LPC214x-GCC/main.c
@@ -57,18 +57,18 @@ static BYTE8 waThread3[UserStackSize(64)];
 
 static t_msg Thread3(void *arg) {
   t_msg TestThread(void *p);
-  
+
   while (TRUE) {
-  	if (!(IO0PIN & 0x00018000)) {
+    if (!(IO0PIN & 0x00018000)) {
       TestThread(&COM1);
       PlaySound(500, 100);
-  	}
-  	else {
+    }
+    else {
       if (!(IO0PIN & 0x00008000)) // Button 1
         PlaySound(1000, 100);
       if (!(IO0PIN & 0x00010000)) // Button 2
         chFDDWrite(&COM1, (BYTE8 *)"Hello World!\r\n", 14);
-  	}
+    }
     chThdSleep(500);
   }
   return 0;
diff --git a/demos/AVR-AT90CANx-GCC/chcore.h b/demos/AVR-AT90CANx-GCC/chcore.h
index d263202d8..799742f47 100644
--- a/demos/AVR-AT90CANx-GCC/chcore.h
+++ b/demos/AVR-AT90CANx-GCC/chcore.h
@@ -97,8 +97,8 @@ typedef struct {
 #define chSysLock() asm("cli")
 #define chSysUnlock() asm("sei")
 
-void chSysHalt(void);
-void chSysPause(void);
+void chSysHalt(void) __attribute__((noreturn)) ;
+void chSysPause(void) __attribute__((noreturn)) ;
 void chSysSwitchI(Context *oldp, Context *newp);
 
 #endif /* _CHCORE_H_ */
diff --git a/readme.txt b/readme.txt
index 01b6ce579..5d37bc16f 100644
--- a/readme.txt
+++ b/readme.txt
@@ -6,6 +6,10 @@
 ./license.txt          - GPL3 license file.
 ./src/                 - ChibiOS/RT portable kernel source files.
 ./src/include/         - ChibiOS/RT include files.
+./src/lib/             - ChibiOS/RT library code that can be included into
+                         user applications but is not part of the core system.
+                         The code in this directory is meant to be portable,
+                         generic and architecture indipendent.
 ./src/templates/       - ChibiOS/RT non portable source templates, new ports
                          are started by copying the templates into a new
                          directory under ./demos/.
@@ -35,7 +39,9 @@ AVR-AT90CANx-GCC    - Port on AVER AT90CAN128, not complete yet.
 *****************************************************************************
 
 *** 0.3.2 ***
-- Removed an obsolete definition in ./src/templates/chtypes.h
+- Added a generic events generator timer to the library code.
+- Added the "#ifdef __cplusplus" stuff to the header files.
+- Removed an obsolete definition in ./src/templates/chtypes.h.
 
 *** 0.3.1 ***
 - Test program added to the demos. Telnet the MinGW and MSVS demos and type
diff --git a/src/include/ch.h b/src/include/ch.h
index aa77df544..b7889a9f5 100644
--- a/src/include/ch.h
+++ b/src/include/ch.h
@@ -92,7 +92,13 @@
 #define NULL        0
 #endif
 
-void chSysInit(void);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chSysInit(void);
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _CH_H_ */
 
diff --git a/src/include/delta.h b/src/include/delta.h
index 7639301e1..46fd3b883 100644
--- a/src/include/delta.h
+++ b/src/include/delta.h
@@ -66,7 +66,6 @@ typedef struct {
     t_time          dl_dtime;
 } DeltaList;
 
-
 extern DeltaList dlist;
 
 #define chVTDoTickI() \
@@ -85,9 +84,15 @@ extern DeltaList dlist;
 /*
  * Virtual Timers APIs.
  */
-void chVTInit(void);
-void chVTSetI(VirtualTimer *vtp, t_time time, t_vtfunc vtfunc, void *par);
-void chVTResetI(VirtualTimer *vtp);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chVTInit(void);
+  void chVTSetI(VirtualTimer *vtp, t_time time, t_vtfunc vtfunc, void *par);
+  void chVTResetI(VirtualTimer *vtp);
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* CH_USE_VIRTUAL_TIMER */
 
diff --git a/src/include/events.h b/src/include/events.h
index 322f7ec7d..94b277692 100644
--- a/src/include/events.h
+++ b/src/include/events.h
@@ -76,18 +76,24 @@ typedef struct EventSource {
 /** Event Handler callback function.*/
 typedef void (*t_evhandler)(t_eventid);
 
-void chEvtRegister(EventSource *esp, EventListener *elp, t_eventid eid);
-void chEvtUnregister(EventSource *esp, EventListener *elp);
-void chEvtClear(t_eventmask mask);
-void chEvtSend(EventSource *esp);
-void chEvtSendI(EventSource *esp);
-t_eventid chEvtWait(t_eventmask ewmask,
-                    t_evhandler handlers[]);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chEvtRegister(EventSource *esp, EventListener *elp, t_eventid eid);
+  void chEvtUnregister(EventSource *esp, EventListener *elp);
+  void chEvtClear(t_eventmask mask);
+  void chEvtSend(EventSource *esp);
+  void chEvtSendI(EventSource *esp);
+  t_eventid chEvtWait(t_eventmask ewmask,
+                      t_evhandler handlers[]);
 #ifdef CH_USE_EVENTS_TIMEOUT
-t_eventid chEvtWaitTimeout(t_eventmask ewmask,
+  t_eventid chEvtWaitTimeout(t_eventmask ewmask,
                            t_evhandler handlers[],
                            t_time time);
 #endif
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* CH_USE_EVENTS */
 
diff --git a/src/include/lists.h b/src/include/lists.h
index 477ab1061..043538457 100644
--- a/src/include/lists.h
+++ b/src/include/lists.h
@@ -55,13 +55,21 @@ typedef struct {
 #define list_init(tlp) ((tlp)->p_next = (Thread *)(tlp))
 
 #ifndef CH_OPTIMIZE_SPEED
-void fifo_insert(Thread *tp, ThreadsQueue *tqp);
-Thread *fifo_remove(ThreadsQueue *tqp);
-Thread *dequeue(Thread *tp);
-void list_insert(Thread *tp, ThreadsList *tlp);
-Thread *list_remove(ThreadsList *tlp);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void fifo_insert(Thread *tp, ThreadsQueue *tqp);
+  Thread *fifo_remove(ThreadsQueue *tqp);
+  Thread *dequeue(Thread *tp);
+  void list_insert(Thread *tp, ThreadsList *tlp);
+  Thread *list_remove(ThreadsList *tlp);
+#ifdef __cplusplus
+}
 #endif
 
+#endif /* CH_OPTIMIZE_SPEED */
+
 #endif  /* _LISTS_H_ */
 
 /** @} */
diff --git a/src/include/messages.h b/src/include/messages.h
index a6ce409f3..a5e88c267 100644
--- a/src/include/messages.h
+++ b/src/include/messages.h
@@ -31,25 +31,31 @@
  * Evaluates to TRUE if the thread has pending messages.
  */
 #define chMsgIsPendingI(tp) \
-			((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue)
+                        ((tp)->p_msgqueue.p_next != (Thread *)&(tp)->p_msgqueue)
 
 /**
  * Returns the first message in the queue.
  */
 #define chMsgGetI(tp) \
-			((tp)->p_msgqueue.p_next->p_msg)
+                        ((tp)->p_msgqueue.p_next->p_msg)
 
-t_msg chMsgSend(Thread *tp, t_msg msg);
-t_msg chMsgWait(void);
-t_msg chMsgGet(void);
-void chMsgRelease(t_msg msg);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  t_msg chMsgSend(Thread *tp, t_msg msg);
+  t_msg chMsgWait(void);
+  t_msg chMsgGet(void);
+  void chMsgRelease(t_msg msg);
 
 #ifdef CH_USE_MESSAGES_EVENT
-t_msg chMsgSendWithEvent(Thread *tp, t_msg msg, EventSource *esp);
+  t_msg chMsgSendWithEvent(Thread *tp, t_msg msg, EventSource *esp);
 #endif
 
 #ifdef CH_USE_MESSAGES_TIMEOUT
-t_msg chMsgSendTimeout(Thread *tp, t_msg msg, t_time time);
+  t_msg chMsgSendTimeout(Thread *tp, t_msg msg, t_time time);
+#endif
+#ifdef __cplusplus
+}
 #endif
 
 #endif /* CH_USE_MESSAGES */
diff --git a/src/include/queues.h b/src/include/queues.h
index 117c6e9e8..31258ce69 100644
--- a/src/include/queues.h
+++ b/src/include/queues.h
@@ -84,28 +84,34 @@ typedef struct {
 #define chOQIsFull(q) \
         (chQSpace(q) <= 0)
 
-/*
- * Input Queues functions. An Input Queue is usually written into by an
- * interrupt handler and read from a thread.
- */
-void chIQInit(Queue *qp, BYTE8 *buffer, t_size size, t_qnotify inotify);
-void chIQReset(Queue *qp);
-t_msg chIQPutI(Queue *qp, BYTE8 b);
-t_msg chIQGet(Queue *qp);
-t_size chIQRead(Queue *qp, BYTE8 *buffer, t_size n);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  /*
+   * Input Queues functions. An Input Queue is usually written into by an
+   * interrupt handler and read from a thread.
+   */
+  void chIQInit(Queue *qp, BYTE8 *buffer, t_size size, t_qnotify inotify);
+  void chIQReset(Queue *qp);
+  t_msg chIQPutI(Queue *qp, BYTE8 b);
+  t_msg chIQGet(Queue *qp);
+  t_size chIQRead(Queue *qp, BYTE8 *buffer, t_size n);
 #ifdef CH_USE_QUEUES_TIMEOUT
-t_msg chIQGetTimeout(Queue *qp, t_time time);
+  t_msg chIQGetTimeout(Queue *qp, t_time time);
 #endif
 
-/*
- * Output Queues functions. An Output Queue is usually written into by a
- * thread and read from an interrupt handler.
- */
-void chOQInit(Queue *queue, BYTE8 *buffer, t_size size, t_qnotify onotify);
-void chOQReset(Queue *queue);
-void chOQPut(Queue *queue, BYTE8 b);
-t_msg chOQGetI(Queue *queue);
-t_size chOQWrite(Queue *queue, BYTE8 *buffer, t_size n);
+  /*
+   * Output Queues functions. An Output Queue is usually written into by a
+   * thread and read from an interrupt handler.
+   */
+  void chOQInit(Queue *queue, BYTE8 *buffer, t_size size, t_qnotify onotify);
+  void chOQReset(Queue *queue);
+  void chOQPut(Queue *queue, BYTE8 b);
+  t_msg chOQGetI(Queue *queue);
+  t_size chOQWrite(Queue *queue, BYTE8 *buffer, t_size n);
+#ifdef __cplusplus
+}
+#endif
 #endif  /* CH_USE_QUEUES */
 
 #ifdef CH_USE_QUEUES_HALFDUPLEX
@@ -155,14 +161,20 @@ typedef struct {
 #define chHDQIsFullReceive(q) \
         (chHDQFilledSpace(q) >= chHDQSize(q))
 
-void chHDQInit(HalfDuplexQueue *qp, BYTE8 *buffer, t_size size,
-               t_qnotify inotify, t_qnotify onotify);
-t_msg chHDQGetReceive(HalfDuplexQueue *qp);
-void chHDQPutTransmit(HalfDuplexQueue *qp, BYTE8 b);
-t_msg chHDQGetTransmitI(HalfDuplexQueue *qp);
-t_msg chHDQPutReceiveI(HalfDuplexQueue *qp, BYTE8 b);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chHDQInit(HalfDuplexQueue *qp, BYTE8 *buffer, t_size size,
+                 t_qnotify inotify, t_qnotify onotify);
+  t_msg chHDQGetReceive(HalfDuplexQueue *qp);
+  void chHDQPutTransmit(HalfDuplexQueue *qp, BYTE8 b);
+  t_msg chHDQGetTransmitI(HalfDuplexQueue *qp);
+  t_msg chHDQPutReceiveI(HalfDuplexQueue *qp, BYTE8 b);
 #ifdef CH_USE_QUEUES_TIMEOUT
-t_msg chHDQGetReceiveTimeout(HalfDuplexQueue *qp, t_time time);
+  t_msg chHDQGetReceiveTimeout(HalfDuplexQueue *qp, t_time time);
+#endif
+#ifdef __cplusplus
+}
 #endif
 
 #endif /* CH_USE_QUEUES_HALFDUPLEX */
diff --git a/src/include/scheduler.h b/src/include/scheduler.h
index 6a3f7f8f8..884b3936c 100644
--- a/src/include/scheduler.h
+++ b/src/include/scheduler.h
@@ -45,14 +45,20 @@ typedef struct {
 /*
  * Scheduler APIs.
  */
-void chSchInit(void);
-Thread *chSchReadyI(Thread *tp);
-void chSchGoSleepI(t_tstate newstate);
-void chSchWakeupI(Thread *tp, t_msg msg);
-void chSchRescheduleI(void);
-void chSchDoRescheduleI(void);
-BOOL chSchRescRequiredI(void);
-void chSchTimerHandlerI(void);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chSchInit(void);
+  Thread *chSchReadyI(Thread *tp);
+  void chSchGoSleepI(t_tstate newstate);
+  void chSchWakeupI(Thread *tp, t_msg msg);
+  void chSchRescheduleI(void);
+  void chSchDoRescheduleI(void);
+  BOOL chSchRescRequiredI(void);
+  void chSchTimerHandlerI(void);
+#ifdef __cplusplus
+}
+#endif
 
 /**
  * Current thread pointer.
diff --git a/src/include/semaphores.h b/src/include/semaphores.h
index c1f3f9db6..dfee499f0 100644
--- a/src/include/semaphores.h
+++ b/src/include/semaphores.h
@@ -37,22 +37,28 @@ typedef struct {
   t_cnt           s_cnt;
 } Semaphore;
 
-void chSemInit(Semaphore *sp, t_cnt n);
-void chSemReset(Semaphore *sp, t_cnt n);
-void chSemResetI(Semaphore *sp, t_cnt n);
-void chSemWait(Semaphore *sp);
-void chSemWaitS(Semaphore *sp);
-t_msg chSemWaitTimeout(Semaphore *sp, t_time time);
-t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time);
-void chSemSignal(Semaphore *sp);
-void chSemSignalI(Semaphore *sp);
-void chSemSignalWait(Semaphore *sps, Semaphore *spw);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chSemInit(Semaphore *sp, t_cnt n);
+  void chSemReset(Semaphore *sp, t_cnt n);
+  void chSemResetI(Semaphore *sp, t_cnt n);
+  void chSemWait(Semaphore *sp);
+  void chSemWaitS(Semaphore *sp);
+  t_msg chSemWaitTimeout(Semaphore *sp, t_time time);
+  t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time);
+  void chSemSignal(Semaphore *sp);
+  void chSemSignalI(Semaphore *sp);
+  void chSemSignalWait(Semaphore *sps, Semaphore *spw);
 
 #ifdef CH_USE_RT_SEMAPHORES
-void chSemRaisePrioWait(Semaphore *sp);
-void chSemLowerPrioSignal(Semaphore *sp);
-void chSemRaisePrioSignalWait(Semaphore *sps, Semaphore *spw);
-void chSemLowerPrioSignalWait(Semaphore *sps, Semaphore *spw);
+  void chSemRaisePrioWait(Semaphore *sp);
+  void chSemLowerPrioSignal(Semaphore *sp);
+  void chSemRaisePrioSignalWait(Semaphore *sps, Semaphore *spw);
+  void chSemLowerPrioSignalWait(Semaphore *sps, Semaphore *spw);
+#endif
+#ifdef __cplusplus
+}
 #endif
 
 /**
diff --git a/src/include/serial.h b/src/include/serial.h
index 3d33975b1..8e3127bac 100644
--- a/src/include/serial.h
+++ b/src/include/serial.h
@@ -72,13 +72,19 @@ typedef struct {
   EventSource       sd_sevent;
 } FullDuplexDriver;
 
-void chFDDInit(FullDuplexDriver *sd,
-               BYTE8 *ib, t_size isize, t_qnotify inotify,
-               BYTE8 *ob, t_size osize, t_qnotify onotify);
-void chFDDIncomingDataI(FullDuplexDriver *sd, BYTE8 b);
-t_msg chFDDRequestDataI(FullDuplexDriver *sd);
-void chFDDAddFlagsI(FullDuplexDriver *sd, t_dflags mask);
-t_dflags chFDDGetAndClearFlags(FullDuplexDriver *sd);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chFDDInit(FullDuplexDriver *sd,
+                 BYTE8 *ib, t_size isize, t_qnotify inotify,
+                 BYTE8 *ob, t_size osize, t_qnotify onotify);
+  void chFDDIncomingDataI(FullDuplexDriver *sd, BYTE8 b);
+  t_msg chFDDRequestDataI(FullDuplexDriver *sd);
+  void chFDDAddFlagsI(FullDuplexDriver *sd, t_dflags mask);
+  t_dflags chFDDGetAndClearFlags(FullDuplexDriver *sd);
+#ifdef __cplusplus
+}
+#endif
 
 /** @see chIQRead()*/
 #define chFDDRead(sd, b, n) \
@@ -128,12 +134,18 @@ typedef struct {
   EventSource       sd_sevent;
 } HalfDuplexDriver;
 
-void chHDDInit(HalfDuplexDriver *sd, BYTE8 *b, t_size size,
-              t_qnotify inotify, t_qnotify onotify);
-void chHDDIncomingDataI(HalfDuplexDriver *sd, BYTE8 b);
-t_msg chHDDRequestDataI(HalfDuplexDriver *sd);
-void chHDDAddFlagsI(HalfDuplexDriver *sd, t_dflags mask);
-t_dflags chHDDGetAndClearFlags(HalfDuplexDriver *sd);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void chHDDInit(HalfDuplexDriver *sd, BYTE8 *b, t_size size,
+                t_qnotify inotify, t_qnotify onotify);
+  void chHDDIncomingDataI(HalfDuplexDriver *sd, BYTE8 b);
+  t_msg chHDDRequestDataI(HalfDuplexDriver *sd);
+  void chHDDAddFlagsI(HalfDuplexDriver *sd, t_dflags mask);
+  t_dflags chHDDGetAndClearFlags(HalfDuplexDriver *sd);
+#ifdef __cplusplus
+}
+#endif
 
 /** @see chHDQGetReceive()*/
 #define chHDDGetReceive(sd) \
diff --git a/src/include/sleep.h b/src/include/sleep.h
index 265500908..e3fa2ffda 100644
--- a/src/include/sleep.h
+++ b/src/include/sleep.h
@@ -25,18 +25,19 @@
 #ifndef _SLEEP_H_
 #define _SLEEP_H_
 
+#ifdef __cplusplus
+extern "C" {
+#endif
 #ifdef CH_USE_SLEEP
-
-void chThdSleep(t_time time);
-
+  void chThdSleep(t_time time);
 #ifdef CH_USE_SYSTEMTIME
-
-void chThdSleepUntil(t_time time);
-t_time chSysGetTime(void);
-
+  void chThdSleepUntil(t_time time);
+  t_time chSysGetTime(void);
 #endif /* CH_USE_SYSTEMTIME */
-
 #endif /* CH_USE_SLEEP */
+#ifdef __cplusplus
+}
+#endif
 
 #endif /* _SLEEP_H_ */
 
diff --git a/src/include/threads.h b/src/include/threads.h
index 12737de2e..2ed92fa39 100644
--- a/src/include/threads.h
+++ b/src/include/threads.h
@@ -186,10 +186,22 @@ static INLINE Thread *list_remove(ThreadsList *tlp) {
 /*
  * Threads APIs.
  */
-Thread *chThdCreate(t_prio prio, t_tmode mode, void *workspace,
-                    t_size wsize, t_tfunc pf, void *arg);
-void chThdResume(Thread *tp);
-void chThdExit(t_msg msg);
+#ifdef __cplusplus
+extern "C" {
+#endif
+  Thread *chThdCreate(t_prio prio, t_tmode mode, void *workspace,
+                      t_size wsize, t_tfunc pf, void *arg);
+  void chThdResume(Thread *tp);
+  void chThdExit(t_msg msg);
+#ifdef CH_USE_TERMINATE
+  void chThdTerminate(Thread *tp);
+#endif
+#ifdef CH_USE_WAITEXIT
+  t_msg chThdWait(Thread *tp);
+#endif
+#ifdef __cplusplus
+}
+#endif
 
 /** Returns the pointer to the \p Thread currently in execution.*/
 #define chThdSelf() currp
@@ -200,20 +212,11 @@ void chThdExit(t_msg msg);
 /** Verifies if the specified thread is in the \p PREXIT state.*/
 #define chThdTerminated(tp) ((tp)->p_state == PREXIT)
 
-#ifdef CH_USE_TERMINATE
 /**
  * Verifies if the current thread has a termination request pending.
  */
 #define chThdShouldTerminate() (currp->p_flags & P_TERMINATE)
 
-void chThdTerminate(Thread *tp);
-#endif
-
-#ifdef CH_USE_WAITEXIT
-t_msg chThdWait(Thread *tp);
-#endif
-
-#ifdef CH_USE_EXIT_EVENT
 /**
  * Returns the exit event source for the specified thread. The source is
  * signaled when the thread terminates.
@@ -235,7 +238,6 @@ t_msg chThdWait(Thread *tp);
  *       option is enabled in \p chconf.h.
  */
 #define chThdGetExitEventSource(tp) (&(tp)->p_exitesource)
-#endif
 
 #endif  /* _THREADS_H_ */
 
diff --git a/src/lib/evtimer.c b/src/lib/evtimer.c
new file mode 100644
index 000000000..212c8f124
--- /dev/null
+++ b/src/lib/evtimer.c
@@ -0,0 +1,68 @@
+/*
+    ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+    This file is part of ChibiOS/RT.
+
+    ChibiOS/RT 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 3 of the License, or
+    (at your option) any later version.
+
+    ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file evtimer.c
+ * @{
+ * Event Timer, this timer generates an event at regular intervals. The
+ * listening threads can use the event to perform time related activities.
+ * Multiple threads can listen to the same timer.
+ */
+
+#include <ch.h>
+
+#include "evtimer.h"
+
+static void tmrcb(void *p) {
+  EvTimer *etp = p;
+
+  chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
+}
+
+/**
+ * Starts the timer, if the timer was already running then the function has
+ * no effect.
+ * @param etp pointer to an initialized \p EvTimer structure.
+ */
+void evtStart(EvTimer *etp) {
+
+  chSysLock();
+
+  if (!etp->et_vt.vt_func)
+    chVTSetI(&etp->et_vt, etp->et_interval, tmrcb, etp);
+
+  chSysUnlock();
+}
+
+/**
+ * Stops the timer, if the timer was already stopped then the function has
+ * no effect.
+ * @param etp pointer to an initialized \p EvTimer structure.
+ */
+void evtStop(EvTimer *etp) {
+
+  chSysLock();
+
+  if (etp->et_vt.vt_func)
+    chVTResetI(&etp->et_vt);
+
+  chSysUnlock();
+}
+
+/** @} */
diff --git a/src/lib/evtimer.h b/src/lib/evtimer.h
new file mode 100644
index 000000000..43b0374ee
--- /dev/null
+++ b/src/lib/evtimer.h
@@ -0,0 +1,65 @@
+/*
+    ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+    This file is part of ChibiOS/RT.
+
+    ChibiOS/RT 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 3 of the License, or
+    (at your option) any later version.
+
+    ChibiOS/RT 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, see <http://www.gnu.org/licenses/>.
+*/
+
+/**
+ * @file evtimer.h
+ * @{
+ * Event Timer definitions.
+ * @see evtimer.c
+ */
+
+#ifndef _EVTIMER_H_
+#define _EVTIMER_H_
+
+
+typedef struct {
+  VirtualTimer  et_vt;
+  EventSource   et_es;
+  t_time        et_interval;
+} EvTimer;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+  void evtStart(EvTimer *etp);
+  void evtStop(EvTimer *etp);
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * Initializes an \p EvTimer structure.
+ */
+#define evtInit(et, i) (chEvtInit(&(etp)->et_es), \
+                       (etp)->et_vt.vt_func = NULL, \
+                       (etp)->et_interval = (i))
+
+/**
+ * Registers the invoking thread as listener on the timer event.
+ */
+#define evtRegister(etp, el, eid) chEvtRegister(&(etp)->et_es, el, eid)
+
+/**
+ * Unregisters the invoking thread as listener on the timer event.
+ */
+#define evtUnregister(etp, el) chEvtUnregister(&(etp)->et_es, el)
+
+#endif /* _EVTIMER_H_ */
+
+/** @} */
diff --git a/test/test.c b/test/test.c
index 4351e79a2..fbaedd280 100644
--- a/test/test.c
+++ b/test/test.c
@@ -35,7 +35,7 @@ static BYTE8 wsT5[UserStackSize(64)];
 static Thread *t1, *t2, *t3, *t4, *t5;
 
 static FullDuplexDriver *comp;
-static Semaphore sem1, sem2;
+static Semaphore sem1;
 
 static void wait(void) {
 
-- 
cgit v1.2.3