Измерение загрузки процессора в режиме прерывания

8

У меня есть ISR, который обновляет дисплей с фиксированной частотой. Я хотел бы настроить свою процедуру так, чтобы минимизировать накладные расходы и оставить как можно больше времени процессора открытым для другой обработки, но у меня нет никакого хорошего способа собрать метрики для определения загрузки моего процессора.

Я мог бы посмотреть на сборку и проанализировать рутину, но у меня нет терпения или способности сделать это точно. Я не чувствую, что мне нужны ужасно мелкие результаты, просто простой процент времени процессора, занимаемый isr.

Я мог бы установить высокий пин только тогда, когда isr активен и измерить его снаружи. Это имеет минимум накладных расходов в коде, но я не знаю, чем его измерять. У меня нет осциллографа или чего-то в этом роде. Есть ли простой микросхема или простой способ использовать другой микро для измерения рабочего цикла? Я слышал о специальных чипах частотомера, но есть ли что-нибудь для рабочего цикла?

captncraig
источник

Ответы:

8

Просто недоделанная идея, вы можете использовать такие таймеры (псевдокод):

int main(void)
{

    /* ... init timers and uart here, enable your interrupts ... */

    start_timer0();
    while (!timer1Started()){}
    stop_timer1();

    uart_puts("Idle ticks: %d, ISR ticks: %d", timer0_value, timer1_value);

}

и на вашем дисплее ISR ...

ISR_display()
{
    stop_timer0();
    start_timer1();

    /* ... your ISR routine ... */
}

Я сделал несколько предположений здесь. 1 - что вы не используете свои таймеры для чего-либо еще, и что 2 - накладные расходы на запуск и останов таймера минимальны (обычно это делается с одной записью в регистр). РЕДАКТИРОВАТЬ: и 3-е предположение, вы можете захватить все это до того, как произойдет переполнение таймера, но, возможно, вы также можете учитывать это.

Там будут некоторые издержки переключения контекста, которые вы не сможете отловить, и это также добавляет две дополнительные операции в ваш ISR (обязательно используйте макросы для вашего start_timer / stop_timer, чтобы исключить накладные расходы при вызове функции). Если вы можете получить общее количество циклов, используемых для макросов таймера запуска и остановки, то вы можете вычесть эти тики из timer1_value, чтобы получить значение тиков ISR немного более точно. Ваш окончательный расчет для% используемого процессорного времени будет просто:

Usagecpu=(TicksisrTicksisr+Ticksidle)100
Джон Л
источник
1
+1 за решение, не требующее внешнего оборудования. Вероятно, более громоздкий способ сделать это, но это вписывается в мои ограничения. Мне просто нужно узнать о таймерах сейчас. Спасибо.
captncraig
Я использовал это на AVR для аналогичного проекта. Это работает очень хорошо.
drxzcl
11

Установите выходной контакт при входе в ISR и очистите его, прежде чем вернуться из него. Фильтруйте вывод с помощью RC-фильтра. Напряжение на конденсаторе должно дать вам рабочий цикл ISR.
Например, если ваш источник питания составляет 3,3 В, а вы измеряете 33 мВ, то вы проводите 1% времени в ISR.

stevenvh
источник
2
Это именно то, что мы делаем, за исключением части фильтра RC. Мы устанавливаем выходной контакт при входе в ISR, затем очищаем его при возврате. Глядя на это в области видимости даст все виды полезной информации.
3
@ Дэвид - я также просто смотрю импульсы на прицеле, но ОП говорит, что у него его нет.
Stevenvh
1
Похоже, мне нужно начать экономить для хорошего объема.
captncraig
@stevenvh, именно то, что я собирался предложить, когда увидел отсутствие прицела. Вот почему эти встроенные парни любят несколько дополнительных выводов цифрового выхода.
Кортук
Фильтрация по метру при отсутствии области видимости хорошая идея. Включите / выключите светодиод и измерьте эффективную яркость: -). (Очень трудно увидеть даже довольно большие вариации - но мило.)
Рассел МакМахон
7

Самый простой способ сделать это - запустить код в симуляторе и измерить циклы, выполняемые подпрограммой прерывания. Например, симулятор Microchip MPLAB имеет удобную функцию секундомера, которая очень полезна для этой цели.

В противном случае может помочь поднятие булавки в начале прерывания и опускание его в конце. Самый простой способ посмотреть на это с помощью осциллографа. Если вы занимаетесь микроконтроллерами и электроникой, вы все равно должны их получить.

Без прицела вы могли бы просто отфильтровать напряжение на контакте, а затем измерить его с помощью вольтметра. Это напряжение, деленное на напряжение питания процессора, даст вам долю времени, в течение которого вывод высок. Например, если процессор работает с напряжением 3,3 В, а напряжение на выводе с фильтром нижних частот составляет 800 мВ, то на выводе высокое напряжение 800 мВ / 3,3 В = 24% времени.

Поскольку вы, очевидно, используете компилятор, вам нужно несколько снизить значение этого ответа. Компилятор, вероятно, добавляет некоторый код ввода прерывания перед выполнением кода и код завершения прерывания после выполнения кода. Истинное время прерывания будет продолжаться на несколько циклов с каждой стороны импульса. Конечно, если вы заботитесь о времени прерывания, вам не следует использовать компилятор.

Олин Латроп
источник