stm32: Change flash IRQ priority from 2 to 6 to prevent preemption.

The flash-IRQ handler is used to flush the storage cache, ie write
outstanding block data from RAM to flash.  This is triggered by a timeout,
or by a direct call to flush all storage caches.

Prior to this commit, a timeout could trigger the cache flushing to occur
during the execution of a read/write to external SPI flash storage.  In
such a case the storage subsystem would break down.

SPI storage transfers are already protected against USB IRQs, so by
changing the priority of the flash IRQ to that of the USB IRQ (what is
done in this commit) the SPI transfers can be protected against any
timeouts triggering a cache flush (the cache flush would be postponed until
after the transfer finished, but note that in the case of SPI writes the
timeout is rescheduled after the transfer finishes).

The handling of internal flash sync'ing needs to be changed to directly
call flash_bdev_irq_handler() sync may be called with the IRQ priority
already raised (eg when called from a USB MSC IRQ handler).
This commit is contained in:
Damien George
2018-09-12 15:46:04 +10:00
parent 6f015d337d
commit 0941a467e7
4 changed files with 15 additions and 15 deletions

View File

@@ -143,14 +143,17 @@ int32_t flash_bdev_ioctl(uint32_t op, uint32_t arg) {
flash_bdev_irq_handler();
return 0;
case BDEV_IOCTL_SYNC:
case BDEV_IOCTL_SYNC: {
uint32_t basepri = raise_irq_pri(IRQ_PRI_FLASH); // prevent cache flushing and USB access
if (flash_flags & FLASH_FLAG_DIRTY) {
flash_flags |= FLASH_FLAG_FORCE_WRITE;
while (flash_flags & FLASH_FLAG_DIRTY) {
NVIC->STIR = FLASH_IRQn;
flash_bdev_irq_handler();
}
}
restore_irq_pri(basepri);
return 0;
}
}
return -MP_EINVAL;
}