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

 
 
4 страниц V  < 1 2 3 4 >  
Reply to this topicStart new topic
> Как программно сгенерить ресет?
zltigo
сообщение May 26 2008, 15:51
Сообщение #31


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(singlskv @ May 26 2008, 17:11) *
Дело в том что у WinAVR есть такая бага/фича (бага с точки зрения стандарта)
что переход по ((void(*)(void))0x0)(); может осуществляться НЕ на нулевой адрес.

Фичи в упор не вижу, а баг 100% - нет ни одной причины не сгенерить, как уже говорилось, ICALL.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 26 2008, 16:00
Сообщение #32


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Да, ну и конечно стоит еще добавить вариант который должен быть правильным для
всех аврок и не использует асм:
Код
volatile unsigned int vect = 0;

void softreset()
{
  ((void(*)(void))vect)();
}

int main(void)
{

  softreset();

  return 0;
}

Код
void softreset()
{
  ((void(*)(void))vect)();
  5c:    e0 91 60 00     lds    r30, 0x0060
  60:    f0 91 61 00     lds    r31, 0x0061
  64:    09 95           icall
  66:    08 95           ret

только при этом рамы 2 байта зазря расходуем

Цитата(zltigo @ May 26 2008, 19:51) *
Фичи в упор не вижу, а баг 100% - нет ни одной причины не сгенерить, как уже говорилось, ICALL.
Бага поведение которой 100% известно, это уже не бага а фича smile.gif
Go to the top of the page
 
+Quote Post
defunct
сообщение May 26 2008, 16:03
Сообщение #33


кекс
******

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



Цитата(singlskv @ May 26 2008, 18:11) *
итого для чипов с <=8Kb лучше так:
Код
__asm__ __volatile__("ldi r30,0\n\t"\
                       "ldi r31,0\n\t"\
                       "ijmp");

А почему только до 8kb, а не до 128kb?
Этот код на m128 точно будет работать - значит это общий случай.
только если делать "asm" вставку, то что мешает написать

Код
asm( "jmp 0x0");

будет работать без ограничений для толтых чипов.

ЗЫ: зачем писать "__asm__ __volatile__" когда уже есть макрос "asm". придерживающийся одинакового синтаксиса и поддерживаемый всеми компиляторами для AVR (по крайней мере теми, которые я пробовал).
Go to the top of the page
 
+Quote Post
Палыч
сообщение May 26 2008, 16:14
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



А, ведь точно - прав singlskv!

Цитата(defunct @ May 26 2008, 19:03) *
А почему только до 8kb, а не до 128kb? Этот код на m128 точно будет работать. только если делать "asm" вставку, то что мешает написать
Код
asm( "jmp 0x0");
Наверное, отсутствие команды jmp в m8
Go to the top of the page
 
+Quote Post
defunct
сообщение May 26 2008, 16:17
Сообщение #35


кекс
******

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



Цитата(Палыч @ May 26 2008, 19:14) *
Наверное, отсутствие команды jmp в m8

не не, я там просто неправильно выразился,
быстро писал sad.gif

я насчет "asm" и "__asm__ __volatile__"
Пост уже подправил.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 26 2008, 16:23
Сообщение #36


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(defunct @ May 26 2008, 20:03) *
А почему только до 8kb, а не до 128kb?
Этот код на m128 точно будет работать.
ну в том смысле что на <=8Кб по другому никак
Цитата
только если делать "asm" вставку, то что мешает написать
Код
asm( "jmp 0x0");

будет работать без ограничений для толтых чипов.
на толстых то и без асм все работает ((void(*)(void))0)();
Цитата
ЗЫ: и нафига писать "__asm__ __volatile__" когда уже есть макрос "asm". придерживающийся одинакового синтаксиса и поддерживаемый всеми компиляторами для AVR (по крайней мере теми, которые я пробовал).
А это немного народное поверие когда-то давно вычитаное из описания avr-libc :

Let us first examine the part of a compiler listing which may have been generated
from our example:
lds r24,value
/* #APP */
in r24, 12
/* #NOAPP */
sts value,r24
The comments have been added by the compiler to inform the assembler that the included
code was not generated by the compilation of C statements, but by inline assembler
statements. The compiler selected register r24 for storage of the value read
from PORTD. The compiler could have selected any other register, though. It may not
explicitely load or store the value and it may even decide not to include your assembler
code at all. All these decisions are part of the compiler’s optimization strategy.
For
example, if you never use the variable value in the remaining part of the C program,
the compiler will most likely remove your code unless you switched off optimization.
To avoid this, you can add the volatile attribute to the asm statement:
asm volatile("in %0, %1" : "=r" (value) : "I" (_SFR_IO_ADDR(PORTD)));

ну а запись "__asm__ __volatile__" это так в самой avr-libc пишут...
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 26 2008, 17:02
Сообщение #37


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zltigo @ May 26 2008, 17:58) *
Это называется возвратисть туда, незнаю куда, но может куда и попадешь.

