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.