реклама на сайте
подробности

 
 
> Вопрос по недокументированной команде ATtiny13., Откуда у ATtiny13 команда jmp ?
kv_addr
сообщение Apr 6 2009, 09:06
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Во избежание открытия в ветке дискуссии по поводу, кошерно ли рестартовать не через watchdog, а переходом по адресу 0, хотел бы заметить, в моём конкретном случае - вполне кошерно. Рестарт происходит по нажатию и отпусканию кнопки путем вывода контроллера из режима глубокой спячки, все необходимое подготовлено перед вводом в спячку.

Перейду к сути. Имеем предельно простую подпрограмму прерывания:
Код
#pragma vector= INT0_vect
__interrupt void Int0(void)
{
  while(!BUTTON);
  __indirect_jump_to(0);
}

Генерируется код:
Код
     18          __interrupt void Int0(void)
   \                     Int0:
     19          {
   \   00000000   93FA               ST      -Y, R31
   \   00000002   93EA               ST      -Y, R30
     20            while(!BUTTON);
   \                     ??Int0_0:
   \   00000004   9BB1               SBIS    0x16, 0x01
   \   00000006   CFFE               RJMP    ??Int0_0
     21            __indirect_jump_to(0);
   \   00000008   E0E0               LDI     R30, 0
   \   0000000A   E0F0               LDI     R31, 0
   \   0000000C   9409               IJMP
   \   0000000E                      REQUIRE _A_PINB
     22          }

Все выполняется верно (и в железе тоже). Пишу с ассемблерной вставкой:
Код
#pragma vector= INT0_vect //В выключеном состоянии ~1...1,5 мкА
__interrupt void Int0(void)
{
  while(!BUTTON);
  asm("jmp 0"); // Не "rjmp 0", а именно "jmp 0" !
}

Генерируется код:
Код
     18          __interrupt void Int0(void)
   \                     Int0:
   \                     ??Int0_0:
     19          {
     20            while(!BUTTON);
   \   00000000   9BB1               SBIS    0x16, 0x01
   \   00000002   CFFE               RJMP    ??Int0_0
     21            asm("jmp 0");
   \   00000004   940C0000           jmp 0
     22          }

И, как ни странно, все выполняется (и в железе тоже).

В таком случае возникает вопрос, откуда у ATtiny13 появилась выполняемая в реале команда "jmp", отсутствующая в наборе команд для этого конкретного контроллера?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ataradov
сообщение Apr 6 2009, 13:53
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 014
Регистрация: 8-01-07
Из: San Jose, CA
Пользователь №: 24 202



Под "random", если я правильно понял понимается любое число. Смысл в том, что ресет потому и происходит, что такой инструкции нет.
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Apr 6 2009, 15:50
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Цитата(Taradov Alexander @ Apr 6 2009, 16:53) *
Под "random", если я правильно понял понимается любое число. Смысл в том, что ресет потому и происходит, что такой инструкции нет.


Практика - критерий истины.

Пишем еще кусок кода с известной точкой входа, и там зацикливаемся:
Код
#pragma vector= INT0_vect
__interrupt void Int0(void)
{
  while(!BUTTON);
  asm("jmp 10");
}

#pragma vector= ANA_COMP_vect
__interrupt void Test(void)
{
  DDRB = 0x08;
  PORTB_Bit3 = 0;
  while(1)  PORTB_Bit3 = !PORTB_Bit3;
}

Компилируем, прошиваем.
По нажатию и отпусканию кнопки на PB3 при помощи бациллоскопа наблюдаем красивый меандр.
Команда jmp 10 отрабатывается безукоризненно. smile.gif

Ваша гипотеза - ошибочна.
Go to the top of the page
 
+Quote Post
defunct
сообщение Apr 7 2009, 00:32
Сообщение #4


кекс
******

Группа: Свой
Сообщений: 3 825
Регистрация: 17-12-05
Из: Киев
Пользователь №: 12 326



Цитата(kv_addr @ Apr 6 2009, 18:50) *
Ваша гипотеза - ошибочна.

Это не страшно, главное что Ваша подтверждена. laughing.gif
Заманчиво конечно, но наверное не стоит расчитывать, что во всех ревизиях чипа недокументированная инструкция будет поддерживаться. При какой-нить очередной оптимизации могут и выкинуть.
Go to the top of the page
 
+Quote Post
kv_addr
сообщение Apr 7 2009, 06:20
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 208
Регистрация: 6-07-04
Из: Полтава
Пользователь №: 279



Цитата(defunct @ Apr 7 2009, 03:32) *
Это не страшно, главное что Ваша подтверждена. laughing.gif
Заманчиво конечно, но наверное не стоит расчитывать, что во всех ревизиях чипа недокументированная инструкция будет поддерживаться. При какой-нить очередной оптимизации могут и выкинуть.

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

Обнаружил в процессе поиска наиболее компактного варианта программного ресета.

Но вот "rjmp" побороть не смог. Как указать в ассемблерной вставке относительному переходу скакнуть по абсолютному адресу способа не нашел.

Зато обнаружил, что __indirect_jump_to(0), в отличие от asm("ldi r30,0\n ldi r31,0\n ijmp"), подавляет генерацию бесполезной reti, а __noreturn убирает столь же бесполезное в этом случае сохранение регистровой пары z.
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 18:20
Рейтинг@Mail.ru


Страница сгенерированна за 0.0141 секунд с 7
ELECTRONIX ©2004-2016