Help/tips to create bootloader from scratch without Bootloadable / Bootloader components

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

Hi all,

   

I want to port my external Adesto DataFlash bootloader from Atmel SAMD21 to a PRoC BLE (CYBLE-022001) and I had a really hard time trying to understand and use the Bootloadable and Bootloader ("Lego") building blocks. I ported the BLE_OTA_External_Memory_Bootloader to use DataFlash, got it working and finally understand how it works, but it's not what I want (for various reasons).

   

Gripes aside, any advice to do the following would be much appreciated:

   

1. For the app, can I remove the Bootloadable building block, but still be able to move the app to the start of a fixed address, e.g. 0x2000 to make space for the bootloader, but only for the RELEASE build? I am guessing that a GCC linker directive of "-Wl,-section-start=.text=0x2000" may work, but is there anything else that I need to do so that the app will successfully execute after the bootloader jumps to it?

   

2. For the bootloader, can I remove the Bootloader building block, but still have an easy way of jumping to the App (at a fixed address, say 0x2000)? Inspecting the bootloader example, it looks like I need to modify CM0Start.c : Reset() to inspect the value of a 32-bit variable cyBtldrRunType stored in the .bootloaderruntype section, etc. Is there an easy way to do just this without extensive hacking? How do I override code in the Generated_Source directory?

   

3. When jumping to the reset vector address of the App (stored at say 0x2004), when / how is the CPU told to use a vector table at this address?

   

4. Is there a recommended API to reprogram the internal flash rows?

   

5. Any tips / hints?

   

Thanks in advance,

   

Pieter

0 Likes
1 Solution
Anonymous
Not applicable

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 🙂

   

Best regards,

   

Pieter

View solution in original post

0 Likes
4 Replies
Anonymous
Not applicable

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

0 Likes
Anonymous
Not applicable

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 🙂

   

Best regards,

   

Pieter

0 Likes
Anonymous
Not applicable

Hi Pieter,

   

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.

0 Likes

Hi pieter_2521576,

Can you share a demo project for the same. It will be helpful.

Thanks

0 Likes