Передача структуры в ISR

Я программирую на C, используя Hi-Tech-PICC v9.65PL1 для программирования PIC16F876.

Для прерываний я использую структуру:

void interrupt isr() {
    if (T0IF) {
               //Do STUFF
     T0IF = 0;
    }
}

Я пытаюсь понять, как передать объект в ISR. Я знаю, что могу просто сделать объект глобальной переменной, но суть не в этом. Я видел, как это делается на C с другой архитектурой. Поскольку я использую C, когда я говорю объект, я имею в виду структуру typedef, например:

typedef struct {
    volatile char state;
    rtc_t rtc;
    shiftReg_t shiftReg;
} clock_t;

Моя цель состоит в том, чтобы ISR изменил «состояние» в структуре clock_t.

Может кто-нибудь объяснить, что связано с этим?


person Michael    schedule 22.04.2013    source источник
comment
Как это было сделано в той другой архитектуре, о которой вы говорите?   -  person    schedule 22.04.2013
comment
qnx.com/developers/docs/6.3.0SP3/ neutrino/prog/inthandler.html под заголовком Обновление общих структур данных примерно на полпути вниз по странице.   -  person Robert Harvey    schedule 22.04.2013


Ответы (2)


Из того, что я вижу, учитывая, что архитектура не сильно отличается, вам нужно будет выполнить атомарную операцию для изменения состояния в структуре clock_t.

Тем не менее, может ли void interrupt isr() принимать параметр? Если да, то вы можете использовать локальную структуру clock_t, иначе лучше всего использовать глобальную переменную.

Если isr ​​принимает параметр, вы можете сделать так:

int main()
{
    clock_t noteState;
    ....
    isr(&noteState);
    ....
}

и определение isr как::

void interrupt isr(clock_t *tmp)
{
    interruptDisable(); // I am guessing that T0IF is a global value, yes?
    /* Perform operation */
    tmp->state = newState /*(whatever you choose to set)*/
    interruptEnable();
}

Затем вы можете повторно использовать noteState в будущем :)

person Binayaka Chakraborty    schedule 22.04.2013

В некоторых случаях обновление переменной в IRQ является «атомарным», если переменная может быть обновлена ​​в одной инструкции, такой как увеличение, уменьшение, только чтение, только запись. Таким образом, вам не нужно отключать и включать прерывание для кода bare-c в обработчике IRQ. Некоторые кодеры ОС предоставляют вам функции для таких ситуаций, чтобы быть уверенным, что переменная обновляется с помощью одной инструкции. Пример функции ОС: http://www.qnx.com/developers/docs/6.3.2/neutrino/lib_ref/a/atomic_add.html

В некоторых других случаях операции чтения/изменения/записи не являются атомарными на большинстве процессоров (хотя они /являются/ атомарными на некоторых процессорах CISC), и нет гарантии атомарности при доступе к нескольким переменным. В этих случаях перед обновлением переменных используются функции enter_critical_section() и после обновления переменных exit_critical_section(). Для случаев bare-c (не ОС) эти функции сводятся к функциям interruptEnable() и interruptDisable().

person Onur Turhan    schedule 22.04.2013