printf function hangs - called from class constructor

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My code:


test_class::test_class()
{
  // TODO Auto-generated constructor stub
  TRACE_USER("Constructor called");
  HAL_LedOn(HAL_LED_2);
}


test_class  tt;

So class constructor is called from
.init6:
Unused for C programs, but used for constructors in C++ programs.

I registered my pre-init debug functions at
.init5:
Unused. User definable.

void preinitDebugs (void) __attribute__ ((naked))  __attribute__ ((section (".init5")));

void preinitDebugs (void)
{
  SYS_PreInitDebugs();
}

And if I am calling TRACE_USER function inside of the preinitDebugs - it works fine.

If I call it from constructor - it hangs my CPU.

For deeper check I also disabled

void HAL_UartWriteByte(uint8_t byte)

for the time of calling Cpp constructors - but it still hangs - so there is not an uart problem

Any ideas ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

it hangs my CPU.

"Hangs" where exactly? If you don't have a debugger then try the simulator.

"hang" usually means "blocks infinitely". Presumably it's waiting for a UDRE that never occurs or something?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It is not related with UART.
I commented out call to UART - and there is only call to printf - which at the end should call HAL_UartWrite.
(which body is commented out)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Then that should make simulation even easier if it's not dependent on hardware events. Just run it till it "hangs" then break and find out where PC execution is happening.

I have a feeling that printf() uses one or more globals. These may be dependent on the _do_copy_data/_do_clear_bss loops though I seem to remember they occur in .init4 so I would have thought it should be OK.

I guess only a debugger/simulator will really reveal what's going on.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks - I will try with debugger.
I have JTAGICE3 - but not configured yet for debugging.
Which one debugging env you suggest: eclipse ? others ?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

One more thing - If I call printf from .init5 - It works fine.
If I call from .init6 (Cpp class constructors) - it hangs.
Is there some potential problems ???
(I am using avr-gcc 4.5.1)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Could this be RAM allocation? Perhaps the operation of previous constructors before the one where this is called have "eaten" all the RAM already?

Anyway I guess the debugger will reveal that kind of thing.

While you can now use JTAGICE3 in Eclipse (etc) (I think support for it has been added to Avarice) the debugging experience is much better if you can use AS6 in Windows.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You cannot use complex stuff in .init sections naked function. There will be no frame pointer set up, but complex code will need a frame. You can call an ordinary noinline function from the .init function so that the callee will set up the frame.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I imaging you don't explicitly put code in .init6; that's just where the constructors for static class variables get called from, right?

You have to remember that avr-c++ doesn't have a real C++ library, nor an operating system. When the C++ startup code allocates static class variables, this is happening before main(), so any of the things that need to be initialized (like UARTS) are NOT set up yet. This limits the things that you can do in the constructor!

(Hmm. The things I've seen just avoid doing "complex things" in constructors. Is there a standard method (putting code in .init5?) for setting up things that you wish to have active by the time the constructors get called?)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

(putting code in .init5?)

That would be the way to do it.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Where I need to do IO in a constructor I actually create a separate member function class::init() that I explicitly call once the uC is up and running.

I use a rtos sometimes and the idea of wait/signal in constructors seems guaranteed to break something.

you could leave the string you want to print in a buffer and print it later when the system is fully running.

regards
Greg