Thread code crashing when statically allocated

ChibiOS public support forum for topics related to the Atmel AT91SAM7x family of micro-controllers.

Moderator: inmarket

JetForMe
Posts: 99
Joined: Mon Jan 31, 2011 8:12 am

Thread code crashing when statically allocated

Postby JetForMe » 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!

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

Jeroen3
Posts: 35
Joined: Wed Apr 02, 2014 10:14 am

Re: Thread code crashing when statically allocated

Postby Jeroen3 » Wed Aug 13, 2014 11:04 am

Isn't the working area allocated on stack when you define it in a template?

JetForMe
Posts: 99
Joined: Mon Jan 31, 2011 8:12 am

Re: Thread code crashing when statically allocated

Postby JetForMe » Wed Aug 13, 2014 4:58 pm

Not necessarily. Depends on where you declare the variable based on the template type.


Return to “AT91SAM7x Support”

Who is online

Users browsing this forum: No registered users and 1 guest