Angelo Quattrociocchi

AN4368 USB Host Bootloader bugs when using gcc tools

Discussion created by Angelo Quattrociocchi on Sep 6, 2014

I have been using the code based on the AN4368 bootloader project for some Coldfire devices, and it loaded S19 files produced by Codewarrior fine.  I recently started working with Kinetis and ported the application projects to the gcc compiler under Codewarrior.  After figuring out how to configure the project to generate an S-record file, (from this page S-Record Generation with gcc for ARM/Kinetis | MCU on Eclipse) I found that the bootloader wouldn't load them.


The first issue was that the first line produced in the S19 file did not start with "S003" as the bootloader expects (see S19_RECORD_HEADER in Bootloader.h), and as the original Codewarrior linker created.  Depending on which method I use from the page listed above, my S-record files started with either "S00A" or "S010".  I changed the S19_RECORD_HEADER define to 0x53300000, and changed this line in the FlashApplication function from Loader.c:


     else if(header ==(uint_32)(S19_RECORD_HEADER))

to this:

     else if((header & 0XFFFF0000) == (uint_32)(S19_RECORD_HEADER))


This allowed it to recognize the different S19 headers, but it still failed to flash.  By stepping through the code I realized the checksum comparison was failing and I found the problem in the FlashLineS19 function.  There are two lines like this:


     for (i = offset; i < (length - 5); i++)


The length calculation wasn't properly accounting for 16 and 24-bit formats (S1 and S2 records).  I changed those two lines to this:


     for (i = offset; i < (length - 2 - type); i++)


The gcc linker produced 24-bit (S2 record) formatted lines, but the position of the checksum and data length calculations weren't accounting for those.  It works now for S2 records, although I haven't confirmed again with S3 or for that matter S1 records.  The math is simple enough however, that I think it will work fine.


There might be a way to specify to the linker to create 32-bit records instead, but I still think the bootloader should handle S1 and S2 records, since it seems to have been intended to do so.


Please let me know if you see any problems with my changes.



[Edit] I found another issue with the bootloader, although not specifically related to gcc.  The previous Coldfire devices I was using had Flash sizes of 512KiB, while the new Kinetis device has 1MiB.  After changing the MAX_FLASH1_ADDRESS value in Bootloader.h from 0x7FFFF to 0xFFFFF, the bootloader would erase forever.  I found that the erase_flash function in main.c of the bootloader used an 8-bit index ("i") to iterate through the Flash space and the calculated limit exceeded 255 with the higher Flash size.  I changed this to a 32-bit uint and it erased twice as much as before.  I haven't verified it properly erased that top area but I assume it did since it's a fairly straightforward function.  I also haven't tried flashing an image that uses more that the lower 512KiB (- 48KiB) of Flash, so I'm not certain there aren't other similar issues on the programming end.