cancel
Showing results for 
Search instead for 
Did you mean: 

FX_IO_ERROR - LX_SYSTEM_INVALID_BLOCK

urbito
Senior
Hello, 
 
I am trying to install FileX + LevelX in an stm32h7 microcontroller using a nor custom driver. I do have in my hardware an AT45DB641 NOR memory.
 
I am working it as an stand alone and also with fault tolerant enable.
 
My flash chip does have 4096 blocks of 2048 bytes each. i can write and read on pages of 256 bytes each.
 
Right now i am being able to format and open the media after doing a full reset of my chip, as i understand, putting everything to 1 (0xFF).
 
I can run the example that stm32 provide about creating a file etc...
 
My issue happens the second time i do run the code, but this time without erasing the chip. 
 
I am getting following error from levelx: LX_SYSTEM_INVALID_BLOCK
 
and from filex: FX_IO_ERROR.
 
My code is as follows:
 
nor_custom_driver
---------------------------------------------------------------------------------
 
#ifndef LX_DIRECT_READ
 
#ifndef NOR_SECTOR_BUFFER_SIZE
#define NOR_SECTOR_BUFFER_SIZE 512
#endif
 
static ULONG nor_sector_memory[NOR_SECTOR_BUFFER_SIZE];
#endif
 
UINT  lx_stm32_nor_custom_driver_initialize(LX_NOR_FLASH *nor_flash)
{
  UINT ret = LX_SUCCESS;
 
  ULONG total_blocks = 0;
  ULONG words_per_block = 0;
 
  /* USER CODE BEGIN Init_Section_0 */
  total_blocks = _45DBXX_ACTUALBLOCKS;
  words_per_block = _45DBXX_BLOCKBYTES / sizeof(ULONG);
 
  nor_flash->lx_nor_flash_base_address = _45DBXX_STARTADD;
 
  /* USER CODE END Init_Section_0 */
 
  nor_flash->lx_nor_flash_total_blocks    = total_blocks;
  nor_flash->lx_nor_flash_words_per_block = words_per_block;
 
  /* USER CODE BEGIN Init_Section_1 */
 
  /* USER CODE END Init_Section_1 */
 
  nor_flash->lx_nor_flash_driver_read = lx_nor_driver_read;
  nor_flash->lx_nor_flash_driver_write = lx_nor_driver_write;
 
  nor_flash->lx_nor_flash_driver_block_erase = lx_nor_driver_block_erase;
  nor_flash->lx_nor_flash_driver_block_erased_verify = lx_nor_driver_block_erased_verify;
 
#ifndef LX_DIRECT_READ
    nor_flash->lx_nor_flash_sector_buffer = nor_sector_memory;
#endif
 
  /* USER CODE BEGIN Init_Section_2 */
 
  /* USER CODE END Init_Section_2 */
 
    return ret;
}
 
static UINT lx_nor_driver_write(ULONG *flash_address, ULONG *source, ULONG words)
{
    UINT ret = LX_SUCCESS;
 
    /* USER CODE BEGIN NOR_DRIVER_WRITE */
 
    uint16_t size = words * sizeof(ULONG); // TRANSFORMAMOS LAS WORDS A BYTES
    uint8_t writeBuffer[_45DBXX_BLOCKBYTES];
for (int i = 0; i < size; ++i)
{
writeBuffer[i] = ((uint8_t *)source)[i];
}
uint16_t arrayElement = 0 ;
ULONG *localFlashAddress = flash_address;
 
    while (size > 0)
    {
        uint32_t chunk_size = (size > _45DBXX_PAGEBYTES) ? _45DBXX_PAGEBYTES : size; // Determine the size of the next chunk
        AT45dbxx_WritePage2(&writeBuffer[arrayElement], (uint16_t)chunk_size, (uint32_t)localFlashAddress);
 
        // Update the buffer and address for the next chunk
        arrayElement += (chunk_size);
        localFlashAddress += chunk_size ;
        size -= chunk_size;
    }
 
    /* USER CODE END  NOR_DRIVER_WRITE */
 
    return ret;
}
 
 
static UINT lx_nor_driver_block_erase(ULONG block, ULONG erase_count)
{
 
    UINT ret = LX_SUCCESS;
 
    /* USER CODE BEGIN NOR_DRIVER_BLOCK  */
 
    uint32_t at45Block = (block * _45DBXX_BLOCKBYTES) + _45DBXX_STARTADD ;
AT45dbxx_EraseBlock(at45Block);
 
 
    /* USER CODE END  NOR_DRIVER_BLOCK  */
 
    return ret;
}
 
static UINT lx_nor_driver_block_erased_verify(ULONG block)
{
    UINT ret = LX_SUCCESS;
 
    /* USER CODE BEGIN NOR_DRIVER_VERIFY  */
 
    // Buffer to store the read data
    uint8_t readBuffer[_45DBXX_PAGEBYTES];
 
    // Calculate the starting address in bytes
    ULONG start_address = block * _45DBXX_BLOCKBYTES + _45DBXX_STARTADD;
 
    // Read and verify the block in chunks
    for (ULONG offset = 0; offset < _45DBXX_BLOCKBYTES; offset += _45DBXX_PAGEBYTES)
    {
        // Calculate the current address within the block
        ULONG current_address = start_address + offset;
 
        // Read a chunk of data
        AT45dbxx_ReadPage2(readBuffer, _45DBXX_PAGEBYTES, current_address);
 
        // Verify that all bytes in the chunk are 0xFF
        for (ULONG i = 0; i < _45DBXX_PAGEBYTES; ++i)
        {
            if (readBuffer[i] != 0xFF)
            {
                ret = LX_ERROR; // Block is not fully erased
                break;
            }
        }
 
        // Break out of the loop if an error is detected
        if (ret != LX_SUCCESS)
        {
            break;
        }
    }
 
    /* USER CODE END  NOR_DRIVER_VERIFY  */
 
    return ret;
}
 
