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.

TMS320F28377D: Is there a possibility to perform flash integrity check in microcontroller

Part Number: TMS320F28377D
Other Parts Discussed in Thread: C2000WARE

hi, 

To perform flash integrity check in microcontroller is a requirement in the Aerospace project. so please share the example link and resources 

thanks 

Muni Niteesh

  • Muni,

    The flash on this device has error correction (ECC) embedded into the memory itself.    Page 140 of the TRM https://www.ti.com/lit/pdf/spruhm8 will give more details on the implementation.

    The logic can correct 1 bit error or detect a 2 bit error for every 128 bits of flash data.  A read of the flash contents will force a compare of the ECC syndrome that is stored vs one calculated on the fly.  You can set the error threshold to fail even on a 1 bit error if needed; this will trigger an NMI on a mismatch and the system can determine what to do from there.

    Best,

    Matthew

  • (1) We also want to perform  firmware integrity check before booting to ensure our firmware is not corrupted by any external effect ( i.e. radiations or environment at high flight altitude)

    (2) We are using internal flash memory area for storing our firmare also, please find logs captured during loading binary .out file in microcontroller:
    -------------------------------------------------------------------------------------------------------------------------
    C28xx_CPU1: GEL Output: 
    Memory Map Initialization Complete
    C28xx_CPU1: If erase/program (E/P) operation is being done on one core, the other core should not execute from shared-RAM (SR) as they are used for the E/P code. Also, CPU1 will be halted to determine SR ownership for the CPU which will run the Flash Plugin code, after which CPU1 will be set to run its application. User code execution from SR could commence after both flash banks are programmed.
    C28xx_CPU1: Writing Flash @ Address 0x00080000 of Length 0x00000002 (page 0)
    C28xx_CPU1: PLL configuration status = 1. PLL configured successfully.
    C28xx_CPU1: Erasing Flash Bank 0, Sector A
    C28xx_CPU1: Erasing Flash Bank 0, Sector B
    C28xx_CPU1: Erasing Flash Bank 0, Sector C
    C28xx_CPU1: Erasing Flash Bank 0, Sector D
    C28xx_CPU1: Erasing Flash Bank 0, Sector E
    C28xx_CPU1: Erasing Flash Bank 0, Sector F
    C28xx_CPU1: Erasing Flash Bank 0, Sector G
    C28xx_CPU1: Erasing Flash Bank 0, Sector H
    C28xx_CPU1: Erasing Flash Bank 0, Sector I
    C28xx_CPU1: Erasing Flash Bank 0, Sector K
    C28xx_CPU1: Erasing Flash Bank 0, Sector L
    C28xx_CPU1: Erasing Flash Bank 0, Sector M
    C28xx_CPU1: Erasing Flash Bank 0, Sector N
    C28xx_CPU1: Data has been buffered at the end of the current data block for 64-bit aligned writes.
    C28xx_CPU1: Writing Flash @ Address 0x00082000 of Length 0x00002a01 (page 0)
    C28xx_CPU1: Data has been buffered at the end of the current data block for 64-bit aligned writes.
    C28xx_CPU1: Verifying Flash @ Address 0x00082000 of Length 0x00004000
    C28xx_CPU1: Verifying Flash @ Address 0x00084000 of Length 0x00001400
    C28xx_CPU1: Writing Flash @ Address 0x00086000 of Length 0x000001f3 (page 0)
    C28xx_CPU1: Data has been buffered at the end of the current data block for 64-bit aligned writes.
    C28xx_CPU1: Verifying Flash @ Address 0x00086000 of Length 0x000003E0
    C28xx_CPU1: Writing Flash @ Address 0x00088000 of Length 0x0000005c (page 0)
    C28xx_CPU1: Verifying Flash @ Address 0x00088000 of Length 0x000000B8
    C28xx_CPU1: Writing Flash @ Address 0x00090000 of Length 0x00000d47 (page 0)
    C28xx_CPU1: Data has been buffered at the end of the current data block for 64-bit aligned writes.
    C28xx_CPU1: Verifying Flash @ Address 0x00090000 of Length 0x00001A88
    C28xx_CPU1: Writing buffered data @ Address 0x00080000 of Length 0x00000004
    C28xx_CPU1: Verifying Flash @ Address 0x00080000 of Length 0x00000008
    C28xx_CPU1: Writing buffered data @ Address 0x00084A00 of Length 0x00000004
    C28xx_CPU1: Verifying Flash @ Address 0x00084A00 of Length 0x00000008
    C28xx_CPU1: Writing buffered data @ Address 0x000861F0 of Length 0x00000004
    C28xx_CPU1: Verifying Flash @ Address 0x000861F0 of Length 0x00000008
    C28xx_CPU1: Writing buffered data @ Address 0x00090D44 of Length 0x00000004
    C28xx_CPU1: Verifying Flash @ Address 0x00090D44 of Length 0x00000008
    ---------------------------------------------------------------------------------------------------------------------------------------------

     

    (3) Is there any reference application available for this microcontroller  to do firmware integrity check before boot ?
    At present we are not clear on how to meet this requirement . We are expecting some suggestions from TI on this regard

    Thanks 

    muni Niteesh

  • //###########################################################################
    //
    // FILE:    checksum.c
    //
    // TITLE:   boot ROM checksum generator
    //
    // Functions:
    //
    //
    // Notes:
    //
    //###########################################################################
    //
    //  Ver | dd mmm yyyy |     Who      | Description of changes
    // =====|=============|==============|=======================================
    //  0.1 |             | LH           | Original Release.
    //      |             |              |
    //###########################################################################
    typedef struct {
           unsigned long firstAddr;
           unsigned long lastAddr;
           unsigned short mem_attribute;	//initialized to 0 for reserved locations and 1 for valid data locations
    } memblock;
    
    
    // Use 4 32-bit values to represent the 64-bit checksum.
    // This is done such that overflow can be monitored at
    // each step in the summation.   If overflow from the lower
    // 16-bits occurs, then the overflow is added to the next
    // significant word.
    
    typedef struct {
           unsigned long highHalfMSW;
           unsigned long highHalfLSW;
           unsigned long lowHalfMSW;
           unsigned long lowHalfLSW;
    } ui64;
    
    typedef struct checksum_data
    {
    	unsigned long total_ones;
    	unsigned long bit_column_cksum[8][3];
    	ui64 row_weight_sum;
    	ui64 fact_weight_sum;
    }composite_checksum_t;
    
    #pragma DATA_SECTION(csum_rom, ".CKSUMLOC");
    const composite_checksum_t csum_rom = {
            0x0003FC9D,	//total_ones
            0x00000BAA, 0x000021CD, 00000000,	//bit_column_cksum[0][3];
            0x0000CEE0, 0x000027B8, 00000000,	//bit_column_cksum[1][3];
            0x000028E6, 0x00002706, 00000000,	//bit_column_cksum[2][3];
            0x0000BB38, 0x00002542, 00000000,	//bit_column_cksum[3][3];
            0x00001075, 0x00002379, 00000000,	//bit_column_cksum[4][3];
            0x00004D33, 0x00002270, 00000000,	//bit_column_cksum[5][3];
            0x0000337F, 0x00002008, 00000000,	//bit_column_cksum[6][3];
            0x0000A44C, 0x00001F22, 00000000,	//bit_column_cksum[7][3];
    		0x00000000, 0x00000008, 0x0000D705, 0x00004372,//row_weight_sum
    		0x00000000, 0x000028F8, 0x00006AD4, 0x00003934	//fact_weight_sum
    };
    
    #if 0/// no stable compiler available
    
    #pragma CODE_SECTION(verify_checksum_onROM, ".CKSUMFUNCS");
    unsigned short verify_checksum_onROM();
    
    #pragma CODE_SECTION(calculate_composite_checksum_on_rom, ".CKSUMFUNCS");
    unsigned short calculate_composite_checksum_on_rom(composite_checksum_t *cksum, memblock *mblock, unsigned int total_mblocks);
    
    #pragma CODE_SECTION(add_to_factorial_sum, ".CKSUMFUNCS");
    void add_to_factorial_sum(unsigned long fact_weight, composite_checksum_t *cksum);
    
    #pragma CODE_SECTION(add_to_row_weight_sum, ".CKSUMFUNCS");
    void add_to_row_weight_sum(unsigned long ones_weight, composite_checksum_t *cksum);
    
    #pragma CODE_SECTION(add_to_bitcolumn_checksum, ".CKSUMFUNCS");
    unsigned long add_to_bitcolumn_checksum(unsigned long bitcolumn, unsigned long bit_weight, composite_checksum_t *cksum);
    
    #pragma CODE_SECTION(compare_two_composite_checksums, ".CKSUMFUNCS");
    unsigned short compare_two_composite_checksums(const composite_checksum_t *goldsum, composite_checksum_t *compsum);
    
    #pragma CODE_SECTION(calculate_checksum, ".CKSUMFUNCS");
    unsigned long calculate_checksum(unsigned long start, unsigned long end, unsigned long offset, composite_checksum_t *cksum);
    
    #pragma CODE_SECTION(test_reserved_memory, ".CKSUMFUNCS");
    unsigned short test_reserved_memory(unsigned long start, unsigned long end);
    
    
    unsigned short test_reserved_memory(unsigned long start, unsigned long end)
    {
    	if(start & ~(0x3FFFFF))	//address beyond 22 bits
    	{
    		while(start <=end )
    		{
    			if(__addr32_read_uint16(start++) != (unsigned long)0xFFFF)
    			{
    				return 0xFFFF;	//error
    			}
    		}
    	}
    	else
    	{
    		while(start <=end )
    		{
    			if(* (volatile unsigned short *)start++ != (unsigned long)0xFFFF)
    			{
    				return 0xFFFF;	//error
    			}
    		}
    	}
    	return 0;
    }
    
    // This main function performs a very simple 64 bit checksum routine.
    // 4 32-bit values are used to calculate the checksum.  This is done so that
    // no overflow is lost.  After each addition, the value is checked to see if
    // it has overflowed the lower 16-bits.  If it has, then the overflow portion
    // in the upper 16-bits is added to the next most significant portion of the
    // checksum.
    //
    // When the routine completes, the upper 16-bits of each portion of the checksum
    // will be 0x000 - this portion should be discarded as it was only used to check
    // for overflow and the checksum is then formed from the lower 16-bits.
    //
    // For example:
    //     lowHalfLSW  = 0x00001111
    //     lowHalfMSW  = 0x00002222
    //     highHalfLSW = 0x00003333
    //     highHalfMSW = 0x00004444
    //
    //     would result in a 64-bit checksum of 0x44443333 22221111
    
    unsigned short calculate_composite_checksum_on_rom(composite_checksum_t *cksum, memblock *mblock, unsigned int total_mblocks)
    {
          unsigned short i;
          unsigned long offset = 0;
          memblock *lmblock = (void *)0;
          unsigned short result = 0;
    
          cksum->row_weight_sum.highHalfMSW = 0;
          cksum->row_weight_sum.highHalfLSW = 0;
          cksum->row_weight_sum.lowHalfLSW = 0;
          cksum->row_weight_sum.lowHalfMSW = 0;
    
          cksum->fact_weight_sum.highHalfMSW = 0;
          cksum->fact_weight_sum.highHalfLSW = 0;
          cksum->fact_weight_sum.lowHalfLSW = 0;
          cksum->fact_weight_sum.lowHalfMSW = 0;
          
          cksum->total_ones = 0;
       
          cksum->bit_column_cksum[0][0] = cksum->bit_column_cksum[1][0] = cksum->bit_column_cksum[2][0] = cksum->bit_column_cksum[3][0] = 0;
          cksum->bit_column_cksum[4][0] = cksum->bit_column_cksum[5][0] = cksum->bit_column_cksum[6][0] = cksum->bit_column_cksum[7][0] = 0;
       
          cksum->bit_column_cksum[0][1] = cksum->bit_column_cksum[1][1] = cksum->bit_column_cksum[2][1] = cksum->bit_column_cksum[3][1] = 0;
          cksum->bit_column_cksum[4][1] = cksum->bit_column_cksum[5][1] = cksum->bit_column_cksum[6][1] = cksum->bit_column_cksum[7][1] = 0;
       
          cksum->bit_column_cksum[0][2] = cksum->bit_column_cksum[1][2] = cksum->bit_column_cksum[2][2] = cksum->bit_column_cksum[3][2] = 0;
          cksum->bit_column_cksum[4][2] = cksum->bit_column_cksum[5][2] = cksum->bit_column_cksum[6][2] = cksum->bit_column_cksum[7][2] = 0;
    
          for(i = 0; i < total_mblocks; i++) {
        	  lmblock = (memblock *)(&mblock[i]);
    		   if (lmblock->mem_attribute == 0)
    		   {
    				result = test_reserved_memory((unsigned long)(lmblock->firstAddr), (unsigned long)(lmblock->lastAddr));
    				if(result == 0xFFFF)
    					return 0xFFFF;
    		   }
    		   else if(lmblock->mem_attribute == 1)
    		   {
    			   offset = calculate_checksum((unsigned long)(lmblock->firstAddr), (unsigned long)(lmblock->lastAddr), offset, cksum);
    		   }
    	  }
        return 0;
    } 
    
    
    void add_to_factorial_sum(unsigned long fact_weight, composite_checksum_t *cksum)
    {
    	   // Add in LSW
    	    cksum->fact_weight_sum.lowHalfLSW += (fact_weight & (unsigned long)0x0000FFFF);
    
    	   // Check for overflow
    	   if(cksum->fact_weight_sum.lowHalfLSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->fact_weight_sum.lowHalfMSW += cksum->fact_weight_sum.lowHalfLSW >> 16;
    		   cksum->fact_weight_sum.lowHalfLSW &= (unsigned long)0x0000FFFF;
    	   }
       
    	   if(cksum->fact_weight_sum.lowHalfMSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->fact_weight_sum.highHalfLSW += cksum->fact_weight_sum.lowHalfMSW >> 16;
    		   cksum->fact_weight_sum.lowHalfMSW &= (unsigned long)0x0000FFFF;
    	   }
    
    	   if(cksum->fact_weight_sum.highHalfLSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->fact_weight_sum.highHalfMSW += cksum->fact_weight_sum.lowHalfLSW >> 16;
    		   cksum->fact_weight_sum.highHalfLSW &= (unsigned long)0x0000FFFF;
    	   }
    
    	   // Add in MSW
    	   cksum->fact_weight_sum.lowHalfMSW += (fact_weight >> 16);
    	   // Check for overflow
    	   if(cksum->fact_weight_sum.lowHalfMSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->fact_weight_sum.highHalfLSW += cksum->fact_weight_sum.lowHalfMSW >> 16;
    		   cksum->fact_weight_sum.lowHalfMSW &= (unsigned long)0x0000FFFF;
    	   }
    
    	   if(cksum->fact_weight_sum.highHalfLSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->fact_weight_sum.highHalfMSW += cksum->fact_weight_sum.lowHalfLSW >> 16;
    		   cksum->fact_weight_sum.highHalfLSW &= (unsigned long)0x0000FFFF;
    	   }
    }
    
    void add_to_row_weight_sum(unsigned long ones_weight, composite_checksum_t *cksum)
    {
    	   // Add in LSW
    	   cksum->row_weight_sum.lowHalfLSW += (ones_weight & (unsigned long)0x0000FFFF);
    
    	   // Check for overflow
    	   if(cksum->row_weight_sum.lowHalfLSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->row_weight_sum.lowHalfMSW += cksum->row_weight_sum.lowHalfLSW >> 16;
    		   cksum->row_weight_sum.lowHalfLSW &= (unsigned long)0x0000FFFF;
    	   }
       
    	   if(cksum->row_weight_sum.lowHalfMSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->row_weight_sum.highHalfLSW += cksum->row_weight_sum.lowHalfMSW >> 16;
    		   cksum->row_weight_sum.lowHalfMSW &= (unsigned long)0x0000FFFF;
    	   }
    
    	   if(cksum->row_weight_sum.highHalfLSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->row_weight_sum.highHalfMSW += cksum->row_weight_sum.lowHalfLSW >> 16;
    		   cksum->row_weight_sum.highHalfLSW &= (unsigned long)0x0000FFFF;
    	   }
    
    	   // Add in MSW
    	   cksum->row_weight_sum.lowHalfMSW += (ones_weight >> 16);
    	   // Check for overflow
    	   if(cksum->row_weight_sum.lowHalfMSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->row_weight_sum.highHalfLSW += cksum->row_weight_sum.lowHalfMSW >> 16;
    		   cksum->row_weight_sum.lowHalfMSW &= (unsigned long)0x0000FFFF;
    	   }
    
    	   if(cksum->row_weight_sum.highHalfLSW >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->row_weight_sum.highHalfMSW += cksum->row_weight_sum.lowHalfLSW >> 16;
    		   cksum->row_weight_sum.highHalfLSW &= (unsigned long)0x0000FFFF;
    	   }
    }
    
    //returns ones weight of the bit just added - ones weight = 8*(bitweight-1)+bitcolumn.
    unsigned long add_to_bitcolumn_checksum(unsigned long bitcolumn, unsigned long bit_weight, composite_checksum_t *cksum)
    {
    	   // Add in LSW
    	   cksum->bit_column_cksum[bitcolumn][0] += (bit_weight & (unsigned long)0x0000FFFF);
    
    	   // Check for overflow
    	   if(cksum->bit_column_cksum[bitcolumn][0] >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->bit_column_cksum[bitcolumn][1] += cksum->bit_column_cksum[bitcolumn][0] >> 16;
    		   cksum->bit_column_cksum[bitcolumn][0] &= (unsigned long)0x0000FFFF;
    	   }
       
    	   if(cksum->bit_column_cksum[bitcolumn][1] >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->bit_column_cksum[bitcolumn][2] += cksum->bit_column_cksum[bitcolumn][1] >> 16;
    		   cksum->bit_column_cksum[bitcolumn][1] &= (unsigned long)0x0000FFFF;
    	   }
    
    	   // Add in MSW
    	   cksum->bit_column_cksum[bitcolumn][1] += (bit_weight >> 16);
    	   // Check for overflow
    	   if(cksum->bit_column_cksum[bitcolumn][1] >= (unsigned long)0x0000FFFF)
    	   {
    		   cksum->bit_column_cksum[bitcolumn][2] += cksum->bit_column_cksum[bitcolumn][1] >> 16;
    		   cksum->bit_column_cksum[bitcolumn][1] &= (unsigned long)0x0000FFFF;
    	   }
    
    	  return (unsigned long)(8*(bit_weight-1) + bitcolumn);
    }
    
    unsigned long calculate_checksum(unsigned long start, unsigned long end, unsigned long offset, composite_checksum_t *cksum)
    {
    	volatile unsigned short data = 0x0000;
    	volatile unsigned short byte_value = 0;
    	volatile unsigned short byte_count = 0;
    	volatile unsigned long byte_offset = 0;
    	volatile unsigned long ones_weight = 0;
    	volatile unsigned long ones_fact_weight = 0; 
    	volatile unsigned long nibble_count = 0;
    	volatile unsigned int nibble_offset = 0;
    
    	while(start <= end)
    	{
    		if(start & ~(0x3FFFFF))	//address beyond 22 bits
    		{
    				data = __addr32_read_uint16(start++);
    		}
    		else
    		{
    			data = *(volatile unsigned short *)start++;	//pointer to a 16 bit value
    		}
    		//each offset has 2 bytes of data on C28x CPUs
    		for(byte_count = 1; byte_count < 3; byte_count++)
    		{
    			byte_offset = byte_count+(offset);
    			ones_fact_weight = 1;
    			//get the byte from word
    			byte_value = (data & (0xFF));
    			data = (data >> 8);
    			ones_weight = 0;			
    			//seperate the byte into two nibbles
    			for(nibble_offset = 0;  nibble_offset <= 4; nibble_offset+=4)
    			{
    				nibble_count++;
    				if((byte_value & 0xF) == 0)
    				{
    					;
    				}
    				else if ((byte_value & 0xF) == 1)
    				{
    					cksum->total_ones += 1;
    				    ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    			    	ones_fact_weight = (nibble_count -1)*(nibble_count + 1);
    				}
    				else if ((byte_value & 0xF) == 2)
    				{
    					cksum->total_ones += 1;
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_fact_weight = (nibble_count -1)*(nibble_count + 2) ;
    				}
    				else if ((byte_value & 0xF) == 3)
    				{
    					cksum->total_ones += 2;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 2);
    				}
    				else if ((byte_value & 0xF) == 4)
    				{
    					cksum->total_ones += 1;
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = (nibble_count -1)*(nibble_count + 3);
    
    				}
    				else if ((byte_value & 0xF) == 5)
    				{
    					cksum->total_ones += 2;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 3);
    				}
    				else if ((byte_value & 0xF) == 6)
    				{
    					cksum->total_ones += 2;
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 2);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 3);
    				}
    				else if ((byte_value & 0xF) == 7)
    				{
    					cksum->total_ones += 3;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 2);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 3);
    				}
    				else if ((byte_value & 0xF) == 8)
    				{
    					cksum->total_ones += 1;
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = (nibble_count -1)*(nibble_count + 4);
    
    				}
    				else if ((byte_value & 0xF) == 9)
    				{
    					cksum->total_ones += 2;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				}
    
    				else if ((byte_value & 0xF) == 10)
    				{
    					cksum->total_ones += 2;
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 2);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				}
    				else if ((byte_value & 0xF) == 11)
    				{
    					cksum->total_ones += 3;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 2);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				}
    				else if ((byte_value & 0xF) == 12)
    				{
    					cksum->total_ones += 2;
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 3);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				}
    				else if ((byte_value & 0xF) == 13)
    				{
    					cksum->total_ones += 3;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 3);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				}
    				else if ((byte_value & 0xF) == 14)
    				{
    					cksum->total_ones += 3;
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 2);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 3);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				    	 
    				}
    				else if ((byte_value & 0xF) == 15)
    				{
    					cksum->total_ones += 4;
    					ones_weight += add_to_bitcolumn_checksum(0+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(1+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(2+nibble_offset,byte_offset, cksum);
    					ones_weight += add_to_bitcolumn_checksum(3+nibble_offset,byte_offset, cksum);
    
    					ones_fact_weight = ones_fact_weight *(nibble_count + 1);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 2);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 3);
    					ones_fact_weight = ones_fact_weight *(nibble_count%2 + 4);
    				    	 
    				}
    				add_to_factorial_sum(ones_fact_weight, cksum);
    				ones_fact_weight = 1;
    				//get the next nibble from byte
    				byte_value = byte_value >> 4;
    			}//for loop on nibble.
    			add_to_row_weight_sum(ones_weight, cksum);
    	    } // for loop on bytes in word.
    			offset++;
    	}//while		
    	return offset;
    }
    
    unsigned short compare_two_composite_checksums(const composite_checksum_t *goldsum, composite_checksum_t *compsum)
    {
    
    	if((goldsum == (void *)0) || (compsum == (void *)0))
    		return 0xFFFF;
    
    	if(goldsum->total_ones != compsum->total_ones )
    		return 0xFFFE;
    
    	if((goldsum->fact_weight_sum.highHalfMSW != compsum->fact_weight_sum.highHalfMSW )
    			|| (goldsum->fact_weight_sum.highHalfLSW != compsum->fact_weight_sum.highHalfLSW )
    			|| (goldsum->fact_weight_sum.lowHalfMSW != compsum->fact_weight_sum.lowHalfMSW )
    			|| (goldsum->fact_weight_sum.lowHalfLSW != compsum->fact_weight_sum.lowHalfLSW ))
    	{
    		return 0xFFFD;
    	}
    
    	if((goldsum->row_weight_sum.highHalfMSW != compsum->row_weight_sum.highHalfMSW )
    			|| (goldsum->row_weight_sum.highHalfLSW != compsum->row_weight_sum.highHalfLSW)
    			|| (goldsum->row_weight_sum.lowHalfMSW != compsum->row_weight_sum.lowHalfMSW)
    			|| (goldsum->row_weight_sum.lowHalfLSW != compsum->row_weight_sum.lowHalfLSW))
    	{
    		return 0xFFFC;
    	}
    
    	if((goldsum->bit_column_cksum[7][2] != compsum->bit_column_cksum[7][2])
    			|| (goldsum->bit_column_cksum[7][1] != compsum->bit_column_cksum[7][1])
    			|| (goldsum->bit_column_cksum[7][0] != compsum->bit_column_cksum[7][0]))
    	{
    		return 0xFFFB;
    	}
    
    	if((goldsum->bit_column_cksum[6][2] != compsum->bit_column_cksum[6][2])
    			|| (goldsum->bit_column_cksum[6][1] != compsum->bit_column_cksum[6][1])
    			|| (goldsum->bit_column_cksum[6][0] != compsum->bit_column_cksum[6][0]))
    	{
    		return 0xFFFA;
    	}
    
    	if((goldsum->bit_column_cksum[5][2] != compsum->bit_column_cksum[5][2])
    			|| (goldsum->bit_column_cksum[5][1] != compsum->bit_column_cksum[5][1])
    			|| (goldsum->bit_column_cksum[5][0] != compsum->bit_column_cksum[5][0]))
    	{
    		return 0xFFF9;
    	}
    
    	if((goldsum->bit_column_cksum[4][2] != compsum->bit_column_cksum[4][2])
    			|| (goldsum->bit_column_cksum[4][1] != compsum->bit_column_cksum[4][1])
    			|| (goldsum->bit_column_cksum[4][0] != compsum->bit_column_cksum[4][0]))
    	{
    		return 0xFFF8;
    	}
    
    	if((goldsum->bit_column_cksum[3][2] != compsum->bit_column_cksum[3][2])
    			|| (goldsum->bit_column_cksum[3][1] != compsum->bit_column_cksum[3][1])
    			|| (goldsum->bit_column_cksum[3][0] != compsum->bit_column_cksum[3][0]))
    	{
    		return 0xFFF7;
    	}
    
    	if((goldsum->bit_column_cksum[2][2] != compsum->bit_column_cksum[2][2])
    			|| (goldsum->bit_column_cksum[2][1] != compsum->bit_column_cksum[2][1])
    			|| (goldsum->bit_column_cksum[2][0] != compsum->bit_column_cksum[2][0]))
    	{
    		return 0xFFF6;
    	}
    
    	if((goldsum->bit_column_cksum[1][2] != compsum->bit_column_cksum[1][2])
    			|| (goldsum->bit_column_cksum[1][1] != compsum->bit_column_cksum[1][1])
    			|| (goldsum->bit_column_cksum[1][0] != compsum->bit_column_cksum[1][0]))
    	{
    		return 0xFFF5;
    	}
    
    	if((goldsum->bit_column_cksum[0][2] != compsum->bit_column_cksum[0][2])
    			|| (goldsum->bit_column_cksum[0][1] != compsum->bit_column_cksum[0][1])
    			|| (goldsum->bit_column_cksum[0][0] != compsum->bit_column_cksum[0][0]))
    	{
    		return 0xFFF4;
    	}
    
    	return 0;
    }
    
    unsigned short verify_checksum_onROM()
    {
    	composite_checksum_t rom_cksum;
    	memblock mblock_rom[6];
    	volatile unsigned long *test_signature;
    	volatile unsigned long *alt_test_signature;
    
    	sysctl_wdog_disable();
    
    	mblock_rom[0].firstAddr = 0x003F8002;
    	mblock_rom[0].lastAddr =  0x003febf1;
    	mblock_rom[0].mem_attribute = 1;	//data is present
    
    	mblock_rom[1].firstAddr = 0x003febf2;
    	mblock_rom[1].lastAddr =  0X003fff39;
    	mblock_rom[1].mem_attribute = 0;	//data is NOT present
    
    	mblock_rom[2].firstAddr = 0x003fff3a;
    	mblock_rom[2].lastAddr =  0x003fff7b;
    	mblock_rom[2].mem_attribute = 1;	//data is present
    
    //	.CKSUMLOC
    //	*          0    003fff7c    00000042
    //	                  003fff7c    00000042     c1brom_checksum.obj (.CKSUMLOC)
    
    	mblock_rom[3].firstAddr = 0x003fffbe;
    	mblock_rom[3].lastAddr =  0x003fffFF;
    	mblock_rom[3].mem_attribute = 1;	//data is present
    
    	mblock_rom[4].firstAddr = 0x01001000;
    	mblock_rom[4].lastAddr =  0x0100186F;
    	mblock_rom[4].mem_attribute = 0;	//data is NOT present
    
    	mblock_rom[5].firstAddr = 0x01001870;
    	mblock_rom[5].lastAddr =  0x01001FFF;
    	mblock_rom[5].mem_attribute = 1;	//data is present
    
    	test_signature = (volatile unsigned long *)0x3f8000;
    	alt_test_signature = (volatile unsigned long *)0x3ffffe;
    
    	//first check if all the data and address lines mapped to ROM are functional
    	if (*(test_signature) != ~(*(alt_test_signature)))
    		return 0xFFF3;
    
    	if ( 0xFFFF == calculate_composite_checksum_on_rom(&rom_cksum, &mblock_rom[0], 6))
    		return 0xFFF2;
    
    	return compare_two_composite_checksums(&csum_rom, &rom_cksum);
    }
    
    // EOF --------
    #endif //no stable compiler available
    
    Muni,

    Attached is some reference code, where we do something similar for our own bootrom, i.e. a checksum that is compared against the stored checksum when we generated the code for the ROM.  You could use a similar strategy on the flash to compute a checksum, add that checksum as part of the flash that you program, then on boot up run this before executing your system code.

    You can find this file in C2000Ware here: C:\ti\c2000\C2000Ware_5_00_00_00\libraries\boot_rom\f2837xd\revB\rom_sources\F2837x_bootROM\cpu01-bootROM\source\c1brom_checksum.

    So, the ECC I mentioned earlier will provide run time protection, and you can use the above to make sure the code is what is expected before running.

    Best,

    Matthew

  • Hi Matthew,

           Thanks for giving the example path , but can you please share the application note or PDF resources to understand how and what steps are required ?

    Thanks,

    Sid C

  • Sid,

    I'm not sure there is an app note around this, but the code should be commented as such that it is pretty self explanatory how we are calculating the checksums.  I'm sure there are some open source code examples for checksums as well like CRC32, etc.

    Best,
    Matthew

  • Hi, 

     We found something call this : , so is it checksum calculated for the application code ? How to check this ?

    Thanks,

    Sid C

  • How to check in executable flash image of bin file ?

    Thanks,

    Sid C

  • Sid,

    I have confirmed that these registers are doing a read of the entire flash and OTP of the connected device to generate these Checksums.

    I will send you a friendship request through the forum and can share the algo details there.

    Best,

    Matthew