git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@655 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2009-01-21 11:32:31 +00:00
parent 12721da8ad
commit 22fe505a81
7 changed files with 73 additions and 33 deletions

View File

@ -192,7 +192,28 @@
*
* @section thread_states Threads States
* The image shows how threads can change their state in ChibiOS/RT.<br>
* @image html states.png
* @dot
digraph example {
/*rankdir="LR";*/
node [shape=circle, fontname=Helvetica, fontsize=8, fixedsize="true", width="0.75", height="0.75"];
start [label="Start", style="bold"];
run [label="Running"];
ready [label="Ready"];
suspend [label="Suspended"];
sleep [label="Sleeping"];
stop [label="Stop", style="bold"];
start -> suspend [label="chThdInit()", fontname=Helvetica, fontsize=8, constraint=false];
start -> run [label="chThdCreate()", fontname=Helvetica, fontsize=8];
start -> ready [label="chThdCreate()", fontname=Helvetica, fontsize=8];
run -> ready [dir="both", label="Reschedulation", fontname=Helvetica, fontsize=8];
suspend -> run [label="chThdResume()", fontname=Helvetica, fontsize=8];
suspend -> ready [label="chThdResume()", fontname=Helvetica, fontsize=8];
run -> sleep [label="chSchGoSleepS()", fontname=Helvetica, fontsize=8];
sleep -> run [label="chSchWakepS()", fontname=Helvetica, fontsize=8];
sleep -> ready [label="chSchWakepS()", fontname=Helvetica, fontsize=8];
run -> stop [label="chThdExit()", fontname=Helvetica, fontsize=8];
}
* @enddot
*
* @section priority Priority Levels
* Priorities in ChibiOS/RT are a contiguous numerical range but the initial
@ -246,6 +267,7 @@
* - @subpage article_atomic
* - @subpage article_saveram
* - @subpage article_interrupts
* - @subpage article_timing
*/
/** @} */

View File

@ -12,17 +12,13 @@
chSemSignalI(&sem1);
chSemSignalI(&sem2);
if (tp != NULL) {
chThdResumeI(tp);
tp = NULL;
}
chSchRescheduleS();
chSysUnlock();
* @endcode
* The above example performs a signal operation on two semaphores, optionally
* resumes a thread, and performs a final reschedulation. The three operations
* are performed atomically.<br>
* The above example performs a signal operation on two semaphores and
* performs a final reschedulation. The two operations are performed
* atomically.<br>
* An hypotetical @p chSemSignalSignalWait() operation could be implemented as
* follow:
* @code

42
docs/src/timing.dox Normal file
View File

@ -0,0 +1,42 @@
/**
* @page article_timing Reliable timings using Threads
* @{
* One common task is to have threads do something at regular, scheduled,
* intervals.
* An obvious solution is to write something like this:
* @code
msg_t my_thread(void *param) {
while (TRUE) {
do_something();
chThdSleepMilliseconds(1000); /* Fixed interval */
}
}
* @endcode
* This example works well assuming that @p do_something() execution time is
* well below the system tick period and that @p my_thread() is not preempted
* by other threads inserting long intervals.<br>
* If the above conditions are not satisfied you may have @p do_something()
* executed at irregular intevals, as example:<br><br>
* T0...T0+1000...T0+2002...T0+3002...T0+4005...etc.<br><br>
* Also note that the error increases over time and this kind of behavior can
* lead anomalies really hard to debug.
* <h2>A better solution</h2>
* It is possible to rewrite the above code using absolute deadlines rather
* than fixed intervals:
* @code
msg_t my_thread(void *param) {
systick_t time = chSysGetTime(); /* T0 */
while (TRUE) {
time += MS2ST(1000); /* Next deadline */
do_something();
chThdSleepUntil(time);
}
}
* @endcode
* Using this code @p do_something() will always be executed at an absolute
* deadline time and the error will not accumulate over time regardless of
* the execution time and delays inserted by other threads.
*/
/** @} */

View File

@ -102,11 +102,13 @@ static void wakeup(void *p) {
#ifdef CH_USE_SEMAPHORES
case PRWTSEM:
chSemFastSignalI(tp->p_wtsemp);
/* Falls into, intentional.*/
/* Falls into, intentional. */
#endif
case PRWTCOND:
chSchReadyI(dequeue(tp))->p_rdymsg = RDY_TIMEOUT;
break;
case PRWTMTX:
/* States requiring dequeuing. */
dequeue(tp);
/* Falls into, intentional. */
default:
chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT;
}

View File

@ -214,26 +214,6 @@ void chThdSetPriority(tprio_t newprio) {
chSysUnlock();
}
/**
* @brief Suspends the invoking thread.
*
* @param tpp pointer to a @p Thread pointer, the @p Thread pointer is set
* to point to the suspended process before it enters the
* @p PRSUSPENDED state. The variable pointed by this parameter
* must be set to @p NULL on entry.
* @note The resume operation is meant to be executed into an interrupt or timer
* handler. The handler is also responsible to clear the variable pointed
* by @p tpp after invoking @p chThdResumeI().
*/
void chThdSuspend(Thread **tpp) {
chSysLock();
chDbgAssert(*tpp == NULL, "chthreads.c, chThdSuspend()");
*tpp = currp;
chSchGoSleepS(PRSUSPENDED);
chSysUnlock();
}
/**
* @brief Resumes a suspended thread.
*

View File

@ -183,7 +183,6 @@ extern "C" {
#endif
void chThdSetPriority(tprio_t newprio);
Thread *chThdResume(Thread *tp);
void chThdSuspend(Thread **tpp);
void chThdTerminate(Thread *tp);
void chThdSleep(systime_t time);
void chThdSleepUntil(systime_t time);

View File

@ -94,7 +94,6 @@ static void sem2_execute(void) {
test_assert(isempty(&sem1.s_queue), "queue not empty");
test_assert(&sem1.s_cnt != 0, "counter not zero");
}
test_assert(chSemGetCounter(&sem1) == 0, "non zero counter");
test_assert_sequence("ABCDE");
test_assert_time_window(target_time, target_time + ALLOWED_DELAY);
}