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.

AM3358: RTOS UART_printf issue

Part Number: AM3358
Other Parts Discussed in Thread: SYSBIOS

Customer report call UART_printf() output float point data, system will hung after a while, ,code as below. message as upper snapshot. if remove the log(message) from below code, it won't hung. except the sysbios tick time, no other interrupt in the system. 

please help to analysis.

While(1)

        for(i=0;i < 128;++i)

        {

            sprintf(message, "%s:%03d A:%9.4f   B:%9.4f   C:%9.4f\n",getName(),i,

                 (INT16)( PHA[i])*220.0/4096,

                 (INT16)( PHB[i])*220.0/4096,

                 (INT16)( PHC[i])*220.0/4096);

                log(message);//  here it is UART_printf();

}

system usually report below error, what it denotes?

No source available for "do_AngelSWI(int, void *) at 0x80168ad0"

 CortxA8: Unhandled ADP_Stopped exception 0x20023

 

Customer also report the UART_printf is slower than Linux UART console output, why and how to improve the speed?

background:   CCS version: V7.2,  BIOS version: bios_6_46_05_55, 

 

  • The RTOS team have been notified. They will respond here.
  • Hi Tony,

    Sorry for the very slow response. This thread was assigned to me around the time I took leave. Is this issue still open?

    Lali
  • Lali,
    yes, it is still open.
  • Tony,

    Could you please share a CCS project that would allow me to reproduce this issue on my side, and I can look into it.

    Lali
  • https://e2e.ti.com/cfs-file/__key/communityserver-discussions-components-files/791/PRO_5F00_TEST.7z

    If you comment these two lines of code from "task1" the program runs ok, or it crashes
            gateKey = GateSwi_enter(gateHead);
            GateSwi_leave(gateHead, gateKey);

    -----------------------main code-----------------------

    /*
     * Copyright (C) 2016 Texas Instruments Incorporated - http://www.ti.com/
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions
     * are met:
     *
     * Redistributions of source code must retain the above copyright
     * notice, this list of conditions and the following disclaimer.
     *
     * Redistributions in binary form must reproduce the above copyright
     * notice, this list of conditions and the following disclaimer in the
     * documentation and/or other materials provided with the
     * distribution.
     *
     * Neither the name of Texas Instruments Incorporated nor the names of
     * its contributors may be used to endorse or promote products derived
     * from this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /* ========================================================================== */
    /*                             Include Files                                  */
    /* ========================================================================== */

    #ifdef __cplusplus
    extern "C" {
    #endif
    #include <xdc/std.h>

    #include <xdc/cfg/global.h>
    #include <xdc/runtime/System.h>
    #include <xdc/runtime/Types.h>

    #include <stdio.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Swi.h>
    #include <ti/sysbios/gates/GateSwi.h>

    #include <ti/sysbios/BIOS.h>
    #include <xdc/runtime/Error.h>

    #include <ti/board/board.h>
    #include <ti/sysbios/hal/Timer.h>
    #include <ti/sysbios/knl/Clock.h>
    #include <ti/drv/uart/UART_stdio.h>

    #include "app_timer.h"

    Void myTimerFunc(UArg a0,UArg a1);
    Void swi0DataProcess(UArg arg0,UArg arg1);

    #ifdef __cplusplus
    }
    #endif

    GateSwi_Handle gateHead;
    UInt gateKey;
    /* ========================================================================== */
    /*                             Func Declare                                   */
    /* ========================================================================== */


    Void myTimerFunc(UArg a0,UArg a1)
    {
        Clock_tick();
    }

    void task1(UArg arg0, UArg arg1)
    {

        char message[32]={0};
        int m_u32FreqFilter=100;
        sprintf(message,"[%s]:%d\n",__FUNCTION__,m_u32FreqFilter);
        while(1)
        {
            gateKey = GateSwi_enter(gateHead);
            UART_printf("task1\n");
            GateSwi_leave(gateHead, gateKey);
        }
    }


    void swi0DataProcess(UArg arg0,UArg arg1)
    {
        int  i=0;;
        gateKey = GateSwi_enter(gateHead);
         i =(++i)%100;
        GateSwi_leave(gateHead, gateKey);
    }
    /* ========================================================================== */
    /*                               Main                                   */
    /* ========================================================================== */
    int main(void)
    {
        /* Call board init functions */
        Board_initCfg boardCfg;

        boardCfg = BOARD_INIT_MODULE_CLOCK |
            BOARD_INIT_PINMUX_CONFIG |
            BOARD_INIT_UART_STDIO;
        //系统模块初始化
        timerClockInit();


        Board_init(boardCfg);

        GateSwi_Params prms;
        Error_Block e;
        Error_init(&e);
        GateSwi_Params_init(&prms);
        gateHead = GateSwi_create(&prms, &e);
        if (gateHead == NULL) {
            printf("error!\n");
        }


        Error_Block eb;
        Error_init(&eb);
        Task_Handle task = NULL;
        Task_Params taskParams;
        Task_Params_init(&taskParams);

        taskParams.priority = 5;
        taskParams.stackSize = 1024;
        task = Task_create(task1, &taskParams, &eb);
        if (task == NULL) {
            System_printf("Task_create() failed!\n");
            BIOS_exit(0);
        }

        BIOS_start();    /* does not return */

        return 0;
    }

  • Hi,

    Can you confirm you are not blowing the stack? Do Tools->ROV->BIOS->Scan for Errors after the system crashes.

    Also check ROV->Tasks->Detailed and ROV->Hwi->Module to see how close the stack peaks are.


    Todd

  • hi,

    Sorry,I don't know what's the means of "blowing the stack".

     Tools->ROV->BIOS->Scan for Errors:

    ,ti.sysbios.family.arm.exc.Exception,Module,N/A,exception,An exception has occurred!
    ,ti.sysbios.knl.Semaphore,Basic,(0x80406708),pendElems,Error: Problem scanning pend Queue: JavaException: java.lang.Exception: Target memory read failed at address: 0x413268e4, length: 8This read is at an INVALID address according to the application's section map. The application is likely either uninitialized or corrupt.
    ,ti.sysbios.knl.Task,Detailed,(0x80406778),blockedOn,Invalid task internal state: pend element address (0x0) is not within the task's stack

    ROV->Tasks->Detailed:

    ,0x804046b4,ti.sysbios.knl.Task.IdleTask,0,Preempted,ti_sysbios_knl_Idle_loop__E,0x0,0x0,780,2048,0x80405580,n/a,n/a,
    ,0x80406778,,5,Blocked,task1,0x0,0x0,852,1024,0x804067c8,n/a,n/a,Internal Error

    ROV->Hwi->Module:

    ,0x804041c8,...,0,0,1052,16384,0x8055faa8

    You can reproduce the problem, which I think is the quickest way to solve the problem.

  • I'm not familiar with the UART_prinf() code, it's not part of TI-RTOS, but I looked at the disassembly of UART_printf() from your posted project and can see that it's calling Semaphore_pend(). Semaphore_pend() cannot be called when the Swi scheduler is disabled, and GateSwi_enter() disables the Swi scheduler.
  • So,GateSwi cannot be called when UART_printf was called,

    or all Gate cannot be called? What do you mean.

  • You can use GateMutex, which is based on a Semaphore.

    Why do you even want to wrap a Gate around the call to UART_printf()?
  • I want to print global variables  in the TaskProcess , this variable is calculated in the SwiProcess,  so the global variable should be protected. 

    But  GateMutex can't be used in Swi.

  • user5183560 said:
    I want to print global variables  in the TaskProcess , this variable is calculated in the SwiProcess,  so the global variable should be protected.

    I guess I don't understand why you need to protect the global variable at all in this case.  If a Swi is calculating a value for the variable, it will complete its calculation before that variable can be used by a Task - there will be no window of inconsistent data.

    The UART_printf("...", global_var) will get a snapshot of global_var at the time of the call to UART_printf().  The global_var might get re-calculated by the Swi immediately after the variable is given to UART_printf(), in which case UART_printf() will print the value before this re-calculation, but isn't that the same thing that will happen if you surround UART_printf() with a Gate?  If the Gate is entered and then the Swi immediately *wants* to run but can't because of the Gate, the Swi will run immediately after the Gate is exited and UART_printf() will have printed the pre-re-calculated value (not that you can do this since a Swi can't "wait" or block waiting for a Gate to be released).

    What is the point of using the Gate inside the Swi?