git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@346 35acf78f-673a-0410-8e92-d51de3d6d3f4
parent
71a1820c4a
commit
49c3629538
|
@ -24,6 +24,8 @@
|
||||||
#include "stm32_serial.h"
|
#include "stm32_serial.h"
|
||||||
#include "stm32lib/stm32f10x_nvic.h"
|
#include "stm32lib/stm32f10x_nvic.h"
|
||||||
|
|
||||||
|
#define USART_BITRATE (38400)
|
||||||
|
|
||||||
#ifdef USE_USART1
|
#ifdef USE_USART1
|
||||||
FullDuplexDriver COM1;
|
FullDuplexDriver COM1;
|
||||||
static uint8_t ib1[SERIAL_BUFFERS_SIZE];
|
static uint8_t ib1[SERIAL_BUFFERS_SIZE];
|
||||||
|
@ -175,7 +177,7 @@ void InitSerial(uint32_t prio1, uint32_t prio2, uint32_t prio3) {
|
||||||
#ifdef USE_USART1
|
#ifdef USE_USART1
|
||||||
chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
|
chFDDInit(&COM1, ib1, sizeof ib1, NULL, ob1, sizeof ob1, OutNotify1);
|
||||||
RCC->APB2ENR |= 0x00004000;
|
RCC->APB2ENR |= 0x00004000;
|
||||||
SetUSARTI(USART1, 38400, 0, CR2_STOP1_BITS | CR2_LINEN, 0);
|
SetUSARTI(USART1, USART_BITRATE, 0, CR2_STOP1_BITS | CR2_LINEN, 0);
|
||||||
GPIOA->CRH = (GPIOA->CRH & 0xFFFFF00F) | 0x000004B0;
|
GPIOA->CRH = (GPIOA->CRH & 0xFFFFF00F) | 0x000004B0;
|
||||||
NVICEnableVector(USART1_IRQChannel, prio1);
|
NVICEnableVector(USART1_IRQChannel, prio1);
|
||||||
#endif
|
#endif
|
||||||
|
@ -183,7 +185,7 @@ void InitSerial(uint32_t prio1, uint32_t prio2, uint32_t prio3) {
|
||||||
#ifdef USE_USART2
|
#ifdef USE_USART2
|
||||||
chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
|
chFDDInit(&COM2, ib2, sizeof ib2, NULL, ob2, sizeof ob2, OutNotify2);
|
||||||
RCC->APB1ENR |= 0x00020000;
|
RCC->APB1ENR |= 0x00020000;
|
||||||
SetUSARTI(USART2, 38400, 0, CR2_STOP1_BITS | CR2_LINEN, 0);
|
SetUSARTI(USART2, USART_BITRATE, 0, CR2_STOP1_BITS | CR2_LINEN, 0);
|
||||||
GPIOA->CRL = (GPIOA->CRL & 0xFFFF00FF) | 0x00004B00;
|
GPIOA->CRL = (GPIOA->CRL & 0xFFFF00FF) | 0x00004B00;
|
||||||
NVICEnableVector(USART2_IRQChannel, prio2);
|
NVICEnableVector(USART2_IRQChannel, prio2);
|
||||||
#endif
|
#endif
|
||||||
|
@ -191,7 +193,7 @@ void InitSerial(uint32_t prio1, uint32_t prio2, uint32_t prio3) {
|
||||||
#ifdef USE_USART3
|
#ifdef USE_USART3
|
||||||
chFDDInit(&COM3, ib3, sizeof ib3, NULL, ob3, sizeof ob3, OutNotify3);
|
chFDDInit(&COM3, ib3, sizeof ib3, NULL, ob3, sizeof ob3, OutNotify3);
|
||||||
RCC->APB1ENR |= 0x00040000;
|
RCC->APB1ENR |= 0x00040000;
|
||||||
SetUSARTI(USART3, 38400, 0, CR2_STOP1_BITS | CR2_LINEN, 0);
|
SetUSARTI(USART3, USART_BITRATE, 0, CR2_STOP1_BITS | CR2_LINEN, 0);
|
||||||
GPIOB->CRH = (GPIOB->CRH & 0xFFFF00FF) | 0x00004B00;
|
GPIOB->CRH = (GPIOB->CRH & 0xFFFF00FF) | 0x00004B00;
|
||||||
NVICEnableVector(USART3_IRQChannel, prio3);
|
NVICEnableVector(USART3_IRQChannel, prio3);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -49,6 +49,12 @@ void chSysHalt(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Start a thread by invoking its work function.
|
||||||
|
*
|
||||||
|
* Start a thread by calling its work function. If the work function returns,
|
||||||
|
* call chThdExit and chSysHalt.
|
||||||
|
*/
|
||||||
__attribute__((naked, weak))
|
__attribute__((naked, weak))
|
||||||
void threadstart(void) {
|
void threadstart(void) {
|
||||||
|
|
||||||
|
@ -80,7 +86,15 @@ void *retaddr;
|
||||||
*/
|
*/
|
||||||
__attribute__((naked))
|
__attribute__((naked))
|
||||||
void SVCallVector(Thread *otp, Thread *ntp) {
|
void SVCallVector(Thread *otp, Thread *ntp) {
|
||||||
|
/* { r0 = otp, r1 = ntp } */
|
||||||
|
/* get the BASEPRI in r3 */
|
||||||
|
/* get the PSP in r12 */
|
||||||
|
/* push the registers on the PSP stack */
|
||||||
|
/* stores the modified PSP into the thread context */
|
||||||
|
/* fetches the PSP position from the new thread context */
|
||||||
|
/* pop the registers from the PSP stack */
|
||||||
|
/* set the PSP from r12 */
|
||||||
|
/* set the BASEPRI from R3 */
|
||||||
#ifdef CH_CURRP_REGISTER_CACHE
|
#ifdef CH_CURRP_REGISTER_CACHE
|
||||||
asm volatile ("mrs r3, BASEPRI \n\t" \
|
asm volatile ("mrs r3, BASEPRI \n\t" \
|
||||||
"mrs r12, PSP \n\t" \
|
"mrs r12, PSP \n\t" \
|
||||||
|
@ -135,6 +149,7 @@ void PendSVVector(void) {
|
||||||
(otp = currp)->p_ctx.r13 = sp_thd;
|
(otp = currp)->p_ctx.r13 = sp_thd;
|
||||||
chSchReadyI(otp);
|
chSchReadyI(otp);
|
||||||
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR;
|
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR;
|
||||||
|
/* set the round-robin time quantum */
|
||||||
rlist.r_preempt = CH_TIME_QUANTUM;
|
rlist.r_preempt = CH_TIME_QUANTUM;
|
||||||
#ifdef CH_USE_TRACE
|
#ifdef CH_USE_TRACE
|
||||||
chDbgTrace(otp, currp);
|
chDbgTrace(otp, currp);
|
||||||
|
|
|
@ -66,6 +66,9 @@ typedef struct {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Platform dependent part of the \p chThdCreate() API.
|
* Platform dependent part of the \p chThdCreate() API.
|
||||||
|
*
|
||||||
|
* The top of the workspace is used for the intctx datastructure.
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
#define SETUP_CONTEXT(workspace, wsize, pf, arg) { \
|
||||||
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
|
tp->p_ctx.r13 = (struct intctx *)((uint8_t *)workspace + \
|
||||||
|
@ -104,7 +107,10 @@ typedef struct {
|
||||||
INT_REQUIRED_STACK)
|
INT_REQUIRED_STACK)
|
||||||
#define WorkingArea(s, n) uint32_t s[UserStackSize(n) >> 2];
|
#define WorkingArea(s, n) uint32_t s[UserStackSize(n) >> 2];
|
||||||
|
|
||||||
|
/* called on each interrupt entry, currently nothing is done */
|
||||||
#define chSysIRQEnterI()
|
#define chSysIRQEnterI()
|
||||||
|
/* called on each interrupt exit, pends a supervisor handler for
|
||||||
|
* execution after all higher priority interrupts; PendSVVector() */
|
||||||
#define chSysIRQExitI() { \
|
#define chSysIRQExitI() { \
|
||||||
SCB_ICSR = ICSR_PENDSVSET; \
|
SCB_ICSR = ICSR_PENDSVSET; \
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ ResetHandler:
|
||||||
ldr r0, =__ram_end__
|
ldr r0, =__ram_end__
|
||||||
ldr r1, =__main_stack_size__
|
ldr r1, =__main_stack_size__
|
||||||
sub r0, r0, r1
|
sub r0, r0, r1
|
||||||
|
/* { r0 = main stack low address } */
|
||||||
msr PSP, r0
|
msr PSP, r0
|
||||||
// ldr r1, =__process_stack_size__
|
// ldr r1, =__process_stack_size__
|
||||||
// sub r0, r0, r1
|
// sub r0, r0, r1
|
||||||
|
|
|
@ -74,6 +74,12 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process,
|
||||||
*** Releases ***
|
*** Releases ***
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
|
*** 0.6.8 ***
|
||||||
|
- FIX: Fixed a bug in the priority inheritance mechanism, the bug was only a
|
||||||
|
problems when the CH_USE_MESSAGES_PRIORITY was enabled, this option is
|
||||||
|
disabled by default in ChibiOS/RT so it should not affect any user.
|
||||||
|
- Merged the documentation fixes submitted by Leon Woestenberg (thank you).
|
||||||
|
|
||||||
*** 0.6.7 ***
|
*** 0.6.7 ***
|
||||||
- NEW: New chThdCreateFast() API, it is a simplified form of chThdCreate()
|
- NEW: New chThdCreateFast() API, it is a simplified form of chThdCreate()
|
||||||
that allows even faster threads creation. The new API does not support
|
that allows even faster threads creation. The new API does not support
|
||||||
|
|
13
src/chinit.c
13
src/chinit.c
|
@ -60,14 +60,19 @@ void chSysInit(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Preemption routine, this function must be called into an interrupt
|
* Handles time ticks for round robin preemption and timer increments.
|
||||||
* handler invoked by a system timer.
|
*
|
||||||
* The frequency of the timer determines the system tick granularity and,
|
* Decrements the remaining time quantum of the running thread and preempts
|
||||||
|
* it when the quantum is used up. Increments system time and manages the
|
||||||
|
* timers.
|
||||||
|
*
|
||||||
|
* @note The frequency of the timer determines the system tick granularity and,
|
||||||
* together with the \p CH_TIME_QUANTUM macro, the round robin interval.
|
* together with the \p CH_TIME_QUANTUM macro, the round robin interval.
|
||||||
*/
|
*/
|
||||||
void chSysTimerHandlerI(void) {
|
void chSysTimerHandlerI(void) {
|
||||||
|
/* running thread has not used up quantum yet? */
|
||||||
if (rlist.r_preempt > 0)
|
if (rlist.r_preempt > 0)
|
||||||
|
/* decrement remaining quantum */
|
||||||
rlist.r_preempt--;
|
rlist.r_preempt--;
|
||||||
#ifdef CH_USE_SYSTEMTIME
|
#ifdef CH_USE_SYSTEMTIME
|
||||||
rlist.r_stime++;
|
rlist.r_stime++;
|
||||||
|
|
25
src/chmtx.c
25
src/chmtx.c
|
@ -51,34 +51,46 @@ void chMtxLock(Mutex *mp) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Locks the specified mutex.
|
* Locks the specified mutex.
|
||||||
|
*
|
||||||
* @param mp pointer to the \p Mutex structure
|
* @param mp pointer to the \p Mutex structure
|
||||||
* @note This function must be called within a \p chSysLock() / \p chSysUnlock()
|
* @note This function must be called within a \p chSysLock() / \p chSysUnlock()
|
||||||
* block.
|
* block.
|
||||||
*/
|
*/
|
||||||
void chMtxLockS(Mutex *mp) {
|
void chMtxLockS(Mutex *mp) {
|
||||||
|
/* the mutex is already locked? */
|
||||||
if (mp->m_owner != NULL) {
|
if (mp->m_owner != NULL) {
|
||||||
/*
|
/*
|
||||||
* Inheritance, explores the thread-mutex dependances adjusting
|
* Priority inheritance protocol; explores the thread-mutex dependencies
|
||||||
* the priority of all the affected threads.
|
* boosting the priority of all the affected threads to equal the priority
|
||||||
|
* of the running thread requesting the mutex.
|
||||||
*/
|
*/
|
||||||
Thread *tp = mp->m_owner;
|
Thread *tp = mp->m_owner;
|
||||||
|
/* { tp is the thread currently owning the mutex } */
|
||||||
|
/* the running thread has higher priority than tp? */
|
||||||
while (tp->p_prio < currp->p_prio) {
|
while (tp->p_prio < currp->p_prio) {
|
||||||
|
/* make priority of thread tp match the running thread's priority */
|
||||||
tp->p_prio = currp->p_prio;
|
tp->p_prio = currp->p_prio;
|
||||||
/*
|
/*
|
||||||
* The following states need priority queues reordering.
|
* The following states need priority queues reordering.
|
||||||
*/
|
*/
|
||||||
switch (tp->p_state) {
|
switch (tp->p_state) {
|
||||||
|
/* thread tp is waiting on a mutex? */
|
||||||
case PRWTMTX:
|
case PRWTMTX:
|
||||||
|
/* requeue tp with its new priority on the mutex wait queue */
|
||||||
prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue);
|
prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue);
|
||||||
|
/* boost the owner of this mutex if needed */
|
||||||
tp = tp->p_wtmtxp->m_owner;
|
tp = tp->p_wtmtxp->m_owner;
|
||||||
continue;
|
continue;
|
||||||
#ifdef CH_USE_MESSAGES_PRIORITY
|
#ifdef CH_USE_MESSAGES_PRIORITY
|
||||||
case PRSNDMSG:
|
case PRSNDMSG:
|
||||||
if (tp->p_flags & P_MSGBYPRIO)
|
if (tp->p_flags & P_MSGBYPRIO)
|
||||||
|
/* requeue tp with its new priority on (?) */
|
||||||
prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue);
|
prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue);
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
/* thread tp is ready? */
|
||||||
case PRREADY:
|
case PRREADY:
|
||||||
|
/* requeue tp with its new priority on the ready list */
|
||||||
chSchReadyI(dequeue(tp));
|
chSchReadyI(dequeue(tp));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -157,21 +169,26 @@ void chMtxUnlock(void) {
|
||||||
* If a thread is waiting on the mutex then the hard part begins.
|
* If a thread is waiting on the mutex then the hard part begins.
|
||||||
*/
|
*/
|
||||||
if (chMtxQueueNotEmptyS(mp)) {
|
if (chMtxQueueNotEmptyS(mp)) {
|
||||||
|
/* get the highest priority thread waiting for the unlocked mutex */
|
||||||
Thread *tp = fifo_remove(&mp->m_queue);
|
Thread *tp = fifo_remove(&mp->m_queue);
|
||||||
/*
|
/*
|
||||||
* Recalculates the optimal thread priority by scanning the owned mutexes list.
|
* Recalculates the optimal thread priority by scanning the owned mutexes list.
|
||||||
*/
|
*/
|
||||||
tprio_t newprio = currp->p_realprio;
|
tprio_t newprio = currp->p_realprio;
|
||||||
|
/* iterate mp over all the (other) mutexes the current thread still owns */
|
||||||
mp = currp->p_mtxlist;
|
mp = currp->p_mtxlist;
|
||||||
while (mp != NULL) {
|
while (mp != NULL) {
|
||||||
|
/* mutex mp has a higher priority thread pending? */
|
||||||
if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio))
|
if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio))
|
||||||
|
/* boost current thread's priority to waiting thread */
|
||||||
newprio = mp->m_queue.p_next->p_prio;
|
newprio = mp->m_queue.p_next->p_prio;
|
||||||
mp = mp->m_next;
|
mp = mp->m_next;
|
||||||
}
|
}
|
||||||
|
/* (possibly) boost the priority of the current thread */
|
||||||
currp->p_prio = newprio;
|
currp->p_prio = newprio;
|
||||||
|
/* awaken the highest priority thread waiting for the unlocked mutex */
|
||||||
chSchWakeupS(tp, RDY_OK);
|
chSchWakeupS(tp, RDY_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
52
src/chschd.c
52
src/chschd.c
|
@ -44,6 +44,7 @@ void chSchInit(void) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Inserts a thread in the Ready List.
|
* Inserts a thread in the Ready List.
|
||||||
|
*
|
||||||
* @param tp the Thread to be made ready
|
* @param tp the Thread to be made ready
|
||||||
* @return the Thread pointer
|
* @return the Thread pointer
|
||||||
* @note The function must be called in the system mutex zone.
|
* @note The function must be called in the system mutex zone.
|
||||||
|
@ -103,9 +104,12 @@ static void wakeup(void *p) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Puts the current thread to sleep into the specified state, the next highest
|
* Put the current thread to sleep.
|
||||||
* priority thread becomes running. The thread is automatically awakened after
|
*
|
||||||
* the specified time elapsed.
|
* Puts the current thread to sleep into the specified state. The next highest
|
||||||
|
* priority thread becomes running. The thread put to sleep is awakened after
|
||||||
|
* the specified time has elapsed.
|
||||||
|
*
|
||||||
* @param newstate the new thread state
|
* @param newstate the new thread state
|
||||||
* @param time the number of ticks before the operation timouts
|
* @param time the number of ticks before the operation timouts
|
||||||
* @return the wakeup message, it is \p RDY_TIMEOUT if a timeout occurs
|
* @return the wakeup message, it is \p RDY_TIMEOUT if a timeout occurs
|
||||||
|
@ -124,8 +128,10 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
|
||||||
#endif /* CH_USE_VIRTUAL_TIMERS */
|
#endif /* CH_USE_VIRTUAL_TIMERS */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wakeups a thread, the thread is inserted into the ready list or made
|
* Wakes up a thread.
|
||||||
* running directly depending on its relative priority compared to the current
|
*
|
||||||
|
* Wakes up a thread. The thread is inserted into the ready list or immediately
|
||||||
|
* made running depending on its relative priority compared to the current
|
||||||
* thread.
|
* thread.
|
||||||
* @param ntp the Thread to be made ready
|
* @param ntp the Thread to be made ready
|
||||||
* @param msg message to the awakened thread
|
* @param msg message to the awakened thread
|
||||||
|
@ -135,11 +141,14 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) {
|
||||||
* \p chSchRescheduleS() but much more efficient.
|
* \p chSchRescheduleS() but much more efficient.
|
||||||
*/
|
*/
|
||||||
void chSchWakeupS(Thread *ntp, msg_t msg) {
|
void chSchWakeupS(Thread *ntp, msg_t msg) {
|
||||||
|
|
||||||
ntp->p_rdymsg = msg;
|
ntp->p_rdymsg = msg;
|
||||||
|
/* the woken thread has equal or lower priority than the running thread? */
|
||||||
if (ntp->p_prio <= currp->p_prio)
|
if (ntp->p_prio <= currp->p_prio)
|
||||||
|
/* put the woken thread on the ready queue */
|
||||||
chSchReadyI(ntp);
|
chSchReadyI(ntp);
|
||||||
|
/* the woken thread has higher priority than the running thread */
|
||||||
else {
|
else {
|
||||||
|
/* put the running thread on the ready queue */
|
||||||
Thread *otp = currp;
|
Thread *otp = currp;
|
||||||
chSchReadyI(otp);
|
chSchReadyI(otp);
|
||||||
(currp = ntp)->p_state = PRCURR;
|
(currp = ntp)->p_state = PRCURR;
|
||||||
|
@ -147,46 +156,59 @@ void chSchWakeupS(Thread *ntp, msg_t msg) {
|
||||||
#ifdef CH_USE_TRACE
|
#ifdef CH_USE_TRACE
|
||||||
chDbgTrace(otp, ntp);
|
chDbgTrace(otp, ntp);
|
||||||
#endif
|
#endif
|
||||||
|
/* switch the thread context */
|
||||||
chSysSwitchI(otp, ntp);
|
chSysSwitchI(otp, ntp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Performs a reschedulation. It is meant to be called if
|
* Switch to the first thread on the runnable queue.
|
||||||
* \p chSchRescRequired() evaluates to \p TRUE.
|
*
|
||||||
|
* Intended to be called if \p chSchRescRequired() evaluates to \p TRUE.
|
||||||
*/
|
*/
|
||||||
void chSchDoRescheduleI(void) {
|
void chSchDoRescheduleI(void) {
|
||||||
|
/* put the running thread on the ready queue */
|
||||||
Thread *otp = currp;
|
Thread *otp = currp;
|
||||||
|
|
||||||
chSchReadyI(otp);
|
chSchReadyI(otp);
|
||||||
|
/* pick the first thread from the ready queue */
|
||||||
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR;
|
(currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR;
|
||||||
rlist.r_preempt = CH_TIME_QUANTUM;
|
rlist.r_preempt = CH_TIME_QUANTUM;
|
||||||
#ifdef CH_USE_TRACE
|
#ifdef CH_USE_TRACE
|
||||||
chDbgTrace(otp, currp);
|
chDbgTrace(otp, currp);
|
||||||
#endif
|
#endif
|
||||||
|
/* switch thread context */
|
||||||
chSysSwitchI(otp, currp);
|
chSysSwitchI(otp, currp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If a thread with an higher priority than the current thread is in the
|
* Reschedule only if a higher priority thread is runnable.
|
||||||
* ready list then it becomes running.
|
*
|
||||||
|
* If a thread with a higher priority than the current thread is in the
|
||||||
|
* ready list then make the higher priority thread running.
|
||||||
|
*
|
||||||
* @note The function must be called in the system mutex zone.
|
* @note The function must be called in the system mutex zone.
|
||||||
*/
|
*/
|
||||||
void chSchRescheduleS(void) {
|
void chSchRescheduleS(void) {
|
||||||
|
/* first thread in the runnable queue has higher priority than the running
|
||||||
|
* thread? */
|
||||||
if (firstprio(&rlist.r_queue) > currp->p_prio)
|
if (firstprio(&rlist.r_queue) > currp->p_prio)
|
||||||
chSchDoRescheduleI();
|
chSchDoRescheduleI();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Evaluates if a reschedulation is required.
|
* Evaluates if rescheduling is required.
|
||||||
|
*
|
||||||
* @return \p TRUE if there is a thread that should go in running state
|
* @return \p TRUE if there is a thread that should go in running state
|
||||||
* immediatly else \p FALSE.
|
* immediately else \p FALSE.
|
||||||
*/
|
*/
|
||||||
bool_t chSchRescRequiredI(void) {
|
bool_t chSchRescRequiredI(void) {
|
||||||
tprio_t p1 = firstprio(&rlist.r_queue);
|
tprio_t p1 = firstprio(&rlist.r_queue);
|
||||||
tprio_t p2 = currp->p_prio;
|
tprio_t p2 = currp->p_prio;
|
||||||
|
/* If the running thread has not reached its time quantum, reschedule only
|
||||||
|
* if the first thread on the ready queue has a higher priority.
|
||||||
|
* Otherwise, if the running thread has used up its time quantum, reschedule
|
||||||
|
* if the first thread on the ready queue has equal or higher priority.
|
||||||
|
*/
|
||||||
return rlist.r_preempt ? p1 > p2 : p1 >= p2;
|
return rlist.r_preempt ? p1 > p2 : p1 >= p2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ void init_thread(tprio_t prio, tmode_t mode, Thread *tp) {
|
||||||
tp->p_flags = mode;
|
tp->p_flags = mode;
|
||||||
tp->p_prio = prio;
|
tp->p_prio = prio;
|
||||||
#ifdef CH_USE_MUTEXES
|
#ifdef CH_USE_MUTEXES
|
||||||
|
/* realprio is the thread's own, non-inherited, priority */
|
||||||
tp->p_realprio = prio;
|
tp->p_realprio = prio;
|
||||||
tp->p_mtxlist = NULL;
|
tp->p_mtxlist = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
@ -89,6 +90,7 @@ static void memfill(uint8_t *p, uint32_t n, uint8_t v) {
|
||||||
*/
|
*/
|
||||||
Thread *chThdCreate(tprio_t prio, tmode_t mode, void *workspace,
|
Thread *chThdCreate(tprio_t prio, tmode_t mode, void *workspace,
|
||||||
size_t wsize, tfunc_t pf, void *arg) {
|
size_t wsize, tfunc_t pf, void *arg) {
|
||||||
|
/* thread structure is layed out in the lower part of the thread workspace */
|
||||||
Thread *tp = workspace;
|
Thread *tp = workspace;
|
||||||
|
|
||||||
chDbgAssert((wsize >= UserStackSize(0)) && (prio <= HIGHPRIO) &&
|
chDbgAssert((wsize >= UserStackSize(0)) && (prio <= HIGHPRIO) &&
|
||||||
|
@ -146,8 +148,9 @@ Thread *chThdCreateFast(tprio_t prio, void *workspace,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the thread priority, reschedules if necessary.
|
* Changes the running thread priority, reschedules if necessary.
|
||||||
* @param newprio the new priority of the invoking thread
|
*
|
||||||
|
* @param newprio the new priority of the running thread
|
||||||
*/
|
*/
|
||||||
void chThdSetPriority(tprio_t newprio) {
|
void chThdSetPriority(tprio_t newprio) {
|
||||||
|
|
||||||
|
@ -236,6 +239,7 @@ void chThdTerminate(Thread *tp) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Terminates the current thread by specifying an exit status code.
|
* Terminates the current thread by specifying an exit status code.
|
||||||
|
*
|
||||||
* @param msg the thread exit code. The code can be retrieved by using
|
* @param msg the thread exit code. The code can be retrieved by using
|
||||||
* \p chThdWait().
|
* \p chThdWait().
|
||||||
*/
|
*/
|
||||||
|
@ -258,6 +262,7 @@ void chThdExit(msg_t msg) {
|
||||||
/**
|
/**
|
||||||
* Blocks the execution of the invoking thread until the specified thread
|
* Blocks the execution of the invoking thread until the specified thread
|
||||||
* terminates then the exit code is returned.
|
* terminates then the exit code is returned.
|
||||||
|
*
|
||||||
* @param tp the pointer to the thread
|
* @param tp the pointer to the thread
|
||||||
* @return the exit code
|
* @return the exit code
|
||||||
* @note The function is available only if the \p CH_USE_WAITEXIT
|
* @note The function is available only if the \p CH_USE_WAITEXIT
|
||||||
|
|
|
@ -27,11 +27,12 @@
|
||||||
|
|
||||||
/** Normal \p chSchReadyI() message. */
|
/** Normal \p chSchReadyI() message. */
|
||||||
#define RDY_OK 0
|
#define RDY_OK 0
|
||||||
/** Returned if the thread was made ready because a timeout.*/
|
/** Returned when the thread was made ready because of a timeout. */
|
||||||
#define RDY_TIMEOUT -1
|
#define RDY_TIMEOUT -1
|
||||||
/** Returned if the thread was made ready because a reset.*/
|
/** Returned when the thread was made ready because of a reset. */
|
||||||
#define RDY_RESET -2
|
#define RDY_RESET -2
|
||||||
|
|
||||||
|
/** The priority of the first thread on the given ready list. */
|
||||||
#define firstprio(rlp) ((rlp)->p_next->p_prio)
|
#define firstprio(rlp) ((rlp)->p_next->p_prio)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,6 +43,7 @@ typedef struct {
|
||||||
tprio_t r_prio;
|
tprio_t r_prio;
|
||||||
cnt_t r_preempt;
|
cnt_t r_preempt;
|
||||||
#ifndef CH_CURRP_REGISTER_CACHE
|
#ifndef CH_CURRP_REGISTER_CACHE
|
||||||
|
/** the currently running thread */
|
||||||
Thread *r_current;
|
Thread *r_current;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CH_USE_SYSTEMTIME
|
#ifdef CH_USE_SYSTEMTIME
|
||||||
|
|
|
@ -101,8 +101,9 @@ struct Thread {
|
||||||
eventmask_t p_epending;
|
eventmask_t p_epending;
|
||||||
#endif
|
#endif
|
||||||
#ifdef CH_USE_MUTEXES
|
#ifdef CH_USE_MUTEXES
|
||||||
/** Owner mutexes list, \p NULL terminated.*/
|
/** List of mutexes owned by this thread, \p NULL terminated.*/
|
||||||
Mutex *p_mtxlist;
|
Mutex *p_mtxlist;
|
||||||
|
/** Thread's own, non-inherited, priority */
|
||||||
tprio_t p_realprio;
|
tprio_t p_realprio;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue