Fixed bug 3530043.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4244 35acf78f-673a-0410-8e92-d51de3d6d3f4master
parent
2b01d72e42
commit
c0cbc2411e
|
@ -102,7 +102,7 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
#define i2cMasterTransmit(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes) \
|
#define i2cMasterTransmit(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes) \
|
||||||
(i2cMasterTransmitTimeout(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes, \
|
(i2cMasterTransmitTimeout(i2cp, addr, txbuf, txbytes, rxbuf, rxbytes, \
|
||||||
TIME_INFINITE))
|
TIME_INFINITE))
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Wrap i2cMasterReceiveTimeout function with TIME_INFINITE timeout.
|
* @brief Wrap i2cMasterReceiveTimeout function with TIME_INFINITE timeout.
|
||||||
|
|
|
@ -165,13 +165,15 @@ static void i2c_lld_abort_operation(I2CDriver *i2cp) {
|
||||||
static void i2c_lld_safety_timeout(void *p) {
|
static void i2c_lld_safety_timeout(void *p) {
|
||||||
I2CDriver *i2cp = (I2CDriver *)p;
|
I2CDriver *i2cp = (I2CDriver *)p;
|
||||||
|
|
||||||
|
chSysLockFromIsr();
|
||||||
if (i2cp->thread) {
|
if (i2cp->thread) {
|
||||||
|
Thread *tp = i2cp->thread;
|
||||||
i2c_lld_abort_operation(i2cp);
|
i2c_lld_abort_operation(i2cp);
|
||||||
chSysLockFromIsr();
|
i2cp->thread = NULL;
|
||||||
i2cp->thread->p_u.rdymsg = RDY_TIMEOUT;
|
tp->p_u.rdymsg = RDY_TIMEOUT;
|
||||||
chSchReadyI(i2cp->thread);
|
chSchReadyI(tp);
|
||||||
chSysUnlockFromIsr();
|
|
||||||
}
|
}
|
||||||
|
chSysUnlockFromIsr();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -768,12 +770,12 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
systime_t timeout) {
|
systime_t timeout) {
|
||||||
I2C_TypeDef *dp = i2cp->i2c;
|
I2C_TypeDef *dp = i2cp->i2c;
|
||||||
VirtualTimer vt;
|
VirtualTimer vt;
|
||||||
msg_t rdymsg;
|
|
||||||
|
|
||||||
chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
|
chDbgCheck((rxbytes > 1), "i2c_lld_master_receive_timeout");
|
||||||
|
|
||||||
/* Global timeout for the whole operation.*/
|
/* Global timeout for the whole operation.*/
|
||||||
chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
|
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.*/
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
@ -789,10 +791,10 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
/* Waits until BUSY flag is reset and the STOP from the previous operation
|
/* Waits until BUSY flag is reset and the STOP from the previous operation
|
||||||
is completed, alternatively for a timeout condition.*/
|
is completed, alternatively for a timeout condition.*/
|
||||||
while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) {
|
while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) {
|
||||||
if (!chVTIsArmedI(&vt)) {
|
chSysLock();
|
||||||
chSysLock();
|
if (!chVTIsArmedI(&vt))
|
||||||
return RDY_TIMEOUT;
|
return RDY_TIMEOUT;
|
||||||
}
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This lock will be released in high level driver.*/
|
/* This lock will be released in high level driver.*/
|
||||||
|
@ -810,11 +812,10 @@ msg_t i2c_lld_master_receive_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
/* Waits for the operation completion or a timeout.*/
|
/* Waits for the operation completion or a timeout.*/
|
||||||
i2cp->thread = chThdSelf();
|
i2cp->thread = chThdSelf();
|
||||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||||
rdymsg = chThdSelf()->p_u.rdymsg;
|
if (chVTIsArmedI(&vt))
|
||||||
if (rdymsg != RDY_TIMEOUT)
|
|
||||||
chVTResetI(&vt);
|
chVTResetI(&vt);
|
||||||
|
|
||||||
return rdymsg;
|
return chThdSelf()->p_u.rdymsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -848,13 +849,13 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
systime_t timeout) {
|
systime_t timeout) {
|
||||||
I2C_TypeDef *dp = i2cp->i2c;
|
I2C_TypeDef *dp = i2cp->i2c;
|
||||||
VirtualTimer vt;
|
VirtualTimer vt;
|
||||||
msg_t rdymsg;
|
|
||||||
|
|
||||||
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
|
chDbgCheck(((rxbytes == 0) || ((rxbytes > 1) && (rxbuf != NULL))),
|
||||||
"i2c_lld_master_transmit_timeout");
|
"i2c_lld_master_transmit_timeout");
|
||||||
|
|
||||||
/* Global timeout for the whole operation.*/
|
/* Global timeout for the whole operation.*/
|
||||||
chVTSetI(&vt, timeout, i2c_lld_safety_timeout, (void *)i2cp);
|
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.*/
|
||||||
chSysUnlock();
|
chSysUnlock();
|
||||||
|
@ -874,10 +875,10 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
/* Waits until BUSY flag is reset and the STOP from the previous operation
|
/* Waits until BUSY flag is reset and the STOP from the previous operation
|
||||||
is completed, alternatively for a timeout condition.*/
|
is completed, alternatively for a timeout condition.*/
|
||||||
while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) {
|
while ((dp->SR2 & I2C_SR2_BUSY) || (dp->CR1 & I2C_CR1_STOP)) {
|
||||||
if (!chVTIsArmedI(&vt)) {
|
chSysLock();
|
||||||
chSysLock();
|
if (!chVTIsArmedI(&vt))
|
||||||
return RDY_TIMEOUT;
|
return RDY_TIMEOUT;
|
||||||
}
|
chSysUnlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This lock will be released in high level driver.*/
|
/* This lock will be released in high level driver.*/
|
||||||
|
@ -895,11 +896,10 @@ msg_t i2c_lld_master_transmit_timeout(I2CDriver *i2cp, i2caddr_t addr,
|
||||||
/* Waits for the operation completion or a timeout.*/
|
/* Waits for the operation completion or a timeout.*/
|
||||||
i2cp->thread = chThdSelf();
|
i2cp->thread = chThdSelf();
|
||||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||||
rdymsg = chThdSelf()->p_u.rdymsg;
|
if (chVTIsArmedI(&vt))
|
||||||
if (rdymsg != RDY_TIMEOUT)
|
|
||||||
chVTResetI(&vt);
|
chVTResetI(&vt);
|
||||||
|
|
||||||
return rdymsg;
|
return chThdSelf()->p_u.rdymsg;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* HAL_USE_I2C */
|
#endif /* HAL_USE_I2C */
|
||||||
|
|
|
@ -81,6 +81,8 @@
|
||||||
*****************************************************************************
|
*****************************************************************************
|
||||||
|
|
||||||
*** 2.5.0 ***
|
*** 2.5.0 ***
|
||||||
|
- FIX: Fixed timeout related race condition in STM32 I2C driver (bug 3530043)
|
||||||
|
(backported to 2.4.2).
|
||||||
- FIX: Fixed wrong macro check in STM32 MAC driver (bug 3527179)(backported
|
- FIX: Fixed wrong macro check in STM32 MAC driver (bug 3527179)(backported
|
||||||
to 2.4.2).
|
to 2.4.2).
|
||||||
- FIX: Fixed error in STM32L-Discovery board.h file (bug 3526918)(backported
|
- FIX: Fixed error in STM32L-Discovery board.h file (bug 3526918)(backported
|
||||||
|
|
Loading…
Reference in New Issue