STM32 Mass Storage con tamaño de unidad de asignación de 8K

0

Tengo un proyecto de Dispositivo Compuesto MSC / CDC que funciona con un tamaño de unidad de asignación 4K para el almacenamiento masivo. Estoy tratando de convertir esto para usar unidades de asignación de 8 K, pero el formato no se completa correctamente.

La memoria flash es un flash QSPI (Cypress) con 32 sectores 4K al principio, y 510 sectores 64K después. Quiero usar los sectores de 64K porque hay más de ellos. Desafortunadamente, no tengo 64K de RAM en la MCU (esto es un STM32L443CCU) para almacenar en caché todo el sector mientras sustituyo datos nuevos. Como tal, he estado usando los sectores 4K como área de respaldo.

No puedo cambiar el flash IC o el microcontrolador, así que tengo que usar lo que tengo. Si uso el tamaño de unidad de asignación 4K para el almacenamiento masivo, funciona bien (es lento, pero funciona). No puede completar el formato para el tamaño de unidad de asignación de 8K.

A continuación se encuentran mis funciones para leer y escribir, agradecería a alguien que las revise para ver si me he perdido algo.

También he actualizado el MSC_MEDIA_PACKET definido para que sea 8192. Aumenté el montón y la pila en el archivo de inicio, pero no he visto ningún cambio en el comportamiento al hacer eso. ¿Hay algo más que estoy olvidando?

Algunos definen primero:

#define STORAGE_BLK_SIZ          8192
#define FLASH_MEMORY_PAGE_SIZE   256

La función de lectura:

int8_t STORAGE_Read_FS (uint8_t lun,
                    uint8_t *buf,
                    uint32_t blk_addr,
                    uint16_t blk_len)
{ 
   uint32_t pages_to_read = STORAGE_BLK_SIZ * blk_len / FLASH_MEMORY_PAGE_SIZE;
   uint8_t err_code;
   uint32_t converted_block_addr = blk_addr * STORAGE_BLK_SIZ + 0x20000; // 0x20000 is where the 64K sectors start in flash

   if (converted_block_addr > 0x2000000)
   {
      // Outta memory :(
      return USBD_FAIL;
   }
   for (uint32_t i = 0; i < pages_to_read; i++)
   {
      err_code = flashMemory_ReadPage((converted_block_addr + i * FLASH_MEMORY_PAGE_SIZE), &buf[i * FLASH_MEMORY_PAGE_SIZE]);
      if (err_code != HAL_OK)
      {
         return (USBD_FAIL);
      }
   }
   return (USBD_OK);
}

La función de escritura:

int8_t STORAGE_Write_FS (uint8_t lun,
                         uint8_t *buf,
                         uint32_t blk_addr,
                         uint16_t blk_len)
{

   // 1. Convert address to match the start of 64K sectors 
   uint32_t converted_block_addr = blk_addr * STORAGE_BLK_SIZ + 0x20000;
   if (converted_block_addr > 0x2000000)
   {
      // Outta memory :(
      return USBD_FAIL;
   }
   // 2. Figure out 64k sector that this address falls into
   uint32_t start_64k_sector = (uint32_t)(converted_block_addr / 0x10000) * 0x10000;
   // 3. Erase 4K sectors (starting at address 0x0) we need to store the 64K backup
   for (uint8_t i = 0; i < (65536/4096); i++)
   {
      flashMemory_EraseSector(i * 4096);
   }
   // 4. Copy 64k sector, one 256 byte page at a time, and store in the 4K sectors
   uint32_t page_64k_sector_addr = start_64k_sector;
   uint8_t buffer[256] = {0};
   for (uint16_t i = 0; i < 256; i++)
   {
      flashMemory_ReadPage(page_64k_sector_addr, buffer);
      flashMemory_WritePage(i * 256, buffer, 256);
      page_64k_sector_addr += 256;
   }
   // 5. Erase 64K sector
   flashMemory_Erase64KSector(start_64k_sector);
   // 6. Find location of data in 64k sector
   uint8_t data_loc_64k_sector = (converted_block_addr - start_64k_sector)/STORAGE_BLK_SIZ;
   // 7. a) Restore old data from 4K sectors, up until the point of new data
   for (uint16_t i = 0; i < data_loc_64k_sector; i++)
   {
      for (uint16_t j = 0; j < (STORAGE_BLK_SIZ/256); j++)
      {
         flashMemory_ReadPage(i * STORAGE_BLK_SIZ + j * 256, buffer);
         flashMemory_WritePage(start_64k_sector + i * STORAGE_BLK_SIZ + j * 256, buffer, 256);
      }
   }
   // 7. b) Write new data
   for (uint16_t j = 0; j < (STORAGE_BLK_SIZ/256); j++)
   {
      flashMemory_WritePage(start_64k_sector + data_loc_64k_sector * STORAGE_BLK_SIZ + j * 256, &buf[j * 256], 256);
   }
   // 7. c) Write all remaining old data after new data
   for (uint16_t i = (data_loc_64k_sector + 1); i < (65536/STORAGE_BLK_SIZ); i++)
   {
      for (uint16_t j = 0; j < (STORAGE_BLK_SIZ/256); j++)
      {
         flashMemory_ReadPage(i * STORAGE_BLK_SIZ + j * 256, buffer);
         flashMemory_WritePage(start_64k_sector + i * STORAGE_BLK_SIZ + j * 256, buffer, 256);
      }
   }
    
pregunta Catsunami

1 respuesta

0

El problema estaba en la llamada a la función Storage_WriteFS, no estaba usando blk_len en absoluto, por lo que solo escribiría un bloque de todos los datos suministrados.

    
respondido por el Catsunami

Lea otras preguntas en las etiquetas