-----------------------------------------------------------------------------------------------------
 
UCHAR             media_memory[512];
UCHAR             media_buffer[512];
ULONG             detected_errors;
UCHAR             sratch_memory[4096];
 
/* Define FileX global data structures.  */
FX_MEDIA        nor_flash_disk;
FX_FILE         fx_file;
 
ULONG fault_tolerant_memory[3072 / sizeof(ULONG)];
 
and my filex code is:
 
UINT MX_FileX_Init(VOID)
{
  UINT ret = FX_SUCCESS;
  /* USER CODE BEGIN MX_FileX_Init */
 
  /* USER CODE END MX_FileX_Init */
 
  /* Initialize FileX.  */
  fx_system_initialize();
 
  /* USER CODE BEGIN MX_FileX_Init 1*/
 
  /* USER CODE END MX_FileX_Init 1*/
 
  return ret;
}
 
void MX_FileX_Process()
{
  /* USER CODE BEGIN fx_app_thread_entry 0 */
 
   UINT status;
   ULONG available_space_pre;
   ULONG available_space_post;
   ULONG bytes_read;
   CHAR read_buffer[32];
   CHAR data[] = "This is FileX working on STM32";
 
   uint8_t err = 0 ;
 
    err = 0x80;
 
do{
err = AT45dbxxx_Dataflash_ReadStatus(&_45DBXX_SPI);
}while(err == 0x80);
 
      AT45dbxx_EraseChip();
 
status =  fx_media_format(&nor_flash_disk,
fx_stm32_levelx_nor_driver,   // Driver entry
(VOID*)CUSTOM_DRIVER_ID, // Device info pointer
(UCHAR*)media_memory,                 // Media buffer pointer
sizeof(media_memory),         // Media buffer size
"NOR_FLASH_DISK",             // Volume Name
1,                            // Number of FATs
32,                           // Directory Entries
0,                            // Hidden sectors
_45DBXX_ACTUALBLOCKS,        // Total sectors
512,           // Sector size
1,                            // Sectors per cluster
1,                            // Heads
1);                           // Sectors per track
 
status =  fx_media_open(&nor_flash_disk, "FX_LX_NOR_DISK", fx_stm32_levelx_nor_driver,(VOID*)CUSTOM_DRIVER_ID , media_buffer, sizeof(media_buffer));
 
status = fx_media_check(&nor_flash_disk, sratch_memory, 4096,
FX_FAT_CHAIN_ERROR |
FX_DIRECTORY_ERROR |
FX_LOST_CLUSTER_ERROR, &detected_errors);
 
  status = fx_fault_tolerant_enable(&nor_flash_disk, fault_tolerant_memory, sizeof(fault_tolerant_memory));
 
  if (status != FX_SUCCESS)
  {
    Error_Handler();
  }
 
  status =  fx_media_space_available(&nor_flash_disk, &available_space_pre);
 
  /* Check the get available state request status.  */
  if (status != FX_SUCCESS)
  {
    Error_Handler();
  }
 
  status =  fx_file_create(&nor_flash_disk, "STM32.TXT");
 
  /* Check the create status.  */
  if (status != FX_SUCCESS)
  {
    /* Check for an already created status. This is expected on the
    second pass of this loop!  */
    if (status != FX_ALREADY_CREATED)
    {
      /* Create error, call error handler.  */
      Error_Handler();
    }
  }
  status =  fx_file_open(&nor_flash_disk, &fx_file, "STM32.TXT", FX_OPEN_FOR_WRITE);
 
  status =  fx_file_seek(&fx_file, 0);
 
  status =  fx_file_write(&fx_file, data, sizeof(data));
 
  status =  fx_file_close(&fx_file);
 
  status = fx_media_flush(&nor_flash_disk);
 
  status =  fx_file_open(&nor_flash_disk, &fx_file, "STM32.TXT", FX_OPEN_FOR_READ);
 
  status =  fx_file_seek(&fx_file, 0);
 
  status =  fx_file_read(&fx_file, read_buffer, sizeof(data), &bytes_read);
 
  status =  fx_file_close(&fx_file);
 
  status =  fx_media_space_available(&nor_flash_disk, &available_space_post);
 
  status =  fx_media_close(&nor_flash_disk);
 
  if (status != FX_SUCCESS)
  {
    /* Error closing the media, call error handler.  */
    Error_Handler();
  }
 
  while(1)
  {
//     BSP_LED_Toggle(LED_GREEN);
//     tx_thread_sleep(40);
  }
 
 
}
 
I really dont understand what is happening, i am even doing a direct read with my memory functions and i am seeing that the text and file name is present in the memory... is this something someone can help me with?
0 REPLIES 0