Нет, это к работающей собаке впридачу. Вот cli() только картину портит не-сишностью.

Цитата(singlskv @ May 26 2008, 19:11) *
Код
__asm__ __volatile__("ldi r30,0\n\t"\
                       "ldi r31,0\n\t"\
                       "ijmp");


Другой вариант, если целый стек smile.gif
Код
__asm__ __volatile__("clr r1\n\t"\
                  "push r1\n\t"\
                 "push r1\n\t"\
                  "ret");


2singlskv: А скажите пожалуйста, __bad_interrupt всегда был jmp 0 ?
Go to the top of the page
 
+Quote Post
zltigo
сообщение May 26 2008, 17:20
Сообщение #38


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(_Pasha @ May 26 2008, 19:02) *
Нет, это к работающей собаке впридачу. Вот cli() только картину портит не-сишностью.

Картину "портит" возврат фиг знает куда, где и прерывания,между прочим могут снова разрешены, вещи типа __disable_interrupt() уже вполне "сишные" для ембедеров smile.gif.

Еще раз напоминаю, что переход по нулевому адресу не есть Reset - перефирия не в исходном состоянии. Особых альтернатив Watchdog-у в этом отношении нет, а тупое соединение ножки с ресетом (если без ресетчика), вообще делать нельзя ввиду непредсказуемой длительности импульса сброса.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
aesok
сообщение May 26 2008, 17:21
Сообщение #39


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Rock @ May 26 2008, 16:21) *
1361: initport();
+00000A3E: D60F RCALL PC+0x0610 Relative call subroutine
1362: ((void(*)(void))0)();
+00000A3F: D60E RCALL PC+0x060F Relative call subroutine


Пожалуста укажите версию WinAVR и опции компилятора. У меня '((void(*)(void))0)();' всегда компилиться в
Код
    ldi r30,lo8(0)    ;  7    call_insn/4    [length = 3]
    ldi r31,hi8(0)
    icall


Анатолий.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение May 26 2008, 17:49
Сообщение #40


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(zltigo @ May 26 2008, 21:20) *
Картину "портит" возврат фиг знает куда, где и прерывания,между прочим могут снова разрешены,


Не верю smile.gif

WinAVR-20071221

Код
000002ac <.do_clear_bss_start>:
     2ac:    a9 30           cpi    r26, 0x09; 9
     2ae:    b1 07           cpc    r27, r17
     2b0:    e1 f7           brne    .-8      ; 0x2aa <.do_clear_bss_loop>
     2b2:    0e 94 9f 07     call    0xf3e; 0xf3e <main>
     2b6:    0c 94 28 23     jmp    0x4650; 0x4650 <_exit>

000002ba <__bad_interrupt>:
     2ba:    0c 94 00 00     jmp    0; 0x0 <__vectors>
................................................................................
.....
00004650 <_exit>:
    4650:    ff cf           rjmp    .-2      ; 0x4650 <_exit>




Цитата(aesok @ May 26 2008, 21:21) *
У меня '((void(*)(void))0)();' всегда компилиться


Попробовал - компилится без проблем.
Код
avr-gcc.exe  -mmcu=atmega640 -Wall -gdwarf-2 -std=gnu99           -DF_CPU=16000000UL -O2 -fsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -MD -MP -MT plc4_v02.o -MF dep/plc4_v02.o.d  -c  ../plc4_v02.c
Go to the top of the page
 
+Quote Post
Rock
сообщение May 26 2008, 17:49
Сообщение #41


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 18-02-06
Пользователь №: 14 478



Цитата(aesok @ May 26 2008, 21:21) *
Пожалуста укажите версию WinAVR и опции компилятора. У меня '((void(*)(void))0)();' всегда компилиться в
Код
    ldi r30,lo8(0);  7    call_insn/4    [length = 3]
    ldi r31,hi8(0)
    icall


Анатолий.


WinAVR-20050214 и какие опции интересны?
Go to the top of the page
 
+Quote Post
aesok
сообщение May 26 2008, 18:01
Сообщение #42


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Rock @ May 26 2008, 21:49) *
WinAVR-20050214 и какие опции интересны?


Извините ни какие. Старенький он. Не буду смотреть.

