Hi,
I'm currently looking into single enhanced and double enhanced images on an LPC54608.
I've found the location in the vector table for addressing the boot block structure located on line 14 in the code below.
__attribute__ ((used, section(".isr_vector")))
void (* const g_pfnVectors[])(void) = {
// Core Level - CM4
&_vStackTop, // The initial stack pointer
ResetISR, // The reset handler
NMI_Handler, // The NMI handler
HardFault_Handler, // The hard fault handler
MemManage_Handler, // The MPU fault handler
BusFault_Handler, // The bus fault handler
UsageFault_Handler, // The usage fault handler
__valid_user_code_checksum, // LPC MCU checksum
0, // ECRP
0, // Reserved - Image Type (0x24)
0, // Reserved - Boot block pointer (0x28)
My question is, how is the CRC for the boot block structure calculated? If the boot block structure is defined within the application code (in non-volatile memory), how do you actually add the image length and then calculate the CRC? The image would first need to be compiled, and then the address of boot block structure->image length be updated within the compiled image. After this, the CRC would need to be calculated (excluding the address of the CRC in the image) and inserted into the address of boot block structure->CRC. Is there any example code for doing this or does anyone know how this can be accomplished as an automated process?
Cheers,
Ben
This is really not my job, but since NXP is dragging their feet on this one, I'll do their job for them and show you how to calculate the CRC for the enhanced image.
First, add the enhanced image marker in the vector table, along with the enhanced image header in the startup file:
__Vectors:
.long __StackTop /* Top of Stack */
.long Reset_Handler /* Reset Handler */
.long NMI_Handler /* NMI Handler */
.long HardFault_Handler /* Hard Fault Handler */
.long MemManage_Handler /* MPU Fault Handler */
.long BusFault_Handler /* Bus Fault Handler */
.long UsageFault_Handler /* Usage Fault Handler */
.long 0 /* Reserved */
.long 0xFFFFFFFF /* ECRP */
.long 0x0FFEB6B6 /* Enhanced image marker */
.long EnhancedImage_Header /* Enhanced image header */
[...]
EnhancedImage_Header:
.long 0xfeeda5a5
.long 1
.long 0
.long 0
.long 0
.long 0
The enhanced image header is at this point just a placeholder, because at this point we don't know the CRC or the image size. After compiling the .bin-file, I have a custom Python script that populates the enhanced image header with image size and CRC.
To get a valid CRC, you first have to add the simple checksum for the first 7 vectors. This is calculated like this
(0 - sum(v for v in vector_table[:7])) & 0xffffffff
This value is written to vector table entry 8.
Then, add the size of the image in the enhanced image header.
Finally, calculate the CRC over the whole image, except for the CRC field in the enhanced image header. Here is a python version of the CRC32 used in the chip:
crc32_table = [
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
0x2d02ef8d
]
def uint32_t(n):
return n & 0xffffffff
def crc32(data):
s = uint32_t(~0)
for c in data:
s = crc32_table[(s ^ c) & 0xff] ^ uint32_t(s >> 8)
return s ^ uint32_t(~0)
I hope this is still useful, even though it's been over two years since you asked your question.
Checkout python script and startup file:
Give this person @bergem a medal.
Hi Thomas Johansen,
Thank you for your interest in NXP Semiconductor products and for the opportunity to serve you.
1) How is the CRC for the boot block structure calculated?
-- You can the Checksum feature in the IDE to do that, for instance, IAR. I'd like to you can introduce what the exact goal you want to achieve, then I can focus on to implementing it.
Fig 1
IAR IELFTOOL Checksum - The basic actions
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Jeremy,
Thanks for the reply. I'm using the MCUXpresso IDE. Are the same options available in it?
What I'm trying to achieve is to automatically compile and create a "Single Enhanced Image" as per the datasheet. I'm referring to UM10912 (rev 2.1) and looking at the boot block structure on page 30, Section 3.3.2.7, Table 8. As discussed in the OP, I can see where in the vector table I need to point to this structure, but if this structure is defined within the image itself (to be loaded into flash), how can we automatically modify the image at the position of the boot block structure to define the CRC and length of the image. i.e. I won't know the crc and length of the image until its compiled in the first place, then after compilation will need insert length, calculate and insert crc at the position of the boot block structure. Is this how it would work or am I missing something here? I want the single enhanced image to point to a boot block structure that verifies the image itself in flash.
Hopefully this explains what I'm trying to achieve a little more but please let me know if you need me to expand on anything.
Cheers,
Ben
Hi Ben,
Thanks for your reply.
I don't find this feature in the MCUXpresso IDE.
1) how can we automatically modify the image at the position of the boot block structure to define the CRC and length of the image?
-- I'd highly recommend you to place the stucture at a specific address and the target image field to be calculated should exclude this structure.
2) Is this how it would work or am I missing something here?
-- I think the process is as same as you said.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi Jeremy,
So there is no way to automatically create a single enhanced or double enhanced image?
Cheers,
Ben
Hi Ben Evans,
I've already contacted AE to request some application notes which describe how to apply the Single Enhanced and Dual Enhanced images, and I'm waiting for their response, I'll inform you if I get the reply.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hi jeremyzhou, It's now been over a year, can you please update us with any information or at least inform us that you don't have any information and aren't aware on how to implement enhanced images.
Hi Ben Evans,
Sorry for reply late.
After confirming with the AE team, there's an application elaborates on the boot procedures in LPC5460x, it also guides the developer on how to make it. However, it needs to sign the NDA for requesting it, so please contact the DFAE or local NXP FAE for requesting it, as we don't have the authority to share it.
Have a great day,
TIC
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
It has almost been a year now.
Has the AE replied to you yet?
What is the algorithm for calculating the CRC value in the boot block structure? Example code would be helpful.
Hi Alex,
No, they have not. I agree that an example and some documentation would be nice as I'm still interested in finding out how this process can be accomplished.
Cheers,
Ben