Arduino malloc problem

Discussions and support about ChibiOS/NIL, the almost nil RTOS.
Acuario
Posts: 5
Joined: Fri Oct 02, 2015 5:39 am

Arduino malloc problem

Postby Acuario » Fri Oct 02, 2015 5:53 am

I am using the (I assume latest) build of nil on Arduino from https://github.com/greiman/NilRTOS-Arduino and it is (or was) all working well.
I have hit a couple of problems that seem to be related to malloc.
Allocating memory always returns 0. Trying to use the String class from Wstring.h also fails for the same reason.
I've searched google for an answer, one of which seems to be delete malloc.c but my version of Arduino (1.6) comes with pre-compiled libraries so the malloc source code isn't there.

Is there a fix/updated version or am I dead in the water?

Acuario

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Arduino malloc problem

Postby Giovanni » Fri Oct 02, 2015 6:45 am

Hi,

Memory allocation is not handled by the RTOS, it is possible that you are just out of free RAM.

Giovanni

Acuario
Posts: 5
Joined: Fri Oct 02, 2015 5:39 am

Re: Arduino malloc problem

Postby Acuario » Fri Oct 02, 2015 7:34 am

Hi,
it doesn't seem to be that. Here is a modified nilBlink sketch that shows the problem.
The string 'Setup' is output then just empty lines.


/*
* Example to demonstrate thread definition, semaphores, and thread sleep.
*/
#include <WString.h>
#include <NilRTOS.h>
#include <NilTwi.h>

// The LED is attached to pin 13 on Arduino.
const uint8_t LED_PIN = 13;

// Declare a semaphore with an inital counter value of zero.
SEMAPHORE_DECL(sem, 0);
//------------------------------------------------------------------------------
/*
* Thread 1, turn the LED off when signalled by thread 2.
*/
// Declare a stack with 128 bytes beyond context switch and interrupt needs.
NIL_WORKING_AREA(waThread1, 128);

// Declare the thread function for thread 1.
NIL_THREAD(Thread1, arg) {
while (TRUE) {

int error;
String statString = String("LED Off");

Wire.beginTransmission(0x80);
error = Wire.endTransmission();

// Wait for signal from thread 2.
nilSemWait(&sem);

// Turn LED off.
Serial.println(statString);

digitalWrite(LED_PIN, LOW);
}
}
//------------------------------------------------------------------------------
/*
* Thread 2, turn the LED on and signal thread 1 to turn the LED off.
*/
// Declare a stack with 128 bytes beyond context switch and interrupt needs.
NIL_WORKING_AREA(waThread2, 128);

// Declare the thread function for thread 2.
NIL_THREAD(Thread2, arg) {

pinMode(LED_PIN, OUTPUT);

while (TRUE) {
String statString = String("LED ON");
// Turn LED on.
Serial.println(statString);
digitalWrite(LED_PIN, HIGH);

// Sleep for 200 milliseconds.
nilThdSleepMilliseconds(200);

// Signal thread 1 to turn LED off.
nilSemSignal(&sem);

// Sleep for 200 milliseconds.
nilThdSleepMilliseconds(200);
}
}
//------------------------------------------------------------------------------
/*
* Threads static table, one entry per thread. A thread's priority is
* determined by its position in the table with highest priority first.
*
* These threads start with a null argument. A thread's name may also
* be null to save RAM since the name is currently not used.
*/
NIL_THREADS_TABLE_BEGIN()
NIL_THREADS_TABLE_ENTRY("thread1", Thread1, NULL, waThread1, sizeof(waThread1))
NIL_THREADS_TABLE_ENTRY("thread2", Thread2, NULL, waThread2, sizeof(waThread2))
NIL_THREADS_TABLE_END()
//------------------------------------------------------------------------------
void setup() {
Serial.begin(115200);
String statString = String("Setup");
Serial.println(statString);

// Start Nil RTOS.
nilSysBegin();

}
//------------------------------------------------------------------------------
// Loop is the idle thread. The idle thread must not invoke any
// kernel primitive able to change its state to not runnable.
void loop() {
// Not used.
}

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Arduino malloc problem

Postby Giovanni » Fri Oct 02, 2015 8:06 am

You may verify if there are stack overflows.

Giovanni

Acuario
Posts: 5
Joined: Fri Oct 02, 2015 5:39 am

Re: Arduino malloc problem

Postby Acuario » Fri Oct 02, 2015 4:16 pm

How do I do that? I tried increasing the stack to a crazy 1024 bytes and still the same result.

User avatar
Giovanni
Site Admin
Posts: 14444
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 1074 times
Been thanked: 921 times
Contact:

Re: Arduino malloc problem

Postby Giovanni » Fri Oct 02, 2015 9:35 pm

Which stack? there is one stack for each thread. You have 2 thread plus the empty loop, which still has its own stack because it serves interrupts.

About how... I never used NIL inside the arduino environment, is it possible to examine the memory? this is how it is done usually.

Giovanni

Acuario
Posts: 5
Joined: Fri Oct 02, 2015 5:39 am

Re: Arduino malloc problem

Postby Acuario » Fri Oct 02, 2015 10:59 pm

I changed the stack on both to 1024 - I guess the empty loop does not need a stack specifically declared as it is empty and not declared as one of the nil threads.
Arduino debugging is unfortunately not that easy as access to the internals is not really available - if it were a pic.. but that's another story..

It seems that as soon as the nil system is started memory allocations using malloc fail irrespective of the stack size.

Acuario

Acuario
Posts: 5
Joined: Fri Oct 02, 2015 5:39 am

Re: Arduino malloc problem

Postby Acuario » Sat Oct 03, 2015 6:10 am

This is as simple a demo as I can make that exhibits the problem.

It prints to the serial monitor:
test
Setup
.. then just blank lines.


#include <NilRTOS.h>
#include <WString.h>

// Declare a stack
NIL_WORKING_AREA(waThread1, 1024);

// Declare the thread function for thread 1.
NIL_THREAD(Thread1, arg) {
while (TRUE) {

String statString = String("Thread");
Serial.println(statString);

// Sleep
nilThdSleepMilliseconds(2000);
}
}
/* Threads static table, one entry per thread. */
NIL_THREADS_TABLE_BEGIN()
NIL_THREADS_TABLE_ENTRY("thread1", Thread1, NULL, waThread1, sizeof(waThread1))
NIL_THREADS_TABLE_END()
//------------------------------------------------------------------------------
void setup() {

Serial.begin(115200);
char* msg = (char*)malloc(6);
sprintf(msg, "test");
Serial.println(msg);

String statString = String("Setup");
Serial.println(statString);

// Start Nil RTOS.
nilSysBegin();

}
void loop() {
// Not used.
}


Return to “ChibiOS/NIL”

Who is online

Users browsing this forum: No registered users and 3 guests