FreeRTOS Support Archive
The FreeRTOS support forum is used to obtain active support directly from Real
Time Engineers Ltd. In return for using our top quality software and services for
free, we request you play fair and do your bit to help others too! Sign up
to receive notifications of new support topics then help where you can.
This is a read only archive of threads posted to the FreeRTOS support forum.
The archive is updated every week, so will not always contain the very latest posts.
Use these archive pages to search previous posts. Use the Live FreeRTOS Forum
link to reply to a post, or start a new support thread.
[FreeRTOS Home] [Live FreeRTOS Forum] [FAQ] [Archive Top] [September 2015 Threads] object pointer hard faultPosted by joe31093 on September 22, 2015 FreeRTOS V8.1.2, MSP432P401R Demo project, CCS Version: 6.1.0.00104
I am try to make a general C++ class for working with tasks. I have a base class that contains the static function for xTaskCreate, which is used by the derived class when creating the task. The derived class this pointer is passed to xTaskCreate and eventually used by the static function to call a derived class method. But in the call to the derived class method, a hard fault is generated. Anyone have any suggestions on where to look to resolve this issue?
TaskBase.h
...
class TaskBase {
public:
TaskBase();
virtual ~TaskBase();
virtual void createTask() = 0;
virtual void run();
static void runTask(void* param);
protected:
string mtaskName;
unsigned short mtaskStackSize;
unsigned long mtaskPriority;
unsigned long mtickDelay;
};
TaskBase.cpp
...
TaskBase::TaskBase():
mtaskName("Base"),
mtaskStackSize(512),
mtaskPriority(tskIDLEPRIORITY + 1),
mtickDelay(pdMSTO_TICKS(100))
{
}
TaskBase::~TaskBase()
{
}
void TaskBase::runTask(void* param)
{
TaskBase* basePtr = static_cast(param);
if (basePtr != NULL)
basePtr->run();** // HARD FAULT HERE**
}
void TaskBase::run()
{
}
TaskSystemData.h
...
class TaskSystemData: public TaskBase {
public:
TaskSystemData();
virtual ~TaskSystemData();
virtual void createTask();
virtual void run();
virtual unsigned long getTickDelay() {return m_tickDelay;}
};
TaskSystemData.cpp
TaskSystemData::TaskSystemData()
{
}
TaskSystemData::~TaskSystemData()
{
}
void TaskSystemData::createTask()
{
xTaskCreate((TaskFunctiont) &TaskBase::runTask, // The function that implements the task.
mtaskName.cstr(), // The text name assigned to the task - for debug only as it is not used by the kernel.
mtaskStackSize, // The size of the stack to allocate to the task.
this, // The parameter passed to the task.
m_taskPriority, // The priority assigned to the task.
NULL);
}
void TaskSystemData::run()
{
unsigned long sequenceIndex = 0;
unsigned long sequenceValue = 0;
unsigned long tickDelay = pdMSTOTICKS(100);
// more code....
}
main.cpp
// more code...
TaskSystemData systemDataTask;
systemDataTask.createTask();
//Start real time scheduler
vTaskStartScheduler();
object pointer hard faultPosted by heinbali01 on September 22, 2015 Hi Joe,
Tonight I will try-out what you want to do.
Except for some asterixes that are removed by formatting, the code looks OK to me.
Regards.
object pointer hard faultPosted by heinbali01 on September 22, 2015 Could you extend the class TaskSystemData with 2 operators:
~~~~~
class TaskSystemData {
public:
static void* operator new (size_t size)
{
return (void*)pvPortMalloc( size );
}
static void operator delete(void *p)
{
vPortFree( p );
}
~~~~~
and use new() to create the object:
~~~~~
TaskSystemData *task;
// Later on...
task = new TaskSystemData;
~~~~~
I haven't tried it out yet, the above is just a guess :-)
Regards, Hein
object pointer hard faultPosted by joe31093 on September 22, 2015 Hi Hein,
Thanks for the reply. I will give what you suggested a try later today. One thing I did last night that got it working was that I move the TaskSystemData object out of the main function (in to global space) and it worked. I don't understand why yet. I looked at the registers when it failed and did not get a lot of informaiton from it. Is it a memory map issue?
main.cpp
TaskSystemData systemDataTask;** // moved out of main scope**
int main( void )
{
SystemConfig systemConfig;
systemConfig.setupHardware();
systemConfig.setupClocks();
//TaskSystemData systemDataTask;
systemDataTask.createTask();
// Start real time scheduler
vTaskStartScheduler();
return 0;
}
object pointer hard faultPosted by heinbali01 on September 22, 2015 That's it, first you declared it as an automatic variable, it was located in the initial application stack.
After starting the scheduler, there will be a new stack per task, and the initial stack might have become unreliable.
That is why I asked you to try create it with new() . But declaring it as a global variable works as well. As long as the constructor is called (implicitly), and as long as the space is not reused for something else.
Make sure that new and delete always refer to a safe memory allocator, the default usage of malloc()/free() won't be thread safe.
One more thing is worth telling: when using C++ and GCC, I get a strange error when declaring a static object within a function:
~~~~~
void foo()
{
static CSomeClass someObject;
// Code using someObject
}
/../main.cpp:415: undefined reference to __cxa_guard_acquire'
/../main.cpp:415: undefined reference to _cxaguard_release'
~~~~~
As I rarely run into this problem, I just avoid the situation by making the object static in the module:
~~~~~
static CSomeClass xSomeObject;
void foo()
{
// Code using xSomeObject
}
~~~~~
Wish you fun with C++ coding!
object pointer hard faultPosted by richard_damon on September 23, 2015 If you want to look at it, I have just posted some code for a FreeRTOS C++ wrapper library at https://github.com/richard-damon/FreeRTOScpp
It is one I have been using for many years. The documentation needs some work (it if very sparse, but the code is simple so fairly understandable).
As to the gcc guard_acquire / release error, my guess is that gcc is looking for some functions to interface to the RTOS for exclusive access. static variables within a function are not created until the function is first entered, and if you are in a multi-threaded enviroment (like in FreeRTOS with the scheduler running) there is a possible race condition for initializing a local static variable. Many compilers, like gcc, have define a set of functions like these that the RTOS is supposed to define to make this work. (sometimes there is also a hook in malloc/free similar to this to make them safe).
I suppose that ideally, someone would dig through the various compilers documentation for what these functions are, and what the really need to do, and add a file in the portable layer to define them. (Sounds like a great way for a user to provide help back).
object pointer hard faultPosted by rtel on September 23, 2015 I really must link to this from the FR.o website!
Regards.
object pointer hard faultPosted by joe31093 on September 24, 2015
Copyright (C) Amazon Web Services, Inc. or its affiliates. All rights reserved.
|