|
WinAVR и ELPM, ставит lpm вместо elpm |
|
|
|
Sep 30 2008, 21:39
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Столкнулся с такой проблемой: ATmega1280, пишу bootloader, в 0 адресе все работает. Передвигаю на 0x01E000 - не запускается. Смотрю дебагером и обнаруживаю, что там, где должна быть инструкция ELPM - стоит LPM (хотя RAMPZ установлен верно). Соответственно данные читаются не из того места, и переход выполняется в адрес где-то за пределами кода. Пока программа лежала в 0 адресе, не было переполнения на 16-й бит адреса и все работало нормально. Кто нибудь сталкивался? Может какие ключи компиляции помогут? Или вручную опкоды править?
Эскизы прикрепленных изображений
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Oct 1 2008, 10:06
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Цитата(demiurg_spb @ Oct 1 2008, 11:33)  Что за версия компилятора? WinAVR-20080610, последняя. До этого использовал 200804xx, то же самое... Цитата(demiurg_spb @ Oct 1 2008, 11:33)  Приведите хоть кусочек исходника с подозреваемой проблемой. А так Вам никто не поможет... В том то и дело, что до самого кода программы дело еще не доходит, затык в начальной инициализации. После старта сначала идет инициализация памяти данных, затем в Z регистр грузится начальный адрес видимо какой-то таблицы (сразу после векторов прерываний) и должно считываться первое значение, судя по всему адрес, по которому должен происходить переход (это видно из приведенного скрина). Но этого не происходит, т.к. адрес читается некорректно, не той командой. Это все происходит до начала функции main(), и я не знаю что из кода на это может повлиять. Весь код программы я выложить не могу. Но могу сказать что он использует операционную систему scmRTOS (gcc). Кто-то может сказать "зачем в бутлоадере ОС?". Просто я использую те-же драйвера внешних устройств, что и в основной программе, заточеные под эту ОС и переписывать все не хотелось бы. Тем более все что нужно вместе с ОС влезают в 8 кб. Кстати, программа под С++ (а не чистый С), может это важно...
Сообщение отредактировал ZyBEX - Oct 1 2008, 10:10
|
|
|
|
|
Oct 1 2008, 10:20
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(ZyBEX @ Oct 1 2008, 14:06)  Весь код программы я выложить не могу. А фрагмент из *.lst файла с этим кодом можете? Анатолий.
Сообщение отредактировал aesok - Oct 1 2008, 10:23
|
|
|
|
|
Oct 1 2008, 10:41
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Цитата(aesok @ Oct 1 2008, 14:20)  А фрагмент из *.lst файла с этим кодом можете?
Анатолий. Я же говорю, описанное происходит еще до вхождения в main(), в сишной инициализации. В каком .lst файле это?
|
|
|
|
|
Oct 1 2008, 10:50
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(ZyBEX @ Oct 1 2008, 13:41)  Я же говорю, описанное происходит еще до вхождения в main(), в сишной инициализации. В каком .lst файле это? Давайте попробуем разобраться. Начнем с получения листинга всей прошивки: avr-objdump -hSCD файл.elf > файл.lss В ней посмотрите, как называется метка по адресу 0xFD0F и, заодно, из какой функции происходит переход на нее. Можете привести здесь отрывок этого листинга. Или вырежьте из него main() и все ваши секретные функции, оставьте только инициализацию, и выложите.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 1 2008, 14:11
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Цитата(Сергей Борщ @ Oct 1 2008, 14:50)  Давайте попробуем разобраться. Начнем с получения листинга всей прошивки: avr-objdump -hSCD файл.elf > файл.lss В ней посмотрите, как называется метка по адресу 0xFD0F и, заодно, из какой функции происходит переход на нее. Можете привести здесь отрывок этого листинга. Или вырежьте из него main() и все ваши секретные функции, оставьте только инициализацию, и выложите. Код 0001e000 <__vectors>: 1e000: 77 c0 rjmp .+238 ; 0x1e0f0 <__ctors_end> 1e002: 00 00 nop 1e004: 9e c0 rjmp .+316 ; 0x1e142 <__bad_interrupt> 1e006: 00 00 nop 1e008: 9c c0 rjmp .+312 ; 0x1e142 <__bad_interrupt> 1e00a: 00 00 nop 1e00c: 9a c0 rjmp .+308 ; 0x1e142 <__bad_interrupt> 1e00e: 00 00 nop 1e010: 98 c0 rjmp .+304 ; 0x1e142 <__bad_interrupt> 1e012: 00 00 nop 1e014: 53 c4 rjmp .+2214 ; 0x1e8bc <__vector_5> 1e016: 00 00 nop 1e018: 94 c0 rjmp .+296 ; 0x1e142 <__bad_interrupt> 1e01a: 00 00 nop 1e01c: 92 c0 rjmp .+292 ; 0x1e142 <__bad_interrupt> 1e01e: 00 00 nop 1e020: 90 c0 rjmp .+288 ; 0x1e142 <__bad_interrupt> 1e022: 00 00 nop 1e024: 8e c0 rjmp .+284 ; 0x1e142 <__bad_interrupt> 1e026: 00 00 nop 1e028: 8c c0 rjmp .+280 ; 0x1e142 <__bad_interrupt> 1e02a: 00 00 nop 1e02c: 8a c0 rjmp .+276 ; 0x1e142 <__bad_interrupt> 1e02e: 00 00 nop 1e030: 88 c0 rjmp .+272 ; 0x1e142 <__bad_interrupt> 1e032: 00 00 nop 1e034: 86 c0 rjmp .+268 ; 0x1e142 <__bad_interrupt> 1e036: 00 00 nop 1e038: 84 c0 rjmp .+264 ; 0x1e142 <__bad_interrupt> 1e03a: 00 00 nop 1e03c: 82 c0 rjmp .+260 ; 0x1e142 <__bad_interrupt> 1e03e: 00 00 nop 1e040: 80 c0 rjmp .+256 ; 0x1e142 <__bad_interrupt> 1e042: 00 00 nop 1e044: 7e c0 rjmp .+252 ; 0x1e142 <__bad_interrupt> 1e046: 00 00 nop 1e048: 7c c0 rjmp .+248 ; 0x1e142 <__bad_interrupt> 1e04a: 00 00 nop 1e04c: 7a c0 rjmp .+244 ; 0x1e142 <__bad_interrupt> 1e04e: 00 00 nop 1e050: 78 c0 rjmp .+240 ; 0x1e142 <__bad_interrupt> 1e052: 00 00 nop 1e054: 0c 94 4a fc jmp 0x1f894; 0x1f894 <__vector_21> 1e058: 74 c0 rjmp .+232 ; 0x1e142 <__bad_interrupt> 1e05a: 00 00 nop 1e05c: 72 c0 rjmp .+228 ; 0x1e142 <__bad_interrupt> 1e05e: 00 00 nop 1e060: 0c 94 c7 f9 jmp 0x1f38e; 0x1f38e <__vector_24> 1e064: 6e c0 rjmp .+220 ; 0x1e142 <__bad_interrupt> 1e066: 00 00 nop 1e068: 6c c0 rjmp .+216 ; 0x1e142 <__bad_interrupt> 1e06a: 00 00 nop 1e06c: 6a c0 rjmp .+212 ; 0x1e142 <__bad_interrupt> 1e06e: 00 00 nop 1e070: 68 c0 rjmp .+208 ; 0x1e142 <__bad_interrupt> 1e072: 00 00 nop 1e074: 66 c0 rjmp .+204 ; 0x1e142 <__bad_interrupt> 1e076: 00 00 nop 1e078: 64 c0 rjmp .+200 ; 0x1e142 <__bad_interrupt> 1e07a: 00 00 nop 1e07c: 62 c0 rjmp .+196 ; 0x1e142 <__bad_interrupt> 1e07e: 00 00 nop 1e080: 60 c0 rjmp .+192 ; 0x1e142 <__bad_interrupt> 1e082: 00 00 nop 1e084: 5e c0 rjmp .+188 ; 0x1e142 <__bad_interrupt> 1e086: 00 00 nop 1e088: 5c c0 rjmp .+184 ; 0x1e142 <__bad_interrupt> 1e08a: 00 00 nop 1e08c: 5a c0 rjmp .+180 ; 0x1e142 <__bad_interrupt> 1e08e: 00 00 nop 1e090: 58 c0 rjmp .+176 ; 0x1e142 <__bad_interrupt> 1e092: 00 00 nop 1e094: 56 c0 rjmp .+172 ; 0x1e142 <__bad_interrupt> 1e096: 00 00 nop 1e098: 54 c0 rjmp .+168 ; 0x1e142 <__bad_interrupt> 1e09a: 00 00 nop 1e09c: 52 c0 rjmp .+164 ; 0x1e142 <__bad_interrupt> 1e09e: 00 00 nop 1e0a0: 50 c0 rjmp .+160 ; 0x1e142 <__bad_interrupt> 1e0a2: 00 00 nop 1e0a4: 4e c0 rjmp .+156 ; 0x1e142 <__bad_interrupt> 1e0a6: 00 00 nop 1e0a8: 4c c0 rjmp .+152 ; 0x1e142 <__bad_interrupt> 1e0aa: 00 00 nop 1e0ac: 4a c0 rjmp .+148 ; 0x1e142 <__bad_interrupt> 1e0ae: 00 00 nop 1e0b0: 48 c0 rjmp .+144 ; 0x1e142 <__bad_interrupt> 1e0b2: 00 00 nop 1e0b4: 46 c0 rjmp .+140 ; 0x1e142 <__bad_interrupt> 1e0b6: 00 00 nop 1e0b8: 44 c0 rjmp .+136 ; 0x1e142 <__bad_interrupt> 1e0ba: 00 00 nop 1e0bc: 42 c0 rjmp .+132 ; 0x1e142 <__bad_interrupt> 1e0be: 00 00 nop 1e0c0: 40 c0 rjmp .+128 ; 0x1e142 <__bad_interrupt> 1e0c2: 00 00 nop 1e0c4: 3e c0 rjmp .+124 ; 0x1e142 <__bad_interrupt> 1e0c6: 00 00 nop 1e0c8: 3c c0 rjmp .+120 ; 0x1e142 <__bad_interrupt> 1e0ca: 00 00 nop 1e0cc: 3a c0 rjmp .+116 ; 0x1e142 <__bad_interrupt> 1e0ce: 00 00 nop 1e0d0: 38 c0 rjmp .+112 ; 0x1e142 <__bad_interrupt> 1e0d2: 00 00 nop 1e0d4: 36 c0 rjmp .+108 ; 0x1e142 <__bad_interrupt> 1e0d6: 00 00 nop 1e0d8: 34 c0 rjmp .+104 ; 0x1e142 <__bad_interrupt> 1e0da: 00 00 nop 1e0dc: 32 c0 rjmp .+100 ; 0x1e142 <__bad_interrupt> 1e0de: 00 00 nop 1e0e0: 30 c0 rjmp .+96 ; 0x1e142 <__bad_interrupt> ...
0001e0e4 <__ctors_start>: 1e0e4: 03 f5 brvc .+64 ; 0x1e126 <__do_global_ctors> 1e0e6: 16 f5 brtc .+68 ; 0x1e12c <__do_global_ctors+0x6> 1e0e8: d1 f9 bld r29, 1 1e0ea: 00 fa bst r0, 0 1e0ec: f6 fa bst r15, 6 1e0ee: 3c fc .word 0xfc3c; ????
0001e0f0 <__ctors_end>: 1e0f0: 11 24 eor r1, r1 1e0f2: 1f be out 0x3f, r1; 63 1e0f4: cf ef ldi r28, 0xFF; 255 1e0f6: d1 e2 ldi r29, 0x21; 33 1e0f8: de bf out 0x3e, r29; 62 1e0fa: cd bf out 0x3d, r28; 61
0001e0fc <__do_copy_data>: 1e0fc: 12 e0 ldi r17, 0x02; 2 1e0fe: a0 e0 ldi r26, 0x00; 0 1e100: b2 e0 ldi r27, 0x02; 2 1e102: e4 e5 ldi r30, 0x54; 84 1e104: fb ef ldi r31, 0xFB; 251 1e106: 01 e0 ldi r16, 0x01; 1 1e108: 0b bf out 0x3b, r16; 59 1e10a: 02 c0 rjmp .+4 ; 0x1e110 <__do_copy_data+0x14> 1e10c: 07 90 elpm r0, Z+ 1e10e: 0d 92 st X+, r0 1e110: ae 31 cpi r26, 0x1E; 30 1e112: b1 07 cpc r27, r17 1e114: d9 f7 brne .-10 ; 0x1e10c <__do_copy_data+0x10>
0001e116 <__do_clear_bss>: 1e116: 17 e0 ldi r17, 0x07; 7 1e118: ae e1 ldi r26, 0x1E; 30 1e11a: b2 e0 ldi r27, 0x02; 2 1e11c: 01 c0 rjmp .+2 ; 0x1e120 <.do_clear_bss_start>
0001e11e <.do_clear_bss_loop>: 1e11e: 1d 92 st X+, r1
0001e120 <.do_clear_bss_start>: 1e120: a8 36 cpi r26, 0x68; 104 1e122: b1 07 cpc r27, r17 1e124: e1 f7 brne .-8 ; 0x1e11e <.do_clear_bss_loop>
0001e126 <__do_global_ctors>: 1e126: 10 ee ldi r17, 0xE0; 224 1e128: c0 ef ldi r28, 0xF0; 240 1e12a: d0 ee ldi r29, 0xE0; 224 1e12c: 04 c0 rjmp .+8 ; 0x1e136 <.do_global_ctors_start>
0001e12e <.do_global_ctors_loop>: 1e12e: 22 97 sbiw r28, 0x02; 2 1e130: fe 01 movw r30, r28 1e132: 0e 94 11 fd call 0x1fa22; 0x1fa22 <__tablejump__>
0001e136 <.do_global_ctors_start>: 1e136: c4 3e cpi r28, 0xE4; 228 1e138: d1 07 cpc r29, r17 1e13a: c9 f7 brne .-14 ; 0x1e12e <.do_global_ctors_loop> 1e13c: 40 d4 rcall .+2176 ; 0x1e9be <main> 1e13e: 0c 94 a8 fd jmp 0x1fb50; 0x1fb50 <_exit>
0001e142 <__bad_interrupt>: 1e142: 5e cf rjmp .-324 ; 0x1e000 <__vectors> подпрограмма называется __tablejump__ Код 0001fa1e <__tablejump2__>: 1fa1e: ee 0f add r30, r30 1fa20: ff 1f adc r31, r31
0001fa22 <__tablejump__>: 1fa22: 05 90 lpm r0, Z+ 1fa24: f4 91 lpm r31, Z+ 1fa26: e0 2d mov r30, r0 1fa28: 09 94 ijmp
|
|
|
|
|
Oct 1 2008, 15:54
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Я понял что у меня за таблица, по которой бродит table_jump. Это таблица конструкторов глобальных объектов. Вот, как раз С++ сыграло свою роль. Цитата(aesok @ Oct 1 2008, 19:23)  GCC Bugzilla Bug 29141 static constructors beyond 64k fail http://gcc.gnu.org/bugzilla/show_bug.cgi?id=29141aesok, не увидел сначала твой ответ. Как раз оно самое...
Сообщение отредактировал ZyBEX - Oct 1 2008, 15:56
|
|
|
|
|
Oct 1 2008, 17:09
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Проблема датируется 2006 годом. Странно что до сих пор не решена.
|
|
|
|
|
Oct 1 2008, 18:33
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
По идее проблему можно решить, создавая объекты только локально. Но, ИМХО, для scmRTOS это невозможно без изменения самой ОС.
Временно решил проблему заменой в хекс редакторе неверных опкодов 9005 и 91F4 соответственно на 9007 и 91F6. Все заработало.
Вот если бы патчик написать, который сам это делать будет.
|
|
|
|
|
Oct 1 2008, 20:04
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
Цитата(ZyBEX @ Oct 1 2008, 21:33)  По идее проблему можно решить, создавая объекты только локально. Ну, это не решение, скорее обход, и не совсем удачный. Цитата(ZyBEX @ Oct 1 2008, 21:33)  Вот если бы патчик написать, который сам это делать будет. Попробуйте добавить в проект ассемблерный файлик, в котором будет правильный код от метки __tablejump2__ до ijmp. При линковке он должен подлинковаться вместо библиотечного.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 2 2008, 06:45
|
Знающий
   
Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484

