Thread code crashing when statically allocated
Posted: Sat May 10, 2014 7:45 am
I've got a C++ class wrapped around ChibiOS threads. It may seem complicated, but it's really pretty straightforward. It allows me to pass the desired stack size as a template parameter. An example of its use is shown here, and the actual classes below. In the example, calling someFuncWorks1() or someFuncWorks2() results in a working program. someFuncHangs() results in the LED turning on and the system hanging. In the first func, the thread is allocated on the stack (not good). In the second, it's a private static allocation. In the third, it's static outside the function. I'm not sure why the last two are different.
I'm pretty sure I've successfully used this code on AVR and ARM before, but I'm not sure what's going on now. Any ideas? Thanks!
I'm pretty sure I've successfully used this code on AVR and ARM before, but I'm not sure what's going on now. Any ideas? Thanks!
Code: Select all
class
BlinkThread : public CThread<128>
{
protected:
virtual msg_t entry();
};
msg_t
BlinkThread::entry()
{
while (true)
{
palClearPad(IOPORT1, PIOA_STATUS_LED); // On
chThdSleepMilliseconds(100);
palSetPad(IOPORT1, PIOA_STATUS_LED); // Off
chThdSleepMilliseconds(900);
}
return 0;
}
void
someFuncWorks1()
{
BlinkThread blinkThread;
blinkThread.start();
}
void
someFuncWorks2()
{
static BlinkThread sBlinkThread;
sBlinkThread.start();
}
BlinkThread sBlinkThread;
void
someFuncHangs()
{
sBlinkThread.start();
}
Code: Select all
/**
CThread.h
Created by Roderick Mann on 2/3/11.
Copyright 2011 Latency: Zero. All rights reserved.
*/
#ifndef __CThread_h__
#define __CThread_h__
#include "ch.h"
class
BaseThread
{
public:
BaseThread(void* inWorkingArea, size_t inWorkingAreaSize);
void start(tprio_t inPriority = NORMALPRIO);
msg_t sendMessage(msg_t inMsg, void* inContext);
Thread* getSysThread() { return mSysThread; }
protected:
virtual msg_t entry();
msg_t messageWait(void** outContext);
void messageRelease(msg_t inMsg);
void
sleep(uint32_t inMilliseconds)
{
chThdSleepMilliseconds(inMilliseconds);
}
private:
static msg_t ThreadEntry(void* inArg);
void* mWorkingArea;
uint32_t mWorkingAreaSize;
void* mMessageContext;
Thread* mSysThread;
};
inline
msg_t
BaseThread::ThreadEntry(void* inArg)
{
BaseThread* self = reinterpret_cast<BaseThread*> (inArg);
return self->entry();
}
template<size_t inStackSize>
class
CThread : public BaseThread
{
public:
CThread()
:
BaseThread(mWorkingArea, sizeof(mWorkingArea))
{
}
protected:
virtual stkalign_t* getWorkingArea() { return mWorkingArea; }
private:
WORKING_AREA(mWorkingArea, inStackSize);
};
#endif // __CThread_h__
Code: Select all
/**
CThread.cpp
Created by Roderick Mann on 2/3/11.
Copyright 2011 Latency: Zero. All rights reserved.
*/
#include "CThread.h"
#include "ch.h"
BaseThread::BaseThread(void* inWorkingArea, size_t inWorkingAreaSize)
:
mWorkingArea(inWorkingArea),
mWorkingAreaSize(inWorkingAreaSize),
mMessageContext(NULL),
mSysThread(NULL)
{
}
msg_t
BaseThread::entry()
{
return 0;
}
void
BaseThread::start(tprio_t inPriority)
{
mSysThread = chThdCreateStatic(mWorkingArea,
mWorkingAreaSize,
inPriority,
ThreadEntry,
this);
}
msg_t
BaseThread::sendMessage(msg_t inMsg, void* inContext)
{
mMessageContext = inContext;
msg_t reply = chMsgSend(getSysThread(), inMsg);
return reply;
}
msg_t
BaseThread::messageWait(void** outContext)
{
Thread* t = chMsgWait();
msg_t msg = chMsgGet(t);
if (outContext != NULL)
{
*outContext = mMessageContext;
}
return msg;
}
void
BaseThread::messageRelease(msg_t inReply)
{
chMsgRelease(mSysThread, inReply);
}
__extension__ typedef int __guard __attribute__((mode (__DI__)));
extern "C" int __cxa_guard_acquire(__guard *);
extern "C" void __cxa_guard_release (__guard *);
extern "C" void __cxa_guard_abort (__guard *);
int __cxa_guard_acquire(__guard *g) {return !*(char *)(g);};
void __cxa_guard_release (__guard *g) {*(char *)g = 1;};
void __cxa_guard_abort (__guard *) {};