good question. In general we encourage users to use the flash memory for Read-only lookup tables, as this puts a lighter load on RAM. A progmem directive is coming in the next release the software tools, but you can hack it like this:
__attribute__((.section("USER_FLASH"))) char myBuf[50] = {......};
obviously you can make progmem via
#define PROGMEM __attribute__((.section("USER_FLASH"))) char myBuf[50]
The reason why we dont encourage users to write to flash in their code, is because - like all flash memories - there is a limited number of write cycles for each flash page. The official docs put this in the tens of thousands, but usually it takes 100s of thousands of writes to break it.
You wont ever break it by uploading code unless youve uploaded 100,000 sketches or something (the same way your flash memory in your camera has a pretty long life). However if you were to write the following loop:
while(True) {
clearFlashPage();
writeFlashPage();
}
you could probably brick your board in a reasonable amount of time (20 minutes? an hour?)
That said, you can read and write to flash via:
1) unlock the flash by writing the unlock code to the KEY register
2) clear the flash page by writing the address you want to clear to the CLEAR register
3) engage the erase operation by setting a bit in the flash CTRL register
4) wait until the clear operation is finished
5) write to that page as if it were normal memory (like so: *((u32*)(0xDEADBEEF)) = something; (where deadbeef is some flash address)
You can only clear a page at a time, on Maple this is 1k, on other variants of the stm32 this is 2k. Flash starts at 0x08000000, and goes to 0x08000000 + 120K. So page 1 is 0x08000000 - 0x080003FF, and page 2 is 0x08000400 - 0x080007FF ... etc.
When you write an address to the flash clear register, it will clear the entire flash page in which that address lives. So dont do:
flashWrite(0x08000000,val)
flashClear(0x08000300)
because those two addresses are on the same page, and you will clear what you just wrote.
Because we dont want users to accidentally brick their flashes, adding this support to libmaple/wirish has been very low on the priority queue. However, you can find code examples of how this done in:
github.com/leaflabs: maple-bootloader/hardware.c
maple-bootloader/dfu.c (look for copyBufferToExec())
use at your own risk! good luck!