0

I am developing a code in which I need to pass a structure pointer value to a function as a parameter. I am calling function "proto485Compare()" in "RS485TaskSlave()". "rs485Msg" contains my data for which I need to verify for checksum, I am checking it in "RS485TaskSlave()" using "if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message)))" but it is showing error on this line.

Please help me to get the values of "rs485Msg" & check for checksum on this line

Below is my code snippet:

 typedef struct
    {
      uint8_t AB;     ///< Address byte (Start byte)
      uint8_t CB;     ///< Command (index) "ASCII-byte"
      uint8_t SI;     ///< Action (sub index) "ASCII-byte"
      uint8_t PH1;    ///< Payload "ASCII-byte" of the high nibble of the high byte of the raw payload
      uint8_t PH0;    ///< Payload "ASCII-byte" of the low nibble of the high byte of the raw payload
      uint8_t PL1;    ///< Payload "ASCII-byte" of the high nibble of the low byte of the raw payload
      uint8_t PL0;    ///< Payload "ASCII-byte" of the low nibble of the low byte of the raw payload
      uint8_t CS1;    ///< Checksum "ASCII-byte" of the high nibble of the raw checksum
      uint8_t CS0;    ///< Checksum "ASCII-byte" of the low nibble of the raw checksum
    } rs485_message_t;

    uint8_t proto485ValidCheckSum(rs485_message_t message)
    { 
      uint8_t rawChecksum = (message.CB - OFFSET_ASCII) + (message.SI - OFFSET_ASCII) +
        (message.PH1 - OFFSET_ASCII) + (message.PH0 - OFFSET_ASCII) +
          (message.PL1 - OFFSET_ASCII) + (message.PL0 - OFFSET_ASCII);

      uint8_t res = (((rawChecksum & 0xF0) >> 4) + OFFSET_ASCII) == message.CS1 &&
        ((rawChecksum & 0x0F) + OFFSET_ASCII) == message.CS0;

      return res;
    }

    void RS485TaskSlave(void *p_arg) //b - RS485 communication Task
    {
        uint8_t res; 
        rs485_message_t rs485Msg;
        uint8_t command, action, value;

        (void)p_arg;
        while(1)
        {      
          res = driver485Read((uint8_t *)&rs485Msg, RS485_MSG_LENGTH); 
          if(RS485_MSG_LENGTH == 9)
         {
            res =  proto485Compare((uint8_t *)&rs485Msg, command, action, value);         
         }
        }      
    }

    int16_t proto485Compare(uint8_t* message, uint8_t* comparec, uint8_t* comparea, uint8_t* comaprev)
    { int j = 0;
      rs485_message_t rs485Msg;
      char res; 
      uint8_t FWmsg[9] = {0x09,0x31,0x30,0x30,0x30,0x30,0x33,0x30,0x34};           
      uint8_t arduinodata[9] = {0x09,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30}; 

     if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message))) //
/*GETTING ERRORVON THIS LINE please help how to pass message value to verify checksum at this line*/
      {
      printf("compare command..........");

        for (j=0; j<9; j++)
        {
          arduinodata[j] = message[j];
          printf("%d ",arduinodata[j]);
        }
        printf("\n");

        if(compareArray(FWmsg,arduinodata,7)==0)
        {   
          uint8_t add, fwc, fwa;
          uint16_t fwv; 
          res = GetABFWversion(&add, &fwc, &fwa, &fwv);
          res = proto485OnlyWrite(add,fwc, fwa, fwv);
        }
      }
      else
      {
        printf("Arrays have different elements.\n");
      } 
      return res;
    }
0

Remove your casting, and change your message parameter to be rs485_message_t *:

int16_t proto485Compare(rs485_message_t * message, uint8_t* comparec, uint8_t* comparea, uint8_t* comaprev) {
    int j = 0;
    rs485_message_t rs485Msg;
    char res; 
    uint8_t FWmsg[9] = {0x09,0x31,0x30,0x30,0x30,0x30,0x33,0x30,0x34};           
    uint8_t arduinodata[9] = {0x09,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30}; 

    if(proto485ValidCheckSum(message))) { ...

And when you call it, simply:

res =  proto485Compare(&rs485Msg, command, action, value);      

To get at the individual bytes you can then cast a new variable:

uint8_t *messageAsBytes = (uint8_t *)message;

Then you can use:

messageAsBytes[i]

etc.

However another cleaner way is to create a union in your structure:

struct rs485_message_t {
    union {
        uint8_t bytes[9];
        struct {
            uint8_t AB;     ///< Address byte (Start byte)
            uint8_t CB;     ///< Command (index) "ASCII-byte"
            uint8_t SI;     ///< Action (sub index) "ASCII-byte"
            uint8_t PH1;    ///< Payload "ASCII-byte" of the high nibble of the high byte of the raw payload
            uint8_t PH0;    ///< Payload "ASCII-byte" of the low nibble of the high byte of the raw payload
            uint8_t PL1;    ///< Payload "ASCII-byte" of the high nibble of the low byte of the raw payload
            uint8_t PL0;    ///< Payload "ASCII-byte" of the low nibble of the low byte of the raw payload
            uint8_t CS1;    ///< Checksum "ASCII-byte" of the high nibble of the raw checksum
            uint8_t CS0;    ///< Checksum "ASCII-byte" of the low nibble of the raw checksum
        };
    };
};   

So you can now access message->CS0, etc, as well as message->bytes[3].

You should also pass a pointer when you call proto485ValidCheckSum - purely to save memory.

uint8_t proto485ValidCheckSum(rs485_message_t *message)
{ 
  uint8_t rawChecksum = (message->CB - OFFSET_ASCII) + (message->SI - OFFSET_ASCII) +
    (message->PH1 - OFFSET_ASCII) + (message->PH0 - OFFSET_ASCII) +
      (message->PL1 - OFFSET_ASCII) + (message->PL0 - OFFSET_ASCII);

  uint8_t res = (((rawChecksum & 0xF0) >> 4) + OFFSET_ASCII) == message->CS1 &&
    ((rawChecksum & 0x0F) + OFFSET_ASCII) == message->CS0;

  return res;
}

And again call it with a pointer, which the first block of code does anyway.

In general, it's better to pass a single pointer to a struct around from function to function instead of cloning it each time.

You can also use "pass by reference" if you like, but I find it's better to stick to pointers when passing something around alot like this.

5
  • Thank you for reply, I have made above mentioned changed & run the code it is showing below errors.... 1) on line "if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message)))" it gives "type name is not allowed" and on line " arduinodata[j] = message[j];" it shows that "a value of type "rs485_message_t" cannot be assigned to an entity of tpe "uint8_t" "
    – swanand
    Mar 29 '19 at 15:48
  • 1
    @swanand Read my first code block and compare it to yours.
    – Majenko
    Mar 29 '19 at 16:06
  • Sorry my bad, i have changed for message element reading it is working fine but I am still getting error on line " if(proto485ValidCheckSum(rs485_message_t ((uint8_t*)message)))" t gives "type name is not allowed" Please inform If I am doing something wrong....
    – swanand
    Mar 29 '19 at 16:11
  • 1
    @swanand Read my first code block and compare it to yours.
    – Majenko
    Mar 29 '19 at 16:12
  • Thank you so much once again for providing guidance......
    – swanand
    Mar 29 '19 at 16:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.