Перейти к содержанию
    

Как программно сгенерить ресет?

А вот и не работает в WinAvr'e, улетает не на нулевой адрес!!! :laughing:
Такие серьезные заявления обычно подтверждаются приведением исходника и отрывка листинга. У меня, например, работает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Такие серьезные заявления обычно подтверждаются приведением исходника и отрывка листинга. У меня, например, работает.

вот кусок из студии

дизассемблер:

@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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А, не выдаёт ли транслятор какого-либо сообщения при трансляции строки ((void(*)(void))0)() ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А, не выдаёт ли транслятор какого-либо сообщения при трансляции строки ((void(*)(void))0)() ?

нет!всё ок!проглатывает....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

АА, не выдаёт ли транслятор какого-либо сообщения при трансляции строки ((void(*)(void))0)() ?

 

В ИАР все прекрасно работает и в CVAVR тоже. Возможно в симуляторе надо поставить птицу старта симуляции и 0-го адреса, а не с main(). В C-SPY IAR такая опция есть. ИМХО обязано работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нет!всё ок!проглатывает....
Странно... Насколько я понимаю, вызывается та же процедура, что и в предыдущем вызове, т.е. вызывается initpotr()... Может у Вас отключены выводы предупреждающих сообщений?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно... Насколько я понимаю, вызывается та же процедура, что и в предыдущем вызове, т.е. вызывается initpotr()... Может у Вас отключены выводы предупреждающих сообщений?

да!именно так и происходит

предупреждения включены,забыл сказать у меня mega8

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть еще

int main(void)
{
.....................
.....................
cli();
return(0);
}

 

:)

похоже что не работает ....

00000A54: CFFF RJMP PC-0x0000 Relative jump

зацикливатся на себя

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сейчас попробовал эту конструкцию в WinAVR - всё хорошо транслирует и выполняет - переход куда и было сказано!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сейчас попробовал эту конструкцию в WinAVR - всё хорошо транслирует и выполняет - переход куда и было сказано!

какую?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть еще

Это называется возвратисть туда, незнаю куда, но может куда и попадешь.

 

 

вот кусок из студии

....

1362: ((void(*)(void))0)();

+00000A3F: D60E RCALL PC+0x060F Relative call subroutine

Кто-то кому-то голову пытается морочить. Вопрос зачем?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это называется возвратисть туда, незнаю куда, но может куда и попадешь.

Кто-то кому-то голову пытается морочить. Вопрос зачем?

всмысле???

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Щаз я Вам все объясню :)

 

Дело в том что у 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");

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...