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

 
 
> Странная ошибка с __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:38
Сообщение #2


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

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



Эм... Хотелось бы увидеть и обсудить Ваше решение указанной в первом сообщении проблеммы.
Go to the top of the page
 
+Quote Post
_Артём_
сообщение Jun 1 2013, 19:56
Сообщение #3


Гуру
******

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



Цитата(desh @ Jun 1 2013, 18:38) *
Эм... Хотелось бы увидеть и обсудить Ваше решение указанной в первом сообщении проблеммы.

Для того чтобы увидеть решение проблемы неплохо было бы увидеть проблему.
ТС тут выложил нам много букв скрипты линкера, который непонятно что линкует, кучу ошибок вызванных непонятно чем, фреймворки которых никто не видел и тп. Вместо того чтобы выложить проект, в котором проблема возникает. ТС наверное думает что тут форум телепатов...

К тому же непонятно как ТС запустил Freertos на M128 - демо-проект с сайта freertos сделан под M323 и для запуска его на M128 требуется некоторая модификация под таргет. Или я не там брал freertos и есть где-то готовый проект под M128 и другие меги? Где такое берут?

Цитата(desh @ Jun 1 2013, 18:38) *
Ваше решение

Скачал с freertos.org демо-проект. Заменил в нём таргет на mega128.

Добавил в файл main.c:
Код
#pragma vector=USART1_UDRE_vect
__interrupt void Uart1_UDRE_Handler()
{
}


Получил в ответ такую ругань:
Цитата
Error[e16]: Segment INTVEC (size: 0x80 align: 0x1) is too long for segment definition. At least 0x44 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-47,CODE:50-8b"
Reserved ranges relevant to this placement:
CODE:0-2f ?FILL1
CODE:30-33 Absolute code from portmacro
CODE:34-47 ?FILL2
CODE:48-4f Absolute code from portmacro
CODE:50-8b ?FILL3
Error while running Linker

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


Убрал в файле portmacro.s90 директиву ASEG (какой-такой ASEG? что они этим сказать хотели?):
Код
    common INTVEC(1)

    ORG TIMER1_COMPA_vect            ; Vector address
        jmp SIG_OUTPUT_COMPARE1A    ; ISR

    ORG USART0_RXC_vect                ; Vector address
        jmp SIG_UART_RECV            ; ISR

    ORG USART0_UDRE_vect                ; Vector address
        jmp SIG_UART_DATA            ; ISR

    
    RSEG CODE



Добавил в main.c:
CODE

volatile char TxData[8];
volatile unsigned char TxIndex, TxSize;

#pragma vector=USART1_UDRE_vect
__interrupt void Uart1_UDRE_Handler()
{
unsigned char tx_index=TxIndex;
UDR1=TxData[tx_index++];
if (tx_index==TxSize)
UCSR1B&=~(1<<UDRIE1);

TxIndex=tx_index;

}

static void vErrorChecks( void *pvParameters )
{
static volatile unsigned long ulDummyVariable = 3UL;
UCSR1A =
0
| (0<<RXC1)
| (1<<TXC1)
| (0<<UDRE1)
| (0<<FE1)
| (0<<DOR1)
| (0<<UPE1)
| (0<<U2X1)
| (0<<MPCM1)
;
UCSR1B=
0
| (0<<RXCIE1)
| (1<<TXCIE1)
| (0<<UDRIE1)
| (0<<RXEN1)
| (1<<TXEN1)
| (0<<UCSZ12)
| (0<<RXB81)
| (0<<TXB81)
;
UCSR1C=
0
| (0<<UMSEL0)
| (0<<UPM01)
| (0<<UPM00)
| (0<<USBS0)
| (1<<UCSZ01)
| (1<<UCSZ00)
| (0<<UCPOL0)
;
UBRR1H=0;
UBRR1L=5;

/* The parameters are not used. */
( void ) pvParameters;

/* Cycle for ever, delaying then checking all the other tasks are still
operating without error. */
unsigned long counter=0;
for( ;; )
{

TxSize=sprintf(TxData, "t=%x", counter++);
TxIndex=0;
UCSR1B|=(1<<UDRIE1);

prvCheckOtherTasksAreStillRunning();
vTaskDelay( 3);//mainCHECK_PERIOD );
}
}


Цитата
IAR Universal Linker V5.2.3.14
Copyright 1987-2011 IAR Systems AB.

12 992 bytes of CODE memory (+ 12 range fill )
1 928 bytes of DATA memory (+ 21 absolute )

Errors: none
Warnings: none


Прерывание работает, но не отвалилось что-нибудь в другом месте не знаю...
Это решение?
Go to the top of the page
 
+Quote Post
Aeore
сообщение Jun 3 2013, 17:57
Сообщение #4





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



Цитата(_Артём_ @ Jun 1 2013, 22:56) *
Убрал в файле portmacro.s90 директиву ASEG (какой-такой ASEG? что они этим сказать хотели?):

..

Прерывание работает, но не отвалилось что-нибудь в другом месте не знаю...
Это решение?


Эм.. удалил у себя - все осталось по прежнему O_o
Go to the top of the page
 
+Quote Post



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

 


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


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