Click here to Skip to main content
Rate this: bad
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[^]
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
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;
            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--)

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
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  
	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--)
   // Not working .

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

Thank you
Posted 17-Dec-12 10:20am
Edited 17-Dec-12 11:40am
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
Please Sign up or sign in to vote.

Solution 1

 char Command_String[BufferCount] ;
   while (BufferCount--)
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.
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 Sergey Alexandrovich Kryukov 345
1 OriginalGriff 210
2 DamithSL 210
3 Kornfeld Eliyahu Peter 210
4 Peter Leow 95
0 OriginalGriff 7,215
1 DamithSL 5,199
2 Maciej Los 4,866
3 Sergey Alexandrovich Kryukov 4,757
4 Kornfeld Eliyahu Peter 4,514

Advertise | Privacy | Mobile
Web01 | 2.8.141223.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