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

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> GCC и прерывания в C коде, __attribute__ ((interrupt ("IRQ"))) и уровни оптимизации
Alex03
сообщение Oct 3 2006, 04:50
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Вчера понадобилать Release версия проекта, скомпилил, ни в какую работать не захотела, глючило всё как могло.
Пол дня убил пока не понял что наступил на известные грабли GCC, неправильное генерение пролога/эпилога для прерываний. Описанные тут и тут


Всё это под CW 1.6 b 3. там GCC 4.1.0.

Притом на сайте Rowley Associates примерно тут (сейчас чтото недоступен) говорится что с уровнем оптимизации 1 ( -O1 ) всё ОК! Но как я понял это в предыдущих версиях (3.х.х) оно работало, а сейчас нет.


Вооот. Качать кучу исходников и патчить их чтото не хочется, мож кто уже проделал сию работу?
Go to the top of the page
 
+Quote Post
PrSt
сообщение Oct 4 2006, 06:12
Сообщение #2


http://uschema.com
****

Группа: Свой
Сообщений: 708
Регистрация: 16-02-06
Из: UK(Ukrainian_Kingdom) Kharkov
Пользователь №: 14 394



Цитата(Alex03 @ Oct 3 2006, 07:50) *
Вооот. Качать кучу исходников и патчить их чтото не хочется, мож кто уже проделал сию работу?

PR16634: Wrong-code for IRQ functions. - http://gcc.gnu.org/ml/gcc-patches/2006-08/msg00230.html
When generating interworked armv4t code gcc generates incorrect function
epilogue code for IRQ/FIQ functions. ...


--------------------
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 4 2006, 07:05
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(PrSt @ Oct 4 2006, 12:12) *
PR16634: Wrong-code for IRQ functions. - http://gcc.gnu.org/ml/gcc-patches/2006-08/msg00230.html
When generating interworked armv4t code gcc generates incorrect function
epilogue code for IRQ/FIQ functions. ...


Так я практически тудаже ссылку дал. Т.е. в конце страницы которую я обозвал как второй "тут" (т.е. http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16634) эта ссылка есть. И я понятно там был.
Мне не хочется качать исходники GCC, патчить, компилять.

Кстати вопрос к знающим, а сам GCC под ARM компилять надо обязательно GCC-x86 (а то и со всякими бинутилами и т.д.)?
Или можно и в MS VC 2003? smile.gif
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 4 2006, 18:43
Сообщение #4


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Цитата(Alex03 @ Oct 4 2006, 11:05) *
Кстати вопрос к знающим, а сам GCC под ARM компилять надо обязательно GCC-x86 (а то и со всякими бинутилами и т.д.)?
Или можно и в MS VC 2003? smile.gif

Попробуйте взять мою сборку 4.1.2 http://www.klen.org/Projects/Embeded-gnu-t...last_build.html
В нем arm.c изменен в части касающей строк которык в патче указаны.
Если будете пробывать напишите че вышло. будем разбиратся.

Сообщение отредактировал klen - Oct 4 2006, 18:58
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 5 2006, 04:24
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(klen @ Oct 5 2006, 00:43) *
Попробуйте взять мою сборку 4.1.2 http://www.klen.org/Projects/Embeded-gnu-t...last_build.html
В нем arm.c изменен в части касающей строк которык в патче указаны.
Если будете пробывать напишите че вышло. будем разбиратся.


Спасибо, но не прокатило.

С код

Код
void testISR(void) __attribute__ ((interrupt ("IRQ")));
void testISR(void)
{
    testIsrFn();
}


Код который генерился ранее, т.е. GCC 4.1.0 с оптимизацией Level 1
Код
       E24EE004   sub lr, lr, #0x00000004
       E92D500F   stmfd sp!, {r0-r3, r12, lr}
       EBFFFFFE   bl 0x000000a4                       // testIsrFn()
       E8BD500F   ldmfd sp!, {r0-r3, r12, lr}
       E25EF004   subs pc, lr, #0x00000004


Код который генерится с GCC 4.1.2 с оптимизацией Level 1
Код
       E24EE004   sub lr, lr, #0x00000004
       E92D500F   stmfd sp!, {r0-r3, r12, lr}
       EBFFFFFE   bl 0x000000b0                       // testIsrFn()
       E8BD500F   ldmfd sp!, {r0-r3, r12, lr}
       E25EF004   subs pc, lr, #0x00000004
}

Т.е. тоже самое, там проблема что 4 из lr дважды вычитается.


Рабочий код который генерится с обоими GCC без оптимизации (дебаг)
Код
       E52DC004   str r12, [sp, #-0x004]!
       E1A0C00D   mov r12, sp
       E92DD80F   stmfd sp!, {r0-r3, r11-r12, lr-pc}
       E24CB004   sub r11, r12, #0x00000004
       EBFFFFFE   bl 0x00000010                       // testIsrFn()
       E24BD01C   sub sp, r11, #0x0000001c
       E89D680F   ldmfd sp, {r0-r3, r11, sp-lr}
       E8BD1000   ldmfd sp!, {r12}
       E25EF004   subs pc, lr, #0x00000004

С ключиком -mapcs-frame код генерится как в дебаге.


Ну и на вот это не ответишь?
Цитата(Alex03 @ Oct 4 2006, 11:05) *
Кстати вопрос к знающим, а сам GCC под ARM компилять надо обязательно GCC-x86 (а то и со всякими бинутилами и т.д.)?
Или можно и в MS VC 2003? smile.gif


И ещё klen почему твои бинарники раза в 3 больше чем которые с crossworks-ом? Мож их стрипом?

Кстати статус у патча нифига не CLOSED.
Go to the top of the page
 
+Quote Post
shhh
сообщение Oct 5 2006, 06:33
Сообщение #6





Группа: Новичок
Сообщений: 2
Регистрация: 14-04-06
Пользователь №: 16 106



По поводу глюка - я правильно понял что он проявляется при отличном от -O0 ключе оптимизации?

Бинарники у меня большие потому что я их так собираю чтоб на любой машинке работали и не требовали никаких библиотек - все статически влинковывается.

Скомпилить часть исходников gcc может получится, другая часть не скомпилируется потому что есть gcc расширения и особенности синтаксиса С языка которые VC++ не пропустит. А вот собрать без binutils не получится и вовсе, как я думаю.

А зачем gcc собирать с помощю не gcc??? какой от этого кайф?
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 5 2006, 10:00
Сообщение #7


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(shhh @ Oct 5 2006, 12:33) *
По поводу глюка - я правильно понял что он проявляется при отличном от -O0 ключе оптимизации?

Правильно. По крайней мере при -O1, -O2 точно.

Цитата
А зачем gcc собирать с помощю не gcc??? какой от этого кайф?


затем что нет его у меня пока! smile.gif Тока в линухе.
Go to the top of the page
 
+Quote Post
yaghtn
сообщение Oct 5 2006, 10:04
Сообщение #8


Участник
*

Группа: Свой
Сообщений: 52
Регистрация: 7-11-05
Из: Чебоксары
Пользователь №: 10 546



Случайно наткнулся: http://www.armkits.com/support/FAQanswer.asp?id=142

Вкраце, советуют описать обработчик irq на асме:
Код
irq_entry:  .EXTERN irq_func
.GLOBAL irq_entry
stmdb sp!, {r0-r11, ip, lr} /* Save r0-r11, ip, lr */
ldr r0, = irq_func
mov lr, pc
bx r0           /* Use C interruption program*/
ldmia sp!, {r0-r11, ip, lr}        /* Resume r0, ip, lr */
subs pc, r14, #4         /* Interruption and return */


из которого и будет вызываться вызывать функция обработки прерывания, описанная на C, но безо всяких __attribute__ ((interrupt ("IRQ")))

Сообщение отредактировал yaghtn - Oct 5 2006, 10:05
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 5 2006, 11:25
Сообщение #9


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(yaghtn @ Oct 5 2006, 16:04) *
Случайно наткнулся: http://www.armkits.com/support/FAQanswer.asp?id=142

Вкраце, советуют описать обработчик irq на асме:
SKIP
из которого и будет вызываться вызывать функция обработки прерывания, описанная на C, но безо всяких __attribute__ ((interrupt ("IRQ")))


Эт всё понятно, можно и naked функцию объявить со своими прологом/эпилогом в виде асм-вставки.
Просто обидно что глюку 2 года а править его никто не думает. smile.gif

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

Но в любом случае спасибо! smile.gif
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 7 2006, 17:59
Сообщение #10


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Цитата(yaghtn @ Oct 5 2006, 14:04) *
Вкраце, советуют описать обработчик irq на асме:
Код
irq_entry:  .EXTERN irq_func
.GLOBAL irq_entry
stmdb sp!, {r0-r11, ip, lr} /* Save r0-r11, ip, lr */
ldr r0, = irq_func
mov lr, pc
bx r0           /* Use C interruption program*/
ldmia sp!, {r0-r11, ip, lr}        /* Resume r0, ip, lr */
subs pc, r14, #4         /* Interruption and return */


тогда уж так лучше, короче на 2 команды
Код
irq_entry:  .EXTERN irq_entry
.GLOBAL irq_entry
stmdb sp!, {r0-r11, ip, lr} /* Save r0-r11, ip, lr */
bl irq_entry           /* Use C interruption program*/
ldmia sp!, {r0-r11, ip, lr}        /* Resume r0, ip, lr */
subs pc, r14, #4         /* Interruption and return */
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 8 2006, 14:26
Сообщение #11


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Убил субботу, ночь и полсегодня в поисках кривизны. Нашел откуда рога растут - функция разворачивания пролога в /gcc/config/arm/arm.c:arm_expand_prologue, поправил, пересобрал, эпилог начал генерится правильно(???) c оптимизацией О1,O2,О3,Оs. компиллер gcc 4.1.2-20060930. Вот результат:

-О0 (без оптимизации)
Код
void uartISR(void)__attribute__ (( interrupt("IRQ")));
void uartISR(void)
{
       E52DC004   str r12, [sp, #-0x004]!
       E1A0C00D   mov r12, sp
       E92DD80F   stmfd sp!, {r0-r3, r11-r12, lr-pc}
       E24CB004   sub r11, r12, #0x00000004
       E24DD008   sub sp, sp, #0x00000008

//-----целевой код прерывания(конец пролога)-----------
  portBASE_TYPE Tmp = U0IIR;
       E3A03903   mov r3, #0x01800000
       E283328E   add r3, r3, #0x80000023
       E5D33000   ldrb r3, [r3]
............................................ 
VICVectAddr = 0;
       E3A03000   mov r3, #0x00000000
       E2433EFD   sub r3, r3, #0x03f40000
       E3A02000   mov r2, #0x00000000
       E5832000   str r2, [r3]
}
//-----целевой код прерывания(начало эпилога)-----------
       E24BD01C   sub sp, r11, #0x0000001c
       E89D680F   ldmfd sp, {r0-r3, r11, sp-lr}
       E8BD1000   ldmfd sp!, {r12}
       E25EF004   subs pc, lr, #0x00000004

оптимизация -О1...Оs
Код
void uartISR(void)__attribute__ (( interrupt("IRQ")));
void uartISR(void)
{
{
       E92D500F   stmfd sp!, {r0-r3, r12, lr}
//-----целевой код прерывания(конец пролога)-----------
  portBASE_TYPE Tmp = U0IIR;
       E3A0320E   mov r3, #0x80000003
       E2832903   add r2, r3, #0x01800000
       E5D23008   ldrb r3, [r2, #+0x008]
.....................................
VICVectAddr = 0;
       E3A02000   mov r2, #0x00000000
       E3E03000   mvn r3, #0x00000000
       E5032FCF   str r2, [r3, #-0xfcf]
}
//-----целевой код прерывания(начало эпилога)-----------
       E8BD500F   ldmfd sp!, {r0-r3, r12, lr}
       E25EF004   subs pc, lr, #0x00000004

В последнем листе приведен для -O1, поскольку при других оптимизациях компиллеров изменялся только целевой код, то приведен только один лист - эпилог и пролог при всех отличгых от -O0 одинаковы.

Завтра или сегодня выложу поправленую сборку (дома интернет сдох, пишу через мобильник). Непроверял при заходе в irq/fiq из THUMB и выходе внего. Прошу проверить. Нужно вобще потестировать.
Лично у меня проект завелся на всех оптимизациях(раньше ессесенго все работало только без оптимизации). Проект состоящий из 4задач FreeRTOS + 20кб всякого разношерстного кода работы с переферией. Работает не жужит. Дмаю что еслиб где былаб ошибочка то хрен работалоб - куча стеков, heap, и тд - все динамически дышит - и не падает уже минут 40. микросхемка lpc2103 Но! я ваще тумб не пользую - нада проверять.

Еще вопрос. При выходе из irq/frq возврат на прерванную команду - subs pc, lr, #0x00000004. А вот при DAbort всетаки на две команды нада отматывать(по моему разумению изза того что это исключение в v4t происходить через одну команду если возникла ошибка озу). Посему нада в пепилоге subs pc, lr, #0x00000008 применять. Сейчас для всех исключений кроме SWI все едино. Делать -8 в аборте или нет? Как считает?

Сообщение отредактировал klen - Oct 8 2006, 14:29
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 9 2006, 05:01
Сообщение #12


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(klen @ Oct 8 2006, 20:26) *
...
SKIP
...

Завтра или сегодня выложу поправленую сборку (дома интернет сдох, пишу через мобильник). Непроверял при заходе в irq/fiq из THUMB и выходе внего. Прошу проверить. Нужно вобще потестировать.
Лично у меня проект завелся на всех оптимизациях(раньше ессесенго все работало только без оптимизации). Проект состоящий из 4задач FreeRTOS + 20кб всякого разношерстного кода работы с переферией. Работает не жужит. Дмаю что еслиб где былаб ошибочка то хрен работалоб - куча стеков, heap, и тд - все динамически дышит - и не падает уже минут 40. микросхемка lpc2103 Но! я ваще тумб не пользую - нада проверять.

Еще вопрос. При выходе из irq/frq возврат на прерванную команду - subs pc, lr, #0x00000004. А вот при DAbort всетаки на две команды нада отматывать(по моему разумению изза того что это исключение в v4t происходить через одну команду если возникла ошибка озу). Посему нада в пепилоге subs pc, lr, #0x00000008 применять. Сейчас для всех исключений кроме SWI все едино. Делать -8 в аборте или нет? Как считает?


По моему и сейчас не едино, и надо не едино.
В частности для FIQ не сохраняется R12, ибо он там свой теневой.
Кстати для пустых обработчиков код для IRQ генерится правильно и состоит из одной команды:
Код
       E25EF004   subs pc, lr, #0x00000004


И даже не только для пустых но и для таких:

Код
void testIsrFn()
{
}
void testISR_IRQ(void) __attribute__ ((interrupt ("IRQ")));
void testISR_IRQ(void)
{
    testIsrFn();
}

Оптимизация блин! smile.gif

Про DAbort и т.д. не скажу т.к. абсолютно не силён в ARM асме и соответственно архитектуре.
Но ИМХО возвращаться из abort-ов в проциках без MMU както не провильно. Т.е. если есть ОС то она должна снять/перезапустить задачу. Если без ОС то итого хуже.
Я у себя в железке матерюсь на индикатор и стопарюсь в пустом цикле, ибо этого не должнобыть никогда!
Для проциков с ММУ, кэшами и т.д. видимо есть другие пути решения, но я с ними не работал.

PS тумб я тоже не пользую.
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 9 2006, 05:42
Сообщение #13


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



Ну че? потестируете?
Go to the top of the page
 
+Quote Post
Alex03
сообщение Oct 9 2006, 08:22
Сообщение #14


Местный
***

Группа: Свой
Сообщений: 359
Регистрация: 9-12-05
Пользователь №: 12 034



Цитата(klen @ Oct 9 2006, 11:42) *
Ну че? потестируете?


Если там же, то там нет?

Может для CW и опции взять соответствующие?
Из вот этого?
Код
Using built-in specs.
Target: arm-unknown-elf
Configured with: ../gcc-2006q1/configure --target=arm-unknown-elf --build=i686-pc-mingw32 --host=i686-pc-mingw32 --prefix=/c/gcc-build/install : (reconfigured) ../gcc-2006q1/configure --target=arm-unknown-elf --build=i686-pc-mingw32 --host=i686-pc-mingw32 --prefix=/c/gcc-build/install
Thread model: single
gcc version 4.1.0 (CodeSourcery ARM)
Go to the top of the page
 
+Quote Post
klen
сообщение Oct 9 2006, 13:23
Сообщение #15


бессмертным стать можно тремя способами
*****

Группа: Свой
Сообщений: 1 405
Регистрация: 9-05-06
Из: Москва
Пользователь №: 16 912



я еще не выложил. завтра постатаюсь с утра закачать.
Go to the top of the page
 
+Quote Post

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

 


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


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