0

Objective

I have a global TX array, and a CRC function that has to progress through this array. The CRC function should not process the first byte. To avoid this I am trying to increment the array by doing TX++. This is causing problems.

Problem

Please take a quick look at the code below:

void Send_To_Manager(void)
{   
    TX[0] = 0x55;
    TX[1] = 0x00;
    TX[2] = 0x01;
    TX[3] = 0x00;
    TX[4] = COMMON_COMMAND;     
    TX++;
    TX[5] = CRC8(TX,4);
    TX[6] = CO_RD_VERSION;
    TX += 5;
    TX[7] = CRC8(TX,1);
    TX -= 6;
    UART_TX(8);     
}

I would like to blind the CRC8 function of the first byte in the TX array. By executing TX++, I am expecting the TX[0] to be 0x00. However I am getting the error:

error: wrong type argument to increment

I am also getting the errors for TX += 5; and TX -= 6 as:

error: incompatible types in assignment

I played around with this, so instead if the function has an array such as:

void Send_To_Manager(unsigned char data[100])
{
    data++; 
}

The above works as intended.

Questions

  • Why can I do this for Function based arrays and not Global arrays?
  • If I do wish to do this for global arrays how can I do it?
  • How would you prefer to achieve the above objective?

Thank you all for your time.

2 Answers 2

4

Why can I do this for Function based arrays and not Global arrays?

Arrays as function parameters are decayed to pointers, data in your example is just a local variable with type unsigned char*, you can modify it as you want. TX however is (I suppose) a static array and not a modifiable pointer.

If I do wish to do this for global arrays how can I do it?

First, make sure that's really what you want to do. Modifying the value of TX will not only affect the call to CRC8 but also all the following instructions that are dereferencing the value of TX.

As instance, TX++; TX[5] = CRC8(TX,4); is equivalent to TX[6] = CRC8(TX+1,4); TX++;.

If you don't want that side effect, don't change the value of TX, just use CRC8(TX+1,4) and CRC8(TX+5,4).

However, if that's really what you want, then you'll have to use a temporary pointer :

void Send_To_Manager(void)
{   
    char* myTX = TX;
    myTX[0] = 0x55;
    myTX[1] = 0x00;
    myTX[2] = 0x01;
    myTX[3] = 0x00;
    myTX[4] = COMMON_COMMAND;     
    myTX++;
    myTX[5] = CRC8(myTX,4);
    myTX[6] = CO_RD_VERSION;
    myTX += 5;
    myTX[7] = CRC8(myTX,1);
    myTX -= 6;
    UART_TX(8);     
}

If the increments of myTX have to be kept for the next call to Send_To_Manager, you could make it static to the function. If the modifications of TX have to be reflected in the whole program, then you have a strong architecture issue.

How would you prefer to achieve the above objective?

If the modification of TX must only impact the Send_To_Manager function, the above solutions will do fine. In other cases, you'll have to rethink your program architecture. A possible solution could be to pass the current progressing state as parameters instead of using a global state variable.

char* Send_To_Manager(char* currentTX)
{   
    currentTX[0] = 0x55;
    ...
    currentTX[4] = COMMON_COMMAND;     
    currentTX++;
    ...
    return currentTX;
}
Sign up to request clarification or add additional context in comments.

2 Comments

I have noticed an additional mistake to what I have been trying to do. instead of TX[5] = CRC8(TX,4); it should actually be TX++; temp = CRC8(TX,4) ; TX--; TX[5] = temp;
@Volcano In that case you don't have to modify TX at all, just call CRC8(TX+1, 4).
1

Instead of trying to alter the array reference itself, why not:

TX[5] = CRC8(TX+1,4);
TX[7] = CRC8(TX+6,1);

2 Comments

Wouldn't it be TX[6] = CRC8(TX+1,4) and TX[13] = CRC8(TX+6,1) in order to reflect the modifications of TX value ?
You're right, zakinster, and that sort of confusion is precisely why it's a bad idea to mess with your array references.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.