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.

TI RTOS UART + SD

Other Parts Discussed in Thread: EK-TM4C123GXL

I am looking at a new project which will log GPS data from a UART to an SD card. I have looked at FatSD as a starting point for the EK-TM4C123GXL which seems to function  fine. I am fairly new to RTOS in general.

The issue now is to add UART Software to the RTOS  to fill some 512 byte PING PONG buffers for writing to the SD card.

The questions I have are many but first off is, can I fill the receive data from the UART while writing to the SD card or will this interfere with the writing to the file?

If this is a problem is DMA the answer?

Should the SDFatFS be run as a SWI so that the data from the UART which can't be missed is a higher priority SWI?

Is there a less simple example than the UART Echo that I can refer to?

Regards,

Lee.

  • What version of TI-RTOS are you using?
  • Hi Todd,

    I am using TI-RTOS 2.14. I noticed that there is a DMA UART setting that I can set to 1 but I'm unsure how to use the DMA. Can it be configured for Ping Pong for example.

    Do you have to configure it as you would without RTOS (The udma_demo.c is a good example of this) and can it post/flag to indicate the assigned buffers are full and hence ready to be written to the SD card?

    Regards,

    Lee.

  • Reading from the UART and writing/reading to the SDSPI module at the same time fine. The UART is buffered (via ring buffer) in 2.14, so you should not have to worry about a Ping-Pong (you might want to increase the size though...default is 32 bytes). Please note that SDSPI driver is polling, so it should have a relatively low priority (to avoid impacting other threads).

    Todd

  • Thanks Todd,

    I could also use the UARTDMA if defined in EK_TM4C123GXL.c and seems to have its object and attributes at around line 528. I am expecting 1k to 10k bytes per second depending on the number of satellites so it would be good to use a Ping-Pong to write to the SD while filling the other buffer however the  <ti/drivers/uart/UARTTivaDMA.h> appears to be Primary only. Probably not good form to modify the code here.

     My concern is that if there is a delay in the write to the SD due to SD card activity and a write takes longer than expected I will miss some of the UART data .

    Is the sector write to the SD card allowed to be interrupted?

    Regards,

    Lee.

  • If you have the task that is writing/reading to the SDSPI module at a low task priority, the higher priority task will preempt it when they have activity.

    You can use the UARTTiva and make the ringbuffer size in the hwAttrs struct large enough to do the buffering.

    Todd
  • I have 2 tasks. 1 for reading the UART and one for writing to the SD card. I am having issues with data being not written correctly. The basic idea is that I have 2 buffers. 1 will be being written to while the other is writing or that's the intention. The writing task pends on the reading task having filled its buffer. The log files seem to indicate the order is correct so I'm unsure where my problem lies, possibly with  how I'm using the RTOS as I noticed multiple posts and pends while the file is being written sometimes. Attached is the code and some images of the ROV/UIA

    Any suggestions with RTOS and how to implement what I'm trying to do would be helpful.

    /*
     *  ======== fatsd.c ========
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/log.h>
    
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDSPI.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/uart/UARTTiva.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    
    /* Buffer size used to read from UART and write to SD card*/
    #define BUFFER_SIZE		512
    
    
    /* String conversion macro */
    
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    const char  outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    
    char dataBufferA[BUFFER_SIZE];
    char dataBufferB[BUFFER_SIZE];
    
    uint16_t bufferFlag = 'A';
    uint8_t closeFlag = 0;
    uint16_t bytesRead = 0;
    /*
     *  ======== gpioButtonFxn0 ========
     *  Callback function for the GPIO interrupt on Board_BUTTON0.
     */
    void gpioButtonFxn0(void)
    {
        /* Clear the GPIO interrupt and toggle an LED */
        GPIO_toggle(Board_LED0);
        closeFlag = 1;
    
    }
    /*
     *  ======== echoFxn ========
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void readUARTFxn(UArg arg0, UArg arg1)
    {
        //char input;
        UART_Handle uart;
        UART_Params uartParams;
        const char Prompt[] = "\fUART Open:\r\n";
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        //uartParams.readMode = UART_MODE_BLOCKING;
        uartParams.writeDataMode =  UART_DATA_BINARY;
        uartParams.readDataMode =  UART_DATA_BINARY;
        uartParams.readReturnMode = UART_RETURN_FULL;
        uartParams.readEcho = UART_ECHO_OFF;
        uartParams.baudRate = 115200;
        uart = UART_open(Board_UART0, &uartParams);
    
        if (uart == NULL) {
            System_abort("Error opening the UART");
        }
    
        UART_write(uart, Prompt, sizeof(Prompt));
    
        while (1) {
        	if(bufferFlag == 'A')
        	{
    
        		bytesRead = UART_read(uart,dataBufferA, sizeof(dataBufferA));
        		Log_info1("Bytes read to dataBufferA = [%d]",bytesRead);
        		bufferFlag = 'B';
        		Semaphore_post (sem_write); // Post to writeSDfxn to write BufferA to SD card
    
        	}
        	else if (bufferFlag == 'B')
        	{
    
        		bytesRead = UART_read(uart,dataBufferB, sizeof(dataBufferB));
        		Log_info1("Bytes read to dataBufferB = [%d]",bytesRead);
        		bufferFlag = 'A';
        		Semaphore_post (sem_write);// Post to writeSDfxn to write BufferB to SD card
        	}
    
         }
    }
    
    /*
     *  ======== writeSDFxn ========
     *  Task to perform a write to a file on a SD card
     *
     *  Task tries to open an existing file outputfile[]. If the file doesn't
     *  exist, create one and write some known content into it.
    
     *
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void writeSDfxn(UArg arg0, UArg arg1)
    {
        SDSPI_Handle sdspiHandle;
        SDSPI_Params sdspiParams;
    
        /* Variables for the CIO functions */
        FILE *src;
    
        uint8_t fileClose = 1;
    
        /* Mount and register the SD Card */
        SDSPI_Params_init(&sdspiParams);
        sdspiHandle = SDSPI_open(Board_SDSPI0, DRIVE_NUM, &sdspiParams);
        if (sdspiHandle == NULL) {
            System_abort("Error starting the SD card\n");
        }
        else {
            System_printf("Drive %u is mounted\n", DRIVE_NUM);
            System_flush();
        }
    
        /* Try to open the source file */
        src = fopen(outputfile, "r");
        if (!src) {
            System_printf("Creating a new file \"%s\"...\n", outputfile);
            System_flush();
    
            /* Open file for both reading and writing */
            src = fopen(outputfile, "a");
            if (!src) {
                System_printf("Error: \"%s\" could not be created.\n"
                              "Please check the Getting Started Guide "
                              "if additional jumpers are necessary.\n",
    						  outputfile
                             );
                System_abort("Aborting...\n");
            }
    
    
            while (!closeFlag){ //GPIO Button Function
            	Semaphore_pend (sem_write,BIOS_WAIT_FOREVER);
            	if(bufferFlag == 'B')
            	{
            		fwrite(dataBufferA, 1, strlen(dataBufferA), src);
            		fflush(src);
            		Log_info1("A Bytes written to file",bufferFlag);
            	}
            	else if (bufferFlag == 'A')
            	{
            		fwrite(dataBufferB, 1, strlen(dataBufferB), src);
            		fflush(src);
            		Log_info1("B Bytes written to file",bufferFlag);
    
            	}
            }
    
            /*Close the file*/
    		fileClose = fclose(src);
            System_printf("File Closed = %d\n",fileClose);
            /* Stopping the SDCard */
    		SDSPI_close(sdspiHandle);
    		System_printf("Drive %u unmounted\n", DRIVE_NUM);
    		BIOS_exit(0);
    
        }
    
    
    }
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
    
    	int i = 0;
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initSDSPI();
        Board_initUART();
    
        /* Turn on user LED */
        GPIO_write(Board_LED0, Board_LED_ON);
    
        /* install Button callback - used to close the filein the write function*/
        GPIO_setCallback(Board_BUTTON0, gpioButtonFxn0);
    
        /* Enable interrupts */
        GPIO_enableInt(Board_BUTTON0);
    
    
        for (i=0;i<BUFFER_SIZE;i++)
        {
        	dataBufferA[i]= '0';
        	dataBufferB[i]= '0';
        }
    
        System_printf("Starting the FatSD example\n");
        System_flush();
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }


    *
     *  ======== fatsd.cfg ========
     */
    
    /* ================ General configuration ================ */
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var FatFS = xdc.useModule('ti.sysbios.fatfs.FatFS');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    
    /*
     *  Program.stack is ignored with IAR. Use the project options in
     *  IAR Embedded Workbench to alter the system stack size.
     */
    if (!Program.build.target.$name.match(/iar/)) {
        /*
         *  Reducing the system stack size (used by ISRs and Swis) to reduce
         *  RAM usage.
         */
    Program.stack = 1024;
    }
    
    /*
     * Comment this line to allow module names to be loaded on the target.
     * The module name strings are placed in the .const section. Setting this
     * parameter to false will save space in the .const section.  Error and
     * Assert messages will contain an "unknown module" prefix instead
     * of the actual module name.
     */
    Defaults.common$.namedModule = false;
    
    /*
     * Minimize exit handler array in System.  The System module includes
     * an array of functions that are registered with System_atexit() to be
     * called by System_exit().
     */
    System.maxAtexitHandlers = 2;
    
    /*
     * Comment this line to allow Error, Assert, and Log strings to be
     * loaded on the target.  These strings are placed in the .const section.
     * Setting this parameter to false will save space in the .const section.
     * Error, Assert and Log message will print raw ids and args instead of
     * a formatted message.
     */
    //Text.isLoaded = false;
    
    /* ================ System configuration ================ */
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    System.SupportProxy = SysMin;
    
    /* Enable Semihosting for GNU targets to print to CCS console */
    if (Program.build.target.$name.match(/gnu/)) {
        var SemiHost = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');
    }
    
    /* ================ BIOS configuration ================ */
    /*
     * Disable unused BIOS features to minimize footprint.
     */
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.logsEnabled = true;
    BIOS.assertsEnabled = true;
    
    /* Reduce the heap size */
    BIOS.heapSize = 4096;
    
    /* Runtime stack checking is performed */
    Task.checkStackFlag = true;
    Hwi.checkStackFlag = true;
    
    /* Reduce the number of task priorities */
    Task.numPriorities = 4;
    
    /* ================ Task configuration ================ */
    var task0Params = new Task.Params();
    task0Params.instance.name = "writeSDTask";
    task0Params.stackSize = 0x400;
    task0Params.priority = 1;
    Program.global.writeSDTask = Task.create("&writeSDfxn", task0Params);
    
    /* ================ Driver configuration ================ */
    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');
    TIRTOS.useGPIO = true;
    TIRTOS.useSDSPI = true;
    var task1Params = new Task.Params();
    task1Params.instance.name = "readUartTask";
    task1Params.priority = 3;
    Program.global.readUartTask = Task.create("&readUARTFxn", task1Params);
    TIRTOS.useUART = true;
    TIRTOS.libType = TIRTOS.LibType_Instrumented;
    var semaphore0Params = new Semaphore.Params();
    semaphore0Params.instance.name = "sem_write";
    semaphore0Params.mode = Semaphore.Mode_BINARY;
    Program.global.sem_write = Semaphore.create(null, semaphore0Params);
    LoggingSetup.sysbiosSemaphoreLogging = true;
    LoggingSetup.loadLoggerSize = 1024;
    LoggingSetup.sysbiosLoggerSize = 4096;
    LoggingSetup.mainLoggerSize = 8192;
    LoggingSetup.loggerType = LoggingSetup.LoggerType_STOPMODE;
    LoggingSetup.mainLoggingRuntimeControl = false;
    

  • Is it always not being written correctly or just occasionally? Have you confirmed that the reading of the UART is always correct?

    You probably want to make the semaphore counting instead of binary. If you had to UART_reads succeed (and do two Semaphore_posts) quickly, you might drop one of the writes. Also, bad things happen if you do three reads quickly.

    If I was writing this, I'd have two Queue objects to maintain a linked list of "free buffers" and "full buffers". I'd have two semaphores also. Prime the "free buffers" queue with buffer A and B (see below for more details on this). The "free" semaphore would have an initial count of 2. The "full" semaphore's count would be initialized to 0. The "full" queue would be empty. The UART read task would do a Semaphore_pend on the "free" semaphore, if successful, Queue_get from the "free queue", use the buffer, put the buffer onto the "full queue" via Queue_put, and then post the "full" semaphore (and then repeat). The writing task would do a Semaphore_pend on the "full" semaphore, when successful, Queue_get from the "full" queue, write the buffer, and then put the buffer back on the "free" queue and post the "free" semaphore.

    Note: you don't actually put the buffer on the queue. You have something like this that goes onto the queue. Note you have two of these and have the first buf point to buffer A and then other to buffer B.

    typedef struct MyBuffer {
       Queue_Elem elem; //must be the first field to be able to put onto a Queue
       void *buf;
       int bufSize;
    } MyBuffer;


    Note: this scales well also. Now you can easily have 3, 4, or N buffers just be changing the priming and the initial count for the free semaphore. The code stays nice and compact. The Queue_put and get operations are atomic.

    Todd

  • Hi,

    I have arranged the code as you suggested. The first 2 uart reads seem ok but then I'm getting  a lot of nulls amid some characters. I seem to have lost the ability to use the log_info as if the file wasn't included but can't see anything wrong. Error is "function "log_info1" declared implicitly" although I haven't changed the logging setup apart from adding the semaphores.

    Eventually the uart ring buffer overflows continuously.

    /*
     *  ======== fatsd.c ========
     */
    
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <stdbool.h>
    
    /* XDCtools Header files */
    #include <xdc/std.h>
    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/log.h>
    
    /* BIOS Header files */
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/sysbios/knl/Queue.h>
    
    /* TI-RTOS Header files */
    #include <ti/drivers/GPIO.h>
    #include <ti/drivers/SDSPI.h>
    #include <ti/drivers/UART.h>
    #include <ti/drivers/uart/UARTTiva.h>
    
    /* Example/Board Header files */
    #include "Board.h"
    
    
    /* Buffer size used to read from UART and write to SD card*/
    #define BUFFER_SIZE		512
    #define NUM_OF_BUFFFERS 2
    
    
    /* String conversion macro */
    
    #define STR_(n)             #n
    #define STR(n)              STR_(n)
    
    
    /* Drive number used for FatFs */
    #define DRIVE_NUM           0
    
    
    //************************************************************
    //Global file declaration
    uint16_t fileClose = 1;
    
    
    const char  outputfile[] = "fat:"STR(DRIVE_NUM)":output.txt";
    
    char dataBuffer[NUM_OF_BUFFFERS][BUFFER_SIZE];
    
    uint16_t bytesRead = 0;
    uint16_t closeFlag = 0;
    
    typedef struct buffObj {
       Queue_Elem elem; //must be the first field to be able to put onto a Queue
       void *buf;
       int bufSize;
    } buffObj;
    
    buffObj* buffObjPtr;
    
    buffObj A,B;
    
    
    /*
    // button used to close file
     */
    void gpioButtonFxn0(void)
    {
    
    
        /* Clear the GPIO interrupt and toggle an LED */
        GPIO_toggle(Board_LED0);
        closeFlag = 1;
    
    }
    /*
     *  ======== readUARTFxn ========
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void readUARTFxn(UArg arg0, UArg arg1)
    {
        //char input;
        UART_Handle uart;
        UART_Params uartParams;
        const char Prompt[] = "\fUART Open:\r\n";
        uint8_t i = 0;
    
        /* Create a UART with data processing off. */
        UART_Params_init(&uartParams);
        //uartParams.readMode = UART_MODE_BLOCKING;
        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, Prompt, sizeof(Prompt));
    
        while (1)
        {
        	if (i == 0)
        	{
        		Semaphore_pend(sem_free,BIOS_WAIT_FOREVER);
        		bytesRead = UART_read(uart,dataBuffer[i],BUFFER_SIZE);
        		//log_info1("Bytes read to dataBufferA = [%d]",bytesRead);
        		Queue_put(queue_full, &A.elem);
        		Semaphore_post (sem_full);
        		i++;
        	}
        	else if (i == 1)
        	{
        		Semaphore_pend(sem_free,BIOS_WAIT_FOREVER);
    			bytesRead = UART_read(uart,dataBuffer[i], sizeof(dataBuffer[i]));
    			//log_info1("Bytes read to dataBufferA = [%d]",bytesRead);
    			Queue_put(queue_full,&B.elem);
    			Semaphore_post (sem_full);
    			i = 0;
        	}
    
        }
    }
    
    
    
    /*
     *  ======== writeSDFxn ========
     *  Task to perform a write to a file on a SD card
     *
     *  Task tries to open an existing file outputfile[]. If the file doesn't
     *  exist, create one and write data to the file.
    
     *
     *  Task for this function is created statically. See the project's .cfg file.
     */
    Void writeSDfxn(UArg arg0, UArg arg1)
    {
        SDSPI_Handle sdspiHandle;
        SDSPI_Params sdspiParams;
    
        /* Variables for the CIO functions */
        FILE *src;
    
      // uint32_t i = 0;
      // uint32_t a = 0;
    
        bool available = FALSE;
    
    
    
        /* Mount and register the SD Card */
        SDSPI_Params_init(&sdspiParams);
        sdspiHandle = SDSPI_open(Board_SDSPI0, DRIVE_NUM, &sdspiParams);
        if (sdspiHandle == NULL) {
            System_abort("Error starting the SD card\n");
        }
        else {
            System_printf("Drive %u is mounted\n", DRIVE_NUM);
            System_flush();
        }
    
        /* Try to open the source file */
        src = fopen(outputfile, "r");
        if (!src) {
            System_printf("Creating a new file \"%s\"...\n", outputfile);
            System_flush();
    
            /* Open file for both reading and writing */
            src = fopen(outputfile, "a");
            if (!src) {
                System_printf("Error: \"%s\" could not be created.\n"
                              "Please check the Getting Started Guide "
                              "if additional jumpers are necessary.\n",
    						  outputfile
                             );
                System_abort("Aborting...\n");
            }
    
     //for (i=0;i<10000;i++)//create a delay for SD initialize
    // {
    //	a++;
    //	if (a > 100)
    //	{
    //		a = 0;
    //	}
    // }
    
            while (!closeFlag)
            {
    			available = Semaphore_pend (sem_full,BIOS_WAIT_FOREVER);
    			if (available)
    			{
    				buffObjPtr = Queue_get(queue_full);
    				fwrite(buffObjPtr->buf, 1,buffObjPtr->bufSize, src);
    				fflush(src);
    				available = 0;
    
    			}
            }
            closeFlag = 0;
            fileClose = fclose(src);
            System_printf("File Closed = %d\n",fileClose);
    		/* Stopping the SDCard */
    		SDSPI_close(sdspiHandle);
    		System_printf("Drive %u unmounted\n", DRIVE_NUM);
    		BIOS_exit(0);
    
    
        }
    
    
    
    
    }
    
    
    /*
     *  ======== main ========
     */
    int main(void)
    {
    
    	int i = 0;
        /* Call board init functions */
        Board_initGeneral();
        Board_initGPIO();
        Board_initSDSPI();
        Board_initUART();
    
        /* Turn on user LED */
        GPIO_write(Board_LED0, Board_LED_ON);
    
        /* install Button callback*/
        GPIO_setCallback(Board_BUTTON0, gpioButtonFxn0);
    
        /* Enable interrupts */
        GPIO_enableInt(Board_BUTTON0);
    
    
        for (i=0;i<BUFFER_SIZE;i++)
        {
        	dataBuffer[0][i]= '0';
        	dataBuffer[1][i]= '1';
        }
    
    
    
        A.buf = dataBuffer[0];
        A.bufSize = BUFFER_SIZE;
    
        B.buf = dataBuffer[1];
        B.bufSize = BUFFER_SIZE;
    
    	//Prime the free buffers Queue
    	Queue_put(queue_free, &A.elem);
    	Queue_put(queue_free, &B.elem);
    
    
        System_printf("Starting the FatSD example\n");
        System_flush();
    
        /* Start BIOS */
        BIOS_start();
    
        return (0);
    }
    

    Config:

    /*
     *  ======== fatsd.cfg ========
     */
    
    /* ================ General configuration ================ */
    var Defaults = xdc.useModule('xdc.runtime.Defaults');
    var Diags = xdc.useModule('xdc.runtime.Diags');
    var Error = xdc.useModule('xdc.runtime.Error');
    var Log = xdc.useModule('xdc.runtime.Log');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');
    
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var Hwi = xdc.useModule('ti.sysbios.hal.Hwi');
    var FatFS = xdc.useModule('ti.sysbios.fatfs.FatFS');
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var Queue = xdc.useModule('ti.sysbios.knl.Queue');
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');
    var Swi = xdc.useModule('ti.sysbios.knl.Swi');
    
    /*
     *  Program.stack is ignored with IAR. Use the project options in
     *  IAR Embedded Workbench to alter the system stack size.
     */
    if (!Program.build.target.$name.match(/iar/)) {
        /*
         *  Reducing the system stack size (used by ISRs and Swis) to reduce
         *  RAM usage.
         */
    Program.stack = 1024;
    }
    
    /*
     * Comment this line to allow module names to be loaded on the target.
     * The module name strings are placed in the .const section. Setting this
     * parameter to false will save space in the .const section.  Error and
     * Assert messages will contain an "unknown module" prefix instead
     * of the actual module name.
     */
    Defaults.common$.namedModule = false;
    
    /*
     * Minimize exit handler array in System.  The System module includes
     * an array of functions that are registered with System_atexit() to be
     * called by System_exit().
     */
    System.maxAtexitHandlers = 2;
    
    /*
     * Comment this line to allow Error, Assert, and Log strings to be
     * loaded on the target.  These strings are placed in the .const section.
     * Setting this parameter to false will save space in the .const section.
     * Error, Assert and Log message will print raw ids and args instead of
     * a formatted message.
     */
    //Text.isLoaded = false;
    
    /* ================ System configuration ================ */
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    System.SupportProxy = SysMin;
    
    /* Enable Semihosting for GNU targets to print to CCS console */
    if (Program.build.target.$name.match(/gnu/)) {
        var SemiHost = xdc.useModule('ti.sysbios.rts.gnu.SemiHostSupport');
    }
    
    /* ================ BIOS configuration ================ */
    /*
     * Disable unused BIOS features to minimize footprint.
     */
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.logsEnabled = true;
    BIOS.assertsEnabled = true;
    
    /* Reduce the heap size */
    BIOS.heapSize = 4096;
    
    /* Runtime stack checking is performed */
    Task.checkStackFlag = true;
    Hwi.checkStackFlag = true;
    
    /* Reduce the number of task priorities */
    Task.numPriorities = 4;
    
    /* ================ Task configuration ================ */
    var task0Params = new Task.Params();
    task0Params.instance.name = "writeSDTask";
    task0Params.stackSize = 0x400;
    task0Params.priority = 2;
    Program.global.writeSDTask = Task.create("&writeSDfxn", task0Params);
    
    /* ================ Driver configuration ================ */
    var TIRTOS = xdc.useModule('ti.tirtos.TIRTOS');
    TIRTOS.useGPIO = true;
    TIRTOS.useSDSPI = true;
    var task1Params = new Task.Params();
    task1Params.instance.name = "readUartTask";
    task1Params.priority = 3;
    task1Params.vitalTaskFlag = true;
    task1Params.stackSize = 1024;
    Program.global.readUartTask = Task.create("&readUARTFxn", task1Params);
    TIRTOS.useUART = true;
    TIRTOS.libType = TIRTOS.LibType_Instrumented;
    var semaphore0Params = new Semaphore.Params();
    semaphore0Params.instance.name = "sem_full";
    semaphore0Params.mode = Semaphore.Mode_COUNTING;
    Program.global.sem_full = Semaphore.create(null, semaphore0Params);
    var queue0Params = new Queue.Params();
    queue0Params.instance.name = "queue_free";
    Program.global.queue_free = Queue.create(queue0Params);
    var queue1Params = new Queue.Params();
    queue1Params.instance.name = "queue_full";
    Program.global.queue_full = Queue.create(queue1Params);
    var semaphore1Params = new Semaphore.Params();
    semaphore1Params.instance.name = "sem_free";
    Program.global.sem_free = Semaphore.create(2, semaphore1Params);
    LoggingSetup.sysbiosSemaphoreLogging = true;
    LoggingSetup.sysbiosLoggerSize = 4096;
    LoggingSetup.mainLoggerSize = 4096;
    LoggingSetup.loadLoggerSize = 4096;
    LoggingSetup.mainLoggingRuntimeControl = false;
    LoggingSetup.loggerType = LoggingSetup.LoggerType_STOPMODE;
    Hwi.dispatcherAutoNestingSupport = true;
    

    Does the code I have now represent your suggestion. It is a little hard to debug without the log_info.

    Regards,

    Lee.

  • Sorry, I missed this response.

    The API is "Log_info", not "log_info".

    Todd
  • Hi,

    I also missed the reply. Does the following code have the correct syntax for putting on the queue? I haven't used it before.

                Semaphore_pend(sem_free,BIOS_WAIT_FOREVER);
                bytesRead = UART_read(uart,dataBuffer[i],BUFFER_SIZE);
                //log_info1("Bytes read to dataBufferA = [%d]",bytesRead);
                Queue_put(queue_full, &A.elem);
                Semaphore_post (sem_full);
                
        

    Regards,

    Lee.

  • Hi Lee,

    Assuming the queue_full is a Queue_Handle, this looks fine. You can look in ROV to see what's going on with your queue. It will be in the instance tab. If you named the queue when you created it, the name will appear. If not, you'll have to see the address of queue_full and then find the corresponding handle address in ROV.

    Todd