Полная версия этой страницы:
Останавливается LPC2138
Есть плата c lpc2138.
Все отлично работает до того момента как я начинаю пользоваться плавающей точкой.
Например
int z = 2;
float a = 10;
a = a;
Вызывает сброс контроллера.
Использую YAGARTO последний.
В чем может быть проблема?
Может что-то с библиотеками?
aaarrr
Aug 19 2008, 14:59
Стек проверьте, есть ли выравнивание по границе 2-х слов.
А как это сделать? Я просто не специалист...
Если вот так буду определать все будет нормально?
.stack ALIGN(256) :
{
. += STACK_SIZE;
PROVIDE (Top_Stack = .);
} > RAM
Если есть возможность покажите startup и ld-script пожалуйста.
aaarrr
Aug 19 2008, 15:12
Цитата(vkle @ Aug 19 2008, 19:07)

А как это сделать? Я просто не специалист...
Надежнее всего симулятором непосредственно при вызове float-функции.
Цитата(vkle @ Aug 19 2008, 19:07)

Если вот так буду определать все будет нормально?
Не факт: испортить выравнивание можно легко.
Опять таки я далеко не уверен, что дело именно в стеке. Просто проверьте.
В map файле стек находится вот так:
.stack 0x40000100 0x2400
*(.stack)
.stack 0x40000100 0x2400 crt0.o
0x40002500 PROVIDE (_stack, .)
0x40002500 . = ALIGN (0x4)
0x40002500 _end = .
0x40002500 PROVIDE (end, .)
Цитата
Надежнее всего симулятором непосредственно при вызове float-функции.
Фух, а что при этом должно быть? Т.е. что смотреть и как распознать выровнен он или нет? И если не выровнен, то что делать?
Как я и говорил я в этом не сильно понимаю.
aaarrr
Aug 19 2008, 15:20
Цитата(vkle @ Aug 19 2008, 19:16)

Фух, а что при этом должно быть? Т.е. что смотреть и как распознать выровнен он или нет?
После перехода на функцию младшие 3 бита R13 должны быть равны 0.
И в eclipse и в insight 12 регистров. Т.е. нужен именно симулятор?
Если я обнаружу что нет выравнивания, то что делать?
Показывает вот такое: когда пытается вызвать _floatsidf
- 0x3280 <__floatsidf>: andeq r0, r0, r0
- 0x3284 <__floatsidf+4>: andeq r0, r0, r0
- 0x3288 <__floatsidf+8>: andeq r0, r0, r0
- 0x328c <__floatsidf+12>: andeq r0, r0, r0
- 0x3290 <__floatsidf+16>: andeq r0, r0, r0
- 0x3294 <__floatsidf+20>: andeq r0, r0, r0
- 0x3298 <__floatsidf+24>: andeq r0, r0, r0
- 0x329c <__floatsidf+28>: andeq r0, r0, r0
- 0x32a0 <__floatsidf+32>: andeq r0, r0, r0
- 0x32a4 <__floatsidf+36>: andeq r0, r0, r0
- 0x32a8 <__floatsidf+40>: andeq r0, r0, r0
Это не похоже на функцию....
aaarrr
Aug 19 2008, 16:04
Значит у Вас с библиотекой что-то не так.
Вместо R13 - есть sp. Это наверняка stack pointer.
С ним все ОК. Он равен 0x40002168.
А вы не могли бы выложить хорошие библиотеки или повосетовать какимы вы сами пользуетесь?
Или на почту vkle ат mail.ru
Спасибо.
aaarrr
Aug 19 2008, 16:11
Дело не в "хорошести", а в том, что библиотека у Вас, судя по всему, просто не прилинковалась. А почему это произошло - не известно.
А как проверить прилинковалась или нет? В map файле она есть.
Линкер при сборке не ругается.
Какие могут быть варианты?
У вас случаем нет Makefile которым вы пользуетесь?
aaarrr
Aug 19 2008, 16:30
Я, к сожалению, не пользуюсь YAGARTO.
aaarrr
Aug 19 2008, 16:41
Вы имеете в виду, какой компилятор? Я давно пользуюсь продукцией ARM (ADS, RVDS) и очень ей доволен.
Все дальше парюсь...
Вобщем написал такой нехитрый код:
int main(){
float a = 10.2;
while(1){
a /= 2.0;
}
return 0;
}
Не использую никаких прерываний.
Если из мейкфайла (из компиляции) удаляю все остальные свои коды, то при входе в функцию деления __divsf3 вижу:
0x4d8 <__divsf3>: mov r12, #255 ; 0xff
0x4dc <__divsf3+4>: ands r2, r12, r0, lsr #23
0x4e0 <__divsf3+8>: andsne r3, r12, r1, lsr #23
0x4e4 <__divsf3+12>: teqne r2, r12
...
Если включаю в компиляцию написанные модули, но main не меняю и в main.c ничего не дописываю, то при входе в __divsf3 вижу шлак:
0x35b0 <__divsf3>: andeq r0, r0, r0
0x35b4 <__divsf3+4>: andeq r0, r0, r0
0x35b8 <__divsf3+8>: andeq r0, r0, r0
0x35bc <__divsf3+12>: andeq r0, r0, r0
0x35c0 <__divsf3+16>: andeq r0, r0, r0
...
Что это может быть?
Alex03
Aug 20 2008, 03:10
Цитата(vkle @ Aug 20 2008, 02:03)

Если из мейкфайла (из компиляции) удаляю все остальные свои коды, то при входе в функцию ....
Не плохо было бы приветсти "все остальные свои коды", ну или там Makefile.
Если мне не изменяет память, то andeq r0, r0, r0 имеет код операции 0x00000000.
Ну да, вываливается в пустую область памяти. При этом вываливается по правильному адресу (судя по map-файлу). Т.е. он переходит на функцию... а там нули.
Теперь про "все остальные коды", я не знаю как они помогут, ведь main.c не меняются, прерывания не используются, т.е. выполняется только приведенный мной код и стартап (crt0.S).
Что делать?
Странно, но кажется, что поведение программы зависит от ее размера.
Для просмотра полной версии этой страницы, пожалуйста,
пройдите по ссылке.