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.

#29 expected an expression how to fix it?



#include <msp430g2553.h>
#include <string.h>
#include <stdio.h>

/*
 * main.c
 */

unsigned char byte_to_crc[];
unsigned short crc;
unsigned int len;
unsigned int pos;
unsigned int i;
unsigned short mod_rtu_crc(char byte_to_crc[], int len);    // generate crc


void main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
	
    byte_to_crc[0] = 0x01;
    byte_to_crc[1] = 0x03;
    byte_to_crc[2] = 0x00;
    byte_to_crc[3] = 0xFA;
    byte_to_crc[4] = 0x00;
    byte_to_crc[5] = 0x04;

    // should give 0x6438 as crc

    mod_rtu_crc(byte_to_crc[] , 6);

	//return 0;
}

unsigned short mod_rtu_crc(char byte_to_crc[], int len)
{
	crc = 0xFFFF;

  for(int pos = len; pos > 0; pos--){
    crc ^= (unsigned short)byte_to_crc[pos-1];          // XOR byte into least sig. byte of crc

    for(int i = 8; i != 0; i--){    // Loop over each bit
      if((crc & 0x0001) != 0){      // If the LSB is set
        crc >>= 1;                    // Shift right and XOR 0xA001
        crc ^= 0xA001;
      }
      else{                            // Else LSB is not set
        crc >>= 1;                    // Just shift right
      }
    }
  // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)

}
return crc;
}

