Skip to content

FX_IO_ERROR #1

Open
Open
@erFalcon

Description

@erFalcon

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?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions