This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Problem in receiving complete string via UART - CC3200

Environment Info:

OS: Windows 7

SDK: 0.5.2

LP: Rev 3.2

RTOS: TI RTOS for simplelink

Problem:


UART-0 => 8N1 at 9600 baudrate, receive interrupt enable


I am not able to receive entire string sent via UART. I am using non-blocking functions for sending and receiving chars. If I send big string containing 15 chars it will get broken and receives only some of the characters. It will receive other characters when I send another string so every time string gets mixed with each other. I am attaching my C  file of project. I have created empty TI RTOS project and modify content of its main .c file.

3618.6036.uart.c


Thank you,

Niral

  • Hi Niral,

    Why aren't you using the UART module in TI-RTOS. Can you take a look at the UART Echo example in TI Resource Explorer. It calls Board_initUART(). Then it opens the UART and reads/writes to it. The UART module is RTOS aware so you don't have to worry about thread-safety.

    Todd

  • Hello Todd,

    I have started with UART Echo example but I did face issue with sending string with UART_write.

    In my application I am receiving string from TCP socket, size of string is not fixed however max is 50 bytes so I have static fixed size array in my application. After receiving string from socket I have to send it to other component via UART. So what I was doing was...

    //! Fixed size array for storing string..
    char rxBuffer[50];
    
    //! After receiving string from socket..
    UART_write(uart, &rxBuffer, sizeof(rxBuffer));
    

    What I had observed was UART module keep on sending upto 50 bytes even if size of actual string is less than 50.

    So what I want is UART must send data till its encounters with NULL while UART_write does not provide this functionality. Is there any other way with UART module of TI RTOS which provide solution of this problem or else how can I get the same functionality using built in UART module of TI RTOS..??

  • Niral,

    You need to use strlen(rxBuffer) instead of sizeof(rxBuffer) in the UART_write function. sizeof(rxBuffer) will allows be 50. strlen(rxBuffer) will be the length of the null terminated string in rxBuffer. Use strlen(rxBuffer) + 1 if you want to send the '\0' character also.

    Todd

  • Todd,

    I did with strlen() as well but didn't work. I can receive string correctly but getting some random value from UART_write(). I have use read return mode UART_RETURN_NEWLINE. Here I am posting screen capture of entire scenario.

    Buffer value after UART_read(uart, &input, 50)

    Serial Terminal

  • Niral,

    UART_read() seems to looks fine. Was the buffer you're using to send data initialized with '\0'?

    It looks like you're just sending binary non-printable ASCII.

    Do you have a .c file that uses the TI-RTOS UART driver?

  • Hello Tom,

    Previously buffer was not initialized, after initializing buffer with '\0' I can receive string however some issues are still existed. Look at the following screen capture..


    I have done some experiments while debugging. As you can see in screen capture I have received 1st 3 string completely. During this I have set break point at UART_write().

    Later I disabled this break point and what I have observed is illustrated in boxes with explanation. The final conclusion is that If target is running completely (without any break point) UART_write() does not function well, It modifies sequence of characters and some characters may get loss while transmitting however UART_read() function properly.

    Code:

    /*
     *  ======== uartecho.c ========
     */
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    #include <stdint.h>
    #include <string.h>
    
    /*
     *  ======== echoFxn ========
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void echoFxn(UArg arg0, UArg arg1)
    {
        char input[50];
        UART_Handle uart;
        UART_Params uartParams;
        const char echoPrompt[] = "\fEchoing characters:\r\n";
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        uartParams.writeDataMode = UART_DATA_BINARY;
        uartParams.readDataMode = UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_NEWLINE;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 9600;
        uart = UART_open(Board_UART0, &uartParams);
    
        if (uart == NULL) {
            System_abort("Error opening the UART");
        }
    
        UART_write(uart, echoPrompt, sizeof(echoPrompt));
    
        /* Loop forever echoing */
        while (1) {
        	memset(input, '\0', 50);
            UART_read(uart, &input, 50);
            UART_write(uart, &input, strlen(input));
            Task_sleep(1000);
        }
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initUART();
    
        /* Turn on user LED */
        GPIO_write(Board_LED0, Board_LED_ON);
    
        /* This example has logging and many other debug capabilities enabled */
        System_printf("This example does not attempt to minimize code or data "
                      "footprint\n");
        System_flush();
    
        System_printf("Starting the UART Echo example\nSystem provider is set to "
                      "SysMin. Halt the target to view any SysMin contents in "
                      "ROV.\n");
        /* SysMin will only print to the console when you call flush or exit */
        System_flush();
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    
  • Hii ,

    I was also facing same issue while receiving data from uart  and some bytes are misplaced ,still i could not able to know the reason,i was analyzed uart driver also but i could not find any mistake .could you please let me know if u have any idea about this issue.

    I was using TI-RTOS version:: ti_rtos_msp430_2_01_00_03 

  • Niral,

    The UART driver doesn't does not store data until you call UART_read(). When the you return from the UART_read(), any incoming data will be put onto the FIFO until it has filled up at what it drops all of the remaining data until your application calls UART_read() again.

    By calling a Task_sleep() in the while(1) loop, you are guaranteeing a 1 second (1000 ticks) window where the UART will drop incoming data. We have a plans to add a FIFO overrun detection and some sort of double-buffering scheme in a future release of TI-RTOS.

    Using the UART driver with UART_RETURN_NEWLINE causes UART_read() to return when the newline character was returned, when the buffer limit was reached, or if the readTimeout value has reached its limit. Try specifying a readTimeout as you open the UART driver and remove the Task_sleep().

  • Tom,

    As I mentioned earlier problem is not with UART_read(). UART_read() read perfectly without dropping any character. The problem is with UART_write(). I think this is a bug as I am not one who is facing the issue.

    I have also tried removing Task_sleep() but did not make any change.

    What can be solution now? I have to send string via UART. Because of this reason I was not using UART module of TI RTOS.

    Regards,

    Niral

  • Issue still exists. Its driving me crazy...!!!

  • Niral,

    Sorry this thread fell through the cracks. The engineer working on this is out of the office until Tues. I'll try to reproduce the issue. Which version of TI-RTOS are you using?

    Todd

  • ToddMullanix,

    I really appreciate it. I'm using TI RTOS v2.00.02.36

    Regards,

    Niral

  • Niral,

    Sorry for the delayed response. I need to know what version of TI-RTOS are you using because I'm not able to reproduce any problems with UART_write() on my end. I've used this code snippet to send out various lengths of data. Can you verify if this works for you? This should help isolate your problem to either UART_read() or UART_write().

    const char test[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789!@#$%^&*()-=_+\|[]{};':\",./<>?`~";
    uint32_t i; while(1) { for (i= 0; i< sizeof(test); i++) { UART_write(uart, test, i); UART_write(uart, "\r\n", 2); Task_sleep(100); } Task_sleep(2000); }

  • Niral,

    sorry, I missed the fact you posted the version number. I ran the test again but it didn't change my results for UART_write().

    I've gotten some good echo results with this code snippet, leading me to believe it's an issue with the receive buffer contents.

    #define LEN 50
    char input[LEN+1];
    
    while(1) {
        	readCount = UART_read(uart, &input, LEN);
        	input[readCount] = '\0';
    	UART_write(uart, &input, strlen(input));
    }
    

  • Tom,

    I tried what you told but dint work as well. As you told you believe that it's an issue with receive buffer I flushed content of receive buffer to console and it is absolutely fine.

    Code:

        #define LEN 50
        char input[LEN+1];
    
        while (1) {
            iRet = UART_read(uart, &input, 50);
            input[iRet] = '\0';
    
            System_printf(input);
            System_flush();
    
            UART_write(uart, &input, strlen(input));
        }

    Sent data from terminal: *11*2*123123546*123154*

    Output of Console:

    Received at Terminal:

    Regards,

    Niral

  • Niral,

    can you post a CCS or IAR project that reproduces this? I can print the entire string without losing any characters.

  • Tom,

    Here's the CCS project. I am modifying uartecho example of TI RTOS..

    3034.uartecho_CC3200.zip

  • Niral,

    I just tried the CCS project you sent me. I understand the confusion here now. I've been terminating my strings with a '\n', not a '\0'.

    In short, the UART driver doesn't consider a NULL as a terminator of any sort. The UART_RETURN_NEWLINE option will return on a '\n' only, so with a '\0' in your string, it'll just consider it as normal data. 

    Can you use a '\n' instead of a '\0' as your terminator?

    I was able to see lost data when I used a '\0' terminated strings and with System_printf()/System_flush() calls. I've replaced the strlen() with the return value from UART_read() and removed System_printf() and System_flush(). After those changes I didn't see any data actually lost, just placed into the buffer into the next UART_read().

        /* Loop forever echoing */
        while (1) {
            iRet = UART_read(uart, &input, 50);
            UART_write(uart, &input, iRet);
        }

    Again, I've been only getting all the data only because the task actually performs UART_read()'s at a short enough interval where the FIFO hasn't completely filled. (On the MSP430, there is no FIFO...). In hindsight, we should have designed this driver a bit differently, but we're currently looking into options to fix this.

  • Tim,

    Issue is resolved now. Serial terminal which I was using is not capable of sending new line character. I have develop my own serial terminal software and tested entire code using it and its working fine now i.e I can receive complete string. Thanks a lot for your inputs.

    Regards,
    Niral