robix 0 1 марта, 2011 Опубликовано 1 марта, 2011 (изменено) · Жалоба Всем привет! заметил странную особенность в программировании NIOSII. При вызове обработчика прерывания передаю ему контекст в виде переменной, похоже он передается по значению, поэтому переменная не меняется при возврате в программу. Ну это еще ладно, я изменяю значение глобальной переменной в обработчике прерывания, по возврату из прерывания ее значение не меняется. И самый прикол, такое ощущение, что при обращении к глобальной переменной в обработчике создается постоянная переменная, которая видна только в обработчике прерывания. Кто нибудь может прокомментировать такое поведение? Как мне вернуть переменную из обработчика прерывания? #include "system.h" #include "alt_types.h" #include "altera_avalon_pio_regs.h" #include "sys/alt_irq.h" alt_u8 led = 0x0; volatile int i,j; static void timer_0_isr (void* context){ led++; IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, led); IOWR_16DIRECT(TIMER_0_BASE, 0, 0); } int main(void) { IOWR_ALTERA_AVALON_PIO_IRQ_MASK(SW_BASE, 0xf); alt_ic_isr_register(TIMER_0_IRQ_INTERRUPT_CONTROLLER_ID, TIMER_0_IRQ, timer_0_isr, led, 0); while(1){ for(i = 0; i < 5000000; i++); led = 0; IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, led); } return 0; } Изменено 1 марта, 2011 пользователем robix Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 1 марта, 2011 Опубликовано 1 марта, 2011 · Жалоба Что-то мутное у вас многое в программе. 1. Функция обработчика прераваний не может иметь параметров. В функцию параметр передается через регистр или стек, в зависимости от процессора и/или компилятора, и делает это вызывающий контекст. Посему static void timer_0_isr (void); 2. Вас интересует переменная led. Ну и объявите ее volatile int led = 0x0; и будет вам счастье. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба 1. Функция обработчика прераваний не может иметь параметров. В функцию параметр передается через регистр или стек, в зависимости от процессора и/или компилятора, и делает это вызывающий контекст. почему это не может? еще как может: alt_ic_isr_register() ... Prototype: int alt_ic_isr_register (alt_u32 ic_id, alt_u32 irq, alt_isr_func isr, void* isr_context, void* flags) ... The function arguments are as follows: ■ ic_id is the interrupt controller ID as defined in system.h, identifying the external interrupt controller in the daisy chain. This argument is ignored if the external interrupt controller interface is not implemented. ■ irq is the IRQ number, as defined in system.h, identifying the interrupt to register. ■ isr is the function that is called when the interrupt is accepted. ■ isr_context is the input argument to isr. isr_context points to a data structure associated with the device driver instance. ■ flags is reserved. The ISR function prototype is defined as follows: typedef void (*alt_isr_func) (void* isr_context); собственно, предполагается, что все переменные, который необходимы внутри обработчика прерывания, передаются через структуру context Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба Да уж, NIOS II это круто. В функции extern int alt_ic_isr_register(alt_u32 ic_id, alt_u32 irq, alt_isr_func isr, void *isr_context, void *flags); 4-ый параметр - это указатель на ваш контекст, нe правда ли? Тогда вы должны вызывать у себя в таком виде: alt_ic_isr_register(TIMER_0_IRQ_INTERRUPT_CONTROLLER_ID, TIMER_0_IRQ, timer_0_isr, &led, NULL); а в обработчике, что-то типа: static void timer_0_isr (void* context){ alt_u8 *pled = ((alt_u8 *)context; (*pled)++; IOWR_ALTERA_AVALON_PIO_DATA(LED_BASE, led); IOWR_16DIRECT(TIMER_0_BASE, 0, 0); } Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ViKo 1 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба С NIOS не знаком. Но, как и sergeeff, недоумеваю. Как в прерывание можно передать аргументы? Оно ж возникает в непредсказуемый момент. Кто ему что-то должен передать? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
robix 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба Всем спасибо. Пока вышел из ситуации использованием объявления переменной с volatile. Но, как я понял, эта проблема (c volatile) относится не только к прерываниям. Как понять когда его нужно использовать когда нет!? У кого нить есть соображения по этому поводу? Пока, как я понимаю, его нужно пихать везде, где к одной и той же переменной нужно обращаться из разных областей видимости или может только для совместного использования с функциями оно нужно? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба Как в прерывание можно передать аргументы? Оно ж возникает в непредсказуемый момент. Кто ему что-то должен передать? ему передается структура, связанная с устройством (файл устройства, дескрипторы и прочая муть). передается при регистрации обработчика прерывания. Но, как я понял, эта проблема (c volatile) относится не только к прерываниям. Как понять когда его нужно использовать когда нет!? возьмите любой справочник по Си, там все расписано. это стандартная практика при работе в многопоточных окружениях. вот погодите, доберетесь до фокусов с data cache, там еще веселее Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
robix 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба С NIOS не знаком. Но, как и sergeeff, недоумеваю. Как в прерывание можно передать аргументы? Оно ж возникает в непредсказуемый момент. Кто ему что-то должен передать? По поводу прерывания скажу, что в ниосе это очень полезная фишка, в смысле удобная, передавать в прерывание контекст обрабатываемого устройства, в общем мне нравится :) И вообще, мне вся эта схема разруливания прерываний в ниосе чем то напоминает менеджер задач. Интересно, учитывая наличие программных прерываний в ниосе, можно их использовать как независимые процессы!? кто нить пробовал? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
barabek 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба Всем спасибо. Пока вышел из ситуации использованием объявления переменной с volatile. Но, как я понял, эта проблема (c volatile) относится не только к прерываниям. Как понять когда его нужно использовать когда нет!? Не совсем то, но в тему из NII software developers handbook For C programmers, note that declaring a pointer as volatile does not cause accesses using that volatile pointer to bypass the data cache. The volatile keyword only prevents the compiler from optimizing out accesses using the pointer. This volatile behavior is different from the methodology for the first-generation Nios processor. И, кажется, еще где-то видел (могу ошибаться), но как я понял слово volatile не всегда спасает от считывания старой (не актуальной) величины из кэша. Если ошибаюсь - поправьте, самому интересно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба И, кажется, еще где-то видел (могу ошибаться), но как я понял слово volatile не всегда спасает от считывания старой (не актуальной) величины из кэша. Если ошибаюсь - поправьте, самому интересно. не спасает, за кэшем надо следить Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба не спасает, за кэшем надо следить За кешем надо следить только, если не процессор пишет/читает данные, например DMA. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 2 марта, 2011 Опубликовано 2 марта, 2011 · Жалоба За кешем надо следить только, если не процессор пишет/читает данные, например DMA. у меня все системы с DMA. и не с одним :) (неужели ниос кто-то без DMA применяет?) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
sergeeff 1 3 марта, 2011 Опубликовано 3 марта, 2011 · Жалоба у меня все системы с DMA. и не с одним :) (неужели ниос кто-то без DMA применяет?) Никто не мешает буфера для DMA разместить в некешируемой области, к примеру. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vadimuzzz 0 3 марта, 2011 Опубликовано 3 марта, 2011 · Жалоба Никто не мешает буфера для DMA разместить в некешируемой области, к примеру. что-то не понял как, поясните Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexPec 3 3 марта, 2011 Опубликовано 3 марта, 2011 · Жалоба что-то не понял как, поясните А старший битик в адресе не означет некэшируемую область? По моему Вы мне про это и говорили летом... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться