git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@655 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
12721da8ad
commit
22fe505a81
24
docs/ch.txt
24
docs/ch.txt
|
@ -192,7 +192,28 @@
|
||||||
*
|
*
|
||||||
* @section thread_states Threads States
|
* @section thread_states Threads States
|
||||||
* The image shows how threads can change their state in ChibiOS/RT.<br>
|
* 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
|
* @section priority Priority Levels
|
||||||
* Priorities in ChibiOS/RT are a contiguous numerical range but the initial
|
* Priorities in ChibiOS/RT are a contiguous numerical range but the initial
|
||||||
|
@ -246,6 +267,7 @@
|
||||||
* - @subpage article_atomic
|
* - @subpage article_atomic
|
||||||
* - @subpage article_saveram
|
* - @subpage article_saveram
|
||||||
* - @subpage article_interrupts
|
* - @subpage article_interrupts
|
||||||
|
* - @subpage article_timing
|
||||||
*/
|
*/
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
|
|
|
@ -12,17 +12,13 @@
|
||||||
|
|
||||||
chSemSignalI(&sem1);
|
chSemSignalI(&sem1);
|
||||||
chSemSignalI(&sem2);
|
chSemSignalI(&sem2);
|
||||||
if (tp != NULL) {
|
|
||||||
chThdResumeI(tp);
|
|
||||||
tp = NULL;
|
|
||||||
}
|
|
||||||
chSchRescheduleS();
|
chSchRescheduleS();
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
* @endcode
|
* @endcode
|
||||||
* The above example performs a signal operation on two semaphores, optionally
|
* The above example performs a signal operation on two semaphores and
|
||||||
* resumes a thread, and performs a final reschedulation. The three operations
|
* performs a final reschedulation. The two operations are performed
|
||||||
* are performed atomically.<br>
|
* atomically.<br>
|
||||||
* An hypotetical @p chSemSignalSignalWait() operation could be implemented as
|
* An hypotetical @p chSemSignalSignalWait() operation could be implemented as
|
||||||
* follow:
|
* follow:
|
||||||
* @code
|
* @code
|
||||||
|
|
|
@ -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.
|
||||||
|
*/
|
||||||
|
/** @} */
|
|
@ -102,11 +102,13 @@ static void wakeup(void *p) {
|
||||||
#ifdef CH_USE_SEMAPHORES
|
#ifdef CH_USE_SEMAPHORES
|
||||||
case PRWTSEM:
|
case PRWTSEM:
|
||||||
chSemFastSignalI(tp->p_wtsemp);
|
chSemFastSignalI(tp->p_wtsemp);
|
||||||
/* Falls into, intentional.*/
|
/* Falls into, intentional. */
|
||||||
#endif
|
#endif
|
||||||
case PRWTCOND:
|
case PRWTCOND:
|
||||||
chSchReadyI(dequeue(tp))->p_rdymsg = RDY_TIMEOUT;
|
case PRWTMTX:
|
||||||
break;
|
/* States requiring dequeuing. */
|
||||||
|
dequeue(tp);
|
||||||
|
/* Falls into, intentional. */
|
||||||
default:
|
default:
|
||||||
chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT;
|
chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
|
|
@ -214,26 +214,6 @@ void chThdSetPriority(tprio_t newprio) {
|
||||||
chSysUnlock();
|
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.
|
* @brief Resumes a suspended thread.
|
||||||
*
|
*
|
||||||
|
|
|
@ -183,7 +183,6 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
void chThdSetPriority(tprio_t newprio);
|
void chThdSetPriority(tprio_t newprio);
|
||||||
Thread *chThdResume(Thread *tp);
|
Thread *chThdResume(Thread *tp);
|
||||||
void chThdSuspend(Thread **tpp);
|
|
||||||
void chThdTerminate(Thread *tp);
|
void chThdTerminate(Thread *tp);
|
||||||
void chThdSleep(systime_t time);
|
void chThdSleep(systime_t time);
|
||||||
void chThdSleepUntil(systime_t time);
|
void chThdSleepUntil(systime_t time);
|
||||||
|
|
|
@ -94,7 +94,6 @@ static void sem2_execute(void) {
|
||||||
test_assert(isempty(&sem1.s_queue), "queue not empty");
|
test_assert(isempty(&sem1.s_queue), "queue not empty");
|
||||||
test_assert(&sem1.s_cnt != 0, "counter not zero");
|
test_assert(&sem1.s_cnt != 0, "counter not zero");
|
||||||
}
|
}
|
||||||
test_assert(chSemGetCounter(&sem1) == 0, "non zero counter");
|
|
||||||
test_assert_sequence("ABCDE");
|
test_assert_sequence("ABCDE");
|
||||||
test_assert_time_window(target_time, target_time + ALLOWED_DELAY);
|
test_assert_time_window(target_time, target_time + ALLOWED_DELAY);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue