Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: GCC и прерывания в C коде
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Alex03
Вчера понадобилать Release версия проекта, скомпилил, ни в какую работать не захотела, глючило всё как могло.
Пол дня убил пока не понял что наступил на известные грабли GCC, неправильное генерение пролога/эпилога для прерываний. Описанные тут и тут


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

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


Вооот. Качать кучу исходников и патчить их чтото не хочется, мож кто уже проделал сию работу?
PrSt
Цитата(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. ...
Alex03
Цитата(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
klen
Цитата(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 изменен в части касающей строк которык в патче указаны.
Если будете пробывать напишите че вышло. будем разбиратся.
Alex03
Цитата(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.
shhh
По поводу глюка - я правильно понял что он проявляется при отличном от -O0 ключе оптимизации?

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

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

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

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

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


затем что нет его у меня пока! smile.gif Тока в линухе.
yaghtn
Случайно наткнулся: 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")))
Alex03
Цитата(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
klen
Цитата(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 */
klen
Убил субботу, ночь и полсегодня в поисках кривизны. Нашел откуда рога растут - функция разворачивания пролога в /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 в аборте или нет? Как считает?
Alex03
Цитата(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 тумб я тоже не пользую.
klen
Ну че? потестируете?
Alex03
Цитата(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)
klen
я еще не выложил. завтра постатаюсь с утра закачать.
klen
Цитата(Alex03 @ Oct 9 2006, 12:22) *
Если там же, то там нет?

Все руки не доходят выложить весь пакет. Но Вам хватит один файл подменить в кроссворке чтоб проверить. Выкладываю сюда попаравленный сс1.exe - собсвенно компилятор, замените им тот что в папке кросвокса gcc/bin/cc1.exe . Попробуйте найти глюки. Пока побочных эфектов не нашел.
Alex03
Цитата(klen @ Oct 12 2006, 02:47) *
Выкладываю сюда


Что-то не вижу этого "сюда"! smile.gif
klen
А как сюда архив выложить в 4 мега. Не дает.
klen
Наконецто FTP заработало!!! blink.gif

http://www.klen.org/Files/cc1_with_IRQ_FIQ_patched.zip
Alex03
Цитата(klen @ Oct 12 2006, 18:58) *
А как сюда архив выложить в 4 мега. Не дает.

Попроситесь в группу "свои" и Вам будет доступен местный FTP
klen
1.
Цитата
Попроситесь в группу "свои" и Вам будет доступен местный FTP

А у кого просить?

2. Ну че? Заработала? "Пилите Шура гири, может они золотые!" или хватит пока?
Alex03
Цитата(klen @ Oct 13 2006, 16:22) *
1.
Цитата

Попроситесь в группу "свои" и Вам будет доступен местный FTP

А у кого просить?


Вот тут http://electronix.ru/forum/index.php?showforum=89 всё почитайте.

Цитата
2. Ну че? Заработала? "Пилите Шура гири, может они золотые!" или хватит пока?


Я только IRQ и только в ARM пользую. Вроде работает.
klen
Цитата
Я только IRQ и только в ARM пользую. Вроде работает.


Это хорошо. Буду выкладывать сборку.
Еще глюки найдете - сообщайте, буду разбиратся.
dimka76
Подниму старую тему.

Вот прошло четыре года, а как сейчас обстоят дела с вопросом корректности обработчиков прерываний?
Исправлены наконец обсуждаемые здесь некорректности компилятора или нет?
Сергей Борщ
Цитата(dimka76 @ Sep 28 2010, 08:05) *
Вот прошло четыре года, а как сейчас обстоят дела с вопросом корректности обработчиков прерываний?
В сборке Yаgarto уже около года исправлены. Если я правильно помню, klen писал, что начиная с какой-то версии в основных исходниках основательно переработали генерацию пролога/эпилога, значит и остальные сборки должны собирать нормально.
dimka76
А как дела обстоят у Sourcery G++. Хотя и у них по идеи должно быть исправлено.

GetSmart
а самому проверить не судьба...
dimka76
Цитата(GetSmart @ Sep 28 2010, 15:06) *
а самому проверить не судьба...


Судьба. Но для этого надо скачать все эти сборки. Потом с каждой потестить. Проще спросить.
IgorKossak
Цитата(dimka76 @ Sep 28 2010, 13:52) *
А как дела обстоят у Sourcery G++. Хотя и у них по идеи должно быть исправлено.

У последних двух Lite исправлено.
dimka76
Всем большое спасибо )))
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.