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

 
 
> Обработчик прерываний в HI-TECH, Вызов подпрограмм
Grigorij
сообщение May 7 2008, 05:00
Сообщение #1


Участник
*

Группа: Участник
Сообщений: 71
Регистрация: 10-03-07
Пользователь №: 26 038



Здравствуйте.

Наконец-таки начал переползать с ассемблера на Си и возникла следующая проблем. Имеется код (приведены только отрывки на которых спотыкается компилятор):

Код
//изменение скорости обмена
void SetBRate(unsigned brate)
{
....
}

//отправка данных
void SendByte(unsigned brate,unsigned char data)
{    
     SetBRate(brate);
....
}

//отправка данных на индикатор
static void _send_byte(unsigned char data)
{
....
    SendByte(br_19200,data);    
....
    SetBRate(br_1200);
}    

//вывод символа на индикатор
void WriteChar(unsigned char chr)
{
     //корректировка кода для русских букв
     if (chr >= 0xC0 && chr <= 0xEF)
         chr -= 0x40;
     else
         if (chr >= 0xF0)
            chr -= 0x10;
    
     _send_byte(chr);
}

//обработчик прерываний от Timer 0    
void INT_TMR0(void)
{    
     static int cnt = 0;
    
      if (++cnt >= 10)
      {
           WriteChar('1');
           cnt = 0;
       }
    
       T0IF = 0;    
}

//обработчик прерываний
void interrupt INTHandler(void)
{
      if (T0IF) INT_TMR0();    //прерывание от Timer 0
      if (RCIF) INT_RxD();    //прерывание от приемника EUSART
}


При комплияции выдаются следующие сообщения об ошибках:

Код
Error   [472]; . non-reentrant function "__send_byte" appears in multiple call graphs: rooted at "_INTHandler" and "_main"

Error   [472]; . non-reentrant function "_SendByte" appears in multiple call graphs: rooted at "_INTHandler" and "_main"

Error   [472]; . non-reentrant function "_SetBRate" appears in multiple call graphs: rooted at "_INTHandler" and "_main"


В документации на HI-TECH написано, что:

(472) non-reentrant function "*" appears in multiple call graphs: rooted at "*" and "*" (Linker)
This function can be called from both main-line code and interrupt code. Use the reentrant keyword, if this compiler supports it, or recode to avoid using local variables or parameters, or duplicate the function, e.g.:


Однако из описания ошибки я так и не понял, как ее исправить. Подскажить, на какие грабли я наступил?

P.S. Используется MPLAB 8.00 + HI-TECH 9.60 LITE (который идет вместе с MPLAB 8.00). Контроллер PIC16F690.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
evc
сообщение May 7 2008, 05:35
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 206
Регистрация: 17-03-07
Из: Москва
Пользователь №: 26 266



Цитата(Grigorij @ May 7 2008, 09:00) *
...
(472) non-reentrant function "*" appears in multiple call graphs: rooted at "*" and "*" (Linker)
This function can be called from both main-line code and interrupt code. Use the reentrant keyword, if this compiler supports it, or recode to avoid using local variables or parameters, or duplicate the function, e.g.:


Однако из описания ошибки я так и не понял, как ее исправить. Подскажить, на какие грабли я наступил?

P.S. Используется MPLAB 8.00 + HI-TECH 9.60 LITE (который идет вместе с MPLAB 8.00). Контроллер PIC16F690.


Компилер вам говорит: "Это НЕ функция которая позволяет многократный вход в нее, а она вызываемая в нескольких мест "*" и "*". Эту функцию возможно вызывать из обеих "main" и "interrupt". Пользуйте ключевое слово "reentrant", если этот компилер его поддерживает, или перепишите ее, чтобы она не использовала локальные переменные или продублируйте ее."

Дело в том что вы пользуете эту функцию и в основной программе и в обработчике прерывании. Задумайтесь что случится с данными, если прерывание наступит во время исполнении именно этой функции и обработчик прерывания попытается тоже вызвать ее!
В прерывании лучше внешние функции вообще не применять.


--------------------
УЭР
Go to the top of the page
 
+Quote Post
DL36
сообщение May 7 2008, 05:56
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 460
Регистрация: 5-10-06
Из: Херсон
Пользователь №: 21 006



Цитата(evc @ May 7 2008, 08:35) *
Компилер вам говорит: "Это НЕ функция которая позволяет многократный вход в нее, а она вызываемая в нескольких мест "*" и "*". Эту функцию возможно вызывать из обеих "main" и "interrupt". Пользуйте ключевое слово "reentrant", если этот компилер его поддерживает, или перепишите ее, чтобы она не использовала локальные переменные или продублируйте ее."

Ключевое слово #pragma interrupt_level 0
Цитата
Дело в том что вы пользуете эту функцию и в основной программе и в обработчике прерывании. Задумайтесь что случится с данными, если прерывание наступит во время исполнении именно этой функции и обработчик прерывания попытается тоже вызвать ее!
В прерывании лучше внешние функции вообще не применять.
Go to the top of the page
 
+Quote Post
evc
сообщение May 7 2008, 07:12
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 206
Регистрация: 17-03-07
Из: Москва
Пользователь №: 26 266



Цитата(DL36 @ May 7 2008, 09:56) *
Ключевое слово #pragma interrupt_level 0


