IAR & static_cast<>

sam-system wrote on Wednesday, June 04, 2008:

I’m trying to use FreeRTOS together with C++.

I’m using IAR AVR compiler.

All of FreeRTOS source files are compiled using the C compiler and my own code using Extended Embedded C++ compiler. All the code are compiled and linked togther without errors.

Inspired by a richard_damon post I’ve made a Runable class, see below.

Running my code I get an RStack warning (JTAGICE mkII)
Wed Jun 04 11:49:06 2008: Target reset
Wed Jun 04 11:49:16 2008: Program exit reached.
Wed Jun 04 11:49:17 2008: The stack ‘RStack’ is filled to 100% (32 bytes used out of 32). The warning threshold is set to 90.%

I’ve traced it down to being this static_cast causing the trouble.

(static_cast<Runable*>(parm))->Run();

If I comment the static_cast and uncomment the loop causing a led to flash everything works fine.

I have tried the same code using winavr c++ compiler and it works. Using the winavr compiler I compile everything using the c++ compiler. Therefore I have to change some cast here and there in the FreeRTOS code in order to satisfy the c++ compiler. When using IAR I can compile a "clean" FreeRTOS (without changing anything) using C compiler and my own code using C++. My guess is that its the reason for my troubles.

Can someone give me an explanation or even a way to fix it?

/Thomas

// runable.c

#include "runable.h"

//*****************************************************
Runable::Runable(unsigned priority, unsigned stacksize)
{
#if INCLUDE_vTaskDelayUntil
  lastWakeTime = NULL;
#endif
  xTaskCreate(&run, "", stacksize, this, priority, &handle);
}

//*****************
Runable::~Runable()
{
#if INCLUDE_vTaskDelete
  vTaskDelete(handle);
#endif 
}

#if INCLUDE_vTaskSuspend

//*********************
void Runable::Suspend()
{
  vTaskSuspend(handle);
}

//********************
void Runable::Resume()
{
  vTaskResume(handle);
}

#endif

#if INCLUDE_vTaskDelay

//*************************************
void Runable::Sleep(portTickType delay)
{
  vTaskDelay(delay);
}

#endif

#if INCLUDE_vTaskDelayUntil

//**********************************************
void Runable::SleepUntil(portTickType increment)
{
  if (lastWakeTime == NULL)
    lastWakeTime = xTaskGetTickCount();
  vTaskDelayUntil(&lastWakeTime, increment);
}

#endif

//***************************
void Runable::run(void* parm)
{
  (static_cast<Runable*>(parm))->Run();
/*
    for(;:wink:
    {
      PORTA = (PORTA & ~0x01) | (~PORTA & 0x01);             
               
      vTaskDelay( 100 );
    }
*/
}

rtel wrote on Thursday, June 05, 2008:

So the problem seems to be when linking C with C++ code.  Is this correct?  Can you compile the whole thing as C++ as when using the WinAVR compiler?

Regards.

sam-system wrote on Monday, June 09, 2008:

I managed to figure it out. I had some errors in my port causing the stack to be currupt.