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.

CCS/MSP430FR6043: Get firmware address start/end, excluding persistent variables?

Part Number: MSP430FR6043

Tool/software: Code Composer Studio

Hi

I need to calculate a CRC checksum on the firmware version on a MSP430 which should stay constant until a firmware update(for security means). I know the FRAM start and end addresses, but the problem is that I have persistent variables in FRAM that is changing during runtime, which would affect the CRC result. 

Is there a way to find the start/end addresses of the firmware and excluding the persistent variables? (without manually checking memory as it would change when the code changes).

Thanks in advance 

  • The linker will (if asked) generate CRC tables for the text. This is done on a per-section basis (so it's a bit clumsy for the interrupt vectors). I'm pretty sure Persistent variables are put in sections separate from the code.

    The procedure is described in the CCS Assembler [sic] User Guide (SLAU131R) Section 8.9. You need to supply the actual CRC-checking code.

  • Bruce McKenney47378 said:

    The linker will (if asked) generate CRC tables for the text. This is done on a per-section basis (so it's a bit clumsy for the interrupt vectors). I'm pretty sure Persistent variables are put in sections separate from the code.

    The procedure is described in the CCS Assembler [sic] User Guide (SLAU131R) Section 8.9. You need to supply the actual CRC-checking code.

    Okey so should the linker only check ".text", not ".data"? From the example it seems like you have to check each .obj file individually, can it be done for the all of them in a simpler way?

    Thanks again

  • You can e.g. do all of .text with something like:

     >   .text             : {} crc_table(_text_crc) >> FRAM2 | FRAM

    and (somewhere) add:

    >     .TI.crctab        : {}  > FRAM

    (Leaving out the second gets a warning which may or may not be harmless.)

    Since each of the interrupt vectors is its own section, doing them is a bit more cumbersome.

    Also, looking through one of my .cmd files there seem to be more "oddball" sections than I remember. I suspect e.g. you would also want to do .cinit (.data initializers) and .text:_isr (low-memory ISR fragments).

    If you use the same name in all the crc_table()-s the table entries are constructed as an array, so the checking code can be somewhat blind.

  • Bruce McKenney47378 said:

    You can e.g. do all of .text with something like:

     >   .text             : {} crc_table(_text_crc) >> FRAM2 | FRAM

    and (somewhere) add:

    >     .TI.crctab        : {}  > FRAM

    (Leaving out the second gets a warning which may or may not be harmless.)

    Since each of the interrupt vectors is its own section, doing them is a bit more cumbersome.

    Also, looking through one of my .cmd files there seem to be more "oddball" sections than I remember. I suspect e.g. you would also want to do .cinit (.data initializers) and .text:_isr (low-memory ISR fragments).

    If you use the same name in all the crc_table()-s the table entries are constructed as an array, so the checking code can be somewhat blind.

    Thank you for your example! Have one problem:

    The first line gets me this warning that doesn't let me run the code: "CRC table operator (_text_crc) ignored for ".text":  CRC table operator cannot be associated with empty output section"

     

  • The first line was a modification to a line which was already there. The second was added.

    Your description got my head itching, so I tried it. I suspect the warning is saying "I consumed all of .text in the previous statement, so there's nothing left to do this statement."

  • I got this working, but not sure if it is the correct way.

    .testInput1:   {*obj(.text)} > FRAM2 | FRAM, crc_table(linkerCrcTable, algorithm=CRC32_PRIME)

    .TI.crctab :{} > FRAM

    Annoyingly the size of my code increases by more than 10K bytes when I do this, why would it do so?

    Thanks in advance 

  • I don't see that behavior when I do what I described. (Disclaimer: I don't have my relevant materials here, so I was hacking up a relatively simple project.)

    What is the purpose of the .testInput1 section? Is that intended to be separate from .text?

  • (testInput1 was just from an example, so no use of it.)

    When I moved your example to the top of the .cmd file in the SECTION directive it did not give any warnings/errors. 

    But still, it adds over 10KB as soon as I use the _text_crc struct in the program code. Did you try to use the variable so that the optimiser doesn't remove it? 

    Thanks again!

  • Oh my bad, I used printf() to debug it which takes 10KB... 

    So then it seems to work!

    I will just need to add .cinit, .const and ._isr

    Thanks

  • Last time I did this (some months back) it was on a G2553, so I know it didn't add 10K to the load image, since it wouldn't have fit. Where is the growth occurring?

    I'm not sure I understand what you moved where. I altered the ".text" line in the .cmd file (equivalent of line 186 in my copy of lnk_msp430fr6043.cmd) to insert  "crc_table(_text_crc)". I added the .TI.crctab line right after it. I didn't move anything anywhere.

    I pasted the example CRC check function [SLAU131R Example 8-29] and added a call to it in main(). (I had to fix a typo, and added a trivial check to stand in for the CRC computation.) It added maybe 100 bytes total to the program. 

    I'm not sure what you and I are doing differently. I don't have an FR6043 to work with.

    [Edit: Ah, I see you answered in the meantime. I'll suppose you're all set.]

  • As I wrote it was printf().

    First it was in the bottom of SECTION{} after the rest of default instructions, but that didn't work. Instead I moved it to the top in the SECTION{} before the rest, which removed the error. 

**Attention** This is a public forum