Анатолий.
Go to the top of the page
 
+Quote Post
singlskv
сообщение May 26 2008, 18:06
Сообщение #43


дятел
*****

Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065



Цитата(zltigo @ May 26 2008, 21:20) *
вещи типа __disable_interrupt() уже вполне "сишные" для ембедеров smile.gif.

Ну это не спортивный подход sad.gif smile.gif

Тогда можно просто написать:
Код
extern void __vectors();

int main(void)
{
  __vectors(); // call/rcall на адрес 0

  return 0;
}
Типа напоминаем компилятору что __vectors у него таки определен, но
к сожалению не вынесен в заголовочные файлы.
ну и получаем mega8:
Код
  __vectors(); // call/rcall на адрес 0
  64:    cd df           rcall    .-102    ; 0x0 <__vectors>

mega16:
Код
  __vectors(); // call/rcall на адрес 0
  96:    0e 94 00 00     call    0x0 <__vectors>

Цитата
Еще раз напоминаю, что переход по нулевому адресу не есть Reset - перефирия не в исходном состоянии. Особых альтернатив Watchdog-у в этом отношении нет,
Я уже приводил пример как оно у меня без проблем работает:
Код
//-------------------------------------------------------------------
// Перезагрузка (рестарт с адреса 0)
//-------------------------------------------------------------------

void Reset()
{
  __asm__ __volatile__ ("cli");  // запретить прерывания
               // останавливаем всю переферию
  SysTimerStop();
  AdcStop();
  SpiStop();
  PwmStop();
  PortsReset();
  I2cStop();
               // переходим на адрес 0
  __asm__ __volatile__("ldi r30,0\n\t"\
                       "ldi r31,0\n\t"\
                       "ijmp");
}



Цитата(aesok @ May 26 2008, 22:01) *
Старенький он. Не буду смотреть.
А 20060421 тоже старенький уже ? (вроде Gcc3.4.6 еще много где поддерживается)
Где смотреть правильный багтрекер на компилятор который в WinAVR ?
Go to the top of the page
 
+Quote Post
aesok
сообщение May 26 2008, 18:11
Сообщение #44


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(singlskv @ May 26 2008, 22:06) *
А 20060421 тоже старенький уже ? (вроде Gcc3.4.6 еще много где поддерживается)


Для меня да.

Цитата(singlskv @ May 26 2008, 22:06) *
Где смотреть правильный багтрекер на компилятор который в WinAVR ?


Здесь: http://www.nongnu.org/avr-libc/bugs.html
И в WinAVR проекте на sourceforge.net: http://sourceforge.net/tracker/?group_id=6...amp;atid=520074

Анатолий.
Go to the top of the page
 
+Quote Post
Rock
сообщение May 26 2008, 18:13
Сообщение #45


Участник
*

Группа: Участник
Сообщений: 60
Регистрация: 18-02-06
Пользователь №: 14 478



Цитата(aesok @ May 26 2008, 22:01) *
Извините ни какие. Старенький он. Не буду смотреть.

Анатолий.

вот простая прога

#include <avr/io.h>
volatile unsigned char x, y, z;
int main(void)
{
x=1;
y=1;
z=x+y;
((void(*)(void))0)();
for(;;);
return(0);
}
вот что компельнул
............................
@0000002E: main
---- main.c ---------------------------------------------------------------------------------------
4: {
+0000002E: E5CF LDI R28,0x5F Load immediate
+0000002F: E0D4 LDI R29,0x04 Load immediate
+00000030: BFDE OUT 0x3E,R29 Out to I/O location
+00000031: BFCD OUT 0x3D,R28 Out to I/O location
5: x=1;
+00000032: E081 LDI R24,0x01 Load immediate
+00000033: 93800060 STS 0x0060,R24 Store direct to data space
6: y=1;
+00000035: 93800062 STS 0x0062,R24 Store direct to data space
7: z=x+y;
+00000037: 91800060 LDS R24,0x0060 Load direct from data space
+00000039: 91900062 LDS R25,0x0062 Load direct from data space
+0000003B: 0F89 ADD R24,R25 Add without carry
+0000003C: 93800061 STS 0x0061,R24 Store direct to data space
8: ((void(*)(void))0)();
+0000003E: DFEF RCALL PC-0x0010 Relative call subroutine
9: for(;;);
+0000003F: CFFF RJMP PC-0x0000 Relative jump
+00000040: FFFF ??? Data or unknown opcode
+00000041: FFFF ??? Data or unknown opcode
Go to the top of the page
 
+Quote Post

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

 


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


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