I'm faced with a weird problem. I'm developing a program for AVR
.
- Microcontroller
ATtiny85
. - Frequency 1 MHz.
- Programmer
pickit2
. - Software for programming
avrdude
on Linux. - Compiler
avr-g++
. - Optimization
-Os
(I tested with-O0
, it doesn't work too).
This program must enable output pin PB3
. But for some reason, it doesn't.
#include <avr/io.h>
#include <avr/interrupt.h>
#define NOINLINE_ENABLED 1
#if NOINLINE_ENABLED == 1
#define NOINLINE __attribute__ ((noinline))
#else
#define NOINLINE
#endif
// Error occurs only if SetLedState method has noinline attribute or function implemented in other .cpp file (also noinline).
// NOINLINE_ENABLED macros enables noinline for this method
void NOINLINE SetLedState(bool state) {
if (state)
PORTB |= (1 << PB3);
else
PORTB &= ~(1 << PB3);
}
class Test {
public:
Test(unsigned int a) : a_(a) {}
void Update() {
// a_ for some reasons doesn't equal 5, but it's impossible.
if (this->a_ == 5)
SetLedState(true);
}
private:
// I don't know why, but error doesn't occur if I add first variable, which can never be used
// unsigned int padding = 0;
const unsigned int a_;
};
static Test *test;
ISR(TIMER1_OVF_vect) {
// error occurs when method called from timer interrupt method
test->Update();
}
[[noreturn]] int main() {
test = new Test(5);
DDRB = (1 << PB3);
PORTB = 0;
TIMSK = (1 << TOIE1);
TCCR1 = (1 << CS10);
sei();
// no error occurs when method called from this place
// test->Update();
while (true);
}
I wrote some comments to explain why it doesn't work. I think the problem is in the optimizer.
Output PB3
doesn't enable if (and):
Test::Update
method calls from timer overflow interrupt.a_
class member has offset 2 and more.SetLedState
is no inlined or implemented in other*.cpp
file.
Why? Thanks in advance!
Edit:
Also, I tried to change the implementation of new
C++ operator.
Earlier it called return alloca(size)
, but now I tried to call return malloc(size)
. And it worked. Also, this initialization works too:
static Test test_static;
test = &test_static;
Why it doesn't work with alloca
? What is the difference with malloc and alloca AVR functions?