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 MSP430 CCSV4 Timer_Create "Unknown File" error at runtime C code versus .cfg file.

Other Parts Discussed in Thread: SYSBIOS, MSP-TS430PN80USB

I'm trying to create a timer in my task.c file.  When I create the timer with following code, I get a runtime error of:

 

dc.runtime.Memory: line 52: out of memory: heap=0x0, size=16

Timer create failed

 

C Excerpt:

 

Void main()

{

Timer_Params timerParams;

Timer_Handle myTimer;

Error_Block eb;

   

/*

     * Uncomment this next line to initialize the port direction for the LED.

     */

   

/* P1DIR |= 0x1; */


   

/*

     * Print "Hello world" to a log buffer.

     */

    Log_info0(

"Hello world\n");

 

Error_init(&eb);

Timer_Params_init(&timerParams);

timerParams.period = 1000;

timerParams.periodType = Timer_PeriodType_MICROSECS;

//timerParams.arg = 1;

     timerParams.startMode = Timer_StartMode_AUTO;

     timerParams.runMode = Timer_RunMode_CONTINUOUS;

 

myTimer = ti_sysbios_hal_Timer_create(Timer_ANY, myTickFxn, &timerParams, &eb);

if

(myTimer == NULL) {

    Log_info0(

"Timer create failed\n");

    System_abort(

"Timer create failed");

}

 

 

   

/*

     * Start BIOS.

     * Begins task scheduling.

     */

    BIOS_start();       

/* does not return */


}

 

 

 

When I use the .cfg file, everything works.

I tried not including the .cfg file in compile, but then the compiler doesn't find some of the .h files being included.

So I tried a hybrid approach with some part of the .cfg file commented out.  I remove everything around the timer creation (to avoid

a memory issues as it is usually the case when something is instanciated twice in CCSV).

It still doesn't work.

My end goal is to create timer and get rid of the whole .cfg file.  I want the code to be portable to another OS and want to avoid the use

of the .cfg file.

 

Here is the full C and the full .cfg.

 

/*

*  MSP430 specific Task example.

*  This example:

*

*  1) prints "Hello world" in main().

*  2) increments a counter within a timer interrupt.

*

*  3) every 10 timer interrupts, the timer interrupt handler

*     posts a semaphore to awaken a task to perform additional

*     work.

*

* 4) prints "10 ticks" from within the task function awakened

*     each time 10 interrupts have been serviced.

*

*  All output is routed to a log buffer which can be viewed

*  using the RTA "Raw Logs" viewer. After loading and running

*  the application, launch the Tools->RTA->Raw Logs tool to

*  view the logs.

*/

/*

* The msp430.h header is included for referencing P1DIR and P1OUT, used below

* to blink an LED connected to P1.0.  Many development boards (e.g.,

* MSP-EXP430F5438, MSP-TS430PN80USB, ...) provide an LED at this port

* location. Because this example can be run on custom development boards, the

* code to control the LED is commented out below.  To enable blinking of the

* LED, remove the comments around the modifications of P1DIR and P1OUT. If

* the LED is at a different location, change the port direction, output,

* and bit locations accordingly.

*/

#include

<msp430.h>

#include

<xdc/std.h>


#include

<xdc/runtime/Error.h>


#include

<xdc/runtime/System.h>


#include

<xdc/runtime/Timestamp.h>


#include

<ti/sysbios/BIOS.h>


#include

<ti/sysbios/knl/Task.h>


#include

<ti/sysbios/hal/Timer.h>


//#include <ti/sysbios/hal/Hwi.h>

 

 

//#include <ti/sysbios/timers/timer64/Timer.h>

//#include <xdc/cfg/global.h>

//#include <xdc/runtime/Error.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;

/*

Timer_Params timerParams;

Timer_Handle myTimer;

Error_Block eb;

*/

/*

*  ======== myTickFxn ========

*  Timer ISR function that posts a Swi to peform

*  the non-realtime service functions.

*/

Void myTickFxn(UArg arg)

{

   

/*

     * Uncomment this next line to toggle the LED state.

     */

   

/* P1OUT ^= 0x1; */


    tickCount += 1;     

/* increment the counter */


   

/* every 10 timer interrupts post the semaphore */


   

if ((tickCount % 10) == 0) {

        Semaphore_post(mySem);

    }

}

 

 

/*

*  ======== main ========

*/

Void main()