Hi, I am very new to embedded coding and I am trying to implement a CRC to modbus frame currently. So I need to test CRC function as a single module for now. And I failed it as you see, at line 29, 38 and 41, I am getting #29 expected an expression error. If you could help me a little I would be very pleased. Thanks.

  • istemihan90 said:
    mod_rtu_crc(byte_to_crc[] , 6);

    Change that line to:

    mod_rtu_crc(byte_to_crc, 6);

    istemihan90 said:
    unsigned short mod_rtu_crc(char byte_to_crc[], int len)

    Change that line to:

    unsigned short mod_rtu_crc(char* byte_to_crc, int len)

    Also, you need to specify a size of the buffer:

    unsigned char byte_to_crc[YOU_NEED_A_SIZE_SPECIFIED_HERE];

  • Also, I would change the name of the first parameter to mod_rtu_crc in the prototype to something other than byte_to_crc (for example, use the variable name "bytes" or "buffer"). This because you use that same name for your global variable and scope can get confusing when debugging.
  • #include <msp430g2553.h>
    #include <string.h>
    #include <stdio.h>
    
    /*
     * main.c
     */
    
    unsigned char byte_to_crc[6];
    unsigned short crc;
    unsigned int len;
    unsigned int pos;
    unsigned int i;
    unsigned short mod_rtu_crc(char*, int);    // generate crc
    
    
    void main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    	
        byte_to_crc[0] = 0x01;
        byte_to_crc[1] = 0x03;
        byte_to_crc[2] = 0x00;
        byte_to_crc[3] = 0xFA;
        byte_to_crc[4] = 0x00;
        byte_to_crc[5] = 0x04;
    
        // should give 0x6438 as crc
    
        //mod_rtu_crc(byte_to_crc[] , 6);
        mod_rtu_crc(byte_to_crc, 6);
    
    	//return 0;
    }
    
    unsigned short mod_rtu_crc(char* bytes, int len)
    {
    	crc = 0xFFFF;
    
      for(int pos = len; pos > 0; pos--){
        crc ^= (unsigned short)bytes[pos-1];          // XOR byte into least sig. byte of crc
    
        for(int i = 8; i != 0; i--){    // Loop over each bit
          if((crc & 0x0001) != 0){      // If the LSB is set
            crc >>= 1;                    // Shift right and XOR 0xA001
            crc ^= 0xA001;
          }
          else{                            // Else LSB is not set
            crc >>= 1;                    // Just shift right
          }
        }
      // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
    
    }
    return crc;
    }
    

    Hi, thanks for reply. I get code changed to this. I made the changes according to your suggestions. This time I get errors in highlighted lines. in line 39 and 42, #29 expected an expression error still exist. this time at line 30-highlighted- error turned into warning like this: #169-D argument of type "unsigned char *" is incompatible with parameter of type "char *"

  • #include <msp430g2553.h>
    #include <string.h>
    #include <stdio.h>
    
    /*
     * main.c
     */
    
    unsigned char byte_to_crc[6];
    unsigned short crc;
    unsigned int len;
    unsigned int pos;
    unsigned int i;
    unsigned short mod_rtu_crc(char*, int);    // generate crc
    
    
    void main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    	
        byte_to_crc[0] = 0x01;
        byte_to_crc[1] = 0x03;
        byte_to_crc[2] = 0x00;
        byte_to_crc[3] = 0xFA;
        byte_to_crc[4] = 0x00;
        byte_to_crc[5] = 0x04;
    
        // should give 0x6438 as crc
    
        //mod_rtu_crc(byte_to_crc[] , 6);
        mod_rtu_crc(byte_to_crc, 6);
    
    	//return 0;
    }
    
    unsigned short mod_rtu_crc(char* bytes, int len)
    {
    	crc = 0xFFFF;
    
      for(pos = len; pos > 0; pos--){
        crc ^= (unsigned short)bytes[pos-1];          // XOR byte into least sig. byte of crc
    
        for(i = 8; i != 0; i--){    // Loop over each bit
          if((crc & 0x0001) != 0){      // If the LSB is set
            crc >>= 1;                    // Shift right and XOR 0xA001
            crc ^= 0xA001;
          }
          else{                            // Else LSB is not set
            crc >>= 1;                    // Just shift right
          }
        }
      // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
    
    }
    return crc;
    }
    
    

    I corrected errors. This time just highlighted line 30 gives a warning: #169-D argument of type "unsigned char *" is incompatible with parameter of type "char *"

  • Oh yeah. Not sure what mode you have the compiler in, but not all compilers support defining the loop variable in the for()... clause.

    unsigned short mod_rtu_crc(char* bytes, int len)
    {
      int pos, i; // <-- add here
      crc = 0xFFFF;
    
    Change here -->  for(pos = len; pos > 0; pos--){
        crc ^= (unsigned short)bytes[pos-1];          // XOR byte into least sig. byte of crc
    
    Change here -->    for(i = 8; i != 0; i--){    // Loop over each bit
          if((crc & 0x0001) != 0){      // If the LSB is set
    

    For the warning, just change your function to take unsigned char array:

    unsigned short mod_rtu_crc(unsigned char* bytes, int len)

    or alternately remove the unsigned qualifier from the byte_to_crc[6] definition

  • Define your loop variables inside the mod_rtu_crc function. Don't make them global. See the example I posted.
  • Also, it is good practice to specify which device and toolchain you are using when asking for help. Some people use CCS, some IAR, some use GCC. Each compiler has it's own error #s and peculiarities. This helps ensure you get the correct people helping you.
  • Thank you so much Brian, removing unsigned qualifier from byte_to_crc[6] definition worked. I will share the code now. CRC works fine :)
  • This is the working code, problem solved. What I was trying to do was implement a CRC module the code for that as it follows:

    #include <msp430g2553.h>
    #include <string.h>
    #include <stdio.h>
    
    /*
     * main.c
     */
    
    char byte_to_crc[6];
    unsigned short crc;
    unsigned int len;
    unsigned int pos;
    unsigned int i;
    unsigned short mod_rtu_crc(char*, int);    // generate crc
    
    
    void main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    	
        byte_to_crc[0] = 0x01;
        byte_to_crc[1] = 0x03;
        byte_to_crc[2] = 0x00;
        byte_to_crc[3] = 0xFA;
        byte_to_crc[4] = 0x00;
        byte_to_crc[5] = 0x04;
    
        // should give 0x6438 as crc
    
        //mod_rtu_crc(byte_to_crc[] , 6);
        mod_rtu_crc(byte_to_crc, 6);
        while(1);
    	//return 0;
    }
    
    unsigned short mod_rtu_crc(char* bytes, int len)
    {
    	crc = 0xFFFF;
    
      for(pos = 0; pos < len; pos++){
        crc ^= (unsigned short)bytes[pos];          // XOR byte into least sig. byte of crc
    
        for(i = 8; i != 0; i--){    // Loop over each bit
          if((crc & 0x0001) != 0){      // If the LSB is set
            crc >>= 1;                    // Shift right and XOR 0xA001
            crc ^= 0xA001;
          }
          else{                            // Else LSB is not set
            crc >>= 1;                    // Just shift right
          }
        }
      // Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
    
    }
    return crc;
    }
    

  • "removing unsigned qualifier from byte_to_crc[6] definition worked. "
    You should know whether your data is signed or unsigned. As long as you only cast them from one to the other, this works (but will throw warnings). But when casting from char to int, an unsigned char of 128 gives an unsigned or signed int of 128, while a signed char of 128 means -128 and casts into an unsigned int of 65408. which likely DOES make a difference.

    In case of a CRC module, using an unsigned type is probably the more fitting interpretation.

**Attention** This is a public forum