mirror of
https://github.com/PX4/PX4-Autopilot.git
synced 2026-05-23 22:58:10 +08:00
Backport of upstream NuttX MTD FLASH driver: Flash corruption fix
0a85a41 MTD FLASH driver: Clone Sebastien Lorquet's m25px change to at25, is25xp, ramtron, and sst25xx. Clone Sebastien Lorquet's m25px change to at25, is25xp, ramtron, and sst25xx.
This commit is contained in:
committed by
Lorenz Meier
parent
e7b7b27ef8
commit
9867ce455d
@@ -1,47 +0,0 @@
|
||||
diff --git NuttX/nuttx/drivers/mtd/ramtron.c NuttX/nuttx/drivers/mtd/ramtron.c
|
||||
index ad448c8..236084f 100644
|
||||
--- NuttX/nuttx/drivers/mtd/ramtron.c
|
||||
+++ NuttX/nuttx/drivers/mtd/ramtron.c
|
||||
@@ -539,7 +539,7 @@ static inline int ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_
|
||||
|
||||
finfo("page: %08lx offset: %08lx\n", (long)page, (long)offset);
|
||||
|
||||
-#ifndef RAMTRON_WRITEWAIT
|
||||
+#ifndef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -574,7 +574,7 @@ static inline int ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
finfo("Written\n");
|
||||
|
||||
-#ifdef RAMTRON_WRITEWAIT
|
||||
+#ifdef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Wait for write completion now so we can report any errors to the caller. Thus
|
||||
* the caller will know whether or not if the data is on stable storage
|
||||
*/
|
||||
@@ -657,13 +657,13 @@ static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
FAR uint8_t *buffer)
|
||||
{
|
||||
FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev;
|
||||
-#ifdef RAMTRON_WRITEWAIT
|
||||
+#ifdef CONFIG_RAMTRON_WRITEWAIT
|
||||
uint8_t status;
|
||||
#endif
|
||||
|
||||
finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
|
||||
|
||||
-#ifndef RAMTRON_WRITEWAIT
|
||||
+#ifndef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -690,7 +690,7 @@ static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
|
||||
SPI_RECVBLOCK(priv->dev, buffer, nbytes);
|
||||
|
||||
-#ifdef RAMTRON_WRITEWAIT
|
||||
+#ifdef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Read the status register. This isn't strictly needed, but it gives us a
|
||||
* chance to detect if SPI transactions are operating correctly, which
|
||||
* allows us to catch complete device failures in the read path. We expect
|
||||
@@ -0,0 +1,187 @@
|
||||
diff --git NuttX/nuttx/drivers/mtd/at25.c NuttX/nuttx/drivers/mtd/at25.c
|
||||
index 777ff38..c775e52 100644
|
||||
--- NuttX/nuttx/drivers/mtd/at25.c
|
||||
+++ NuttX/nuttx/drivers/mtd/at25.c
|
||||
@@ -524,6 +524,12 @@ static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
|
||||
|
||||
finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
|
||||
|
||||
+ /* Lock the SPI bus NOW because the following call must be executed with
|
||||
+ * the bus locked.
|
||||
+ */
|
||||
+
|
||||
+ at25_lock(priv->dev);
|
||||
+
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -532,9 +538,8 @@ static ssize_t at25_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbytes,
|
||||
|
||||
at25_waitwritecomplete(priv);
|
||||
|
||||
- /* Lock the SPI bus and select this FLASH part */
|
||||
+ /* Select this FLASH part */
|
||||
|
||||
- at25_lock(priv->dev);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
|
||||
/* Send "Read from Memory " instruction */
|
||||
diff --git NuttX/nuttx/drivers/mtd/is25xp.c NuttX/nuttx/drivers/mtd/is25xp.c
|
||||
index 55b677b..4919344 100644
|
||||
--- NuttX/nuttx/drivers/mtd/is25xp.c
|
||||
+++ NuttX/nuttx/drivers/mtd/is25xp.c
|
||||
@@ -748,6 +748,12 @@ static ssize_t is25xp_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyte
|
||||
|
||||
finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
|
||||
|
||||
+ /* Lock the SPI bus NOW because the following call must be executed with
|
||||
+ * the bus locked.
|
||||
+ */
|
||||
+
|
||||
+ is25xp_lock(priv->dev);
|
||||
+
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -759,9 +765,8 @@ static ssize_t is25xp_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyte
|
||||
is25xp_waitwritecomplete(priv);
|
||||
}
|
||||
|
||||
- /* Lock the SPI bus and select this FLASH part */
|
||||
+ /* Select this FLASH part */
|
||||
|
||||
- is25xp_lock(priv->dev);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
|
||||
/* Send "Read from Memory " instruction */
|
||||
@@ -782,6 +787,7 @@ static ssize_t is25xp_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyte
|
||||
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
is25xp_unlock(priv->dev);
|
||||
+
|
||||
finfo("return nbytes: %d\n", (int)nbytes);
|
||||
return nbytes;
|
||||
}
|
||||
diff --git NuttX/nuttx/drivers/mtd/ramtron.c NuttX/nuttx/drivers/mtd/ramtron.c
|
||||
index ad448c8..23e4ad1 100644
|
||||
--- NuttX/nuttx/drivers/mtd/ramtron.c
|
||||
+++ NuttX/nuttx/drivers/mtd/ramtron.c
|
||||
@@ -532,14 +532,14 @@ static inline void ramtron_sendaddr(const struct ramtron_dev_s *priv, uint32_t a
|
||||
* Name: ramtron_pagewrite
|
||||
************************************************************************************/
|
||||
|
||||
-static inline int ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_t *buffer,
|
||||
- off_t page)
|
||||
+static inline int ramtron_pagewrite(struct ramtron_dev_s *priv,
|
||||
+ FAR const uint8_t *buffer, off_t page)
|
||||
{
|
||||
off_t offset = page << priv->pageshift;
|
||||
|
||||
finfo("page: %08lx offset: %08lx\n", (long)page, (long)offset);
|
||||
|
||||
-#ifndef RAMTRON_WRITEWAIT
|
||||
+#ifndef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -574,7 +574,7 @@ static inline int ramtron_pagewrite(struct ramtron_dev_s *priv, FAR const uint8_
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, false);
|
||||
finfo("Written\n");
|
||||
|
||||
-#ifdef RAMTRON_WRITEWAIT
|
||||
+#ifdef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Wait for write completion now so we can report any errors to the caller. Thus
|
||||
* the caller will know whether or not if the data is on stable storage
|
||||
*/
|
||||
@@ -657,13 +657,19 @@ static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
FAR uint8_t *buffer)
|
||||
{
|
||||
FAR struct ramtron_dev_s *priv = (FAR struct ramtron_dev_s *)dev;
|
||||
-#ifdef RAMTRON_WRITEWAIT
|
||||
+#ifdef CONFIG_RAMTRON_WRITEWAIT
|
||||
uint8_t status;
|
||||
#endif
|
||||
|
||||
finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
|
||||
|
||||
-#ifndef RAMTRON_WRITEWAIT
|
||||
+ /* Lock the SPI bus NOW because the ramtron_waitwritecomplete call must be
|
||||
+ * executed with the bus locked.
|
||||
+ */
|
||||
+
|
||||
+ ramtron_lock(priv);
|
||||
+
|
||||
+#ifndef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -673,9 +679,8 @@ static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
(void)ramtron_waitwritecomplete(priv);
|
||||
#endif
|
||||
|
||||
- /* Lock the SPI bus and select this FLASH part */
|
||||
+ /* Select this FLASH part */
|
||||
|
||||
- ramtron_lock(priv);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
|
||||
/* Send "Read from Memory " instruction */
|
||||
@@ -690,7 +695,7 @@ static ssize_t ramtron_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
|
||||
SPI_RECVBLOCK(priv->dev, buffer, nbytes);
|
||||
|
||||
-#ifdef RAMTRON_WRITEWAIT
|
||||
+#ifdef CONFIG_RAMTRON_WRITEWAIT
|
||||
/* Read the status register. This isn't strictly needed, but it gives us a
|
||||
* chance to detect if SPI transactions are operating correctly, which
|
||||
* allows us to catch complete device failures in the read path. We expect
|
||||
diff --git NuttX/nuttx/drivers/mtd/sst25xx.c NuttX/nuttx/drivers/mtd/sst25xx.c
|
||||
index 9f88348..22d71cc 100644
|
||||
--- NuttX/nuttx/drivers/mtd/sst25xx.c
|
||||
+++ NuttX/nuttx/drivers/mtd/sst25xx.c
|
||||
@@ -679,7 +679,8 @@ static ssize_t sst25xx_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t
|
||||
|
||||
/* On this device, we can handle the block read just like the byte-oriented read */
|
||||
|
||||
- nbytes = sst25xx_read(dev, startblock << priv->pageshift, nblocks << priv->pageshift, buffer);
|
||||
+ nbytes = sst25xx_read(dev, startblock << priv->pageshift,
|
||||
+ nblocks << priv->pageshift, buffer);
|
||||
if (nbytes > 0)
|
||||
{
|
||||
return nbytes >> priv->pageshift;
|
||||
@@ -726,6 +727,12 @@ static ssize_t sst25xx_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
|
||||
finfo("offset: %08lx nbytes: %d\n", (long)offset, (int)nbytes);
|
||||
|
||||
+ /* Lock the SPI bus NOW because the following conditional call to
|
||||
+ * sst25xx_waitwritecomplete must be executed with the bus locked.
|
||||
+ */
|
||||
+
|
||||
+ sst25xx_lock(priv->dev);
|
||||
+
|
||||
/* Wait for any preceding write to complete. We could simplify things by
|
||||
* perform this wait at the end of each write operation (rather than at
|
||||
* the beginning of ALL operations), but have the wait first will slightly
|
||||
@@ -737,9 +744,8 @@ static ssize_t sst25xx_read(FAR struct mtd_dev_s *dev, off_t offset, size_t nbyt
|
||||
sst25xx_waitwritecomplete(priv);
|
||||
}
|
||||
|
||||
- /* Lock the SPI bus and select this FLASH part */
|
||||
+ /* Select this FLASH part */
|
||||
|
||||
- sst25xx_lock(priv->dev);
|
||||
SPI_SELECT(priv->dev, SPIDEV_FLASH, true);
|
||||
|
||||
/* Send "Read from Memory " instruction */
|
||||
diff --git NuttX/nuttx/drivers/mtd/w25.c NuttX/nuttx/drivers/mtd/w25.c
|
||||
index 279525e..22e7ea5 100644
|
||||
--- NuttX/nuttx/drivers/mtd/w25.c
|
||||
+++ NuttX/nuttx/drivers/mtd/w25.c
|
||||
@@ -1004,6 +1004,7 @@ static ssize_t w25_bread(FAR struct mtd_dev_s *dev, off_t startblock, size_t nbl
|
||||
{
|
||||
nbytes >>= W25_SECTOR512_SHIFT;
|
||||
}
|
||||
+
|
||||
#else
|
||||
nbytes = w25_read(dev, startblock << W25_PAGE_SHIFT, nblocks << W25_PAGE_SHIFT, buffer);
|
||||
if (nbytes > 0)
|
||||
@@ -51,7 +51,6 @@ set(nuttx_patches
|
||||
00017-BACKPORT-cdcacm.patch
|
||||
00018-BACKPORT-stm32-serial-break.patch
|
||||
00019-BACKPORT-stm32-rcc-keep-HSI-on.patch
|
||||
00020-BACKPORT-ramtron-CONFIG-prefix.patch
|
||||
00021-BACKPORT-stm32f3x-add-BKP.patch
|
||||
00022-BACKPORT-stm32-bkp-reference-fix.patch
|
||||
00023-BACKPORT-stm32f7-bkp-reference-fix.patch
|
||||
@@ -60,6 +59,7 @@ set(nuttx_patches
|
||||
00026-BACKPORT-stm32fX-serial-fix-freezing.patch
|
||||
00027-BACKPORT-stm32-sdio-1-bit-and-16G-fix.patch
|
||||
00030-BACKPORT-fix-arm-none-eabi-gcc-7-warnings-nuttx.patch
|
||||
00028-BACKPORT-mtd-FLASH-corruption.patch
|
||||
00031-BACKPORT-fix-arm-none-eabi-gcc-7-warnings-apps.patch
|
||||
90000-PENDING-wip-inflight-to-upstream.patch
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user