-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Preventing race conditions with multiple bus users #2289
Description
I have multiple drivers that are using the same bus (SPI_0) for communicating with their hardware. Has anyone considered or experienced the possible race conditions between different device drivers communicating over the bus without mutual exclusion?
I would like to introduce one mutex per bus device (SPI_0, SPI_1, ... , I2C_0, I2C_1 etc) that must be acquired before using the bus in order to prevent multiple chip select signals being asserted causing all kinds of trouble with the hardware devices.
Example taken from at86rf231 driver:
uint8_t at86rf231_reg_read(uint8_t addr)
{
char value;
/* Start the SPI transfer */
gpio_clear(AT86RF231_CS);
/* read from register */
spi_transfer_reg(AT86RF231_SPI, AT86RF231_ACCESS_REG | AT86RF231_ACCESS_READ | addr, 0, &value);
/* End the SPI transfer */
gpio_set(AT86RF231_CS);
return (uint8_t)value;
}
Running the above with interrupts enabled and getting a context switch anywhere between gpio_clear and gpio_set opens up for the potential that another SPI device driver will attempt to write something to the bus, but ends up sending it to both the at86rf231 as well as the originally intended hardware device.
Adding mutex_lock(&SPI_0_MUTEX) before calling gpio_clear(), and mutex_unlock(&SPI_0_MUTEX) after gpio_set() (or similar) will make sure only one device driver can access the bus at any given time.
The same race condition can also occur on i2c busses (which have no chip select line) where the device driver needs to send more than a single byte (or whatever the atomic size is for the i2c hardware).
It would be necessary to update all drivers using I2C or SPI busses to actually achieve anything with the change. I would be glad for any comments and suggestions on my proposed solution.
ChibiOS has a similar design where a bus user must first call spiAcquireBus and spiReleaseBus in order to ensure exclusive access to the bus.
I recommend adopting something similar to what ChibiOS does in order to allow multiple bus users to coexist safely.