This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
Tool/software:
Hi,
I would like to calculate the CRC of different sections of RAM through the MCRC module and compare it with the value calculated by the linker.
In the linker I added these parts to calculate the CRC:
[...] GROUP { .text: {} palign(8) /* This is where code resides */ .rodata: {} palign(8) /* This is where const's go */ } crc_table(application_crctab) > DDR_CORE_0_APP [...] .TI.crctab : {} > DDR_CORE_0_CRC [...] DDR_CORE_0_CRC : ORIGIN = 0x83E00000, LENGTH = 0x00200000 /* 2 MB */ [...]
Then in source code I have a task with:
#include <crc_tbl.h> #include <kernel/dpl/AddrTranslateP.h> #include <drivers/crc.h> #include "ti_drivers_open_close.h" #include "ti_board_open_close.h" #define APP_CRC_PATTERN_SIZE ((uint32_t) 8U) #define APP_CRC_SECT_CNT ((uint32_t) 1U) #define APP_CRC_WATCHDOG_PRELOAD_VAL ((uint32_t) 0U) #define APP_CRC_BLOCK_PRELOAD_VAL ((uint32_t) 0U) extern CRC_TABLE application_crctab; static void taskCrc(void *args) { uint32_t loopCnt, patternCnt, baseAddr; CRC_Channel_t chNumber; CRC_Signature signVal; CRC_SignatureRegAddr psaSignRegAddr; CRC_RECORD crc_rec = application_crctab.recs[0]; /* Configure CRC parameters */ baseAddr = (uint32_t) AddrTranslateP_getLocalAddr(CONFIG_CRC0_BASE_ADDR); DebugP_assert(crc_rec.size % APP_CRC_PATTERN_SIZE == 0); patternCnt = crc_rec.size / APP_CRC_PATTERN_SIZE; chNumber = CRC_CHANNEL_3; /* Get CRC PSA signature register address */ CRC_getPSASigRegAddr(baseAddr, chNumber, &psaSignRegAddr); /* Initialize and Configure CRC channel */ CRC_initialize(baseAddr, chNumber, APP_CRC_WATCHDOG_PRELOAD_VAL, APP_CRC_BLOCK_PRELOAD_VAL); CRC_configure(baseAddr, chNumber, patternCnt, APP_CRC_SECT_CNT, CRC_OPERATION_MODE_FULLCPU); /* Reset the CRC channel*/ CRC_channelReset(baseAddr, chNumber); uint64_t* buffer = (uint64_t*) crc_rec.addr; /* compute the CRC by writing the data buffer on which CRC computation is needed */ for (loopCnt = 0; loopCnt < patternCnt ; loopCnt++) { *(volatile uint64_t *) ((uintptr_t) psaSignRegAddr.regL) = buffer[loopCnt]; } /* Fetch CRC signature value */ CRC_getPSASig(baseAddr, chNumber, &signVal); /* Compare CRC signature value against reference CRC signature */ char CRCresult = ( ((crc_rec.crc_value & 0xFFFFFFFF) == signVal.regH) && (((crc_rec.crc_value >> 32) & 0xFFFFFFFF) == signVal.regL) ); [...] }
For now as a test I only calculate the CRC of the section .text. The result is always wrong, why?
I read here that the MCRC module calculates CRC with the TMS570_CRC64_ISO algorithm, so I make copies directly with uint64_t data on the psaSignRegAddr.regL register, is this correct?
Best regards,
Andrea
Hello Andrea Politano,
I am looking at the your queries and you may expect reply in one or two days .
Regards,
Anil.
Hello Andrea Politano,
My suggestion is that instead of calculating CRC for more data like,text size, use 10 bytes of data, calculate the CRC from the linker and calculate the CRC from the MCRC module and check both the CRC values.
This can give a clue to us.
I assume that the method is calculated by TMS570_CRC64_ISO is swapped the data bytes and preforms the CRC based on the link below.
And, we are not swapping this data and passing it to the MCRC module.
Finally, we will be checking if both are the same or not.
So, please do CRC validation for 10 bytes or less and share all the CRC values this gives clue to us.
From the next time onwards please share your project. This will be helpful to resolve the issue quicker.
I don't need your entire project and need only the CRC module Application.
Regards,
Anil.
Hi Anil,
thank you for your response.
We are still working on it, we will have answers to your suggestions next week.
Thank you.
Best regards,
Andrea
Hello Andrea,
Thanks for the update.
Once you have done the testing please share the test results.
Regards,
Anil.
Hi,
I did this test by passing only a 64-bit value to the MCRC module and checking the result, i used the same code I wrote in this post. The data I write is 0x24421A80240003C0, the result is signVal.regL = 0xB4033CED and signVal.regH = 0x0AF753AD.
I also did a test by simply not writing any data, and as expected here the result is signVal.regL = 0x0 and signVal.regH = 0x0.
For now I have temporarily solved this problem by implementing the CRC by hand following this link that shows how CRC should be calculated by the linker, but it would be very useful then to be able to take advantage of the MCRC module and calculate the CRC64 algorithm instead of CRC8-16-32 used in the link.
I tried calculating the CRC of that 64-bit value with this tool online using the CRC 64 ISO algorithm but, even trying changing the endianess of the value, I can't figure out how to get that result.
Thank you,
Best regards,
Andrea
Hello Andrea,
can you please share the crc value of the above 64bit value from the Linker ?
Regards,
Anil
Hi,
sure, the linker instead calculates the CRC as 0x0C00266D0AF75383.
Thank you,
Best regards,
Andrea
Hello Andrea,
The CRC ISO 64 bit does not match the MCRC module that is available on SOC.
With CRC ISO, initially, it will take the initial Hex data and will perform the CRC and this CRC ISO results does not matches with the MCRC module.
You can use this tool below and keep the settings as below.
https://www.lddgo.net/en/encrypt/crc
For the "0x24421A80240003C0", I am getting different CRC values from the tool.
Can you please confirm if you gave the above data is correct or not?
Based on the above data, I am getting this 0AF753830C00266D CRC result.
Regards,
Anil.
sure, the linker instead calculates the CRC as 0x0C00266D0AF75383.
Andreas,
The above linker result exactly matches with the Tool and the results in the linker is given swapped 32 bits.
Please look at the tool result and in this case the MCRC module is giving the wrong CRC calculation.
Regards,
Anil.
Hello Andreas,
The MCRC module is connected to the 32bit VBUSP, so the 64bit atomic write is not possible.
So, the MCRC module that is available on the AM64X does not support the 64bit CRC and supports only 8, 16 and 32 bit.
In the above code, you need to type cast with 32bit and perform the crc calculation for the 32 source buffer.
And, similarly, you need to calculate the CRC from the linker also with the 32-bit.
Then only both SOC CRC and Linker CRC should be matched.
uint32_t* buffer = (uint32_t*) crc_rec.addr; /* compute the CRC by writing the data buffer on which CRC computation is needed */ for (loopCnt = 0; loopCnt < patternCnt ; loopCnt++) { *(volatile uint32_t *) ((uintptr_t) psaSignRegAddr.regL) = buffer[loopCnt]; }
Regards,
Anil.
Hi Anil,
thank you for your response.
We will test your suggestions next week.
Thank you.
Best regards,
Andrea