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.

TM4C123GH6PM: How to write/print the data in UART

Part Number: TM4C123GH6PM
Other Parts Discussed in Thread: SYSBIOS

Hi Experts,

Currently i am trying to write the interrupt count to UART and Print the data based on UART input so i take UART echo and GPIO interrupt example for this but i can't print the interrupt count i have tried lot of method for this but i can't achieve the output so kindly suggest the best way to achieve the output 

i have shared my code for your reference 

i want to print interrupt count when i press the button 

*/ ======== uartecho.c ========
*/

/* XDCtools Header files */
#include <xdc/std.h>
#include <xdc/runtime/System.h>

/* BIOS Header files */
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Task.h>

/* TI-RTOS Header files */
#include <ti/drivers/GPIO.h>
#include <ti/drivers/UART.h>

/* Example/Board Header files */
#include "Board.h"
#include "UARTUtils.h"

#include <stdint.h>

#define TASKSTACKSIZE 768

Task_Struct task0Struct;
Char task0Stack[TASKSTACKSIZE];

int count = 0;

void gpioButtonFxn0(unsigned int index)
{
/* Clear the GPIO interrupt and toggle an LED */
GPIO_toggle(Board_LED0);

if (count++ == 100) {
count = 0;
}

}

void gpioButtonFxn1(unsigned int index)
{
/* Clear the GPIO interrupt and toggle an LED */
GPIO_toggle(Board_LED1);

if (count++ == 100) {
count = 0;
}
}

Void echoFxn(UArg arg0, UArg arg1)
{
char input;
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_FULL;
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) {
UART_read(uart, &input, 1);
UART_write(uart, &input, 1);
}
}

/*
* ======== main ========
*/
int main(void)
{
/* Call board init functions */
Board_initGeneral();
Board_initGPIO();
Board_initUART();

/* Construct BIOS objects */
Task_Params taskParams;

Task_Params_init(&taskParams);
taskParams.stackSize = TASKSTACKSIZE;
taskParams.stack = &task0Stack;
taskParams.instance->name = "echo";
Task_construct(&task0Struct, (Task_FuncPtr)echoFxn, &taskParams, NULL);

/* Turn on user LED */
GPIO_write(Board_LED0, Board_LED_ON);

// UARTUtils_systemInit(0);

/* 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();

/* install Button callback */
GPIO_setCallback(Board_BUTTON0, gpioButtonFxn0);

/* Enable interrupts */
GPIO_enableInt(Board_BUTTON0);

/*
* If more than one input pin is available for your device, interrupts
* will be enabled on Board_BUTTON1.
*/
if (Board_BUTTON0 != Board_BUTTON1) {
/* install Button callback */
GPIO_setCallback(Board_BUTTON1, gpioButtonFxn1);
GPIO_enableInt(Board_BUTTON1);
}

/* Start BIOS */
BIOS_start();

return (0);
}

regards 

surya

  • You did not really describe what you tried, but I understand that you would have difficulties. The problem is that you are trying to use one peripheral (UART) with two asynchronous tasks (uart receive and pushbutton). The TI-RTOS UART driver tries to prevent you from doing so. You can imagine that it would be possible for a key to be pressed at the same time as a button is pressed. The printed count could be corrupted by the echoed character. 

    Here is a proposed solution. I put all of the UART functions in a single task. If a button is pushed, a volatile static flag is set in the button's callback routine. The uart task (printFxn) polls for the flag to be set. If set, it prints the count. Then it checks for a received character. If one is received it will print it.  There is a complication that if using the blocked mode to read a character, the task stops executing and cannot check the button flag. Therefore the UART_read() function is configure to use a callback routine. (The callback routine doesn't do anything because the character buffer itself is polled to see if a new character has arrived.)

    I exported my example project to a .zip file and attached it for your review.

    customer_EK_TM4C123GXL_TI.zip

  • Hi 

    Thanks for the example and sorry for incomplete description, i am trying to create a general serial function, like, uart call back function read the data simultaneously when serial data is available and i just pass the read data to function as a arguments to check which request  is received then i just called the the function which action is required

    i have faced some count and data losses in you shared example, the serial log shown below for your reference 

    Count = 14

    Count = 15
    UART DATA LOSS TEST
    AT DTA OSS TST
    UART DATA LOSS TEST
    UARTDATA OSSTES
    UART DATA LOSS TEST
    ATDATA LOSSTES
    UART DATA LOSS TEST
    ARTDATA LOS TST

    Count = 16

    Count = 17

    i can't understand what is the use of uart read and write callback in shared example kindly let me know how to use those callbacks 

    my requirement needs any extra task creation kindly share the task details with how to create task semaphore, mutex to complete my need 

    how to create this same actions for other uart's because tiva have a 4 uarts

    regards

    surya

  • I think you are trying to use the TI-RTOS UART driver in ways it was not designed to be used. I suggest you implement HWI functions for each of the four UARTS and handle the TX and RX interrupts directly. 

  • Hi Bob,

    thanks for your suggestion,

    i try to another method for Uart Lagging example 

    #include <file.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdbool.h>

    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/utils/Load.h>
    #include <ti/sysbios/knl/Task.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/UART.h>

    /* Example/Board Header files */
    #include "Board.h"
    #include "UARTUtils.h"
    #include "USBCDCD_LoggerIdle.h"

    #define TASKSTACKSIZE 1536

    Task_Struct task0Struct;
    Char task0Stack[TASKSTACKSIZE];

    int count2 = 0;
    //volatile char outputChar = 0; // char to print
    char string[80];
    /*
    * ======== consoleFxn ========
    * Task for this function is created statically. See the project's .cfg file.
    */
    Void consoleFxn(UArg arg0, UArg arg1)
    {
    unsigned int sleepDur;
    unsigned int count;
    unsigned int cpuLoad;
    char input[128];

    count = 1;

    /* printf goes to the UART com port */
    printf("\f======== Welcome to the Console ========\n");
    printf("Enter a command followed by return.\n"
    "Type help for a list of commands.\n\n");

    printf("%d %% ", count++);
    fflush(stdout);

    /* Loop forever receiving commands */
    while(true) {
    /* Get the user's input */
    scanf("%s", input);
    /* Flush the remaining characters from stdin since they are not used. */
    fflush(stdin);

    if (!strcmp(input, "load")) {
    /* Print the CPU load */
    cpuLoad = Load_getCPULoad();
    printf("CPU Load: %d\n", cpuLoad);
    }
    else if (!strcmp(input, "sleep")) {
    /* Put the task to sleep for X ms. */
    printf("Enter a duration (ms): ");
    fflush(stdout);
    scanf("%d", &sleepDur);
    fflush(stdin);
    Task_sleep(sleepDur);
    }
    else if (!strcmp(input, "exit")) {
    /* Exit the console task */
    printf("Are you sure you want to exit the console? Y/N: ");
    fflush(stdout);
    scanf("%s", input);
    fflush(stdin);
    if ((input[0] == 'y' || input[0] == 'Y') && input[1] == 0x00) {
    printf("Exiting console, goodbye.\n");
    Task_exit();
    }
    }
    else {
    /* Print a list of valid commands. */
    printf("Valid commands:\n"
    "- load: Get the CPU and task load.\n"
    "- sleep: Put the console task to sleep.\n"
    "- exit: Exit the console task.\n");
    }

    printf("%d %% ", count++);
    fflush(stdout);
    }
    }

    void gpioButtonFxn0(unsigned int index)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED0);

    if (count2++ == 100)
    {
    count2 = 0;
    }
    // printf("Count=%d", count2);
    //flag = true;
    System_printf("KARIoT\n");
    sprintf(string, "\n\rCount = %d\n\r\0", count2);
    System_printf(string);
    }

    void gpioButtonFxn1(unsigned int index)
    {
    /* Clear the GPIO interrupt and toggle an LED */
    GPIO_toggle(Board_LED1);

    if (count2++ == 100)
    {
    count2 = 0;
    }
    System_printf("KARIoT\n");

    // printf("Count=%d", count2);
    // flag = true;
    }

    /*
    * ======== main ========
    */
    int main(void)
    {
    /* Call board init functions. */
    Board_initGeneral();
    Board_initGPIO();
    Board_initUART();
    Board_initUSB(Board_USBDEVICE);

    /* Construct BIOS objects */
    Task_Params taskParams;

    Task_Params_init(&taskParams);
    taskParams.stackSize = TASKSTACKSIZE;
    taskParams.stack = &task0Stack;
    Task_construct(&task0Struct, (Task_FuncPtr)consoleFxn, &taskParams, NULL);

    /* Turn on user LED */
    GPIO_write(Board_LED0, Board_LED_ON);

    /*
    * Add the UART device to the system.
    * All UART peripherals must be setup and the module must be initialized
    * before opening. This is done by Board_initUART(). The functions used
    * are implemented in UARTUtils.c.
    */
    add_device("UART", _MSA, UARTUtils_deviceopen,
    UARTUtils_deviceclose, UARTUtils_deviceread,
    UARTUtils_devicewrite, UARTUtils_devicelseek,
    UARTUtils_deviceunlink, UARTUtils_devicerename);

    /* Open UART0 for writing to stdout and set buffer */
    freopen("UART:0", "w", stdout);
    setvbuf(stdout, NULL, _IOLBF, 128);

    /* Open UART0 for reading from stdin and set buffer */
    freopen("UART:0", "r", stdin);
    setvbuf(stdin, NULL, _IOLBF, 128);

    /*
    * Initialize UART port 0 used by SysCallback. This and other SysCallback
    * UART functions are implemented in UARTUtils.c. Calls to System_printf
    * will go to UART0, the same as printf.
    */
    UARTUtils_systemInit(0);

    System_printf("Starting the UART Console example\n");

    System_printf("\f======== Welcome to KARIOT ========\n");

    /* Initialize the USB CDC device for logging transport */
    USBCDCD_init();

    GPIO_setCallback(Board_BUTTON0, gpioButtonFxn0);

    /* Enable interrupts */
    GPIO_enableInt(Board_BUTTON0);

    /*
    * If more than one input pin is available for your device, interrupts
    * will be enabled on Board_BUTTON1.
    */
    if (Board_BUTTON0 != Board_BUTTON1)
    {
    /* install Button callback */
    GPIO_setCallback(Board_BUTTON1, gpioButtonFxn1);
    GPIO_enableInt(Board_BUTTON1);
    }

    /* Start BIOS */
    BIOS_start();

    return (0);
    }

    Error:

    ti.sysbios.hal.Hwi: line 174: E_stackOverflow: ISR stack overflow.
    xdc.runtime.Error.raise: terminating execution

    how to resolve the issue 

    Surya

  • You may need to increase the size of the interrupt stack:

    Here is a project that creates a HWI for UART0 and uses a semaphore to allow it to be used by different tasks:

    TM4C123TiRtosUartHwi.zip

  • Hi Bob,

    i try this code but i have come to Source File Missing Error Hwi.h,

    Error console bellow,

    Code Header ,

    /* XDCtools Header files */
    #include <xdc/std.h>

    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>

    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    //#include <Error.h>
    //#include <Hwi.h>
    //#include <System.h>
    #include <xdc/runtime/Error.h>
    #include <xdc/runtime/System.h>
    //#include <xdc/runtime/Hwi.h>
    //#include <ti/sysbios/interfaces/IHwi.h>
    //#include "package/internal/Hwi.xdc.h"

    #include <stdint.h>
    #include <stdbool.h>
    #include <string.h>
    #include "inc/hw_memmap.h"
    #include "inc/hw_types.h"
    #include "driverlib/gpio.h"
    #include "driverlib/pin_map.h"
    #include "driverlib/rom.h"
    #include "driverlib/rom_map.h"
    #include "driverlib/sysctl.h"
    #include <ti/sysbios/knl/Semaphore.h>
    #include "Uart0Hwi.h"

    /* Board Header file */
    #include "Board.h"

    >> Compilation failure
    subdir_rules.mk:9: recipe for target 'empty.obj' failed
    "../empty.c", line 100: error #20: identifier "Hwi_Params" is undefined
    "../empty.c", line 101: error #20: identifier "Hwi_Handle" is undefined
    "../empty.c", line 142: warning #225-D: function "Hwi_Params_init" declared implicitly
    "../empty.c", line 145: warning #225-D: function "Hwi_create" declared implicitly
    2 errors detected in the compilation of "../empty.c".
    gmake: *** [empty.obj] Error 1
    gmake: Target 'all' not remade because of errors.

    **** Build Finished ****

    Kindly check and ho to solve this issue , how to Config Hwi Interrupt in new project ?

    Thanks

    Surya

  • Did you use the "File" -> "Import" option of CCS to add the project to your workspace? If so, it should have included the path search options to find the header files. Check that your "ARM Compiler" "Include Options" includes "${COM_TI_RTSC_TIRTOSTIVAC_INSTALL_DIR}\products\bios_6_45_01_29\packages\ti\sysbios\hal"

    Here is what the include option page should look like if you imported the project:

  • hi bob,

    how to resolve the stack size error and stack management , i try to implement the hwi.h  but same error will be come , same hwi interrupt and urat interrupt issue , so kindly suggest the working process 

    thanks 

    surya

  • My post of April 23rd shows an image of how to increase the stack size of a TI-RTOS project using XGCONF.  Right click on the .cfg file in Code Composer's "Project Explorer" window and select "Open with" -> "XGCONF".

    Alternatively, you can open the .cfg file with an ordinary text editor and search for "program.stack" and edit the value.