Hi everyone,
I'd like to ask for a help with MFS related problem. I'm working with MQX 4.1.0 on Kinetis K53 (MK53DN512ZCLQ10, mask 4N30D). My board is equipped with a SD card connected to eSDHC controller. I'm using BSP for TWR-K53 (incl. eSDHC driver) customized for my board. File operations work well as long as the size of accessed file is not multiple of 32768 (that is, 32 kB). Please see code below. MFS is initialized by function task_card_proc_cmd_en(). Given file is written by subsequent calls of task_card_proc_cmd_wr_bulk(), every call opens file, performs fwrite() and closes file (I know that this approach is ineffective but consider this to be just a demo code). My application use task_card_proc_cmd_wr_bulk() to append just one byte to identical file by every call. When the file grows to 32 kB, any subsequent fopen() fails and _task_get_error() returns FS_EOF (0x3067). MFS starts to work again when one byte is appended to the file outside of MQX but everything fails again at 64 kB.
Please, does anyone have a clue how to fix this? Thank you.
Best regards,
Martin
static ESDHC_INIT_STRUCT task_card_esdhc0_init;
static SDCARD_INIT_STRUCT task_card_sdcard0_init;
static MQX_FILE_PTR task_card_iface_handle;
static MQX_FILE_PTR task_card_sd_handle;
static MQX_FILE_PTR task_card_part_handle;
static MQX_FILE_PTR task_card_fs_handle;
static uint8_t task_card_part_flag;
static uint8_t task_card_proc_cmd_wr_bulk(TASK_CARD_CMD_DATA *cmd)
{
MQX_FILE_PTR file;
_mqx_int ret;
#if APP_DEBUG
printf("\nCARD -> task_card_proc_cmd_wr_bulk()\n");
printf("\nCARD -> filename: %s\n", (char *) cmd->fs_fname);
#endif
file = fopen((char *) cmd->fs_fname, "a");
if (file == NULL) {
#if APP_DEBUG
printf("\nCARD -> fopen() error %d\n", _task_get_error());
#endif
*cmd->data_len = 0;
return 1;
}
ret = fwrite((void *) cmd->data, 1, *cmd->data_len, file);
if (ret == IO_ERROR) {
#if APP_DEBUG
printf("\nCARD -> fwrite() error\n");
#endif
fclose(file);
*cmd->data_len = 0;
return 1;
}
fclose(file);
*cmd->data_len = ret;
return 0;
}
static uint8_t task_card_proc_cmd_en(void)
{
task_card_esdhc0_init.CHANNEL = 0;
//#define TASK_CARD_SHDC_FCLK_MAX 4000000ul
task_card_esdhc0_init.MAX_BAUD_RATE = TASK_CARD_SHDC_FCLK_MAX;
task_card_esdhc0_init.CLOCK_SPEED = BSP_SYSTEM_CLOCK;
task_card_sdcard0_init.INIT_FUNC = _io_sdcard_esdhc_init;
task_card_sdcard0_init.READ_FUNC = _io_sdcard_esdhc_read_block;
task_card_sdcard0_init.WRITE_FUNC = _io_sdcard_esdhc_write_block;
task_card_sdcard0_init.SIGNALS = ESDHC_BUS_WIDTH_4BIT;
if (_esdhc_install("esdhc0:", &task_card_esdhc0_init) != MQX_OK) {
return 1;
}
task_card_iface_handle = fopen("esdhc0:", NULL);
if (task_card_iface_handle == NULL) {
_io_dev_uninstall("esdhc0:");
return 1;
}
if (_io_sdcard_install("sdcard0:", &task_card_sdcard0_init, task_card_iface_handle) != MQX_OK) {
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
task_card_sd_handle = fopen("sdcard0:", NULL);
if (task_card_sd_handle == NULL) {
_io_dev_uninstall("sdcard0:");
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
if (_io_part_mgr_install(task_card_sd_handle, "pm:", 0) != MFS_NO_ERROR) {
fclose(task_card_sd_handle);
_io_dev_uninstall("sdcard0:");
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
task_card_part_handle = fopen("pm:1", NULL);
if (task_card_part_handle == NULL) {
_io_dev_uninstall("pm:");
task_card_part_flag = 0;
if (_io_mfs_install(task_card_sd_handle, "fs:", 0) != MFS_NO_ERROR) {
fclose(task_card_sd_handle);
_io_dev_uninstall("sdcard0:");
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
} else {
task_card_part_flag = 1;
if (ioctl(task_card_part_handle, IO_IOCTL_VAL_PART, NULL) != MQX_OK) {
fclose(task_card_part_handle);
_io_dev_uninstall("pm:");
fclose(task_card_sd_handle);
_io_dev_uninstall("sdcard0:");
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
if (_io_mfs_install(task_card_part_handle, "fs:", 0) != MFS_NO_ERROR) {
fclose(task_card_part_handle);
_io_dev_uninstall("pm:");
fclose(task_card_sd_handle);
_io_dev_uninstall("sdcard0:");
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
}
task_card_fs_handle = fopen("fs:", NULL);
if (task_card_fs_handle == NULL) {
_io_dev_uninstall("fs:");
if (task_card_part_flag) {
fclose(task_card_part_handle);
_io_dev_uninstall("pm:");
}
fclose(task_card_sd_handle);
_io_dev_uninstall("sdcard0:");
fclose(task_card_iface_handle);
_io_dev_uninstall("esdhc0:");
return 1;
}
return 0;
}
Solved! Go to Solution.
Hi Martin,
Yes, you are right. It is known issue. Unfortunately, append mode is implemented wrongly in MQX 4.1.1 and older versions.
As workaround, please use r+/w/w+ modes instead of append mode and seeks manually to end of file or according your needs.
MQX 4.2 release contains complete redesigned MFS subsystem which solves this issue.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
I had the same problem, instead 0x3067 FS_EOF, I received 0x3014 FS_BAD_DISK_UNIT error. And my problem was when the file reached 544 bytes, strange? Now changing from "a" append mode to "r+" r/w with fseek it's working.
Hi Martin,
Yes, you are right. It is known issue. Unfortunately, append mode is implemented wrongly in MQX 4.1.1 and older versions.
As workaround, please use r+/w/w+ modes instead of append mode and seeks manually to end of file or according your needs.
MQX 4.2 release contains complete redesigned MFS subsystem which solves this issue.
I hope it helps you.
Have a great day,
RadekS
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Radek,
thank you for help, your solution works. I'd like to add that 32kB boundary is cluster size of the SD card. If the card is formatted with 8kB clusters, then MFS fails on 8kB boundary. Function fseek(file, 0, SEEK_END) appears to fail on cluster boundary (does not return MQX_OK) but in fact the seek operation is performed (checked with ftell).
Best regards,
Martin
Hi Martin,
I am glad that it works now.
I would like just note, that MFS was already reworked and version in MQX 4.2 do not suffer by this issue.
I hope it helps you.
Have a great day,
RadekS