This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

is volatile array needed?

There is a string buffer referenced by both an ISR and the main(). The ISR collects a sentence from UART and put it into the buffer. Once the received sentence is completed a flag is raised. The main() checks the flag and copies the sentence to another buffer. The code is like

unsigned char xdata RxBuffer[];
unsigned char xdata buffer[];
bit RxFlag = 0;

void uart( void )
{
  //receive data from sbuf
  RxBuffer[] = sbuf;
  //if done
    RxFlag = 1;
}

void main( void )
{
  while( 1 )
  {
    if( RxFlag )
      strcpy( buffer, RxBuffer );
  }
}
The question is "Should I declare RxBuffer as volatile?" RxFlag doesn't need to be volatile because it is an automatic variable. The assembly code is "JNB RxFlag, xxxx". By the way, strcpy() is a reentrant function and the UART is at 4800 bps. The worst case is while strcpy is coping data, RxBuffer starts storing another new sentence. The purpose is to keep the integrity of the received data very time. I know I can use ES = 0 and ES = 1 before and after strcpy().

Three more questions:
1. Do I misunderstand the usage of volatile on array?
2. Does the reentrancy play any significant role here?
3. What is the difference between memcpy() and strcpy()? What are the advantages and disadvatages on each?

Thank you for answering my questions.

chao.

Parents
  • You will have to be more careful to avoid that the ISR overwrites parts of the buffer the main routine is currently working on. I.e. you'll need more status than just a single bit, so the main() function the ISR where in the buffer it currently is. In the end, you'll most probably end up with a ring buffer. Both the ISR and main maintain one pointer (or index) into the ring each, and check that theirs doesn't run over the location of the pointer maintained by the other. Both of these pointers will have to be made volatile.

    RxFlag doesn?t need to be volatile because it is an automatic variable.

    Wrong. It's most definitely not an automatic, as shown, and it has to be flagged volatile.

    You should flag the array volatile, too, because its contents do change without the current thread of control knowing about it.

Reply
  • You will have to be more careful to avoid that the ISR overwrites parts of the buffer the main routine is currently working on. I.e. you'll need more status than just a single bit, so the main() function the ISR where in the buffer it currently is. In the end, you'll most probably end up with a ring buffer. Both the ISR and main maintain one pointer (or index) into the ring each, and check that theirs doesn't run over the location of the pointer maintained by the other. Both of these pointers will have to be made volatile.

    RxFlag doesn?t need to be volatile because it is an automatic variable.

    Wrong. It's most definitely not an automatic, as shown, and it has to be flagged volatile.

    You should flag the array volatile, too, because its contents do change without the current thread of control knowing about it.

Children