{

Timer_Params timerParams;

Timer_Handle myTimer;

Error_Block eb;

   

/*

     * Uncomment this next line to initialize the port direction for the LED.

     */

   

/* P1DIR |= 0x1; */


   

/*

     * Print "Hello world" to a log buffer.

     */

    Log_info0(

"Hello world\n");

 

Error_init(&eb);

Timer_Params_init(&timerParams);

timerParams.period = 1000;

timerParams.periodType = Timer_PeriodType_MICROSECS;

//timerParams.arg = 1;

     timerParams.startMode = Timer_StartMode_AUTO;

     timerParams.runMode = Timer_RunMode_CONTINUOUS;

 

myTimer = ti_sysbios_hal_Timer_create(Timer_ANY, myTickFxn, &timerParams, &eb);

if

(myTimer == NULL) {

    Log_info0(

"Timer create failed\n");

    System_abort(

"Timer create failed");

}

 

 

   

/*

     * Start BIOS.

     * Begins task scheduling.

     */

    BIOS_start();       

/* does not return */


}

/*

*  ======== myTaskFxn ========

*  Task function that pends on a semaphore until 10 ticks have

*  expired.

*/

Void myTaskFxn(Void)

{

   

/*

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

    }

}

 

 

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');

/*

* 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 = 1000000;

timerParams.periodType = Timer.PeriodType_MICROSECS;

var

myTimer = Timer.create(1, '&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;

Thanks.

 

  • Hans,

    I think the reason you are getting that out of memory error is because the Timer create is attempting a dynamic allocation but the heap size is set to zero:

    BIOS.heapSize = 0;

    You won’t be able to “get rid of the whole .cfg file”.  This file is used to specify how you want your application built (for example, the heap size), as well as specifying the modules you want to use/bind into your application.  

    Even if you wanted to accept all the default configuration values, you would not be able to get the program to successfully link without specifying the modules you will use.

    To make the code “portable to another OS”, I guess you plan on some abstraction layer?  If so, can’t the C code still be portable, but with SYS/BIOS builds you need a .cfg file too?  And for that other OS, you’ll need some other configuration mechanism, or maybe additional C code that configures that OS, that you won't include for the SYS/BIOS case?

    Scott

  • Hi Scott,

     

    I tried placing a none-zero value on BIOS.heapSize (16 and other bigger values).  It doesn't help.

    Now, I'm getting a .out exceeds code size limit.

     

    I tried playing with:

     

    Defaults.common$.memoryPolicy = xdc.module("xdc.runtime.Types").STATIC_POLICY;

    Defaults.common$.memoryPolicy = xdc.module("xdc.runtime.Types").CREATE_POLICY;

    Defaults.common$.memoryPolicy = xdc.module("xdc.runtime.Types").DELETE_POLICY;

    No luck.

     

    I tried moving the heap somewhere else:

     

    //var HeapMem = xdc.useModule('ti.sysbios.heaps.HeapMem');

    //var heapMemParams = new HeapMem.Params;

    //heapMemParams.size = 2048;

    //heapMemParams.sectionName = "systemHeap";

    //Program.global.systemHeap = HeapMem.create(heapMemParams);

    //Program.sectMap["systemHeap"] = "DDR";

    //Memory.defaultHeapInstance = Program.global.systemHeap;

     

    no luck.

     

    From what I can see, if th heap is not set at 0, the files is too big for the .out (exceeds code limit).  Which is BS.

    Looks to mee like the heap has to be displaced so that it can be a none-zero value so that I can finally create at

    runtime the timer.

    Any idea on how to do this?

     

    I lost the whole day on this...

     

    Thanks.

     

    Hans.

     

  • Hans,

    What device are you building for? 

    If it is one with a very small amount of RAM, then yes, you can be pretty limited in what will fit.  For low memory devices it is best to do static allocations by creating the objects in the .cfg file, and specifying STATIC_POLICY.  This will significantly reduce memory usage by eliminating code for dynamic creations and deletions.

    Have you looked at the examples that come with SYS/BIOS?  There are several examples with non-zero heaps, with Task_create(), Semaphore_create(), Event_create(), etc.  The bigtime (C++) example has a 2K heap. 

    Some of the examples will build only for larger memory MSP430 devices, but some will build for all the MSP430 devices we support.

    The configuration settings in the .cfg file are critical to reducing the memory footprint, and allowing scaling of the OS to fit on these small memory devices.

    I think the best thing to suggest is to look at the example templates to see what best fits the type of application you want to build, and then start with that one, using the settings in the .cfg file, and modifying them as you need to add functionality.

    Scott

  • Hi Scott,

     

    I'm using MSP-EXP430F5529.  My goal is to avoid being tied to CCSV* in case I want to change the OS some day.

     

    Do you have a path for the examples?  Or do I simply use different templates in CCSV4?

     

    Thanks.

     

    Hans.

     

  • Hi Scott,

    According to 430F5529 I would have 128 KB for FLASH and at least 8KB for RAM.

    When I take a look at the .map file I see that I'm using about 3KB for RAM and 23KB for flash.

     

    MEMORY CONFIGURATION

             name            origin    length      used     unused   attr    fill

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

      SFR                   00000000   00000010  00000000  00000010  RWIX

      PERIPHERALS_8BIT      00000010   000000f0  00000000  000000f0  RWIX

      PERIPHERALS_16BIT     00000100   00000100  00000000  00000100  RWIX

      INFOD                 00001800   00000080  00000000  00000080  RWIX

      INFOC                 00001880   00000080  00000000  00000080  RWIX

      INFOB                 00001900   00000080  00000000  00000080  RWIX

      INFOA                 00001980   00000080  00000000  00000080  RWIX

      RAM                   00002400   00002000  00000c5e  000013a2  RWIX

      FLASH                 00004400   0000bb80  00005c76  00005f0a  RWIX

     

    Why can't I fit runtime SYS/BIOS on the device?

     

    Thanks.

     

    Hans.

     

  • Hans,

    1) You can find the sources for the examples in the packages\ti\sysbios\examples subdirectory of the SYS/BIOS installation.  For example:

    C:\ti\bios_6_33_01_20\packages\ti\sysbios\examples

    The generic examples are in the “generic” subdirectory and the MSP430-specific examples are in “msp430”.  A particular example may have an MSP430-specific configuration file, and that is in the “msp430” subdirectory of the example.  For example, for the “clock” example the main .c file is generic\clock\clock.c, and the MSP430-specific configuration file is generic\clock\msp430\clock.cfg.  Usually the only change for the MSP430-specific configuration files is to shrink heap, stack, and buffer sizes from unnecessarily large defaults.

    The easiest thing to do for each of these is to run the new project wizard.  When you select a particular example template the wizard will pick the right .c and .cfg file to include in your project.

    2) Can you explain your comment “Why can't I fit runtime SYS/BIOS on the device”?  The map file shows the sizes are OK to fit, with plenty of space left.  If it didn’t fit the program wouldn’t link successfully.  Are you getting some sort of program load error?

    Scott

  • 2) Well, I can't change the heap size to a non-zero value because I'm getting: .out exceeds code size limit.

     

    And from your comment:

     

    "If it is one with a
    very small amount of RAM, then yes, you can be pretty limited in what will
    fit.  For low memory devices it is best to do static allocations by
    creating the objects in the .cfg file, and specifying STATIC_POLICY.  This
    will significantly reduce memory usage by eliminating code for dynamic
    creations and deletions."

     

    I assume that you meant that I didn't have enough RAM.

    But I have plenty...  So, why am I getting this "size limit" error?

     

    Thanks.

     

    Hans.

     

     

     

  • Hans,

    OK, I think what is going on is that you have hit the code size limit of your CCS license.  It is not the amount of device memory that is the limiting factor.  

    I’m not that familiar with all the different CCS licensing options, but see a description here: http://processors.wiki.ti.com/index.php/Licensing_-_CCS

    Which version of CCS license do you have?  Is it one of the code-size limited variants?  Do you think this is the problem?

    Scott

  • Interesting.

    I have

    Version: 4.2.4.00033

    and the attached list.

    Do I have to buy some license or upgrade?

     

    Thanks.

     

    Hans.

     

     

  • Hans,

    I’m told that if you are getting the message “.out exceeds code size limit” then you are definitely using a code-size limited version of CCS.  And you will need to upgrade to a more capable version.  With the code-size limited tools for CCSv4 different linkers are used versus the full tools, so you won’t be able to simply ‘drop in’ a new license to the existing version you have.

    If you want to find out specifically which license you have, you’ll have to look at the license file as described on that wiki page.

    Scott

  • OK.

    Thanks for your help.

    You can close the call.

    Hans.