git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6175 35acf78f-673a-0410-8e92-d51de3d6d3f4
This commit is contained in:
parent
b4e2fca4a0
commit
c3b9392212
|
@ -126,6 +126,7 @@
|
||||||
*/
|
*/
|
||||||
#define STM32_I2C_USE_I2C1 TRUE
|
#define STM32_I2C_USE_I2C1 TRUE
|
||||||
#define STM32_I2C_USE_I2C2 TRUE
|
#define STM32_I2C_USE_I2C2 TRUE
|
||||||
|
#define STM32_I2C_BUSY_TIMEOUT 50
|
||||||
#define STM32_I2C_I2C1_IRQ_PRIORITY 10
|
#define STM32_I2C_I2C1_IRQ_PRIORITY 10
|
||||||
#define STM32_I2C_I2C2_IRQ_PRIORITY 10
|
#define STM32_I2C_I2C2_IRQ_PRIORITY 10
|
||||||
#define STM32_I2C_I2C1_DMA_PRIORITY 1
|
#define STM32_I2C_I2C1_DMA_PRIORITY 1
|
||||||
|
|
|
@ -92,6 +92,32 @@ typedef enum {
|
||||||
/* Driver macros. */
|
/* Driver macros. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up the waiting thread notifying no errors.
|
||||||
|
*
|
||||||
|
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define _i2c_wakeup_isr(i2cp) do { \
|
||||||
|
osalSysLockFromISR(); \
|
||||||
|
osalThreadResumeI(&(i2cp)->thread, MSG_OK); \
|
||||||
|
osalSysUnlockFromISR(); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up the waiting thread notifying errors.
|
||||||
|
*
|
||||||
|
* @param[in] i2cp pointer to the @p I2CDriver object
|
||||||
|
*
|
||||||
|
* @notapi
|
||||||
|
*/
|
||||||
|
#define _i2c_wakeup_error_isr(i2cp) do { \
|
||||||
|
osalSysLockFromISR(); \
|
||||||
|
osalThreadResumeI(&(i2cp)->thread, MSG_RESET); \
|
||||||
|
osalSysUnlockFromISR(); \
|
||||||
|
} while(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wrap i2cMasterTransmitTimeout function with TIME_INFINITE timeout.
|
* @brief Wrap i2cMasterTransmitTimeout function with TIME_INFINITE timeout.
|
||||||
* @api
|
* @api
|
||||||
|
|
|
@ -383,7 +383,6 @@ static inline void osalSysUnlockFromISR(void) {
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if CH_PORT_SUPPORTS_RT || defined(__DOXYGEN__)
|
|
||||||
/**
|
/**
|
||||||
* @brief Polled delay.
|
* @brief Polled delay.
|
||||||
* @note The real delay is always few cycles in excess of the specified
|
* @note The real delay is always few cycles in excess of the specified
|
||||||
|
@ -393,6 +392,7 @@ static inline void osalSysUnlockFromISR(void) {
|
||||||
*
|
*
|
||||||
* @xclass
|
* @xclass
|
||||||
*/
|
*/
|
||||||
|
#if CH_PORT_SUPPORTS_RT || defined(__DOXYGEN__)
|
||||||
static inline void osalSysPolledDelayX(rtcnt_t cycles) {
|
static inline void osalSysPolledDelayX(rtcnt_t cycles) {
|
||||||
|
|
||||||
chSysPolledDelayX(cycles);
|
chSysPolledDelayX(cycles);
|
||||||
|
@ -510,7 +510,32 @@ static inline void osalThreadSleep(systime_t time) {
|
||||||
*/
|
*/
|
||||||
static inline msg_t osalThreadSuspendS(thread_reference_t *trp) {
|
static inline msg_t osalThreadSuspendS(thread_reference_t *trp) {
|
||||||
|
|
||||||
return osalThreadSuspendS(trp);
|
return chThreadSuspendS(trp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends the current thread sleeping and sets a reference variable.
|
||||||
|
* @note This function must reschedule, it can only be called from thread
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] timeout the timeout in system ticks, the special values are
|
||||||
|
* handled as follow:
|
||||||
|
* - @a TIME_INFINITE the thread enters an infinite sleep
|
||||||
|
* state.
|
||||||
|
* - @a TIME_IMMEDIATE the thread is not enqueued and
|
||||||
|
* the function returns @p MSG_TIMEOUT as if a timeout
|
||||||
|
* occurred.
|
||||||
|
* .
|
||||||
|
* @return The wake up message.
|
||||||
|
* @retval MSG_TIMEOUT if the operation timed out.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
static inline msg_t osalThreadSuspendTimeoutS(thread_reference_t *trp,
|
||||||
|
systime_t timeout) {
|
||||||
|
|
||||||
|
return chThreadSuspendTimeoutS(trp, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -92,25 +92,6 @@ I2CDriver I2CD2;
|
||||||
/* Driver local functions. */
|
/* Driver local functions. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Wakes up the waiting thread.
|
|
||||||
*
|
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
|
||||||
* @param[in] msg wakeup message
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
#define wakeup_isr(i2cp, msg) { \
|
|
||||||
osalSysLockFromISR(); \
|
|
||||||
if ((i2cp)->thread != NULL) { \
|
|
||||||
thread_t *tp = (i2cp)->thread; \
|
|
||||||
(i2cp)->thread = NULL; \
|
|
||||||
tp->p_u.rdymsg = (msg); \
|
|
||||||
chSchReadyI(tp); \
|
|
||||||
} \
|
|
||||||
osalSysUnlockFromISR(); \
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Aborts an I2C transaction.
|
* @brief Aborts an I2C transaction.
|
||||||
*
|
*
|
||||||
|
@ -134,27 +115,6 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
|
||||||
dmaStreamDisable(i2cp->dmarx);
|
dmaStreamDisable(i2cp->dmarx);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Handling of stalled I2C transactions.
|
|
||||||
*
|
|
||||||
* @param[in] i2cp pointer to the @p I2CDriver object
|
|
||||||
*
|
|
||||||
* @notapi
|
|
||||||
*/
|
|
||||||
static void i2c_lld_safety_timeout(void *p) {
|
|
||||||
I2CDriver *i2cp = (I2CDriver *)p;
|
|
||||||
|
|
||||||
osalSysLockFromISR();
|
|
||||||
if (i2cp->thread) {
|
|
||||||
thread_t *tp = i2cp->thread;
|
|
||||||
i2c_lld_abort_operation(i2cp);
|
|
||||||
i2cp->thread = NULL;
|
|
||||||
tp->p_u.rdymsg = MSG_TIMEOUT;
|
|
||||||
chSchReadyI(tp);
|
|
||||||
}
|
|
||||||
osalSysUnlockFromISR();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2C shared ISR code.
|
* @brief I2C shared ISR code.
|
||||||
*
|
*
|
||||||
|
@ -202,12 +162,11 @@ static void i2c_lld_serve_interrupt(I2CDriver *i2cp, uint32_t isr) {
|
||||||
dmaStreamDisable(i2cp->dmatx);
|
dmaStreamDisable(i2cp->dmatx);
|
||||||
dmaStreamDisable(i2cp->dmarx);
|
dmaStreamDisable(i2cp->dmarx);
|
||||||
|
|
||||||
if (i2cp->errors) {
|
/* The wake up message depends on the presence of errors.*/
|
||||||
wakeup_isr(i2cp, MSG_RESET);
|
if (i2cp->errors)
|
||||||
}
|
_i2c_wakeup_error_isr(i2cp);
|
||||||
else {
|
else
|
||||||
wakeup_isr(i2cp, MSG_OK);
|
_i2c_wakeup_isr(i2cp);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -233,7 +192,7 @@ static void i2c_lld_serve_rx_end_irq(I2CDriver *i2cp, uint32_t flags) {
|
||||||
|
|
||||||
dmaStreamDisable(i2cp->dmarx);
|
dmaStreamDisable(i2cp->dmarx);
|
||||||
dp->CR2 |= I2C_CR2_STOP;
|
dp->CR2 |= I2C_CR2_STOP;
|
||||||
wakeup_isr(i2cp, MSG_OK);
|
_i2c_wakeup_isr(i2cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -285,7 +244,7 @@ static void i2c_lld_serve_error_interrupt(I2CDriver *i2cp, uint32_t isr) {
|
||||||
|
|
||||||
/* If some error has been identified then sends wakes the waiting thread.*/
|
/* If some error has been identified then sends wakes the waiting thread.*/
|
||||||
if (i2cp->errors != I2C_NO_ERROR)
|
if (i2cp->errors != I2C_NO_ERROR)
|
||||||
wakeup_isr(i2cp, MSG_RESET);
|
_i2c_wakeup_error_isr(i2cp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
@ -612,33 +571,39 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
uint8_t *rxbuf, size_t rxbytes,
|
uint8_t *rxbuf, size_t rxbytes,
|
||||||
systime_t timeout) {
|
systime_t timeout) {
|
||||||
I2C_TypeDef *dp = i2cp->i2c;
|
I2C_TypeDef *dp = i2cp->i2c;
|
||||||
virtual_timer_t vt;
|
|
||||||
uint32_t addr_cr2 = addr & I2C_CR2_SADD;
|
uint32_t addr_cr2 = addr & I2C_CR2_SADD;
|
||||||
|
systime_t start, end;
|
||||||
|
|
||||||
osalDbgCheck((rxbytes > 0));
|
osalDbgCheck((rxbytes > 0));
|
||||||
|
|
||||||
/* Resetting error flags for this transfer.*/
|
/* Resetting error flags for this transfer.*/
|
||||||
i2cp->errors = I2C_NO_ERROR;
|
i2cp->errors = I2C_NO_ERROR;
|
||||||
|
|
||||||
/* Global timeout for the whole operation.*/
|
|
||||||
if (timeout != TIME_INFINITE)
|
|
||||||
chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
|
|
||||||
|
|
||||||
/* Releases the lock from high level driver.*/
|
/* Releases the lock from high level driver.*/
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
||||||
/* Waits until BUSY flag is reset and the STOP from the previous operation
|
/* Calculating the time window for the timeout on the busy bus condition.*/
|
||||||
is completed, alternatively for a timeout condition.*/
|
start = osalOsGetSystemTimeX();
|
||||||
while (dp->ISR & I2C_ISR_BUSY) {
|
end = start + OSAL_MS2ST(STM32_I2C_BUSY_TIMEOUT);
|
||||||
|
|
||||||
|
/* Waits until BUSY flag is reset or, alternatively, for a timeout
|
||||||
|
condition.*/
|
||||||
|
while (true) {
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt))
|
|
||||||
|
/* If the bus is not busy then the operation can continue, note, the
|
||||||
|
loop is exited in the locked state.*/
|
||||||
|
if (dp->ISR & I2C_ISR_BUSY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* If the system time went outside the allowed window then a timeout
|
||||||
|
condition is returned.*/
|
||||||
|
if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), start, end))
|
||||||
return MSG_TIMEOUT;
|
return MSG_TIMEOUT;
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This lock will be released in high level driver.*/
|
|
||||||
osalSysLock();
|
|
||||||
|
|
||||||
/* Adjust slave address (master mode) for 7-bit address mode */
|
/* Adjust slave address (master mode) for 7-bit address mode */
|
||||||
if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0)
|
if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0)
|
||||||
addr_cr2 = (addr_cr2 & 0x7f) << 1;
|
addr_cr2 = (addr_cr2 & 0x7f) << 1;
|
||||||
|
@ -658,22 +623,12 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
/* Enable RX DMA */
|
/* Enable RX DMA */
|
||||||
dmaStreamEnable(i2cp->dmarx);
|
dmaStreamEnable(i2cp->dmarx);
|
||||||
|
|
||||||
/* Atomic check on the timer in order to make sure that a timeout didn't
|
|
||||||
happen outside the critical zone.*/
|
|
||||||
if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt))
|
|
||||||
return MSG_TIMEOUT;
|
|
||||||
|
|
||||||
/* Starts the operation.*/
|
/* Starts the operation.*/
|
||||||
dp->CR2 |= I2C_CR2_RD_WRN;
|
dp->CR2 |= I2C_CR2_RD_WRN;
|
||||||
dp->CR2 |= I2C_CR2_START;
|
dp->CR2 |= I2C_CR2_START;
|
||||||
|
|
||||||
/* Waits for the operation completion or a timeout.*/
|
/* Waits for the operation completion or a timeout.*/
|
||||||
i2cp->thread = chThdGetSelfX();
|
return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
|
||||||
chSchGoSleepS(CH_STATE_SUSPENDED);
|
|
||||||
if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt))
|
|
||||||
chVTResetI(&vt);
|
|
||||||
|
|
||||||
return chThdGetSelfX()->p_u.rdymsg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -706,33 +661,39 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
uint8_t *rxbuf, size_t rxbytes,
|
uint8_t *rxbuf, size_t rxbytes,
|
||||||
systime_t timeout) {
|
systime_t timeout) {
|
||||||
I2C_TypeDef *dp = i2cp->i2c;
|
I2C_TypeDef *dp = i2cp->i2c;
|
||||||
virtual_timer_t vt;
|
|
||||||
uint32_t addr_cr2 = addr & I2C_CR2_SADD;
|
uint32_t addr_cr2 = addr & I2C_CR2_SADD;
|
||||||
|
systime_t start, end;
|
||||||
|
|
||||||
osalDbgCheck(((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))));
|
osalDbgCheck(((rxbytes == 0) || ((rxbytes > 0) && (rxbuf != NULL))));
|
||||||
|
|
||||||
/* Resetting error flags for this transfer.*/
|
/* Resetting error flags for this transfer.*/
|
||||||
i2cp->errors = I2C_NO_ERROR;
|
i2cp->errors = I2C_NO_ERROR;
|
||||||
|
|
||||||
/* Global timeout for the whole operation.*/
|
|
||||||
if (timeout != TIME_INFINITE)
|
|
||||||
chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
|
|
||||||
|
|
||||||
/* Releases the lock from high level driver.*/
|
/* Releases the lock from high level driver.*/
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
|
|
||||||
/* Waits until BUSY flag is reset and the STOP from the previous operation
|
/* Calculating the time window for the timeout on the busy bus condition.*/
|
||||||
is completed, alternatively for a timeout condition.*/
|
start = osalOsGetSystemTimeX();
|
||||||
while (dp->ISR & I2C_ISR_BUSY) {
|
end = start + OSAL_MS2ST(STM32_I2C_BUSY_TIMEOUT);
|
||||||
|
|
||||||
|
/* Waits until BUSY flag is reset or, alternatively, for a timeout
|
||||||
|
condition.*/
|
||||||
|
while (true) {
|
||||||
osalSysLock();
|
osalSysLock();
|
||||||
if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt))
|
|
||||||
|
/* If the bus is not busy then the operation can continue, note, the
|
||||||
|
loop is exited in the locked state.*/
|
||||||
|
if (dp->ISR & I2C_ISR_BUSY)
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* If the system time went outside the allowed window then a timeout
|
||||||
|
condition is returned.*/
|
||||||
|
if (!osalOsIsTimeWithinX(osalOsGetSystemTimeX(), start, end))
|
||||||
return MSG_TIMEOUT;
|
return MSG_TIMEOUT;
|
||||||
|
|
||||||
osalSysUnlock();
|
osalSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This lock will be released in high level driver.*/
|
|
||||||
osalSysLock();
|
|
||||||
|
|
||||||
/* Adjust slave address (master mode) for 7-bit address mode */
|
/* Adjust slave address (master mode) for 7-bit address mode */
|
||||||
if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0)
|
if ((i2cp->config->cr2 & I2C_CR2_ADD10) == 0)
|
||||||
addr_cr2 = (addr_cr2 & 0x7f) << 1;
|
addr_cr2 = (addr_cr2 & 0x7f) << 1;
|
||||||
|
@ -757,11 +718,6 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
/* Enable TX DMA */
|
/* Enable TX DMA */
|
||||||
dmaStreamEnable(i2cp->dmatx);
|
dmaStreamEnable(i2cp->dmatx);
|
||||||
|
|
||||||
/* Atomic check on the timer in order to make sure that a timeout didn't
|
|
||||||
happen outside the critical zone.*/
|
|
||||||
if ((timeout != TIME_INFINITE) && !chVTIsArmedI(&vt))
|
|
||||||
return MSG_TIMEOUT;
|
|
||||||
|
|
||||||
/* Transmission complete interrupt enabled.*/
|
/* Transmission complete interrupt enabled.*/
|
||||||
dp->CR1 |= I2C_CR1_TCIE;
|
dp->CR1 |= I2C_CR1_TCIE;
|
||||||
|
|
||||||
|
@ -770,12 +726,7 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
dp->CR2 |= I2C_CR2_START;
|
dp->CR2 |= I2C_CR2_START;
|
||||||
|
|
||||||
/* Waits for the operation completion or a timeout.*/
|
/* Waits for the operation completion or a timeout.*/
|
||||||
i2cp->thread = chThdGetSelfX();
|
return osalThreadSuspendTimeoutS(&i2cp->thread, timeout);
|
||||||
chSchGoSleepS(CH_STATE_SUSPENDED);
|
|
||||||
if ((timeout != TIME_INFINITE) && chVTIsArmedI(&vt))
|
|
||||||
chVTResetI(&vt);
|
|
||||||
|
|
||||||
return chThdGetSelfX()->p_u.rdymsg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAL_USE_I2C */
|
#endif /* HAL_USE_I2C */
|
||||||
|
|
|
@ -77,6 +77,13 @@
|
||||||
#define STM32_I2C_USE_I2C2 FALSE
|
#define STM32_I2C_USE_I2C2 FALSE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief I2C timeout on busy condition in milliseconds.
|
||||||
|
*/
|
||||||
|
#if !defined(STM32_I2C_BUSY_TIMEOUT) || defined(__DOXYGEN__)
|
||||||
|
#define STM32_I2C_BUSY_TIMEOUT 50
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief I2C1 interrupt priority level setting.
|
* @brief I2C1 interrupt priority level setting.
|
||||||
*/
|
*/
|
||||||
|
@ -287,7 +294,7 @@ struct I2CDriver{
|
||||||
/**
|
/**
|
||||||
* @brief Thread waiting for I/O completion.
|
* @brief Thread waiting for I/O completion.
|
||||||
*/
|
*/
|
||||||
thread_t *thread;
|
thread_reference_t thread;
|
||||||
/**
|
/**
|
||||||
* @brief Current slave address without R/W bit.
|
* @brief Current slave address without R/W bit.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -75,7 +75,7 @@
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time);
|
msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t timeout);
|
||||||
void chQueueWakeupOneI(threads_queue_t *tqp, msg_t msg);
|
void chQueueWakeupOneI(threads_queue_t *tqp, msg_t msg);
|
||||||
void chQueueWakeupAllI(threads_queue_t *tqp, msg_t msg);
|
void chQueueWakeupAllI(threads_queue_t *tqp, msg_t msg);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -168,6 +168,7 @@ extern "C" {
|
||||||
thread_t *chThdStart(thread_t *tp);
|
thread_t *chThdStart(thread_t *tp);
|
||||||
tprio_t chThdSetPriority(tprio_t newprio);
|
tprio_t chThdSetPriority(tprio_t newprio);
|
||||||
msg_t chThreadSuspendS(thread_reference_t *trp);
|
msg_t chThreadSuspendS(thread_reference_t *trp);
|
||||||
|
msg_t chThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout);
|
||||||
void chThreadResumeI(thread_reference_t *trp, msg_t msg);
|
void chThreadResumeI(thread_reference_t *trp, msg_t msg);
|
||||||
void chThreadResumeS(thread_reference_t *trp, msg_t msg);
|
void chThreadResumeS(thread_reference_t *trp, msg_t msg);
|
||||||
void chThreadResume(thread_reference_t *trp, msg_t msg);
|
void chThreadResume(thread_reference_t *trp, msg_t msg);
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
* dequeued or the specified timeouts expires.
|
* dequeued or the specified timeouts expires.
|
||||||
*
|
*
|
||||||
* @param[in] tqp pointer to the threads queue object
|
* @param[in] tqp pointer to the threads queue object
|
||||||
* @param[in] time the timeout in system ticks, the special values are
|
* @param[in] timeout the timeout in system ticks, the special values are
|
||||||
* handled as follow:
|
* handled as follow:
|
||||||
* - @a TIME_INFINITE the thread enters an infinite sleep
|
* - @a TIME_INFINITE the thread enters an infinite sleep
|
||||||
* state.
|
* state.
|
||||||
|
@ -74,13 +74,13 @@
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t time) {
|
msg_t chQueueGoSleepTimeoutS(threads_queue_t *tqp, systime_t timeout) {
|
||||||
|
|
||||||
if (TIME_IMMEDIATE == time)
|
if (TIME_IMMEDIATE == timeout)
|
||||||
return MSG_TIMEOUT;
|
return MSG_TIMEOUT;
|
||||||
|
|
||||||
queue_insert(currp, tqp);
|
queue_insert(currp, tqp);
|
||||||
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, time);
|
return chSchGoSleepTimeoutS(CH_STATE_QUEUED, timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -147,6 +147,9 @@ static void wakeup(void *p) {
|
||||||
another thread with higher priority.*/
|
another thread with higher priority.*/
|
||||||
chSysUnlockFromISR();
|
chSysUnlockFromISR();
|
||||||
return;
|
return;
|
||||||
|
case CH_STATE_SUSPENDED:
|
||||||
|
*(thread_reference_t *)tp->p_u.wtobjp = NULL;
|
||||||
|
break;
|
||||||
#if CH_CFG_USE_SEMAPHORES
|
#if CH_CFG_USE_SEMAPHORES
|
||||||
case CH_STATE_WTSEM:
|
case CH_STATE_WTSEM:
|
||||||
chSemFastSignalI((semaphore_t *)tp->p_u.wtobjp);
|
chSemFastSignalI((semaphore_t *)tp->p_u.wtobjp);
|
||||||
|
|
|
@ -280,14 +280,48 @@ tprio_t chThdSetPriority(tprio_t newprio) {
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
msg_t chThreadSuspendS(thread_reference_t *trp) {
|
msg_t chThreadSuspendS(thread_reference_t *trp) {
|
||||||
|
thread_t *tp = chThdGetSelfX();
|
||||||
|
|
||||||
chDbgAssert(*trp == NULL, "not NULL");
|
chDbgAssert(*trp == NULL, "not NULL");
|
||||||
|
|
||||||
*trp = (thread_reference_t)chThdGetSelfX();
|
*trp = tp;
|
||||||
|
tp->p_u.wtobjp = &trp;
|
||||||
chSchGoSleepS(CH_STATE_SUSPENDED);
|
chSchGoSleepS(CH_STATE_SUSPENDED);
|
||||||
return chThdGetSelfX()->p_msg;
|
return chThdGetSelfX()->p_msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Sends the current thread sleeping and sets a reference variable.
|
||||||
|
* @note This function must reschedule, it can only be called from thread
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* @param[in] trp a pointer to a thread reference object
|
||||||
|
* @param[in] timeout the timeout in system ticks, the special values are
|
||||||
|
* handled as follow:
|
||||||
|
* - @a TIME_INFINITE the thread enters an infinite sleep
|
||||||
|
* state.
|
||||||
|
* - @a TIME_IMMEDIATE the thread is not enqueued and
|
||||||
|
* the function returns @p MSG_TIMEOUT as if a timeout
|
||||||
|
* occurred.
|
||||||
|
* .
|
||||||
|
* @return The wake up message.
|
||||||
|
* @retval MSG_TIMEOUT if the operation timed out.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
msg_t chThreadSuspendTimeoutS(thread_reference_t *trp, systime_t timeout) {
|
||||||
|
thread_t *tp = chThdGetSelfX();
|
||||||
|
|
||||||
|
chDbgAssert(*trp == NULL, "not NULL");
|
||||||
|
|
||||||
|
if (TIME_IMMEDIATE == timeout)
|
||||||
|
return MSG_TIMEOUT;
|
||||||
|
|
||||||
|
*trp = tp;
|
||||||
|
tp->p_u.wtobjp = &trp;
|
||||||
|
return chSchGoSleepTimeoutS(CH_STATE_SUSPENDED, timeout);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wakes up a thread waiting on a thread reference object.
|
* @brief Wakes up a thread waiting on a thread reference object.
|
||||||
* @note This function must not reschedule because it can be called from
|
* @note This function must not reschedule because it can be called from
|
||||||
|
|
Loading…
Reference in New Issue