0
votes

I am trying to modify a function to be more sensible for my purposes;

int getc0 (void)
{
    while ( (U0LSR & 0x01) == 0 ); //Wait for character
    return U0RBR;
}

The above code causes the function to hang until a character is received on serial port 0 and then returns it. I was calling it using a while loop like so;

while((str = getc0())!='\r'){
    strcat(&route_buffer,&str);
}

So now I have it waiting until a return carriage is received over the serial port and each character before this is copied into a buffer. Now my problem, I am having some issues with reading data in at the moment and I cannot determine where the problem lies, either way it is not recognising return carriages or newlines correctly, but it is picking up on some output! I know this as I have it saving everything to a file once it completes, but to do this I have to have a i!=5 on the while loop and just read in 5 characters. If I do it to 20 it hangs again and appears to not be reading anything else (Even though I am sending data over uart)

Is there a way I can modify it to read for X amount of time and then continue with the rest of the function?

Edit:

char route_data[512], route_buffer[200];

Edit 2:

char *str;

Ok, here is a function I wrote to read in user input;

char* readInput(void){

    userinput = 0;
    str = 0;

    while((str=getc0())!='\r'){
        strcat(&userinput,&str);

    }
    return &userinput;

}

and it is called like so;

strcat(config.nodeid,readInput());

It is called a lot but that is one example of how i call it. I then output this to a file and it works 100% of the time.

It would probably help to explain the whole problem; I have an ARM board with a wireless module attached to the serial port (RX and TX). The readInput function above is used to read input from a user who has telnet'ed into the wireless module and enables the ARM board to read all input from the user. What I am trying to achieve now is to read the input from the wireless module after executing a command on it. Using a printf statement I can execute commands by putting the command into the statement. What I need to acomplish is to read in the output from the wireless module, this is where I am having difficulties. I am getting some output but it is very limited and not what expected, but it is clearly something from the module.

1
Please show the definition for route_buffer.Throwback1986
How is str defined? How is route_buffer defined? str should be an int, to be compatible with the function getc0() and you can't pass an int to strcat() like that!pmg
I have edited the above to include the requested information. Give me five minutes and I will expand on why I have done the above and what I have done to verify it.Draineh

1 Answers

3
votes

str is not a nul terminated string passing its address to strcat() will concatenate an indeterminate amount of data to route_buffer.

Using strcat() is a bad idea in any case for a number of reasons, and your usage is especially ill-advised. You have no protection against buffer overrun, and strcat() must needlessly redetermine the length of the string in route_buffer every time it is called.

A marginally better solution would be:

int index = strlen(route_buffer) ;
int ch ;
while( index < sizeof(route_buffer) - 1 && (ch = getc0()) != '\r')
{
    route_buffer[index] = ch ;
    index++ ;
}
route_buffer[index] = 0 ;

I have made a number of assumptions from your original code here, such as route_buffer is in fact a nul terminated string. Those are your design decisions; they may or may not be correct or good ones.

A better solution to your problem would be to put the received characters in a ring buffer from a UART Rx interrupt handler, then have read functions take their data asynchronously from the buffer. You could then easily implement blocking, baulking and timeout access if necessary. You could even have the ISR count the number of newlines buffered so you would know in advance how many lines were available in the buffer. The buffering would also allow your code to not have to worry about servicing the UART in time to prevent a character overrun and data loss.

If you want timeout behaviour, both the while loop in getc0() and the line input loop must additionally test some timer source.