git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@30 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
1b269aa139
commit
2310f80695
|
@ -63,6 +63,10 @@
|
||||||
* in the kernel.*/
|
* in the kernel.*/
|
||||||
#define CH_USE_SEMAPHORES
|
#define CH_USE_SEMAPHORES
|
||||||
|
|
||||||
|
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
|
||||||
|
* APIs are included in the kernel.*/
|
||||||
|
#define CH_USE_SEMSW
|
||||||
|
|
||||||
/** Configuration option: if specified then the Semaphores with timeout APIs
|
/** Configuration option: if specified then the Semaphores with timeout APIs
|
||||||
* are included in the kernel.
|
* are included in the kernel.
|
||||||
* @note requires \p CH_USE_SEMAPHORES.
|
* @note requires \p CH_USE_SEMAPHORES.
|
||||||
|
|
|
@ -182,6 +182,13 @@
|
||||||
RelativePath="..\..\ports\Win32\simcom.c">
|
RelativePath="..\..\ports\Win32\simcom.c">
|
||||||
</File>
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
|
<Filter
|
||||||
|
Name="test"
|
||||||
|
Filter="">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\test\test.c">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
|
|
|
@ -68,6 +68,10 @@
|
||||||
* in the kernel.*/
|
* in the kernel.*/
|
||||||
#define CH_USE_SEMAPHORES
|
#define CH_USE_SEMAPHORES
|
||||||
|
|
||||||
|
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
|
||||||
|
* APIs are included in the kernel.*/
|
||||||
|
#define CH_USE_SEMSW
|
||||||
|
|
||||||
/** Configuration option: if specified then the Semaphores with timeout APIs
|
/** Configuration option: if specified then the Semaphores with timeout APIs
|
||||||
* are included in the kernel.
|
* are included in the kernel.
|
||||||
* @note requires \p CH_USE_SEMAPHORES.
|
* @note requires \p CH_USE_SEMAPHORES.
|
||||||
|
@ -134,11 +138,11 @@
|
||||||
|
|
||||||
/** Configuration option: Frequency of the system timer that drives the system
|
/** Configuration option: Frequency of the system timer that drives the system
|
||||||
* ticks. This also defines the system time unit.*/
|
* ticks. This also defines the system time unit.*/
|
||||||
#define CH_FREQUENCY 100
|
#define CH_FREQUENCY 1000
|
||||||
|
|
||||||
/** Configuration option: This constant is the number of ticks allowed for the
|
/** Configuration option: This constant is the number of ticks allowed for the
|
||||||
* threads before preemption occurs.*/
|
* threads before preemption occurs.*/
|
||||||
#define CH_TIME_QUANTUM 10
|
#define CH_TIME_QUANTUM 20
|
||||||
|
|
||||||
/** Configuration option: Defines a CPU register to be used as storage for the
|
/** Configuration option: Defines a CPU register to be used as storage for the
|
||||||
* global \p currp variable. Caching this variable in a register can greatly
|
* global \p currp variable. Caching this variable in a register can greatly
|
||||||
|
|
|
@ -36,6 +36,8 @@ static t_msg WatchdogThread(void *arg);
|
||||||
static t_msg ConsoleThread(void *arg);
|
static t_msg ConsoleThread(void *arg);
|
||||||
static t_msg InitThread(void *arg);
|
static t_msg InitThread(void *arg);
|
||||||
|
|
||||||
|
t_msg TestThread(void *p);
|
||||||
|
|
||||||
void InitCore(void);
|
void InitCore(void);
|
||||||
extern FullDuplexDriver COM1, COM2;
|
extern FullDuplexDriver COM1, COM2;
|
||||||
|
|
||||||
|
@ -73,7 +75,7 @@ static t_msg WatchdogThread(void *arg) {
|
||||||
printf("Halted by watchdog");
|
printf("Halted by watchdog");
|
||||||
chSysHalt();
|
chSysHalt();
|
||||||
}
|
}
|
||||||
chThdSleep(5);
|
chThdSleep(50);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +146,7 @@ static t_msg HelloWorldThread(void *arg) {
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
|
|
||||||
PrintLineFDD(sd, "Hello World\r\n");
|
PrintLineFDD(sd, "Hello World\r\n");
|
||||||
c = chFDDGetTimeout(sd, 33);
|
c = chFDDGetTimeout(sd, 333);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case -1:
|
case -1:
|
||||||
continue;
|
continue;
|
||||||
|
@ -154,7 +156,7 @@ static t_msg HelloWorldThread(void *arg) {
|
||||||
PrintLineFDD(sd, "^C\r\n");
|
PrintLineFDD(sd, "^C\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
chThdSleep(33);
|
chThdSleep(333);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -202,6 +204,7 @@ static t_msg ShellThread(void *arg) {
|
||||||
PrintLineFDD(sd, " exit - Logout from ChibiOS/RT\r\n");
|
PrintLineFDD(sd, " exit - Logout from ChibiOS/RT\r\n");
|
||||||
PrintLineFDD(sd, " time - Prints the system timer value\r\n");
|
PrintLineFDD(sd, " time - Prints the system timer value\r\n");
|
||||||
PrintLineFDD(sd, " hello - Runs the Hello World demo thread\r\n");
|
PrintLineFDD(sd, " hello - Runs the Hello World demo thread\r\n");
|
||||||
|
PrintLineFDD(sd, " test - Runs the System Test thread\r\n");
|
||||||
}
|
}
|
||||||
else if (stricmp(lp, "exit") == 0) {
|
else if (stricmp(lp, "exit") == 0) {
|
||||||
if (checkend(sd))
|
if (checkend(sd))
|
||||||
|
@ -223,6 +226,14 @@ static t_msg ShellThread(void *arg) {
|
||||||
if (chThdWait(tp))
|
if (chThdWait(tp))
|
||||||
break; // Lost connection while executing the hello thread.
|
break; // Lost connection while executing the hello thread.
|
||||||
}
|
}
|
||||||
|
else if (stricmp(lp, "test") == 0) {
|
||||||
|
if (checkend(sd))
|
||||||
|
continue;
|
||||||
|
tp = chThdCreate(NORMALPRIO, 0, tarea, sizeof(tarea),
|
||||||
|
TestThread, arg);
|
||||||
|
if (chThdWait(tp))
|
||||||
|
break; // Lost connection while executing the hello thread.
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
PrintLineFDD(sd, lp);
|
PrintLineFDD(sd, lp);
|
||||||
PrintLineFDD(sd, " ?\r\n");
|
PrintLineFDD(sd, " ?\r\n");
|
||||||
|
|
|
@ -57,7 +57,7 @@ UADEFS =
|
||||||
|
|
||||||
# List C source files here
|
# List C source files here
|
||||||
SRC = chcore.c demo.c \
|
SRC = chcore.c demo.c \
|
||||||
../../ports/win32/simcom.c \
|
../../test/test.c ../../ports/win32/simcom.c \
|
||||||
../../src/chinit.c ../../src/chlists.c ../../src/chdelta.c ../../src/chschd.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 \
|
../../src/chthreads.c ../../src/chsem.c ../../src/chevents.c ../../src/chmsg.c \
|
||||||
../../src/chsleep.c ../../src/chqueues.c ../../src/chserial.c
|
../../src/chsleep.c ../../src/chqueues.c ../../src/chserial.c
|
||||||
|
|
|
@ -68,6 +68,10 @@
|
||||||
* in the kernel.*/
|
* in the kernel.*/
|
||||||
#define CH_USE_SEMAPHORES
|
#define CH_USE_SEMAPHORES
|
||||||
|
|
||||||
|
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
|
||||||
|
* APIs are included in the kernel.*/
|
||||||
|
#define CH_USE_SEMSW
|
||||||
|
|
||||||
/** Configuration option: if specified then the Semaphores with timeout APIs
|
/** Configuration option: if specified then the Semaphores with timeout APIs
|
||||||
* are included in the kernel.
|
* are included in the kernel.
|
||||||
* @note requires \p CH_USE_SEMAPHORES.
|
* @note requires \p CH_USE_SEMAPHORES.
|
||||||
|
@ -134,11 +138,11 @@
|
||||||
|
|
||||||
/** Configuration option: Frequency of the system timer that drives the system
|
/** Configuration option: Frequency of the system timer that drives the system
|
||||||
* ticks. This also defines the system time unit.*/
|
* ticks. This also defines the system time unit.*/
|
||||||
#define CH_FREQUENCY 100
|
#define CH_FREQUENCY 1000
|
||||||
|
|
||||||
/** Configuration option: This constant is the number of ticks allowed for the
|
/** Configuration option: This constant is the number of ticks allowed for the
|
||||||
* threads before preemption occurs.*/
|
* threads before preemption occurs.*/
|
||||||
#define CH_TIME_QUANTUM 10
|
#define CH_TIME_QUANTUM 20
|
||||||
|
|
||||||
/** Configuration option: Defines a CPU register to be used as storage for the
|
/** Configuration option: Defines a CPU register to be used as storage for the
|
||||||
* global \p currp variable. Caching this variable in a register can greatly
|
* global \p currp variable. Caching this variable in a register can greatly
|
||||||
|
|
|
@ -52,7 +52,7 @@ void InitCore(void) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Win32 ChobiOS/RT simulator\n\n");
|
printf("Win32 ChibiOS/RT simulator\n\n");
|
||||||
printf("Thread structure %d bytes\n", sizeof(Thread));
|
printf("Thread structure %d bytes\n", sizeof(Thread));
|
||||||
if (!QueryPerformanceFrequency(&slice)) {
|
if (!QueryPerformanceFrequency(&slice)) {
|
||||||
printf("QueryPerformanceFrequency() error");
|
printf("QueryPerformanceFrequency() error");
|
||||||
|
|
|
@ -39,5 +39,5 @@
|
||||||
.p2align 4,,15
|
.p2align 4,,15
|
||||||
.globl @threadstart@0
|
.globl @threadstart@0
|
||||||
@threadstart@0:
|
@threadstart@0:
|
||||||
push %ecx
|
push %eax
|
||||||
call _chThdExit
|
call _chThdExit
|
||||||
|
|
|
@ -36,6 +36,8 @@ static t_msg WatchdogThread(void *arg);
|
||||||
static t_msg ConsoleThread(void *arg);
|
static t_msg ConsoleThread(void *arg);
|
||||||
static t_msg InitThread(void *arg);
|
static t_msg InitThread(void *arg);
|
||||||
|
|
||||||
|
t_msg TestThread(void *p);
|
||||||
|
|
||||||
void InitCore(void);
|
void InitCore(void);
|
||||||
extern FullDuplexDriver COM1, COM2;
|
extern FullDuplexDriver COM1, COM2;
|
||||||
|
|
||||||
|
@ -73,7 +75,7 @@ static t_msg WatchdogThread(void *arg) {
|
||||||
printf("Halted by watchdog");
|
printf("Halted by watchdog");
|
||||||
chSysHalt();
|
chSysHalt();
|
||||||
}
|
}
|
||||||
chThdSleep(5);
|
chThdSleep(50);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +146,7 @@ static t_msg HelloWorldThread(void *arg) {
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
|
|
||||||
PrintLineFDD(sd, "Hello World\r\n");
|
PrintLineFDD(sd, "Hello World\r\n");
|
||||||
c = chFDDGetTimeout(sd, 33);
|
c = chFDDGetTimeout(sd, 333);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case -1:
|
case -1:
|
||||||
continue;
|
continue;
|
||||||
|
@ -154,7 +156,7 @@ static t_msg HelloWorldThread(void *arg) {
|
||||||
PrintLineFDD(sd, "^C\r\n");
|
PrintLineFDD(sd, "^C\r\n");
|
||||||
return 0;
|
return 0;
|
||||||
default:
|
default:
|
||||||
chThdSleep(33);
|
chThdSleep(333);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -202,6 +204,7 @@ static t_msg ShellThread(void *arg) {
|
||||||
PrintLineFDD(sd, " exit - Logout from ChibiOS/RT\r\n");
|
PrintLineFDD(sd, " exit - Logout from ChibiOS/RT\r\n");
|
||||||
PrintLineFDD(sd, " time - Prints the system timer value\r\n");
|
PrintLineFDD(sd, " time - Prints the system timer value\r\n");
|
||||||
PrintLineFDD(sd, " hello - Runs the Hello World demo thread\r\n");
|
PrintLineFDD(sd, " hello - Runs the Hello World demo thread\r\n");
|
||||||
|
PrintLineFDD(sd, " test - Runs the System Test thread\r\n");
|
||||||
}
|
}
|
||||||
else if (stricmp(lp, "exit") == 0) {
|
else if (stricmp(lp, "exit") == 0) {
|
||||||
if (checkend(sd))
|
if (checkend(sd))
|
||||||
|
@ -223,6 +226,14 @@ static t_msg ShellThread(void *arg) {
|
||||||
if (chThdWait(tp))
|
if (chThdWait(tp))
|
||||||
break; // Lost connection while executing the hello thread.
|
break; // Lost connection while executing the hello thread.
|
||||||
}
|
}
|
||||||
|
else if (stricmp(lp, "test") == 0) {
|
||||||
|
if (checkend(sd))
|
||||||
|
continue;
|
||||||
|
tp = chThdCreate(NORMALPRIO, 0, tarea, sizeof(tarea),
|
||||||
|
TestThread, arg);
|
||||||
|
if (chThdWait(tp))
|
||||||
|
break; // Lost connection while executing the hello thread.
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
PrintLineFDD(sd, lp);
|
PrintLineFDD(sd, lp);
|
||||||
PrintLineFDD(sd, " ?\r\n");
|
PrintLineFDD(sd, " ?\r\n");
|
||||||
|
|
|
@ -241,7 +241,8 @@ PREDEFINED = __JUST_STUBS__ \
|
||||||
CH_USE_SERIAL_HALFDUPLEX \
|
CH_USE_SERIAL_HALFDUPLEX \
|
||||||
CH_USE_MESSAGES \
|
CH_USE_MESSAGES \
|
||||||
CH_USE_MESSAGES_TIMEOUT \
|
CH_USE_MESSAGES_TIMEOUT \
|
||||||
CH_USE_MESSAGES_EVENT
|
CH_USE_MESSAGES_EVENT \
|
||||||
|
CH_USE_SEMSW
|
||||||
EXPAND_AS_DEFINED =
|
EXPAND_AS_DEFINED =
|
||||||
SKIP_FUNCTION_MACROS = YES
|
SKIP_FUNCTION_MACROS = YES
|
||||||
#---------------------------------------------------------------------------
|
#---------------------------------------------------------------------------
|
||||||
|
|
21
readme.txt
21
readme.txt
|
@ -33,23 +33,36 @@ LPC214x-GCC - ChibiOS/RT port for ARM7 LPC2148, the demo targets the
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 0.3.1 ***
|
*** 0.3.1 ***
|
||||||
|
- Test program added to the MinGW and MSVS demos. Telnet the demo and type
|
||||||
|
"test" at the "ch>" prompt. The test performs integrity tests on the main
|
||||||
|
ChibiOS/RT functionalities.
|
||||||
|
The test code is also a good example of APIs usage and ChibiOS/RT behavior.
|
||||||
|
- Fixed bug in chEvtWaitTimeout(), the timeout code performed an useless
|
||||||
|
dequeue operation.
|
||||||
|
- Fixed a bug in chSemWaitTimeoutS() and chSemWaitTimeout(), the semaphore
|
||||||
|
counter was not atomically updated on a timeout condition.
|
||||||
|
- Fixed bug on RT semaphores, the priority queuing was broken.
|
||||||
|
- Fixed a bug in the MinGW demo, the chThdExit() code was not correctly
|
||||||
|
reported to the thread waiting in chThdWait().
|
||||||
|
- Fixed a function declaration in semaphores.h.
|
||||||
- Lists code moved into chlists.c from various other places optimized and
|
- Lists code moved into chlists.c from various other places optimized and
|
||||||
reorganized.
|
reorganized.
|
||||||
- The list of the threads waiting in chThdWait() is now a single link list,
|
- The list of the threads waiting in chThdWait() is now a single link list,
|
||||||
this saves some space.
|
this saves some space.
|
||||||
- Cleaned the template files code, the files contained some obsolete
|
- Cleaned the template files code, the files contained some obsolete
|
||||||
declarations.
|
declarations.
|
||||||
- Code optimization in scSemSignalWait().
|
- Code optimization in chSemWaitTimeoutS(), chSemWaitTimeout() and
|
||||||
|
chSemSignalWait().
|
||||||
- Code optimization in chEvtSend().
|
- Code optimization in chEvtSend().
|
||||||
|
- Code optimization in chVTDoTickI().
|
||||||
- Added a Semaphore pointer to the Thread structure, this allows to know on
|
- Added a Semaphore pointer to the Thread structure, this allows to know on
|
||||||
which semaphore a thread is waiting on. It takes no space because it is
|
which semaphore a thread is waiting on. It takes no space because it is
|
||||||
located in the union inside the Thread structure. This also allowed a minor
|
located in the union inside the Thread structure. This also allowed a minor
|
||||||
optimization inside chSemWaitTimeout() and chSemWaitTimeoutS().
|
optimization inside chSemWaitTimeout() and chSemWaitTimeoutS().
|
||||||
- Changed the priority type to unsigned in order to make it compatible
|
- Changed the priority type to unsigned in order to make it compatible
|
||||||
with a byte value, this is very important for 8 bits architectures.
|
with a byte value, this is very important for 8 bits architectures.
|
||||||
- Fixed bug in chEvtWaitTimeout(), the timeout code performed a useless
|
- Modified the MinGW and MSVS demos to use 1ms ticks instead of 10ms as
|
||||||
dequeue operation.
|
before.
|
||||||
- Fixed bug on RT semaphores, the priority queuing was broken.
|
|
||||||
|
|
||||||
*** 0.3.0 ***
|
*** 0.3.0 ***
|
||||||
- ChibiOS/RT goes beta.
|
- ChibiOS/RT goes beta.
|
||||||
|
|
17
src/chsem.c
17
src/chsem.c
|
@ -138,12 +138,8 @@ t_msg chSemWaitTimeout(Semaphore *sp, t_time time) {
|
||||||
fifo_insert(currp, &sp->s_queue);
|
fifo_insert(currp, &sp->s_queue);
|
||||||
currp->p_semp = sp;
|
currp->p_semp = sp;
|
||||||
chSchGoSleepI(PRWTSEM);
|
chSchGoSleepI(PRWTSEM);
|
||||||
msg = currp->p_rdymsg; // Note, got value *before* invoking CH_LEAVE_SYSTEM().
|
msg = currp->p_rdymsg;
|
||||||
if (!vt.vt_func) {
|
if (vt.vt_func)
|
||||||
|
|
||||||
chSysUnlock();
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
chVTResetI(&vt);
|
chVTResetI(&vt);
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
@ -173,8 +169,7 @@ t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time) {
|
||||||
fifo_insert(currp, &sp->s_queue);
|
fifo_insert(currp, &sp->s_queue);
|
||||||
currp->p_semp = sp;
|
currp->p_semp = sp;
|
||||||
chSchGoSleepI(PRWTSEM);
|
chSchGoSleepI(PRWTSEM);
|
||||||
if (!vt.vt_func)
|
if (vt.vt_func)
|
||||||
return currp->p_rdymsg;
|
|
||||||
chVTResetI(&vt);
|
chVTResetI(&vt);
|
||||||
return currp->p_rdymsg;
|
return currp->p_rdymsg;
|
||||||
}
|
}
|
||||||
|
@ -211,6 +206,7 @@ void chSemSignalI(Semaphore *sp) {
|
||||||
chSchReadyI(fifo_remove(&sp->s_queue));
|
chSchReadyI(fifo_remove(&sp->s_queue));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CH_USE_SEMSW
|
||||||
/**
|
/**
|
||||||
* Performs atomic signal and wait operations on two semaphores.
|
* Performs atomic signal and wait operations on two semaphores.
|
||||||
* @param sps pointer to a \p Semaphore structure to be signaled
|
* @param sps pointer to a \p Semaphore structure to be signaled
|
||||||
|
@ -235,6 +231,7 @@ void chSemSignalWait(Semaphore *sps, Semaphore *spw) {
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
#endif /* CH_USE_SEMSW */
|
||||||
|
|
||||||
#ifdef CH_USE_RT_SEMAPHORES
|
#ifdef CH_USE_RT_SEMAPHORES
|
||||||
/*
|
/*
|
||||||
|
@ -299,6 +296,7 @@ void chSemLowerPrioSignal(Semaphore *sp) {
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CH_USE_SEMSW
|
||||||
/**
|
/**
|
||||||
* Performs atomic signal and wait operations on two semaphores with priority
|
* Performs atomic signal and wait operations on two semaphores with priority
|
||||||
* boost.
|
* boost.
|
||||||
|
@ -326,7 +324,7 @@ void chSemRaisePrioSignalWait(Semaphore *sps, Semaphore *spw) {
|
||||||
if (!currp->p_rtcnt++)
|
if (!currp->p_rtcnt++)
|
||||||
currp->p_prio += MEPRIO;
|
currp->p_prio += MEPRIO;
|
||||||
|
|
||||||
chSchRescheduleI();
|
chSchRescheduleI(); // Really needed ?
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
@ -360,6 +358,7 @@ void chSemLowerPrioSignalWait(Semaphore *sps, Semaphore *spw) {
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
#endif /* CH_USE_SEMSW */
|
||||||
|
|
||||||
#endif /* CH_USE_RT_SEMAPHORES */
|
#endif /* CH_USE_RT_SEMAPHORES */
|
||||||
|
|
||||||
|
|
|
@ -77,8 +77,7 @@ extern DeltaList dlist;
|
||||||
while (!(vtp = dlist.dl_next)->vt_dtime) { \
|
while (!(vtp = dlist.dl_next)->vt_dtime) { \
|
||||||
t_vtfunc fn = vtp->vt_func; \
|
t_vtfunc fn = vtp->vt_func; \
|
||||||
vtp->vt_func = 0; \
|
vtp->vt_func = 0; \
|
||||||
vtp->vt_prev->vt_next = vtp->vt_next; \
|
(vtp->vt_next->vt_prev = (VirtualTimer *)&dlist)->vt_next = vtp->vt_next; \
|
||||||
vtp->vt_next->vt_prev = vtp->vt_prev; \
|
|
||||||
fn(vtp->vt_par); \
|
fn(vtp->vt_par); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ t_msg chSemWaitTimeout(Semaphore *sp, t_time time);
|
||||||
t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time);
|
t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time);
|
||||||
void chSemSignal(Semaphore *sp);
|
void chSemSignal(Semaphore *sp);
|
||||||
void chSemSignalI(Semaphore *sp);
|
void chSemSignalI(Semaphore *sp);
|
||||||
void chSignalWait(Semaphore *sps, Semaphore *spw);
|
void chSemSignalWait(Semaphore *sps, Semaphore *spw);
|
||||||
|
|
||||||
#ifdef CH_USE_RT_SEMAPHORES
|
#ifdef CH_USE_RT_SEMAPHORES
|
||||||
void chSemRaisePrioWait(Semaphore *sp);
|
void chSemRaisePrioWait(Semaphore *sp);
|
||||||
|
|
|
@ -64,6 +64,10 @@
|
||||||
* in the kernel.*/
|
* in the kernel.*/
|
||||||
#define CH_USE_SEMAPHORES
|
#define CH_USE_SEMAPHORES
|
||||||
|
|
||||||
|
/** Configuration option: if specified then the Semaphores atomic Signal+Wait
|
||||||
|
* APIs are included in the kernel.*/
|
||||||
|
#define CH_USE_SEMSW
|
||||||
|
|
||||||
/** Configuration option: if specified then the Semaphores with timeout APIs
|
/** Configuration option: if specified then the Semaphores with timeout APIs
|
||||||
* are included in the kernel.
|
* are included in the kernel.
|
||||||
* @note requires \p CH_USE_SEMAPHORES.
|
* @note requires \p CH_USE_SEMAPHORES.
|
||||||
|
|
|
@ -0,0 +1,273 @@
|
||||||
|
/*
|
||||||
|
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/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ch.h>
|
||||||
|
|
||||||
|
#if defined(WIN32) && defined(_DEBUG)
|
||||||
|
static BYTE8 wsT1[UserStackSize(512)];
|
||||||
|
static BYTE8 wsT2[UserStackSize(512)];
|
||||||
|
static BYTE8 wsT3[UserStackSize(512)];
|
||||||
|
static BYTE8 wsT4[UserStackSize(512)];
|
||||||
|
static BYTE8 wsT5[UserStackSize(512)];
|
||||||
|
#else
|
||||||
|
static BYTE8 wsT1[UserStackSize(64)];
|
||||||
|
static BYTE8 wsT2[UserStackSize(64)];
|
||||||
|
static BYTE8 wsT3[UserStackSize(64)];
|
||||||
|
static BYTE8 wsT4[UserStackSize(64)];
|
||||||
|
static BYTE8 wsT5[UserStackSize(64)];
|
||||||
|
#endif
|
||||||
|
static Thread *t1, *t2, *t3, *t4, *t5;
|
||||||
|
|
||||||
|
static FullDuplexDriver *comp;
|
||||||
|
static Semaphore sem1, sem2;
|
||||||
|
|
||||||
|
static void wait(void) {
|
||||||
|
|
||||||
|
chThdWait(t1);
|
||||||
|
chThdWait(t2);
|
||||||
|
chThdWait(t3);
|
||||||
|
chThdWait(t4);
|
||||||
|
chThdWait(t5);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void println(char *msgp) {
|
||||||
|
|
||||||
|
while (*msgp)
|
||||||
|
chFDDPut(comp, *msgp++);
|
||||||
|
chFDDPut(comp, '\r');
|
||||||
|
chFDDPut(comp, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread1(void *p) {
|
||||||
|
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread2(void *p) {
|
||||||
|
|
||||||
|
chSemWait(&sem1);
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread3(void *p) {
|
||||||
|
|
||||||
|
chSemRaisePrioWait(&sem1);
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread4(void *p) {
|
||||||
|
|
||||||
|
chSemWait(&sem1);
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
/*
|
||||||
|
* NOTE: chSemSignalWait() is not the same of chSemSignal()+chSemWait().
|
||||||
|
* The former is performed atomically, try it.
|
||||||
|
*/
|
||||||
|
chSemSignalWait(&sem1, &sem2);
|
||||||
|
// chSemSignal(&sem1);
|
||||||
|
// chSemWait(&sem2);
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
chSemSignal(&sem2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread5(void *p) {
|
||||||
|
|
||||||
|
chSemWait(&sem1);
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
chSemRaisePrioSignalWait(&sem1, &sem2);
|
||||||
|
// chSemSignal(&sem1);
|
||||||
|
// chSemRaisePrioWait(&sem2);
|
||||||
|
chFDDPut(comp, *(BYTE8 *)p);
|
||||||
|
chSemLowerPrioSignal(&sem2);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread6(void *p) {
|
||||||
|
t_msg msg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
msg = chMsgSend(p, 'A' + i);
|
||||||
|
chFDDPut(comp, msg);
|
||||||
|
}
|
||||||
|
chMsgSend(p, 0);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
t_msg Thread7(void *p) {
|
||||||
|
|
||||||
|
// NOTE, this thread does not serve messages this causes the client to
|
||||||
|
// timeout.
|
||||||
|
chThdSleep(3000);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tester thread, this thread must be created with priority \p NORMALPRIO.
|
||||||
|
*/
|
||||||
|
t_msg TestThread(void *p) {
|
||||||
|
t_msg msg;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
comp = p;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ready list ordering test.
|
||||||
|
*/
|
||||||
|
println("*** Ready List, priority enqueuing test #1, you should read ABCDE:");
|
||||||
|
t5 = chThdCreate(NORMALPRIO-5, 0, wsT5, sizeof(wsT5), Thread1, "E");
|
||||||
|
t4 = chThdCreate(NORMALPRIO-4, 0, wsT4, sizeof(wsT4), Thread1, "D");
|
||||||
|
t3 = chThdCreate(NORMALPRIO-3, 0, wsT3, sizeof(wsT3), Thread1, "C");
|
||||||
|
t2 = chThdCreate(NORMALPRIO-2, 0, wsT2, sizeof(wsT2), Thread1, "B");
|
||||||
|
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread1, "A");
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Ready List, priority enqueuing test #2, you should read ABCDE:");
|
||||||
|
t4 = chThdCreate(NORMALPRIO-4, 0, wsT4, sizeof(wsT4), Thread1, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO-5, 0, wsT5, sizeof(wsT5), Thread1, "E");
|
||||||
|
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread1, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO-2, 0, wsT2, sizeof(wsT2), Thread1, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO-3, 0, wsT3, sizeof(wsT3), Thread1, "C");
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Semaphores test.
|
||||||
|
*/
|
||||||
|
chSemInit(&sem1, 0);
|
||||||
|
println("*** Semaphores, FIFO enqueuing test, you should read ABCDE:");
|
||||||
|
t1 = chThdCreate(NORMALPRIO+5, 0, wsT1, sizeof(wsT1), Thread2, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+1, 0, wsT2, sizeof(wsT2), Thread2, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread2, "C");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread2, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+2, 0, wsT5, sizeof(wsT5), Thread2, "E");
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, priority enqueuing test #1, you should read ABCDE:");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+1, 0, wsT5, sizeof(wsT5), Thread3, "E");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+2, 0, wsT4, sizeof(wsT4), Thread3, "D");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread3, "C");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+4, 0, wsT2, sizeof(wsT2), Thread3, "B");
|
||||||
|
t1 = chThdCreate(NORMALPRIO+5, 0, wsT1, sizeof(wsT1), Thread3, "A");
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, priority enqueuing test #2, you should read ABCDE:");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+2, 0, wsT4, sizeof(wsT4), Thread3, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+1, 0, wsT5, sizeof(wsT5), Thread3, "E");
|
||||||
|
t1 = chThdCreate(NORMALPRIO+5, 0, wsT1, sizeof(wsT1), Thread3, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+4, 0, wsT2, sizeof(wsT2), Thread3, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread3, "C");
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
chSemLowerPrioSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, atomicity test #1, you should read ABCDEABCDE:");
|
||||||
|
chSemInit(&sem1, 0);
|
||||||
|
chSemInit(&sem2, 1);
|
||||||
|
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread4, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+2, 0, wsT2, sizeof(wsT2), Thread4, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread4, "C");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread4, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+5, 0, wsT5, sizeof(wsT5), Thread4, "E");
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, atomicity test #2, you should read ABCDEABCDE:");
|
||||||
|
chSemInit(&sem1, 0);
|
||||||
|
chSemInit(&sem2, 1);
|
||||||
|
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread4, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+5, 0, wsT2, sizeof(wsT2), Thread4, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+2, 0, wsT3, sizeof(wsT3), Thread4, "C");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread4, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+3, 0, wsT5, sizeof(wsT5), Thread4, "E");
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, atomicity test #3, you should read AABBCCDDEE:");
|
||||||
|
chSemInit(&sem1, 0);
|
||||||
|
chSemInit(&sem2, 1);
|
||||||
|
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread5, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+2, 0, wsT2, sizeof(wsT2), Thread5, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+3, 0, wsT3, sizeof(wsT3), Thread5, "C");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread5, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+5, 0, wsT5, sizeof(wsT5), Thread5, "E");
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, atomicity test #4, you should read AABBCCDDEE:");
|
||||||
|
chSemInit(&sem1, 0);
|
||||||
|
chSemInit(&sem2, 1);
|
||||||
|
t1 = chThdCreate(NORMALPRIO+1, 0, wsT1, sizeof(wsT1), Thread5, "A");
|
||||||
|
t2 = chThdCreate(NORMALPRIO+5, 0, wsT2, sizeof(wsT2), Thread5, "B");
|
||||||
|
t3 = chThdCreate(NORMALPRIO+2, 0, wsT3, sizeof(wsT3), Thread5, "C");
|
||||||
|
t4 = chThdCreate(NORMALPRIO+4, 0, wsT4, sizeof(wsT4), Thread5, "D");
|
||||||
|
t5 = chThdCreate(NORMALPRIO+3, 0, wsT5, sizeof(wsT5), Thread5, "E");
|
||||||
|
chSemSignal(&sem1);
|
||||||
|
wait();
|
||||||
|
println("");
|
||||||
|
println("*** Semaphores, timeout test, you should read ABCDE (slowly):");
|
||||||
|
chSemInit(&sem1, 0);
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
chFDDPut(comp, 'A'+i);
|
||||||
|
chSemWaitTimeout(&sem1, 500);
|
||||||
|
}
|
||||||
|
println("");
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Messages test.
|
||||||
|
*/
|
||||||
|
println("*** Messages, dispatch test, you should read AABBCCDDEE:");
|
||||||
|
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread6, chThdSelf());
|
||||||
|
do {
|
||||||
|
chMsgRelease(msg = chMsgWait());
|
||||||
|
if (msg)
|
||||||
|
chFDDPut(comp, msg);
|
||||||
|
} while (msg);
|
||||||
|
chThdWait(t1);
|
||||||
|
println("");
|
||||||
|
println("*** Messages, timeout test, you should read ABCDE (slowly):");
|
||||||
|
t1 = chThdCreate(NORMALPRIO-1, 0, wsT1, sizeof(wsT1), Thread7, chThdSelf());
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
chFDDPut(comp, 'A'+i);
|
||||||
|
chMsgSendTimeout(t1, 'A'+i, 500);
|
||||||
|
}
|
||||||
|
chMsgSendTimeout(t1, 0, 500);
|
||||||
|
chThdWait(t1);
|
||||||
|
println("");
|
||||||
|
|
||||||
|
println("\r\nTest complete");
|
||||||
|
return 0;
|
||||||
|
}
|
Loading…
Reference in New Issue