Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Прототип обработчика прерывания
Форум разработчиков электроники ELECTRONIX.ru > Сайт и форум > В помощь начинающему > Программирование
aspID
Решил попробовать воспользоваться параметром --require_prototypes и понял, что не знаю, как правильно работать с обработчиками прерываний.

Что должно выноситься в заголовочный файл, а что быть только в .c-файле? Как правильно описать прототип функции-обработчика прерывания?

На форуме пытался найти ответ на этот вопрос, но видимо, не умею правильно его задать.

alexeyv
Прототип функции - это объявление функции перед ее вызовом, для того чтобы компилятор мог правильно проверить типы параметров и возвращаемого значения функции. Обычно записывается в *.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)
{
......
.............
}


Подробнее - в книге Керигана/Ричи, откуда и были взяты примеры.
aspID
Цитата(alexeyv @ May 24 2012, 10:25) *
Подробнее - в книге Керигана/Ричи, откуда и были взяты примеры.


За изложение матчасти, конечно, спасибо, может быть, кому-то пригодится... В принципе, о прототипах я и сам могу несколько подробнее рассказать. И --require_prototypes использовал намеренно, в общем-то. Вопрос только был несколько в другом - я не совсем понимаю, как правильно объявить прототип обработчика прерывания. fman.gif
Gorby
Цитата(aspID @ May 26 2012, 09:58) *
В принципе, о прототипах я и сам могу несколько подробнее рассказать.
- я не совсем понимаю, как правильно объявить прототип обработчика прерывания. fman.gif


Как-то не согласуется одно утверждение с другим sm.gif

Прерывания НЕ являются частью языка Си. Их НЕЛЬЗЯ правильно объявить, пользуясь K&R Си.

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

Поэтому объявление прерываний абсолютно зависит от компилятора. Ищите в хелпе на компилятор.

В общем случае это будет

void UART1TransmittComplete(void);

А где-то рядом с ним будет ключевое слово interrupt, ISR или как там у вашего компилятора.
Также может указываться вектор прерывания (номер в таблице прерываний, или иная релевантная информация).

Удачи!
Сергей Борщ
QUOTE (aspID @ May 26 2012, 09:58) *
Вопрос только был несколько в другом - я не совсем понимаю, как правильно объявить прототип обработчика прерывания. fman.gif
Пока не признаетесь, какой компилятор используете - никто помочь не сможет. Ибо, как заметил Gorby, прерывания являются расширением компилятора.
aspID
Цитата(Сергей Борщ @ May 26 2012, 15:15) *
Пока не признаетесь, какой компилятор используете - никто помочь не сможет. Ибо, как заметил 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
Код
//---------------------------
// 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

Загляните по ссылке, как раз для Вас.
А вообще - читать доку на компилятор. Там много есть интересного.
aspID
Цитата(Gorby @ May 26 2012, 20:31) *
Все верно. Вы случайно угадали правильный синтаксис.


Вы привели пример declaration, меня же интересует definition... И случай с interrupt definition или что-то подобное я действительно не могу найти в "IAR C/C++ Compiler Reference Guide for Atmel® Corporation’s AVR Microcontroller Family" blink.gif
_Артём_
Цитата(aspID @ May 26 2012, 20:51) *
Вы привели пример declaration, меня же интересует definition...

Не знаю почему написано declaration, это definition и есть.

Цитата(aspID @ May 26 2012, 20:51) *
И случай с interrupt definition или что-то подобное я действительно не могу найти в "IAR C/C++ Compiler Reference Guide for Atmel® Corporation’s AVR Microcontroller Family" blink.gif

Из 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

aspID
Цитата(_Артём_ @ May 27 2012, 01:02) *
Не знаю почему написано declaration, это definition и есть.


Действительно... Но опять же, не совсем так. Это definition with declaration скорее sm.gif То есть сразу объявление и описание. Равносильно записи
Код
char x=1;
; И этот фрагмент, в том числе, приведенный Вами из EWAVR_CompilerReference.pdf - по сути, должен находиться в .c-файле. Вопрос сводится к тому, как его "упомянуть" в .h-файле?

_Артём_
Цитата(aspID @ May 27 2012, 07:11) *
Вопрос сводится к тому, как его "упомянуть" в .h-файле?

А оно надо?

Код
__interrupt void MyInterruptRoutine(void);
aspID
Цитата(_Артём_ @ May 27 2012, 11:17) *
А оно надо?
Допустим, ну очень хочется откомпилироваться с --require_prototypes
Цитата(_Артём_ @ May 27 2012, 11:17) *
Код
__interrupt void MyInterruptRoutine(void);
Смею не согласиться: Warning[Ta006]: Interrupt function has no assigned vector. C:\asp\asp_Prj\sms\USART.h 64 
_Артём_
Цитата(aspID @ May 27 2012, 12:40) *
Допустим, ну очень хочется откомпилироваться с --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);
aspID
Цитата(_Артём_ @ May 27 2012, 16:47) *
Тогда так:

Код
#pragma vector=TIMER3_COMPA_vect
__interrupt void timer_1khz_isr(void);


Вот я тоже на таком варианте остановился (см мои предыдущие сообщения), но как-то метод тыка, хоть и научного, не очень устраивает w00t.gif хотелось бы понять, как действительно должно быть.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.