Search code examples
cstm32

Checksum function on STM32


I'm trying to make a function to calculate the checksum of an array. I should add all values in the array and take two's complement. I've tested my code and the result is correct. As soon as i try to implement this code in a separate function the result is wrong. Can somebody help me solve this issue.

The function call is:

  uint8_t Testframe[] = {0xAA,0x43,0x10,0x97,0x55,0xBE, 0x6A, 0xEA, 0xF3, 0xBE, 0xF4, 0x71, 0x9D, 0xB2, 0x4B, 0x0B, 0x45, 0x56, 0x55};

  uint8_t result2 = 0;
  result2 = CalculateChecksum(Testframe);

The function is:

uint8_t CalculateChecksum( uint8_t array[])
{
uint64_t result = 0;
uint8_t  output = 0;

for(int i = 0; i < sizeof(array); i++)
{
    result = result + array[i];
}
output = (uint8_t) result;
output = output ^ 0xFF;
output = output + 0x01;
return output;

}

The result should be 0x5A


Solution

  • Depending on whether you are using 32 or 64 bit addressing, your for loop is only iterating 4 or 8 times, not the required 19 times.

    This is because Arrays in C always decay into a pointer when passed as a function argument.
    The following statement:

    for(int i = 0; i < sizeof(array); i++)  
    

    Should have resulted in a compiler warning. I see this one on my system:

    " 23, 30 warning: sizeof on array function parameter will return size of 'uint8_t *' (aka 'unsigned char *') instead of 'uint8_t []' "

    Which is basically saying sizeof(array), once array has been passed as a function parameter, will yield the sizeof a pointer, not the sizeof the array itself, resulting in the wrong number of iterations.

    Passing another parameter in your prototype is one way to address this. eg:

    uint8_t CalculateChecksum( uint8_t array[], size_t size);
    

    Allowing the function to use a value representing the count of elements in array:

    for(int i = 0; i < size; i++)
    { ...
    

    Calling example:

      size_t size = sizeof Testframe/sizeof Testframe[0];//provides number of elements in array
      result2 = CalculateChecksum(Testframe, size);  
    

    Finally, if you do not already have your compiler set to show warnings, change it to do so. (eg -Wall if using GCC)