это слово указывает линкеру, что потребитель гарантирует и береть на себя ответственость, что эта функция не будет вызвана обработчиком прерывании и основной программы одновременно, что бы тот (линкер) не выдавал сообщении об ошибке. В некоторых компиляторах (поддерживающие рекурсию, например) есть возможность объявить функцию как "reentrant", т.е. она может быть вызвана еще раз не завершив свою работу.


--------------------
УЭР
Go to the top of the page
 
+Quote Post
DL36
сообщение May 7 2008, 08:54
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 460
Регистрация: 5-10-06
Из: Херсон
Пользователь №: 21 006



Цитата(evc @ May 7 2008, 10:12) *
это слово указывает линкеру, что потребитель гарантирует и береть на себя ответственость, что эта функция не будет вызвана обработчиком прерывании и основной программы одновременно, что бы тот (линкер) не выдавал сообщении об ошибке. В некоторых компиляторах (поддерживающие рекурсию, например) есть возможность объявить функцию как "reentrant", т.е. она может быть вызвана еще раз не завершив свою работу.
Все правильно, также правильно не использовать функции в прерываниях.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 7 2008, 10:13
Сообщение #6


Гуру
******

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



Цитата(DL36 @ May 7 2008, 11:54) *
Все правильно, также правильно не использовать функции в прерываниях.
Глупости. Если надо сделать однотипное логически завершенное действие несколько раз, то для улучшения читаемости программы и уменьшения вероятности ошибки в общем случае можно и нужно такое действие оформлять в виде функции. Даже если общих кусков кода и нет, вынесение в функции логически завершенных кусков кода очень способствует читаемости программы. Другое дело, что недостаточно хороший компилятор может наложить свои ограничения, но это не повод заявлять "не использовать вообще".


--------------------
На любой вопрос даю любой ответ
"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
DL36
сообщение May 7 2008, 19:34
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 460
Регистрация: 5-10-06
Из: Херсон
Пользователь №: 21 006



Цитата(Сергей Борщ @ May 7 2008, 13:13) *
Глупости. Если надо сделать однотипное логически завершенное действие несколько раз, то для улучшения читаемости программы и уменьшения вероятности ошибки в общем случае можно и нужно такое действие оформлять в виде функции. Даже если общих кусков кода и нет, вынесение в функции логически завершенных кусков кода очень способствует читаемости программы. Другое дело, что недостаточно хороший компилятор может наложить свои ограничения, но это не повод заявлять "не использовать вообще".
Мое замечание относилось, только к увеличении времени сохранения,восстановления контекста.
При использовании одной функции в основном коде и прерываниях Хайтек сохраняет наверно все используемые переменные, а это здорово увеличивает время обработки.

Касательно выделения логических блоков в функцию совершенно согласен.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Grigorij   Обработчик прерываний в HI-TECH   May 7 2008, 05:00
- - Vanizma   ты используешь одну функцию и в основном теле прог...   May 7 2008, 05:28
||- - Vanizma   Цитата(Сергей Борщ @ May 7 2008, 14:13) Е...   May 7 2008, 15:10
|- - Grigorij   Цитата(evc @ May 7 2008, 11:12) это слово...   May 8 2008, 04:24
|- - DL36   Цитата(Grigorij @ May 8 2008, 07:24) К со...   May 8 2008, 05:19
|- - Grigorij   Цитата(DL36 @ May 8 2008, 09:19) Надо доб...   May 8 2008, 06:59
|- - DL36   Цитата(Grigorij @ May 8 2008, 09:59) Спас...   May 8 2008, 09:24
|- - Галстук   Цитата(DL36 @ May 8 2008, 13:24) ...у Вас...   May 8 2008, 10:16
|- - Grigorij   2DL36: Постараюсь в кратце описать программу. Она...   May 8 2008, 11:06
|- - DL36   Цитата(Grigorij @ May 8 2008, 14:06) В це...   May 8 2008, 11:38
- - Сергей Борщ   Цитата(Grigorij @ May 7 2008, 08:00) or r...   May 7 2008, 06:18
- - XVR   Цитата(Grigorij @ May 7 2008, 09:00) Здра...   May 8 2008, 06:46
- - asmon   А кто может обьяснить назначение директивы хайтека...   May 22 2008, 14:22
|- - xemul   Цитата(asmon @ May 22 2008, 18:22) А кто ...   May 22 2008, 15:16
|- - Grigorij   2xemul Рассказываю. В моей программе USART исполь...   May 23 2008, 04:45
|- - xemul   Цитата(Grigorij @ May 23 2008, 08:45) 2xe...   May 23 2008, 08:57
|- - Grigorij   Цитата(xemul @ May 23 2008, 12:57) Заведи...   May 23 2008, 10:54
|- - xemul   Цитата(Grigorij @ May 23 2008, 14:54) Нав...   May 24 2008, 12:45
- - Mad_max   Если еще, не решили свою проблему, то вот почитайт...   Jun 7 2008, 13:10
- - Grigorij   Цитата(Mad_max @ Jun 7 2008, 17:10) Если ...   Jun 10 2008, 05:31


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

 


RSS Текстовая версия Сейчас: 20th July 2025 - 19:44
Рейтинг@Mail.ru


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