gretis 0 23 мая, 2012 Опубликовано 23 мая, 2012 · Жалоба Решил попробовать воспользоваться параметром --require_prototypes и понял, что не знаю, как правильно работать с обработчиками прерываний. Что должно выноситься в заголовочный файл, а что быть только в .c-файле? Как правильно описать прототип функции-обработчика прерывания? На форуме пытался найти ответ на этот вопрос, но видимо, не умею правильно его задать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alexeyv 0 24 мая, 2012 Опубликовано 24 мая, 2012 (изменено) · Жалоба Прототип функции - это объявление функции перед ее вызовом, для того чтобы компилятор мог правильно проверить типы параметров и возвращаемого значения функции. Обычно записывается в *.h и подключается include'ом в начале *.c-файла в котором используется, но можно указать и явно в начале файла: #include <stdio.h> int power(int m, int n); /* тестирование power - функции возведения в степень */ main() { int i; for (i = 0; i < 10; ++i) printf("%d %d %d\n", i, power(2,i), power(-3,i)); return 0; } /* power: возводит base в п-ю степень; n >= 0 */ int power(int base, int n) { int i, p; P = 1; for (i = 1; i <= n; ++i) p = p * base; return p; } Перед функцией main можно заметить такую строку: int power(int m, int n); Она сообщает, что power является функцией с двумя аргументами типа int, возвращающей также значение типа int. Эта декларация называется прототипом функции и обязана согласовываться по форме как с определением (заголовком) функции power, так и с любыми ее вызовами. Если определение функции отличается от ее прототипа или формы вызова, возникает ошибка. Имена параметров согласовывать не обязательно. Вообще-то не обязательно даже указывать имена параметров в прототипе функции, поэтому предыдущий прототип можно было бы записать так: int power(int, int); Однако хорошо выбранные имена являются своеобразной документацией к программе, так что они будут часто использоваться. Опция компилятора --require_prototypes, заставляет в обязательном порядке всем функциям иметь прототипы, иначе он выдаст ошибку Прототип функции прерывания - как и у всех остальных функций interrupt void dmaXmtIsr(void); /// <--- прототип функции ....... void main (void) { ...... } ...... interrupt void dmaXmtIsr(void) { ...... ............. } Подробнее - в книге Керигана/Ричи, откуда и были взяты примеры. Изменено 24 мая, 2012 пользователем alexeyv Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба Подробнее - в книге Керигана/Ричи, откуда и были взяты примеры. За изложение матчасти, конечно, спасибо, может быть, кому-то пригодится... В принципе, о прототипах я и сам могу несколько подробнее рассказать. И --require_prototypes использовал намеренно, в общем-то. Вопрос только был несколько в другом - я не совсем понимаю, как правильно объявить прототип обработчика прерывания. :fman: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Gorby 6 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба В принципе, о прототипах я и сам могу несколько подробнее рассказать. - я не совсем понимаю, как правильно объявить прототип обработчика прерывания. :fman: Как-то не согласуется одно утверждение с другим :) Прерывания НЕ являются частью языка Си. Их НЕЛЬЗЯ правильно объявить, пользуясь K&R Си. Ибо прерывание - очень особая функция, требует особых пролога-эпилога и команду возврата. Поэтому объявление прерываний абсолютно зависит от компилятора. Ищите в хелпе на компилятор. В общем случае это будет void UART1TransmittComplete(void); А где-то рядом с ним будет ключевое слово interrupt, ISR или как там у вашего компилятора. Также может указываться вектор прерывания (номер в таблице прерываний, или иная релевантная информация). Удачи! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 140 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба Вопрос только был несколько в другом - я не совсем понимаю, как правильно объявить прототип обработчика прерывания. :fman:Пока не признаетесь, какой компилятор используете - никто помочь не сможет. Ибо, как заметил Gorby, прерывания являются расширением компилятора. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба Пока не признаетесь, какой компилятор используете - никто помочь не сможет. Ибо, как заметил Gorby, прерывания являются расширением компилятора. ИАР, на данный момент работает так: #pragma vector=USART0_RX_vect __interrupt void usart_rx_complete ( void ); ... #pragma vector=USART0_RX_vect __interrupt void usart_rx_complete ( void ) { // If buffer not overflowed if ( rbuf_RX.ui_Len < USART_BUF_SIZE ) { rbuf_RX.uc_Data[rbuf_RX.ui_Next] = UDR; // Incrementing buffer counters and pointers rbuf_RX.ui_Len += 1; rbuf_RX.ui_Next += 1; // Check for pointer to next is in range if ( rbuf_RX.ui_Next == USART_BUF_SIZE ) rbuf_RX.ui_Next = 0; } } но это не более, чем эмпирическим путем полученная компиляция без ошибок. Ни подтверждения, ни опровержения правильности такого использования найти не смог. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Gorby 6 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба //--------------------------- // IAR - AVR IAR Compiler [ICCAVR] (Current Version) // required includes #include <processor-specific include> #include <inavr.h> // Architecture include // brings in __enable_interrupt() and __disable_interrupt() // not requred for the ISR itself, but will be needed to // enable interrupts in your code //handler declaration #pragma vector=interrupt-vector-name __interrupt void my_name_for_this_isr(void) { //rest of code } // NOTE: The ISR function must immediately follow the #pragma Все верно. Вы случайно угадали правильный синтаксис. http://www.avrfreaks.net/index.php?name=PN...pic&t=54318 Загляните по ссылке, как раз для Вас. А вообще - читать доку на компилятор. Там много есть интересного. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба Все верно. Вы случайно угадали правильный синтаксис. Вы привели пример declaration, меня же интересует definition... И случай с interrupt definition или что-то подобное я действительно не могу найти в "IAR C/C++ Compiler Reference Guide for Atmel® Corporation’s AVR Microcontroller Family" :blink: Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 26 мая, 2012 Опубликовано 26 мая, 2012 · Жалоба Вы привели пример declaration, меня же интересует definition... Не знаю почему написано declaration, это definition и есть. И случай с interrupt definition или что-то подобное я действительно не могу найти в "IAR C/C++ Compiler Reference Guide for Atmel® Corporation’s AVR Microcontroller Family" :blink: Из EWAVR_CompilerReference.pdf Defining an interrupt function—an example To define an interrupt function, the __interrupt keyword and the #pragma vector directive can be used. For example: #pragma vector = 0x14 __interrupt void MyInterruptRoutine(void) { /* Do something */ } Note: An interrupt function must have the return type void, and it cannot specify any parameters Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба Не знаю почему написано declaration, это definition и есть. Действительно... Но опять же, не совсем так. Это definition with declaration скорее :) То есть сразу объявление и описание. Равносильно записи char x=1; ; И этот фрагмент, в том числе, приведенный Вами из EWAVR_CompilerReference.pdf - по сути, должен находиться в .c-файле. Вопрос сводится к тому, как его "упомянуть" в .h-файле? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба Вопрос сводится к тому, как его "упомянуть" в .h-файле? А оно надо? __interrupt void MyInterruptRoutine(void); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба А оно надо? Допустим, ну очень хочется откомпилироваться с --require_prototypes __interrupt void MyInterruptRoutine(void); Смею не согласиться: Warning[Ta006]: Interrupt function has no assigned vector. C:\asp\asp_Prj\sms\USART.h 64 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба Допустим, ну очень хочется откомпилироваться с --require_prototypes Смею не согласиться: Warning[Ta006]: Interrupt function has no assigned vector. C:\asp\asp_Prj\sms\USART.h 64 Тогда так: #pragma vector=TIMER3_COMPA_vect __interrupt void timer_1khz_isr(void); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gretis 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба Тогда так: #pragma vector=TIMER3_COMPA_vect __interrupt void timer_1khz_isr(void); Вот я тоже на таком варианте остановился (см мои предыдущие сообщения), но как-то метод тыка, хоть и научного, не очень устраивает :w00t: хотелось бы понять, как действительно должно быть. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться