I have not messed with the bootload(able|er)s due to the frustrations you mentioned :)
But I can give you the Flash API that is recommended; Will post the API tomorrow once I have some time
Hi e.pratt (and others also searching for a solution),
In the end I made a compromise and still use the Bootloadable and Bootloader blocks, but only for a few select features. The Bootloadable block is only used to locate the Application at the desired start address and generate a *.cyacd file with the 128-byte metadata row at the end to keep the Bootloader block happy.
I created a command-line parser tool that reads the *.cyacd file and generates a custom *.bin file suitable for storage in external DataFlash. See PSoC Creator\cybootloaderutils\cybtldr_parse.h & cybtldr_parse.c and read AN60317 "PSoC 3 and PSoC 5LP I2C Bootloader"
My custom bootloader reads the *.bin file from external DataFlash and writes the new application to internal flash as well as the metadata row at the end using CySysFlashWriteRow (uint32 rowNum, const uint8 rowData). It then jumps to the new application using Bootloader_SET_RUN_TYPE(Bootloader_SCHEDULE_BTLDB); CySoftwareReset();
Now my custom bootloader is less than 4k :)
Based on your post I would assume you have things working how you want now :)
My code is actually using the CYREG_CPUSS_SYS registers to write to the SFLASH if that is of interest, otherwise:
The CySysFlashWriteRow() and the CyBle_StoreAppData() APIs should work for writing data to flash.