Click here to Skip to main content
15,860,972 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
This is a narrow-down from my previous post. I'm trying to use some functions that implement a Ring buffer in USART. They are defined in a header file.
http://www.fourwalledcubicle.com/files/LightweightRingBuff.h[^]
I've attempted to use these functions in main.c, but I think somewhere I screw up some pointer/char/uint8_t type. In short, i've program this code to my microcontroller but don't seem to receive anything back from it after sending "ABC"

Could you gurus spot anything fishy about the way I'm using the char/pointers? let me know if clarifications needed.

C#
RingBuffer_InitBuffer(&Buffer);
      char holder;

   // if a key has been pressed, then process it
        if(usart_kbhit())   {
            holder = usart_getchar();
            if (!RingBuffer_IsFull(&Buffer))
            {
            RingBuffer_Insert(&Buffer, holder);
            }


    if (holder == 'C')   {
             uint16_t BufferCount = RingBuffer_GetCount(&Buffer);


            char* Command_String = malloc (BufferCount);

            while (BufferCount--) {


             if (!RingBuffer_IsEmpty(&Buffer))
              {

             *Command_String = RingBuffer_Remove(&Buffer); // is this a screw up?
             Command_String++;
               }
                                   }

            if (strncmp(Command_String,"ABC",3))//another screw up?

            usart_printstring(Command_String);

             free (Command_String);


                        }
                               }



P.S. some definitions in .h
C#
static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
                                             const uint8_t Data){...}


C#
void usart_putchar(char data) {
    // Wait for empty transmit buffer
    while ( !(UCSR0A & (1<<UDRE0)) );
    // Start transmission
    UDR0 = data;
}


C#
void usart_printstring(char *s) {
    // loop through entire string
    while (*s) {
        usart_putchar(*s);
        s++;
               }                            }

################################################
UPDATE:
if I do this after receiving the chars and store them in the Buffer, it works
C++
uint16_t BufferCount = RingBuffer_GetCount(&Buffer);
while (BufferCount--)          
 usart_putchar(RingBuffer_Remove(&Buffer));

But when I try to move the chars in Buffer to this char* Command_String, which I define to read the whole string in Buffer once a terminating char (I could use 'C' or \n or \0) is received, I get nothing from Command_String


C++
...
char holder ;
  holder = usart_getchar();
  RingBuffer_Insert(&Buffer, holder);

 if (holder == 'C')   {
uint16_t BufferCount = RingBuffer_GetCount(&Buffer);
char* Command_String = malloc (BufferCount);
  
 while (BufferCount--)    {
*Command_String = RingBuffer_Remove(&Buffer);
  Command_String++;       }
  usart_pstr(Command_String);
  free (Command_String); } 

So there's something wrong about my approach with this char* Command_String
Posted
Updated 18-Dec-12 11:00am
v4

It's difficult to be sure quite what is wrong without actually runningthat, but... Did you mean to only send data when it wasn't "ABC"?

C++
if (strncmp(Command_String,"ABC",3))//another screw up?

usart_printstring(Command_String);
Which conflicts with your earlier comments:
"don't seem to receive anything back from it after sending "ABC""Perhaps if you tried:
C++
if (strncmp(Command_String,"ABC",3) == 0)
   {
   usart_printstring(Command_String);
   }
 
Share this answer
 
Comments
SandiegoSSD 18-Dec-12 15:59pm    
I was trying to use 'C' as a terminating char. I could've use \0 or \n to be more explicit.
OriginalGriff 19-Dec-12 4:25am    
I wouldn't recommend either of them: '\0' has a specific meaning in C - "end of string" and '\n' is a variable character since it depends on the host operating system - it can mean ascii CR, or LF, or CR and LF. I would also not use 'C' as it is too easy to use for other things! :laugh:
If I was in charge of both ends of the communications (and I assume you are) I would use a prefix (such as ascii STX) and a suffix (such as Ascii ETX)
This allows you to ignore partial messages a lot more easily - you wait for an STX, then assemble message until an ETX (and possibly a check code to ensure accurate communications)

But nv3 probably has located the source of your main current problem! :)
SandiegoSSD 19-Dec-12 14:25pm    
Thank you for the tips.
Regarding the strncmp, I thought it would give non zero for identical strings..but now I see that it actually gives 0 for identical ones. Thanks
OriginalGriff 19-Dec-12 14:52pm    
You're welcome!
It does make sense when you think about it - a negative value means less than, a positive value greater than.
C++
*Command_String = RingBuffer_Remove(&Buffer); // is this a screw up?
Command_String++;

Yes, it is. Don't you want to save the pointer to your buffer first? Otherwise, the following
C++
strncmp(Command_String,"ABC",3)

is not seeing the string that you just copied in, but the stuff that's behind it.

So try the following:
C++
char* pBuffer = malloc (BufferCount + 1);
for (int idx = 0; idx < BufferCount; ++idx)
    pBuffer[idx] = RingBuffer_Remove(&Buffer);
pBuffer[BufferCount] = '\0';

// plausibility test
if (strncmp (pBuffer, "ABC", 3))
    usart_printstring (pBuffer);

free (pBuffer);
 
Share this answer
 
Comments
SandiegoSSD 18-Dec-12 17:57pm    
Enlightening! will try tomorrow
SandiegoSSD 19-Dec-12 14:40pm    
it Works now!
also I intended to say
if (strncmp(Command_String,"ABC",3) == 0)
printstring(Command_String);

I didn't realize 0 indicates the two strings are the same.
nv3 19-Dec-12 14:55pm    
I am glad you made it!

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



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900