реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Прототип обработчика прерывания, попробовал воспользоваться --require_prototypes
aspID
сообщение May 23 2012, 07:51
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Решил попробовать воспользоваться параметром --require_prototypes и понял, что не знаю, как правильно работать с обработчиками прерываний.

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

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

Go to the top of the page
 
+Quote Post
alexeyv
сообщение May 24 2012, 03:25
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 298
Регистрация: 26-01-09
Из: Пермь
Пользователь №: 43 940



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


Подробнее - в книге Керигана/Ричи, откуда и были взяты примеры.

Сообщение отредактировал alexeyv - May 24 2012, 03:27
Go to the top of the page
 
+Quote Post
aspID
сообщение May 26 2012, 06:58
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



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


За изложение матчасти, конечно, спасибо, может быть, кому-то пригодится... В принципе, о прототипах я и сам могу несколько подробнее рассказать. И --require_prototypes использовал намеренно, в общем-то. Вопрос только был несколько в другом - я не совсем понимаю, как правильно объявить прототип обработчика прерывания. fman.gif
Go to the top of the page
 
+Quote Post
Gorby
сообщение May 26 2012, 07:20
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 449
Регистрация: 28-10-04
Из: Украина
Пользователь №: 1 002



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


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

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

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

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

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

void UART1TransmittComplete(void);

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

Удачи!


--------------------
Умею молчать на 37 языках...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 26 2012, 08:15
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
aspID
сообщение May 26 2012, 13:03
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(Сергей Борщ @ 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;
    }
}


но это не более, чем эмпирическим путем полученная компиляция без ошибок. Ни подтверждения, ни опровержения правильности такого использования найти не смог.
Go to the top of the page
 
+Quote Post
Gorby
сообщение May 26 2012, 13:31
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 449
Регистрация: 28-10-04
Из: Украина
Пользователь №: 1 002



Код
//---------------------------
// 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

Загляните по ссылке, как раз для Вас.
А вообще - читать доку на компилятор. Там много есть интересного.


--------------------
Умею молчать на 37 языках...
Go to the top of the page
 
+Quote Post
aspID
сообщение May 26 2012, 17:51
Сообщение #8


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(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
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 26 2012, 18:02
Сообщение #9


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(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

Go to the top of the page
 
+Quote Post
aspID
сообщение May 27 2012, 04:11
Сообщение #10


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



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


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

Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 27 2012, 04:17
Сообщение #11


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



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

А оно надо?

Код
__interrupt void MyInterruptRoutine(void);
Go to the top of the page
 
+Quote Post
aspID
сообщение May 27 2012, 09:40
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(_Артём_ @ 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 
Go to the top of the page
 
+Quote Post
_Артём_
сообщение May 27 2012, 09:47
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322



Цитата(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);
Go to the top of the page
 
+Quote Post
aspID
сообщение May 27 2012, 10:06
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 343
Регистрация: 24-01-07
Из: Новосибирск
Пользователь №: 24 714



Цитата(_Артём_ @ May 27 2012, 16:47) *
Тогда так:

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


Вот я тоже на таком варианте остановился (см мои предыдущие сообщения), но как-то метод тыка, хоть и научного, не очень устраивает w00t.gif хотелось бы понять, как действительно должно быть.
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 30th June 2025 - 14:43
Рейтинг@Mail.ru


Страница сгенерированна за 0.01514 секунд с 7
ELECTRONIX ©2004-2016