Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C Microcontroller GCC
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.
 
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
static inline void RingBuffer_Insert(RingBuff_t* const Buffer,
                                             const uint8_t Data){...}
 
void usart_putchar(char data) {
    // Wait for empty transmit buffer
    while ( !(UCSR0A & (1<<UDRE0)) );
    // Start transmission
    UDR0 = data;
}
 
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
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
 

...
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 18-Dec-12 9:45am
Edited 18-Dec-12 12:00pm
v4
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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"?
 
            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:
            if (strncmp(Command_String,"ABC",3) == 0)
               {
               usart_printstring(Command_String);
               }
  Permalink  
Comments
SandiegoSSD at 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 at 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 at 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 at 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.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

     *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
    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:
    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);
  Permalink  
Comments
SandiegoSSD at 18-Dec-12 17:57pm
   
Enlightening! will try tomorrow
SandiegoSSD at 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 at 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)

  Print Answers RSS
0 OriginalGriff 350
1 Jochen Arndt 150
2 Richard MacCutchan 135
3 PIEBALDconsult 110
4 Sergey Alexandrovich Kryukov 104
0 OriginalGriff 6,055
1 DamithSL 4,621
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,500
4 Sergey Alexandrovich Kryukov 3,294


Advertise | Privacy | Mobile
Web04 | 2.8.141220.1 | Last Updated 18 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