Перейти к содержанию

SDCC не линкует прерывания вне main.c

Всем привет!

Не понятен момент описания прерываний. Точнее описывать их получается, но вот поведение линковщика неоднозначно.

К примеру имеем main.c в котором скопом весь код программы в том числе и прерывания:
Код
void main(void)
{
бла бла бла
}

UART0_ISR()
{
обработчик
}

Теперь собираем его, и получаем примерно следующее:
Код
                                    563;--------------------------------------------------------
                                    564; interrupt vector
                                    565;--------------------------------------------------------
                                    566     .area HOME    (CODE)
      000000                        567 __interrupt_vect:
      000000 02 00 29         [24]  568     ljmp    __sdcc_gsinit_startup
      000003 32               [24]  569     reti
      000004                        570     .ds    7
      00000B 32               [24]  571     reti
      00000C                        572     .ds    7
      000013 32               [24]  573     reti
      000014                        574     .ds    7
      00001B 32               [24]  575     reti
      00001C                        576     .ds    7
      000023 02 01 C9         [24]  577     ljmp    _isr_uart
                                    578;--------------------------------------------------------
                                    579; global & static initialisations
                                    580;--------------------------------------------------------

Теперь "причёсываем" код. Создаём uart.c и переносим в него прерывание. собираем. Линкуем.
Код
                                    526;--------------------------------------------------------
                                    527; interrupt vector
                                    528;--------------------------------------------------------
                                    529     .area HOME    (CODE)
      000000                        530 __interrupt_vect:
      000000 02 00 06         [24]  531     ljmp    __sdcc_gsinit_startup
                                    532;--------------------------------------------------------
                                    533; global & static initialisations
                                    534;--------------------------------------------------------

А где?! wacko.gif
Нет, сама функция собирается, но как обычная:
Код
                                    560;--------------------------------------------------------
                                    561; code
                                    562;--------------------------------------------------------
                                    563     .area CSEG    (CODE)
                                    564;------------------------------------------------------------
                                    565;Allocation info for local variables in function '_isr_uart'
                                    566;------------------------------------------------------------
                                    567;    uart.c:41: _ISR_UART()
                                    568;    -----------------------------------------
                                    569;     function _isr_uart
                                    570;    -----------------------------------------
      0000D8                        571 _isr_uart:
                           00000F   572     ar7 = 0x0F
                           00000E   573     ar6 = 0x0E
                           00000D   574     ar5 = 0x0D
                           00000C   575     ar4 = 0x0C
                           00000B   576     ar3 = 0x0B
                           00000A   577     ar2 = 0x0A
                           000009   578     ar1 = 0x09
                           000008   579     ar0 = 0x08

Что я могу сделать не так? Это что получается прерывания должны быть только в основном коде?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Я sdcc для 51-х уже лет 10 не использовал, но раньше прерывания объявлялись вот так:
Код
void Timer0_ISR( void )    interrupt 1    using 2

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(AHTOXA @ May 16 2015, 12:46) <{POST_SNAPBACK}>
Я sdcc для 51-х уже лет 10 не использовал, но раньше прерывания объявлялись вот так:
Код
void Timer0_ISR( void )    interrupt 1    using 2

оно и сейчас так, только __interrupt 1 __using 2, а толку...

если не SDCC, то что?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Хм. Открываем SDCC Compiler User Guide, находим главу про прерывания, читаем:
Цитата
If you have multiple source files in your project, interrupt service routines can be present in any of them, but a
prototype of the isr MUST be present or included in the file that contains the function main.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Это уже давно не так. Компиляю под STM8 и не парюсь. А вот с годик назад - да, у sdcc была такая проблема. А еще он не компилялся, если в первом файле не было функции main.
Изменено пользователем Эдди

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Это всё конечно хорошо, но что я то не так делаю? Почему у меня не создаёт таблицу прерываний как надо?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Какая версия?
Код
sdcc --version
SDCC : mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8 3.4.0 #8981 (Apr  1 2015) (Linux)
published under GNU General Public License (GPL)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Цитата(Alexey Belyaev @ May 16 2015, 21:02) <{POST_SNAPBACK}>
Это всё конечно хорошо, но что я то не так делаю? Почему у меня не создаёт таблицу прерываний как надо?

Вы должны включить прототипы обработчиков прерываний в тот файл, где у вас расположена функция main().

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация