LINUX.ORG.RU

простой в avr-gdb (simavr)

 , ,


0

1

Сразу к делу, есть такой код:

#include <avr/io.h>
#include <avr/interrupt.h>

ISR(TIMER1_COMPA_vect) {
    PORTB ^= 0x01;
}

inline void init_timer(void) {
    TCCR1B |= (1 << WGM12); // CTC
    TCCR1B |= (1 << CS12); // clk/256
    OCR1AH = 0x1E; 
    OCR1AL = 0x84; // надо отсчитать секунду
}

int main(void) {
    DDRB = 0x01;
    PORTB = 0x00;
    init_timer();
    sei();
    while(1) {

    }
    return 0;
}

Собираю так:

avr-gcc -g -Og -DF_CPU=2000000UL -mmcu=atmega8a -o a.out test.c

Запускаю simavr так:

simavr -v -v -g -m atmega8 -f 2000000UL a.out

в avr-gdb запускаю так:

(gdb) file a.out 
Reading symbols from a.out...
(gdb) target remote :1234

В итоге, когда код подходит к sei() (прохожу по строчкам: n), выполнение встает после sei():

13          OCR1AL = 0x84;
(gdb) n
20          sei();
(gdb) n
^C^C^CRemote communication error.  Target disconnected.: Connection reset by peer.

Я хочу чтобы по таймеру происходило прерывание и переключало состояние первого бита PORTB. Такое ощущение, что avr-gdb не умеет в простой (или прерывания, хотя я могу и ошибаться), потому что я так и не дождался заветного PORTB ^= 0x01; по display.

Ответ на: комментарий от izzholtik

На реальной железке не работает. Тогда пойду разбираться где я ошибся…

Не проверял я на железке с мыслью: «Ну я же simavr ставил, чтобы можно было и без железки все пробовать»

snake266 ★★
() автор топика
Ответ на: комментарий от izzholtik

На железке заработало, да, забыл TIMSK поставить, но OCIE1A я же с 1E84 сравниаю. Но, к сожалению, с simavr и avr-gdb не завелось (надо наверно зарепортить). Ладно, попробую написать тестбенч с помощью simvar и уже в vcd файле смотреть результат.

snake266 ★★
() автор топика
Последнее исправление: snake266 (всего исправлений: 1)
Ответ на: комментарий от snake266

Не, ну хотя может прерывание и срабатывает, но gdb ничего не показывает, поэтому не понятно – работает оно или нет. Попробую чуть позже сделать vcd файл, может там что видно будет.

snake266 ★★
() автор топика

В общем, я разобрался: если поставить точку останова в блок ISR, то gdb остановиться в прерывании и покажет результат. Правда при continue он нормально подождет секунду (как я и хочу в коде), а по next, gdb либо подождет нужную секунду, либо будет очень долго думать, но потом в итоге в точку останова все-таки попадет.

Если говорить конкретнее, то, переходя с помощью n, сначала будет нормальная пауза с переходом из 0 в 1 (или наоборот), а потом очень долгая пауза, при которой состояние не меняется. c отрабатывает нормально

(gdb) n
6	}
1: PORTB = 0 '\000'
(gdb) n

Breakpoint 1, __vector_6 () at test.c:5
5	    PORTB ^= 0x01; //долгая пауза
1: PORTB = 0 '\000' 
(gdb) n
6	} // нормальная задержка
1: PORTB = 1 '\001' 
(gdb) n

Breakpoint 1, __vector_6 () at test.c:5
5	    PORTB ^= 0x01; // долгая пауза
1: PORTB = 1 '\001'
(gdb) n
6	} // нормальная задержка
1: PORTB = 0 '\000'
(gdb) 
snake266 ★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.