Сергей Борщ 140 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба А вот и не работает в WinAvr'e, улетает не на нулевой адрес!!! :laughing:Такие серьезные заявления обычно подтверждаются приведением исходника и отрывка листинга. У меня, например, работает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вован 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Такие серьезные заявления обычно подтверждаются приведением исходника и отрывка листинга. У меня, например, работает. вот кусок из студии дизассемблер: @00000A2D: main 1350: { +00000A2D: E5C6 LDI R28,0x56 Load immediate +00000A2E: E0D4 LDI R29,0x04 Load immediate +00000A2F: BFDE OUT 0x3E,R29 Out to I/O location +00000A30: BFCD OUT 0x3D,R28 Out to I/O location 1356: if ((MCUCSR>>WDRF)&1) //Watchdog Reset Flag +00000A31: B784 IN R24,0x34 In from I/O location +00000A32: 9586 LSR R24 Logical shift right +00000A33: 9586 LSR R24 Logical shift right +00000A34: 9586 LSR R24 Logical shift right +00000A35: FF80 SBRS R24,0 Skip if bit in register set +00000A36: C005 RJMP PC+0x0006 Relative jump 1357: conditions.start =1; +00000A37: 91800079 LDS R24,0x0079 Load direct from data space +00000A39: 6082 ORI R24,0x02 Logical OR with immediate +00000A3A: 93800079 STS 0x0079,R24 Store direct to data space 1358: MCUCSR =0; +00000A3C: BE14 OUT 0x34,R1 Out to I/O location 1359: init_ctc(); +00000A3D: DBF7 RCALL PC-0x0408 Relative call subroutine 1361: initport(); +00000A3E: D60F RCALL PC+0x0610 Relative call subroutine 1362: ((void(*)(void))0)(); +00000A3F: D60E RCALL PC+0x060F Relative call subroutine Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба А, не выдаёт ли транслятор какого-либо сообщения при трансляции строки ((void(*)(void))0)() ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вован 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба А, не выдаёт ли транслятор какого-либо сообщения при трансляции строки ((void(*)(void))0)() ? нет!всё ок!проглатывает.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladimirYU 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба АА, не выдаёт ли транслятор какого-либо сообщения при трансляции строки ((void(*)(void))0)() ? В ИАР все прекрасно работает и в CVAVR тоже. Возможно в симуляторе надо поставить птицу старта симуляции и 0-го адреса, а не с main(). В C-SPY IAR такая опция есть. ИМХО обязано работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба нет!всё ок!проглатывает.... Странно... Насколько я понимаю, вызывается та же процедура, что и в предыдущем вызове, т.е. вызывается initpotr()... Может у Вас отключены выводы предупреждающих сообщений? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вован 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Странно... Насколько я понимаю, вызывается та же процедура, что и в предыдущем вызове, т.е. вызывается initpotr()... Может у Вас отключены выводы предупреждающих сообщений? да!именно так и происходит предупреждения включены,забыл сказать у меня mega8 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_Pasha 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Есть еще int main(void) { ..................... ..................... cli(); return(0); } :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вован 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Есть еще int main(void) { ..................... ..................... cli(); return(0); } :) похоже что не работает .... 00000A54: CFFF RJMP PC-0x0000 Relative jump зацикливатся на себя Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Сейчас попробовал эту конструкцию в WinAVR - всё хорошо транслирует и выполняет - переход куда и было сказано! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вован 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Сейчас попробовал эту конструкцию в WinAVR - всё хорошо транслирует и выполняет - переход куда и было сказано! какую? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 2 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Есть еще Это называется возвратисть туда, незнаю куда, но может куда и попадешь. вот кусок из студии .... 1362: ((void(*)(void))0)(); +00000A3F: D60E RCALL PC+0x060F Relative call subroutine Кто-то кому-то голову пытается морочить. Вопрос зачем? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Вован 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Это называется возвратисть туда, незнаю куда, но может куда и попадешь. Кто-то кому-то голову пытается морочить. Вопрос зачем? всмысле??? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба какую? Вот такую: ((void(*)(void))0)() ! Что-то Вы не так делаете.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 26 мая, 2008 Опубликовано 26 мая, 2008 · Жалоба Щаз я Вам все объясню :) Дело в том что у WinAVR есть такая бага/фича (бага с точки зрения стандарта) что переход по ((void(*)(void))0x0)(); может осуществляться НЕ на нулевой адрес. Это зависит от того сколько флеша есть у контроллера. Если на проце >8Kb(4Кслов) , то такой вызов будет правильным call 0x0000 , если же на проце меньше или равно 8Kb то у проца просто нет инструкций call/jmp а есть только rcall/rjmp те абсолютные адреса понимать он не может(на этапе компиляции), поэтому для таких процов джамп будет не на 0 адрес. Вот примеры одного и того же кода для mega16: int main(void) { 8e: cf e5 ldi r28, 0x5F; 95 90: d4 e0 ldi r29, 0x04; 4 92: de bf out 0x3e, r29; 62 94: cd bf out 0x3d, r28; 61 ((void(*)(void))0x0)(); 96: 0e 94 00 00 call 0x0 <__vectors> Прыгнули куда надо! и для mega8: int main(void) { 5c: cf e5 ldi r28, 0x5F; 95 5e: d4 e0 ldi r29, 0x04; 4 60: de bf out 0x3e, r29; 62 62: cd bf out 0x3d, r28; 61 ((void(*)(void))0x0)(); 64: fb df rcall .-10 ; 0x5c <main> Не знали куда надо прыгать, поэтому прыгнули на main! А теперь добавляем функцию на мега8: void softreset() { ((void(*)(void))0x0)(); 5c: ff df rcall .-2 ; 0x5c <softreset> 5e: 08 95 ret 00000060 <main>: } int main(void) { 60: cf e5 ldi r28, 0x5F; 95 62: d4 e0 ldi r29, 0x04; 4 64: de bf out 0x3e, r29; 62 66: cd bf out 0x3d, r28; 61 softreset(); 68: f9 df rcall .-14 ; 0x5c <softreset> ОБА-НА, прыжок то на адрес начала функции(интересно что будет когда стек налезет на на регистры :) ) Почему разработчики WinAVR не сделали вполне валидный в этом случае icall для меня загадка, наверное регистры r31:r30 решили сэкономить :) итого для чипов с <=8Kb лучше так: __asm__ __volatile__("ldi r30,0\n\t"\ "ldi r31,0\n\t"\ "ijmp"); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться