-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
The current hardware_flash/flash.c implementation validates parameters to flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) ensuring that 'flash_offs' is on a page boundary (% 256 == 0) as well as byte countis a multiple of a full page (256), which is also documented in the API documentation:
// pico-sdk/src/rp2_common/hardware_flash/include/hardware/flash.h
/*! \brief Program flash
* \ingroup hardware_flash
*
* \param flash_offs Flash address of the first byte to be programmed. Must be aligned to a 256-byte flash page.
* \param data Pointer to the data to program into flash
* \param count Number of bytes to program. Must be a multiple of 256 bytes (one page).
*/
void flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count);Implementation: /src/rp2_common/hardware_flash/flash.c:
// pico-sdk/src/rp2_common/hardware_flash/flash.c
void __no_inline_not_in_flash_func(flash_range_program)(uint32_t flash_offs, const uint8_t *data, size_t count) {
...
invalid_params_if(FLASH, flash_offs & (FLASH_PAGE_SIZE - 1));
invalid_params_if(FLASH, count & (FLASH_PAGE_SIZE - 1));
...When implementing EEPROM emulation or a File System backed by the QSPI (NOR) Flash (above the XIP address range), it severely restricts the potential speed and increases SRAM requirements, as every writes to Flash will require a read-modify-write cycle:
- Full page (256 bytes) read
- Modify page
- Full page (256 bytes) program using
flash_range_program()
The SPI connected Serial Flash IC used with the RP2040, does not have ANY restrictions regarding starting address or number of bytes written, when using the Page Program (02h) instruction (see Winbond W25Q16JV datasheet, section 9.2.13 for details):
The Page Program instruction allows from one byte to 256 bytes (a page) of data to be programmed at
previously erased (FFh) memory locations
Would it be possible to add a facility (library function) allowing partial page programming at arbitrary addresses, using an API similar to the flash_range_program(uint32_t flash_offs, const uint8_t *data, size_t count) function?
This function may likely restrict all data to be written to be located in ONE 256 byte page, and not allow wrapping (to the beginning of the page, which is the standard behavior of the underlying Serial Flash.