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

 
 
> Странная ошибка с __interrupt
Aeore
сообщение May 31 2013, 18:06
Сообщение #1





Группа: Участник
Сообщений: 12
Регистрация: 10-08-07
Из: Odessa
Пользователь №: 29 704



Контроллер : ATMega128 + 64KB внешней памяти
Используется внешний xcl файл (настройки линкера)

Есть смешанный C/C++ проект, в котором крутится FreeRTOS. Во FreeRTOS используется одно прерывание, которое там описано в ассемблерном исходнике с помощью директивы ORG. Проект компилится и кое-как работает, с прерываниями проблем нет. Теперь я хочу описать еще одно прерывание, пишу:
Код
// --------------------------------------------------------------------------
// USART1_TXC_vect = 0x80
#pragma vector = USART1_TXC_vect
extern "C" __interrupt void interrupt_UART1_TXComplete( void )
// --------------------------------------------------------------------------
{
   // nop
}


и тут же получаю ошибку:
CODE
Building configuration: p45g - Debug
Updating build tree...
CPTracePrinterStrategy.cpp
Linking
Error[e16]: Segment INTVEC (size: 0x84 align: 0x1) is too long for segment definition. At least 0x2c more bytes needed.
The problem occurred while processing the segment placement command
"-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)", where at the moment of placement the available memory ranges were
"CODE:0-2f,CODE:34-8b"
Reserved ranges relevant to this placement:
CODE:0-2f ?FILL1
CODE:30-33 Absolute code from portmacro
CODE:34-8b ?FILL2
Warning[w18]: Segment INTVEC (seg part no 7, symbol "interrupt_UART1_TXComplete::??INTVEC 128" in module
"CPTracePrinterStrategy", address [0-83]) overlaps segment ?FILL1 (from module "?FILLER_BYTES", address [0-2f])
Warning[w18]: Segment on the address 30-33 in the module portmacro (F:\PROJECTS\Ð-45\P45G\Firmware\1.00\out\obj\
Debug\portmacro.r90) overlaps segment INTVEC (seg part no 7, symbol "interrupt_UART1_TXComplete::??INTVEC
128" in module "CPTracePrinterStrategy", address [0-83])
Warning[w18]: Segment INTVEC (seg part no 7, symbol "interrupt_UART1_TXComplete::??INTVEC 128" in module
"CPTracePrinterStrategy", address [0-83]) overlaps segment ?FILL2 (from module "?FILLER_BYTES", address [34-8b])
Warning[w70]: The segment "?FILL1" on address 0 overlaps previous content in the raw-binary output file. The previously
content will be overwritten.
Error while running Linker

Total number of errors: 1
Total number of warnings: 4


Теперь немного арифметики: размер сегмента INTVEC_SIZE равен 8C (140 байт), а значит сюда поместятся 35 (140 / 4) векторов. В параметре vector указан адрес 0x80, что равно 128 байтам, т.е. адрес находится в пределе сегмента кода прерываний. Так что его тогда не устраивает?

Вот XCL с конфигурацией:
CODE
-ca90

-D_..X_INTVEC_SIZE=8C /* 4 bytes * 35 vectors */
-D_..X_FLASH_TEND=FF /* End of tiny flash memory */
-D_..X_FLASH_NEND=FFFF /* End of near flash memory */
-D_..X_FLASH_END=1FFFF /* End of flash memory */

-D_..X_SRAM_BASE=100 /* Start of ram memory */
-D_..X_SRAM_TEND=100 /* End of tiny ram memory */
-D_..X_SRAM_END=10FF /* End of ram memory */

-D_..X_EEPROM_END=FFF /* End of eeprom memory */

-D_..X_CSTACK_SIZE=400 /* 1024 bytes for auto variables and saved registers. */
-D_..X_RSTACK_SIZE=400 /* 1024 bytes for return addresses */
-D_SVC_STACK_SIZE=0 /* not used */
-D_IRQ_STACK_SIZE=0 /* scmRTOS uses CSTACK for irq */
-D_..X_NEAR_HEAP_SIZE=CAFA /* 0 bytes of heap. */

-D_..X_EXT_SRAM_BASE=1100
-D_..X_EXT_SRAM_END=FFFF

-D_..X_EXT_EPROM_BASE=_..X_SRAM_BASE
-D_..X_EXT_EPROM_END=_..X_SRAM_END

-D_..X_EXT_EEPROM_BASE=_..X_SRAM_BASE
-D_..X_EXT_EEPROM_END=_..X_SRAM_END





-Z(CODE)INTVEC=0-(_..X_INTVEC_SIZE-1)
-H1895 -h(CODE)0-_..X_INTVEC_SIZE /* RETI */
-Z(CODE)TINY_F=_..X_INTVEC_SIZE-_..X_FLASH_TEND
-Z(CODE)NEAR_F,SWITCH,DIFUNCT=_..X_INTVEC_SIZE-_..X_FLASH_NEND
-Z(CODE)CODE=_..X_INTVEC_SIZE-_..X_FLASH_END
-Z(FARCODE)FAR_F=_..X_INTVEC_SIZE-_..X_FLASH_END
-Z(CODE)HUGE_F,INITTAB=_..X_INTVEC_SIZE-_..X_FLASH_END
-Z(CODE)TINY_ID,NEAR_ID=_..X_INTVEC_SIZE-_..X_FLASH_END
-Z(CODE)CHECKSUM#_..X_FLASH_END

-Z(DATA)TINY_I,TINY_Z,TINY_N=_..X_SRAM_BASE-_..X_SRAM_TEND
-Z(DATA)NEAR_I,NEAR_Z=_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END
-Z(DATA)RSTACK+_..X_RSTACK_SIZE=_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END
-Z(DATA)CSTACK+_..X_CSTACK_SIZE=_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END
-Z(DATA)IOSTREAM_N#_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END
-Z(DATA)NEAR_HEAP+_..X_NEAR_HEAP_SIZE=_..X_EXT_SRAM_BASE-_..X_EXT_SRAM_END
-Z(XDATA)EEPROM_I,EEPROM_N=0-_..X_EEPROM_END
-Z(CONST)NEAR_C=_..X_EXT_EPROM_BASE-_..X_EXT_EPROM_END
-Z(DATA)NEAR_N=_..X_EXT_EEPROM_BASE-_..X_EXT_EEPROM_END

-e_PrintfLarge=_Printf
-e_medium_write=_formatted_write
-e_small_write_P=_formatted_write_P
-e_ScanfLarge=_Scanf
-e_medium_read=_formatted_read
-e_medium_read_P=_formatted_read_P

-w29


А вот и два MAP файла (сегменты)

ДО добавления прерывания
Код
INTVEC     CODE     00000000 - 00000003     4     Common     1
?FILL1     CODE     00000004 - 0000002F     2C     Relative     0
?FILL2     CODE     00000034 - 0000008B     58     Relative     0
NEAR_F     CODE     0000008C - 00000275     1EA     Relative     0
SWITCH     CODE     00000276 - 000002A9     34     Relative     1
CODE     CODE     000002AA - 000070D5     6E2C     Relative     1
HUGE_F     CODE     000070D6         Predefined     0
INITTAB     CODE     000070D6 - 000070E3     E     Relative     0
TINY_ID     CODE     000070E4         Predefined     0
NEAR_ID     CODE     000070E4 - 000072ED     20A     Relative     0


и ПОСЛЕ:
Код
?FILL1     CODE     00000000 - 0000002F     30     Relative     0
INTVEC     CODE     00000000 - 00000083     84     Common     1
?FILL2     CODE     00000034 - 0000008B     58     Relative     0
NEAR_F     CODE     0000008C - 00000275     1EA     Relative     0
SWITCH     CODE     00000276 - 000002A9     34     Relative     1
CODE     CODE     000002AA - 000070D7     6E2E     Relative     1
HUGE_F     CODE     000070D8         Predefined     0
INITTAB     CODE     000070D8 - 000070E5     E     Relative     0
TINY_ID     CODE     000070E6         Predefined     0
NEAR_ID     CODE     000070E6 - 000072EF     20A     Relative     0


Сообщение отредактировал IgorKossak - May 31 2013, 19:11
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
desh
сообщение Jun 1 2013, 15:01
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 113
Регистрация: 25-10-07
Из: Краснодар
Пользователь №: 31 725



Цитата
Зачем так делать? Или порт сделан так что по другому не сделать?


А чем этот то способ плох? Такой стиль используется в оригинальном примере из FreeRTOS.
FreeRTOS поддерживает 2 схемы многозадачности: кооперативную и вытесняющую.
При кооперативной многозадачности можно использовать стандартный способ работы с прерываниями, если изменить соответствующим образом порт.
При вытесняющей многозадачности работа прерывания от системного таймера отличается от работы остальных прерываний.
Поэтому системное прерывание вызывается из ассемблерного кода. Линкеру не нравится, что в одном сегменте необходимо расположить и ассемблерный и сишный код.


Цитата
Обычно этого достаточно. Без редактирования ассемблерных файлов.


Обратите внимание, здесь используется директива подавления предупреждения, а не установки адреса прерывания.

Цитата
Опять же ИАР сам с этим справлялся.

В этом случае не справляется, так как сегмент разбит на несколько частей ассемблерными вызовами.

Цитата
P.S. И лучше заполнить вектора не reti, а сбросом.

А вот тут я с Вами совсем не согласен. Что лучше - надо решать исходя из назначения устройства.
Не всех порадует самопроизвольный сброс конечного продукта.

Сообщение отредактировал desh - Jun 1 2013, 15:04
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 1 2013, 15:24
Сообщение #3


Гуру
******

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



Цитата(desh @ Jun 1 2013, 18:01) *
А чем этот то способ плох? Такой стиль используется в оригинальном примере из FreeRTOS.

Тем что надо прописывать вектора вручную. То есть приходится брать на себя работу ИАРа.

Цитата(desh @ Jun 1 2013, 18:01) *
При вытесняющей многозадачности работа прерывания от системного таймера отличается от работы остальных прерываний.
Поэтому системное прерывание вызывается из ассемблерного кода.

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

Цитата(desh @ Jun 1 2013, 18:01) *
Линкеру не нравится, что в одном сегменте необходимо расположить и ассемблерный и сишный код.
В этом случае не справляется, так как сегмент разбит на несколько частей ассемблерными вызовами.

Ерунда какая-то...
Что же по-вашему нельзя объявлять обработчики в *.с и *.asm файлах без каких-то трюков?
Не видел такой ситуации когда "Линкеру не нравится". Но создать её на свою голову наверное можно...


Цитата(desh @ Jun 1 2013, 18:01) *
А вот тут я с Вами совсем не согласен. Что лучше - надо решать исходя из назначения устройства.
Не всех порадует самопроизвольный сброс конечного продукта.

Случаи бывают разные, это - да...
Go to the top of the page
 
+Quote Post



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

 


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


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