Перейти к содержанию
    

Быстрое прерывание на AVR GCC

Здравствуйте. Использую связку STK500 + mega128 + AStudio6 в качестве даталоггера.

По прерыванию INT2 читаются значения двух пинов. Вот такой простой код:

 

 

 

 

ISR (INT2_vect)
{
    m_master_byte |= (PINF & 0x01);
    m_slave_byte |= (PINC & 0x01);

    if (m_bit_counter <= 7)
    {
        ++m_bit_counter;
        if (m_bit_counter <= 7) {
            m_master_byte <<= 1;
            m_slave_byte <<= 1;
        } else {
            a_master_byte_array[m_byte_counter] = m_master_byte;
            a_slave_byte_array[m_byte_counter] = m_slave_byte;
        }
    } else {
        m_master_byte = 0;
        m_slave_byte = 0;
        m_bit_counter = 0;
        ++m_byte_counter;
    }
}

 

Но AVR GCC как известно наворачивает сохранение и восстановление контекста при работе с подпрограммами, вот касок листинга:

 

00000204 <__vector_3>:
204:    1f 92           push    r1
206:    0f 92           push    r0
208:    0f b6           in    r0, 0x3f; 63
20a:    0f 92           push    r0
20c:    11 24           eor    r1, r1
20e:    0b b6           in    r0, 0x3b; 59
210:    0f 92           push    r0
212:    8f 93           push    r24
214:    9f 93           push    r25
216:    ef 93           push    r30
218:    ff 93           push    r31

... собственно сама работа ...

246:    ff 91           pop    r31
248:    ef 91           pop    r30
24a:    9f 91           pop    r25
24c:    8f 91           pop    r24
24e:    0f 90           pop    r0
250:    0b be           out    0x3b, r0; 59
252:    0f 90           pop    r0
254:    0f be           out    0x3f, r0; 63
256:    0f 90           pop    r0
258:    1f 90           pop    r1
25a:    18 95           reti

 

 

 

Т.е. время реакции на прерывание увеличивается.

 

Подскажите, есть ли какие опции у AVR GCC, позволяющие отключать эту обёртку. А то уже думаю этот ISR в отдельном asm файле сделать. Но обработчик хоть и небольшой, придётся повозиться, да и перепроверять заново надо будет. Отказаться от ISR тоже не выходить, т.к. там в основном цикле while тоже кода много. Кто-нибудь сталкивался с таким?

 

P.S. Кусок конечно у листинга, а не касок. Вроде текст перечитывал...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно, например, так:

 

ISR (INT2_vect,ISR_NAKED)

{

...

}

 

Но функция будет действительно голой, без сохранения регистра статуса и даже без reti (avr-gcc 4.7.2). Минимально нужно хотя бы asm("reti"); в конце поставить.

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо большое. Это очень хорошо. Дальше буду смотреть по документации.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Использую связку в качестве даталоггера.
А что це такэ - даталоггер?

 

По прерыванию INT2 читаются значения двух пинов. Вот такой простой код:
Не такой уж и простой - там ещё и сохранение прочитанных битов в байты, а потом сохранение байтов в массивы.

 

Но AVR GCC как известно наворачивает сохранение и восстановление контекста при работе с подпрограммами, вот касок листинга:

Т.е. время реакции на прерывание увеличивается.

Подскажите, есть ли какие опции у AVR GCC, позволяющие отключать эту обёртку.
GCC не наворачивает, а сохраняет используемые в прерывании регистры. Как без этого?

 

А то уже думаю этот ISR в отдельном asm файле сделать.
Тоже можно, но не факт что намного быстрее получится.

 

Отказаться от ISR тоже не выходить, т.к. там в основном цикле while тоже кода много. Кто-нибудь сталкивался с таким?
Все рано или поздно с таким сталкиваются...Думаю, что надо менять прерывание в сторону его упрощения:

1) сохранять в ISR (INT2_vect) только биты и увеличивать счётчик принятых битов.

2) Когда будет принят байт нужно его сохранить во временной переменной и установить флаг приёма байта.

3а) Далее по этому флагу в основной программе записать байт в массив.

3б) Если цикл основной программы может быть дольше чем время передачи байта, вызвать программное прерывание, в котором байт записывается в массив.

3в) Можно что-нибудь ещё придумать. Например не логировать ничего - вам действительно нужны эти байты? Может эту задачу и решать-то не надо?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1) Даталоггер - в моём понимании читает значения линий (цифровых) в определённые значения времени. простенький цифровой осциллограф. А дальше уже на данные компьютере просматриваю что и как.

 

 

2) Я все переменные объявил как register. В листинге посмотрел - по честному в регистрах находятся.

 

3), 4) Попробую рискнуть без сохранения контекста поработать.

 

5) Тем более что написание программ на ассемблере чревато сложноуловимыми багами.

 

6) Да. Скорее всего буду сохранять значения линий во время ISR, а в основном теле уже смотреть.

 

 

 

 

3в) Можно что-нибудь ещё придумать. Например не логировать ничего - вам действительно нужны эти байты? Может эту задачу и решать-то не надо?

 

Лучший выход - купить хороший цифровой осциллограф. Или PCI плату сбора данных...

Пробую сам сделать на ARM LPC, но пока не доделал.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нужно сократить число переменных в прерывании.

так что пишите оба сигнала в одих байт ( четный бит - одна линия, нечетный - другая линия ) И все в итоге пишите в один массив

 

еще как вариант зарезервировать пару регистров, чтобы компилятор их не юзал. А вы использовали бы их как глобальные переменные. Тогда не нужно лишний раз работать со стеком

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...