Embedded development

From miki
Revision as of 07:31, 24 September 2018 by Mip (talk | contribs) (Created page with "= Pits = == Race condition when reading twice a status register == Embedded devices have usually status register for various components (like I2C status bits). When testing b...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Pits

Race condition when reading twice a status register

Embedded devices have usually status register for various components (like I2C status bits).

When testing bits in these register, do not read several times the same register. Doing so will create a race condition. For instance:

while (R_I2C_STAT & (C_I2C_OVERFLOW | C_I2C_BUS_ERROR | C_I2C_STOP | C_I2C_ADDRESS_MATCH | C_I2C_ARBITRATION_LOSS)) {
    if (R_I2C_STAT & C_I2C_RX_NOT_EMPTY) {
        // Read the byte
    }
}

This code has two problems:

  • First, don't read twice the R_I2C_STAT. Doing so will create a race condition.
  • We might miss a byte if the STOP event occurs at the same time as RX_NOT_EMPTY event.

A better implementation:

int i2c_stat = 0;
while (stat & (C_I2C_OVERFLOW | C_I2C_BUS_ERROR | C_I2C_STOP | C_I2C_ADDRESS_MATCH | C_I2C_ARBITRATION_LOSS)) {
    if ((i2c_stat = R_I2C_STAT) & C_I2C_RX_NOT_EMPTY) {
        // Read the byte
    }
}
  • We read the register only once.
  • We first test the RX_NOT_EMPTY.