|
Цитата(ZyBEX @ Oct 1 2008, 22:33)  Временно решил проблему заменой в хекс редакторе неверных опкодов 9005 и 91F4 соответственно на 9007 и 91F6. Все заработало. А Вы так быстро ВСЕ проверили? __tablejump2__ используеться для реализации оператора case. Ваши исправления сделатют его не работоспособным для случая когда в case больше 16 ветвей и RAMPZ == 0. Анатолий.
|
|
|
|
|
Oct 2 2008, 08:21
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
Цитата(aesok @ Oct 2 2008, 10:45)  А Вы так быстро ВСЕ проверили?
__tablejump2__ используеться для реализации оператора case. Ваши исправления сделатют его не работоспособным для случая когда в case больше 16 ветвей и RAMPZ == 0.
Анатолий. Я об этом думал. Но все равно бутлоадер работает только в верхней памяти и уходит оттуда когда он уже не нужен. Так что все должно работать. Главное мне каждый раз после записи флеш нижних адресов, восстанавливать RAMPZ обратно на 1.
|
|
|
|
|
Oct 2 2008, 20:22
|
Участник

Группа: Участник
Сообщений: 54
Регистрация: 5-05-08
Пользователь №: 37 279

|
[SOLVED]Цитата(Сергей Борщ @ Oct 2 2008, 00:04)  Попробуйте добавить в проект ассемблерный файлик, в котором будет правильный код от метки __tablejump2__ до ijmp. При линковке он должен подлинковаться вместо библиотечного. Действительно, сработало. Создал файл tablejump_patch.S со следующим содержимым: Код ;.global __tablejump2__ ;__tablejump2__: ; add r30, r30 ; adc r31, r31
.global __tablejump__ __tablejump__: elpm r0, Z+ elpm r31, Z mov r30, r0 ijmp Здесь tablejump2 закомментирован потому, что он не используется в моем варианте (хотя case есть, вопреки тому что сказал aesok, ссылка на tablejump только в одном месте). Когда наращу программу, если компилятор попросит, раскомментирую. Если что, сюда же можно добавить работу с RAMPZ... Всем спасибо!
Сообщение отредактировал ZyBEX - Oct 2 2008, 20:25
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|