Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C GCC
Hey guys I'm writing a C code in Atmel Studio 6.0 with GCC C compiler. Essentially I'm doing USART communication on a microcontroller, and I found a sample code(a header file) that handles sending/receiving (Tx/Rx) using a circular receiving buffer from an Atmel employee's blog
http://www.fourwalledcubicle.com/files/LightweightRingBuff.h[^]
 
Code excerpt that works:
 
Besides initializing the Buffer and other functions, it insert the char type data it receives into the Buffer as such:
static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
                                         const RingBuff_Data_t Data)  // type of Data: uint8_t
    {
        *Buffer->In = Data;//store the char data in the Buffer.

        if (++Buffer->In == &Buffer->Buffer[BUFFER_SIZE])
          Buffer->In = Buffer->Buffer;
 
        ATOMIC_BLOCK(ATOMIC_RESTORESTATE)  // ignore this detail, not relevant to topic
        {
            Buffer->Count++;
        }
    }
and here's the function in the header file to get'em out
static inline RingBuff_Data_t RingBuffer_Remove(RingBuff_t* const Buffer)
        {
            RingBuff_Data_t Data = *Buffer->Out;
 
            if (++Buffer->Out == &Buffer->Buffer[BUFFER_SIZE])
              Buffer->Out = Buffer->Buffer;
 
            ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
            {
                Buffer->Count--;
            }
 
            return Data;
        }
 
And then in main.c we can use this to read out chars in the Buffer
  // Print contents of the buffer one character at a time
       while (BufferCount--)
         putc(RingBuffer_Remove(&Buffer));

My goal: I'm trying to wait until an entire string of chars is stored in the Buffer (terminated with a '\0' or '\n'? ), read out the string, and maybe parse it.

 
Code excerpt that doesn't work:
 
Now as an absolute C newbie, here's what I have attempted to do (buggy code with blatantly wrong pointer usage coming thru) Just to illustrate what I hope to achieve:
int main( void ) {
 //... some initialization
RingBuffer_InitBuffer(&Buffer);
unsigned char holder;
 
while(true) {
if(usart_kbhit()) // this detects the receiving flag in USART register
  {	holder = usart_getchar();  //holder is char type. Stores the char received 
       //in the Rx register
	RingBuffer_Insert(&Buffer, holder); // function above
        
        if (holder == '\n')   { // I suppose I can send  '\n'  as the last char to 
          //terminate my string?
	 //now I'm trying to read the chars in Buffer and store'em in 
         // 'Command_String' which I suppose should be a char [] ??
         // Not so sure about how I should define 'Command_String'

        uint16_t BufferCount = RingBuffer_GetCount(&Buffer); // get the char count
       
        char Command_String[BufferCount];  //  I know this is seriously wrong in 
         //terms of how the pointer should be used.
					
        while (BufferCount--)
	  strcat(Command_String,RingBuffer_Remove(&Buffer)); // trying to append 
          // the char that I read off the Buffer to Command_String
          // but this doesn't work.
			
	  // Not working .  RingBuffer_Remove() gives a string, strcat requires  
          //pointer??  
			
						
	if strncmp(Command_String,"ABC\n",4) // my attempt to compare the string I 
         //get in Command_String with a hard-coded list of commands 
        tell_the_microcontroller_to_do_stuff (); // if received "ABC" then do stuff
                                }
   }
             }
                  }
 
 
Sorry about the long post but all I need are some comments about the way I read out the string from Buffer, store it in Command_String, and compare Command_String with "ABC"

 
Here's my code without the wordy comments
 
while(true) {
      // if a key has been pressed, then process it
if(usart_kbhit())   {
   holder = usart_getchar();
 
   RingBuffer_Insert(&Buffer, holder);
 
   if (holder == '\n')   {
uint16_t BufferCount = RingBuffer_GetCount(&Buffer);
 char Command_String[BufferCount] ;
 
   while (BufferCount--)
               strcat(Command_String,RingBuffer_Remove(&Buffer));
   // Not working .

 
   if strncmp(Command_String,"ABC\n",4)
    tell_the_microcontroller_to_do_stuff ();
 
                                }
   }
             }
                  }
 

Thank you
Posted 17-Dec-12 9:20am
Edited 17-Dec-12 10:40am
v8
Comments
SandiegoSSD at 17-Dec-12 16:03pm
   
I guess I should narrow down my question to : I have some doubts about what type I should use for that "Command_String", which holds the char data read from Buffer. Also some clarification on whether I should be checking '\n' or '\0' as the string terminator? (while this checking happens on the microcontroller side, on my VB GUI which sends data to the microcontroller, I can send either \n or \0 whichever is necessary)

1 solution

Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

 char Command_String[BufferCount] ;
 
   while (BufferCount--)
               strcat(Command_String,RingBuffer_Remove(&Buffer));
 
That won't work in C. You cannot allocate an array of char on the stack (as auto variable) with a variable length. The length must be know at compile time. So either allocate an array of fixed size, say the maximim chunk of chars you expect in a row, or you must allocate the space from the heap, and later free it, e.g.
    char* pBuffer = malloc (bufferCount);
    ...
    free (pBuffer);
As for your question about '\n' or '\0' as terminator, that depends entirely on your situation. Ususally, you want to wait for '\0' on a USART. But that depends on your buffering mechanism any what your trying to accomplish.
  Permalink  
Comments
SandiegoSSD at 17-Dec-12 18:29pm
   
Thank you for the heads up

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 540
1 Sergey Alexandrovich Kryukov 432
2 Yogesh Kumar Tyagi 384
3 Prakriti Goyal 280
4 Maciej Los 205
0 OriginalGriff 6,472
1 Sergey Alexandrovich Kryukov 5,404
2 Maciej Los 3,434
3 Peter Leow 3,259
4 DamithSL 2,495


Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 17 Dec 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100