aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demos/ARM7-LPC214x-GCC/Makefile10
-rw-r--r--demos/ARM7-LPC214x-GCC/chcore.h2
-rw-r--r--demos/ARM7-LPC214x-GCC/main.c10
-rw-r--r--demos/AVR-AT90CANx-GCC/chcore.h4
-rw-r--r--readme.txt8
-rw-r--r--src/include/ch.h8
-rw-r--r--src/include/delta.h13
-rw-r--r--src/include/events.h22
-rw-r--r--src/include/lists.h18
-rw-r--r--src/include/messages.h22
-rw-r--r--src/include/queues.h64
-rw-r--r--src/include/scheduler.h22
-rw-r--r--src/include/semaphores.h34
-rw-r--r--src/include/serial.h38
-rw-r--r--src/include/sleep.h17
-rw-r--r--src/include/threads.h30
-rw-r--r--src/lib/evtimer.c68
-rw-r--r--src/lib/evtimer.h65
-rw-r--r--test/test.c2
19 files changed, 334 insertions, 123 deletions
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) {