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.

SYS/BIOS console output

Other Parts Discussed in Thread: MSP430F6638, CCSTUDIO, SYSBIOS

I am using CCS 5.3 with SYS/BIOS 6.34.2.18 on MSP430F6638.

My question is how could I write something to Console from my program?

I have tried to follow the recommendation about "printf()" from TI Wiki, enabled full printf support and increased heap size to 1024. But nothing works. In a contrary, in a simple CCS project without SYS/BIOS all works just fine only with heap increasing.

  • Hi Denis,

    Which TI Wiki are you referring to?

    Could you attach your .c and .cfg file?

    Todd

  • I have tried with http://processors.wiki.ti.com/index.php/Printf_support_for_MSP430_CCSTUDIO_compiler

    The project is based on a standard example (RTOS with tasks):

    // ----------- .c file -----------------

    #include <msp430.h>
    #include <stdio.h>

    #include <xdc/std.h>
    #include <xdc/runtime/Log.h>
    #include <ti/sysbios/BIOS.h>
    #include <ti/sysbios/knl/Task.h>
    #include <ti/sysbios/knl/Semaphore.h>

    /* Semaphore handle defined in task.cfg */
    extern const Semaphore_Handle mySem;

    /* Counter incremented by timer interrupt */
    volatile UInt tickCount = 0;

    /*
     *  ======== main ========
     */
    Void main()
    {
        /*
         * Print "Hello world" to a log buffer.
         */
        Log_info0("Hello world\n");

        BIOS_start();        /* does not return */
    }

    /*
     *  ======== myTickFxn ========
     *  Timer ISR function that posts a Swi to peform
     *  the non-realtime service functions.
     */
    Void myTickFxn(UArg arg)
    {
        tickCount += 1;      /* increment the counter */

        /* every 10 timer interrupts post the semaphore */
        if ((tickCount % 10) == 0) {
            Semaphore_post(mySem);
        }
    }

    /*
     *  ======== myTaskFxn ========
     *  Task function that pends on a semaphore until 10 ticks have
     *  expired.
     */
    Void myTaskFxn(Void)
    {
        unsigned int cProbe = 0x0C;

        printf("Current probe value: %d\n", cProbe);

        /*
         * Do this forever
         */
        while (TRUE) {
            /*
             * Pend on "mySemaphore" until the timer ISR says
             * its time to do something.
             */
            Semaphore_pend(mySem, BIOS_WAIT_FOREVER);

            /*
             * Print the current value of tickCount to a log buffer.
             */
            Log_info1("10 ticks. Tick Count = %d\n", tickCount);

        }
    }

    // ----------- .cfg --------------------------

    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 LoggerBuf = xdc.useModule('xdc.runtime.LoggerBuf');
    var Main = xdc.useModule('xdc.runtime.Main');
    var Memory = xdc.useModule('xdc.runtime.Memory')
    var SysMin = xdc.useModule('xdc.runtime.SysMin');
    var System = xdc.useModule('xdc.runtime.System');
    var Text = xdc.useModule('xdc.runtime.Text');

    var Hwi = xdc.useModule('ti.sysbios.family.msp430.Hwi');
    var LoggingSetup = xdc.useModule('ti.uia.sysbios.LoggingSetup');

    /*
     * Program.argSize sets the size of the .args section.
     * The examples don't use command line args so argSize is set to 0.
     */
    Program.argSize = 0x0;

    /*
     * Uncomment this line to globally disable Asserts.
     * All modules inherit the default from the 'Defaults' module.  You
     * can override these defaults on a per-module basis using Module.common$.
     * Disabling Asserts will save code space and improve runtime performance.
    Defaults.common$.diags_ASSERT = Diags.ALWAYS_OFF;
     */

    /*
     * Uncomment this line to keep module names from being 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;
     */

    /*
     * Comment this line out if you want to dynamically create instance
     * objects.
     */
    Defaults.common$.memoryPolicy = xdc.module("xdc.runtime.Types").STATIC_POLICY;

    /*
     * 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 = 4;       

    /*
     * Uncomment this line to disable the Error print function.  
     * We lose error information when this is disabled since the errors are
     * not printed.  Disabling the raiseHook will save some code space if
     * your app is not using System_printf() since the Error_print() function
     * calls System_printf().
    Error.raiseHook = null;
     */

    /*
     * Uncomment this line to keep Error, Assert, and Log strings from being
     * 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;
     */

    /*
     * Uncomment this line to disable the output of characters by SysMin
     * when the program exits.  SysMin writes characters to a circular buffer.
     * This buffer can be viewed using the SysMin Output view in ROV.
    SysMin.flushAtExit = false;
     */

    /*
     * Use SysMin for output (System_printf() and error messages) and
     * minimize the output buffer size to save data space.
     */
    System.SupportProxy = SysMin;
    SysMin.bufSize = 80;

    /*
     * Create a LoggerBuf and make it the default logger for all modules.
     */
    var LoggerBufParams = new LoggerBuf.Params();
    LoggerBufParams.numEntries = 16;
    var logger0 = LoggerBuf.create(LoggerBufParams);
    Defaults.common$.logger = logger0;

    Main.common$.diags_INFO = Diags.ALWAYS_ON;

    /* System stack size (used by ISRs and Swis) */
    Program.stack = 0x200;

    /*
     * Application specific configuration
     */
     
    /*
     * Disable unused BIOS features to minimize footprint.
     * This example uses Tasks but not Swis or Clocks.
     */
    var BIOS = xdc.useModule('ti.sysbios.BIOS');
    BIOS.swiEnabled = false;
    BIOS.taskEnabled = true;
    BIOS.clockEnabled = false;

    /* Minimize system heap */
    BIOS.heapSize = 0;

    /* Use Custom BIOS lib to achieve minimal footprint */
    BIOS.libType = BIOS.LibType_Custom;

    /*
     * Create a timer instance to generate a periodic interrupts.
     *
     * The timer will be started within the BIOS_start()
     * thread
     */
    var Timer = xdc.useModule('ti.sysbios.family.msp430.Timer');
    var timerParams = new Timer.Params();
    timerParams.startMode = Timer.StartMode_AUTO;
    timerParams.runMode = Timer.RunMode_CONTINUOUS;
    /* Timer period is 1/2 second (500,000 uSeconds) */
    timerParams.period = 500000;
    timerParams.periodType = Timer.PeriodType_MICROSECS;
    var myTimer = Timer.create(0, '&myTickFxn', timerParams);

    /* Create a task with priority 1 */
    var Task = xdc.useModule('ti.sysbios.knl.Task');
    var taskParams = new Task.Params();
    taskParams.priority = 1;
    var myTask = Task.create('&myTaskFxn', taskParams);

    /* Inhibit the creation of a task to run idle functions */
    Task.enableIdleTask = false;

    /* Allow SYS/BIOS to idle the CPU while waiting for an interrupt */
    var Power = xdc.useModule('ti.sysbios.family.msp430.Power');

    /*
     * Create a binary semaphore for the timer ISR to use to
     * signal the pended task every 10 ticks
     */
    var Semaphore = xdc.useModule('ti.sysbios.knl.Semaphore');
    var semParams = new Semaphore.Params();
    semParams.mode = Semaphore.Mode_BINARY;
    Program.global.mySem = Semaphore.create(0, semParams);

    /*
     * Build a custom BIOS library.  The custom library will be smaller than the
     * pre-built "instrumented" (default) and "non-instrumented" libraries.
     *
     * The BIOS.logsEnabled parameter specifies whether the Logging is enabled
     * within BIOS for this custom build.  These logs are used by the RTA and
     * UIA analysis tools.
     *
     * The BIOS.assertsEnabled parameter specifies whether BIOS code will
     * include Assert() checks.  Setting this parameter to 'false' will generate
     * smaller and faster code, but having asserts enabled is recommended for
     * early development as the Assert() checks will catch lots of programming
     * errors (invalid parameters, etc.)
     */
    BIOS.libType = BIOS.LibType_Custom;
    BIOS.logsEnabled = false;
    BIOS.assertsEnabled = true;

    I noticed that I have "logsEnable = false" in the config, but altering it via XGCONF causes errors:

     -------------------

    Description    Resource    Path    Location    Type
    #10099-D program will not fit into available memory.  placement with alignment fails for section ".cinit" size 0x36c .  Available memory ranges:    lnk_msp430f6638.cmd    /minimal_sysbios_tasks    line 113    C/C++ Problem
    #10010 errors encountered during linking; "minimal_sysbios_tasks.out" not built    minimal_sysbios_tasks             C/C++ Problem

    --------------------

    So, I completely confused with it.

  • Hi Denis,

    Sorry, this thread fell through the cracks over the holidays. Did this get resolved?

    Todd

  • No, I still experience this issue. Any help would be appreciated.

  • Hi Denis,

    You need to set the BIOS.heapSize in the .cfg. It is currently 0. This is over-writing the value you are specifying in the build options. So try

    BIOS.heapSize = 512;

    Todd