Problem Code:
/* main.c */ uint8_t testBuf[] = {1, 2, 3, 4, 5}, FILE * fwr = fopen("tst1.txt", "w"); fwrite(testBuf, sizeof(uint8_t), sizeof(testBuf), fwr); fflush(fwr); fclose(fwr); /* flash_cmsis_driver.c */ int32_t ARM_Flash_ProgramData(uint32_t addr, const void *data, uint32_t cnt) { /* Problem: cnt is 8 while it should be 5 */ /* cnt is next nearest multiple of 4 */ }
/* Driver Capabilities */ static const ARM_FLASH_CAPABILITIES DriverCapabilities = { 1, /* Supports event ready status */ 0, /* data_width = 0:8-bit, 1:16-bit, 2:32-bit */ 0, /* Don't support chip erase */ 0U /* Reserved */ }; /* Flash Information */ static ARM_FLASH_INFO FlashInfo = { FLASH_SECTOR_INFO, FLASH_SECTOR_COUNT, FLASH_SECTOR_SIZE, 8, /* FLASH_PAGE_SIZE */ 1, /*FLASH_PROGRAM_UNIT */ 0xFF, /* FLASH_ERASED_VALUE */ { 0U, 0U, 0U } /* Reserved */ };
Hi,
in EFS everything is aligned to 4-bytes so what you observe is the normal operation. This is the consequence of its design, since old (and internal) NOR flashes required 4-byte alignment for program operation. It is therefore also not recommended to write small chunks of data, since the overhead (alignment together with block signatures) is to big in such cases.
Which flash device was used for your tests?Vladimir
It makes sense what you are saying. Could you also point out to a resource, if possible that mentions EFS program is 4-byte aligned?It is integrated Flash on ADSP-CM419F (if that's what you are asking)"The memory cell size depends on the device architecture and is 8- (byte), 16- (half word) or 32-bit wide (word). The memory cell architecture also defines smallest programmable unit, which must be maximum 32-bit for use with the Embedded File System." Referred from: Line 7, Link: https://www.keil.com/pack/doc/mw/FileSystem/html/emb_fs.htmlI assumed looking at this, that it might be possible. Hence, I tried to change the configuration so that the EFS's smallest program unit is 8-bit wide (or 1-byte).
Yes, I was interested in the type of device used, just to check the properties of flash array.
During mount operation EFS only checks if smallest programmable unit is 4-byte or less and is happy if this is true. There is no actual handling of this setting (except extending data to 4-bytes as you noticed).
Just keep in mind that every open/write/close sequence also appends "allocation information" which is 8-bytes. Writing only one byte actually requires 12 bytes of memory. It is obvious then why it is recommended that data is written in large chunks. But sure, there are many situations where writing one or few bytes is how we want to get things done.
Thanks for the answers Vladimir, I will accept your answer after reply to the following.As you said, I do acknowledge that it is preferable to write in large chunks considering the overhead of 8-bytes/allocation record.To summarise and confirm the answer:
Is that right?
Yes, this is correct for EFS.And just to clarify to avoid potential confusion for future readers: "Smallest programmable unit" configuration is part of CMSIS-Driver Flash (see ARM_FLASH_INFO) and should therefore be correctly handled in the Flash driver.