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

 
 
9 страниц V  < 1 2 3 4 5 > »   
Reply to this topicStart new topic
> WinAVR-20100110, Пишем отзывы сюда
_Pasha
сообщение Jan 21 2010, 03:59
Сообщение #31


;
******

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



Цитата(SysRq @ Jan 21 2010, 02:23) *
убраны debug symbols из всех *.a;

По этому поводу E.W. на avrfreaks писал типа "а что мешает самостоятельно их пострипать?" smile.gif
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jan 21 2010, 14:34
Сообщение #32


Гуру
******

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



Цитата(Сергей Борщ @ Jan 17 2010, 00:36) *
Размеры проектов - 1836->1854 (загрузчик) и 6042->5816 (приложение, мега8, С++, виртуальные функции). Работоспособность не проверял.
Проверил. Код работает. Сравнил листинги (правда для другого проекта). Основное отличие - обращение к eeprom. В 20090313 процедура чтения|записи блока принимала в качестве параметра указатель на функцию чтения|записи байта и косвенно вызывала эту функцию. Теперь функция чтения/записи байта встроена в чтение/запись блока, благодаря чему экономится место как на загрузке указателя так и на перетасовке регистров при косвенном вызове. В 20100110 вся процедура чтения/записи блока (со встроенным обращением) меньше, чем обертка вызова функции чтения/записи байта в 20090313. Кроме этого в 20090313 независимо от -msave-prologue запись/чтение блока вызывала процедуры сохранения/восстановления регистров, которые в 20100110 не понадобились. Результат - уменьшение кода на 148 байт. В остальном код на этом конкретном проекте идентичный до байта. Вывод - теперь можно смело использовать eeprom_read_block(). В 20090313 эффективнее получалось вручную читать побайтно в цикле.


Остался недостаток оптимизации при работе с байтовыми аргументами функций: При вызове функции, объявленной с аргументом типа "байт" в регистры заносится 2 байта (старший = 0), внутри функции копия аргумента тоже хранится как двухбайтовая переменная, хотя используется только младший байт:
Код
void hd44780::write_data(uint8_t byte)
162:    ff 92           push    r15
164:    0f 93           push    r16
166:    1f 93           push    r17                             <-----------------------------------
168:    8c 01           movw    r16, r24                       <-----------------------------------
16a:    f6 2e           mov    r15, r22
{
    write_tetrade(byte & 0xF0);
16c:    60 7f           andi    r22, 0xF0; 240
16e:    ec df           rcall    .-40    ; 0x148 <_ZN7hd4478013write_tetradeEh>
    write_tetrade(byte << 4);
170:    f2 94           swap    r15
172:    80 ef           ldi    r24, 0xF0; 240
174:    f8 22           and    r15, r24
176:    c8 01           movw    r24, r16                            <-----------------------------------
178:    6f 2d           mov    r22, r15
17a:    e6 df           rcall    .-52    ; 0x148 <_ZN7hd4478013write_tetradeEh>
17c:    8d e3           ldi    r24, 0x3D; 61
17e:    8a 95           dec    r24
180:    f1 f7           brne    .-4     ; 0x17e <_ZN7hd4478010write_dataEh+0x1c>
    _delay_us(50);
    ON(LCD_RS);
182:    c1 9a           sbi    0x18, 1; 24
}
184:    1f 91           pop    r17                        <-----------------------------------
186:    0f 91           pop    r16
188:    ff 90           pop    r15
18a:    08 95           ret


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Vova75
сообщение Jan 27 2010, 12:16
Сообщение #33





Группа: Участник
Сообщений: 10
Регистрация: 11-08-08
Из: г. Тверь
Пользователь №: 39 554



Ошибку  в прологе/эпилоге при использовании ISR(xxx_vect, ISR_NOBLOCK) так и не исправили sad.gif
Проект для меги1280 на С++ в 14КБ собрался на 150 байт меньше, это хорошо.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 4 2010, 21:24
Сообщение #34


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Однако...

То-то я чуйкой какой-то ("шестое чувство в пятой точке") играюсь разными версиями, а рабочие компиляции в 20071221 делаю :-)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Feb 8 2010, 06:04
Сообщение #35


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

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



Цитата
Code:
#include <avr/io.h>
volatile uint8_t v;

int main(void) {
while (1) {
v;
v;
v;
#if BUG
uint8_t* p = (uint8_t*) &v; PORTC = *p;
#endif
}
}

avr-gcc 3.4.6 (WinAVR-20060421):
Code:

.text
.global main
.type main, @function
main:

ldi r28,lo8(__stack - 0)
ldi r29,hi8(__stack - 0)
out __SP_H__,r29
out __SP_L__,r28

lds r25,v
.L2:
lds r24,v
lds r24,v
lds r24,v
out 40-0x20,r25
rjmp .L2
(yes, first lds is placed out of loop)

avr-gcc 4.1.2 (WinAVR-20070525) - the same except no stack pointer initialisation
avr-gcc 4.2.2 (WinAVR=20071221) - the same except no stack pointer initialisation
avr-gcc 4.3.2 (WinAVR-20081205) and later - as WinAVR-20100110


А чего тут криминального? Чтений из volatile ровно столько, сколько надо. А от чтения по указателю на простой (не volatile) тип - ничего, кроме знаачения не гарантируется. А откуда оно его взяло - целиком на усмотрение оптимизатора. Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 8 2010, 10:48
Сообщение #36


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(Genadi Zawidowski @ Feb 8 2010, 08:04) *
А чего тут криминального?
Тут всё нормально. Вы посмотрите что из этого делают версии WinAVR-2008, 2009 и та 2010, которая в теме и обсуждается. Там из v при -DBUG=1 делется одно чтение.
Вот это "as WinAVR-20100110"
Код
.global    main
    .type    main, @function
main:
.L2:
    lds r24,v
    out 53-32,r24
    rjmp .L2
У Klen-сборок 4.4.0 и 4.5.0 и у WinAVR по 20071221 включительно (т.е. по 4.2.x включительно) всё нормально.
Т.е. - похоже, что ошибка в 4.3.x

Цитата(Genadi Zawidowski @ Feb 8 2010, 08:04) *
Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.
И, если не зависит друг от друга, то переставлено местами (в том числе и с обращениями к volatile), и вообще выброшено.
А то я этого не знаю :-)


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 8 2010, 12:59
Сообщение #37


;
******

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



Цитата(ReAl @ Feb 5 2010, 01:24) *
Однако...

Однако, дубль два.
Имеем:
Код
double res;
//..............
return (int16_t) (lround(res) - 273);

Скомпилировано с опцией -mint8

Получаем:
Код
+000007BC:   01C8        MOVW    R24,R16          
+000007BD:   01B7        MOVW    R22,R14          
+000007BE:   D12D        RCALL   PC+0x012E   // lround(res) R23:R22:r25:r24 = 0x01870000
+000007BF:   019C        MOVW    R18,R24       // осторожно, грабли!  
+000007C0:   5121        SUBI    R18,0x11   // - 273      
+000007C1:   4031        SBCI    R19,0x01        
+000007C2:   01C9        MOVW    R24,R18

Вместо того чтобы правильный результат в старшей половине, отдает ноль.
Без опции -mint8 - все нормально.
Просьба советы никогда не применять указанную опцию не давать! smile.gif
А вначале был оч.рад, когда используя stdint.h получал утоптанные выражения целого типа. Недолго музыка играла.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 12 2010, 17:49
Сообщение #38


;
******

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



Цитата(_Pasha @ Feb 8 2010, 16:59) *
Однако, дубль два.

sad.gif Боян оказываеццо, с 2004 года так и не удосужились подрихтовать.

Еще прикол. Кто нибудь знает, как избавиться от неправильного назначения регистровых пар? Например, имеем указатель на структуру, и поля в ней интенсивно используются. Сабж так любит регистры XH:XL, что поручает именно Х эту непосильную работу. В итоге, послав все к чертям, я прибил эти регистры
Код
register volatile uint8_t xL asm("r26");
register volatile uint8_t xH asm("r27");

Компилер немедленно взялся за ум и функция изрядно похудела, т.к. пошли в ход инструкции LDD/STD
cranky.gif Неужели эту фигню никогда не причешут?
А у KGP как с этим дела? (Нету времени попробовать...)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Feb 17 2010, 06:59
Сообщение #39


;
******

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



1111493779.gif Ау, я что, в палате №6? Не спим!
Нашел серьезную багу.
Предположим, имеется глобальная переменная или extern
Код
uint8_t period;

Попытка сделать задаром арифметическую операцию по модулю 100, например так
Код
period += 33;
if(period > 100) period -= 100;

Приводит к созданию неожиданного кода, наподобие
Код
  lds r24,period
  subi r24,0xdf // period += 33
  cpi  r24,0x64
  brlo label
  subi r24,0x43 // !!! а должно быть 0x64
label:

Оптимизация -Os
Это катастрофа. У оптимизатора появилась ложная зависимость, и он посчитал что надо вычесть не 100, а 100-33 = 67
Сколько таких случаев надо отсматривать в листинге - ХЗ smile3046.gif
Мне повезло, что вносилась доработка в уже готовое софто.

Проблема имеет workaround, як кажуть кляті англійці
Для того, чтобы код выполнялся правильно, надо period объявить volatile
Такие дела.
Видимо, придется возвращаться в WinAVR-20071221 cranky.gif
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Feb 17 2010, 15:39
Сообщение #40


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Друг спросил как разместить данные во флеш поопределенному адресу.

Сделал как по ссылке.

http://8515.avrfreaks.net/index.php?name=P...ic&p=589365

WinAVR-20100110.

Судя по листингу программа обращается к данным как задано

Код
  
const uint8_t part_number __attribute__ ((section (".part_number")))='A';

i = pgm_read_byte(&part_number);    
     2ee:    e0 ef           ldi    r30, 0xF0; 240    
     2f0:    ff e3           ldi    r31, 0x3F; 63    
     2f2:    e4 91           lpm    r30, Z+


Но ни в HEX ни в bin файле нету данных.

Обычное объявление переменных в памяти программ работает.
Совместить два аттрибута у меня не получилось.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Feb 17 2010, 17:50
Сообщение #41


Гуру
******

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



Цитата(misyachniy @ Feb 17 2010, 17:39) *
Но ни в HEX ни в bin файле нету данных.
попробйте обозвать секцию .text.partnumber или .progmem.partnumber
Я указываю секцию в скрипте линкера, --section-start не пользовался.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SysRq
сообщение Feb 17 2010, 19:45
Сообщение #42


Чайник, 1 литр
****

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



Цитата(_Pasha @ Feb 17 2010, 09:59) *
Нашел серьезную багу.
Воссоздать не получается.

Используется два регистра, оттуда и такой подход с константами:
Код
    lds r25,period
    mov r24,r25
    subi r24,lo8(-(33))
    sts period,r24    
    cpi r24,lo8(101)
    brlo .L3
    subi r25,lo8(-(-67))
    sts period,r25
.L3
Дайте проект, в котором у вас такая ошибка возникает, ибо пока не понятно (доприбивались вы регистры, хехе laughing.gif).

--

Цитата(misyachniy @ Feb 17 2010, 18:39) *
Сделал как по ссылке.
Тоже сделал. Данные все на месте. Разница в оптимизации? Показывайте Makefile.
Go to the top of the page
 
+Quote Post
ReAl
сообщение Feb 17 2010, 19:53
Сообщение #43


Нечётный пользователь.
******

Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417



Цитата(_Pasha @ Feb 17 2010, 08:59) *
Попытка сделать задаром арифметическую операцию по модулю 100, например так
...
Оптимизация -Os
Это катастрофа. У оптимизатора появилась ложная зависимость, и он посчитал что надо вычесть не 100, а 100-33 = 67
Мне не удалось полeчить такую бяку. Код странноватый (оптимизатор явно перемудрил) но корректный.
Более того - он не отличается от кода 20071221
Код
#include <avr/io.h>
      
extern uint8_t period;

void foo()
{
    period += 33;
    if(period > 100) period -= 100;
}


uint8_t moo(uint8_t i)
{
    i += 33;
    if(i > 100) i -= 100;
    return i;
}

-Os
Код
    .text
.global    foo
    .type    foo, @function
foo:
    lds r25,period
    mov r24,r25
    subi r24,lo8(-(33))
    sts period,r24
    cpi r24,lo8(101)
    brlo .L3
    subi r25,lo8(-(-67))       ; 67 вычитается из _исходного_ значения (+33-100) <=> (-67)
    sts period,r25
.L3:
    ret

.global    moo
    .type    moo, @function
moo:
    subi r24,lo8(-(33))
    cpi r24,lo8(101)
    brlo .L5
    subi r24,lo8(-(-100))
.L5:
    ret


--------------------
Ну, я пошёл… Если что – звоните…
Go to the top of the page
 
+Quote Post
ZiB
сообщение Feb 18 2010, 06:48
Сообщение #44


Частый гость
**

Группа: Свой
Сообщений: 122
Регистрация: 26-07-05
Из: Россия, Томск
Пользователь №: 7 109



аналогично, не удалось воссоздать ошибку.
проверил на готовом проекте код уменьшился, сравнил - лучше оптимизация в условиях.
правда у меня во всех проектах оптимизция равна 2.
Go to the top of the page
 
+Quote Post
misyachniy
сообщение Feb 18 2010, 09:49
Сообщение #45


Знающий
****

Группа: Свой
Сообщений: 716
Регистрация: 27-05-05
Из: Kyiv
Пользователь №: 5 454



Цитата(Сергей Борщ @ Feb 17 2010, 19:50) *
попробйте обозвать секцию .text.partnumber или .progmem.partnumber
Я указываю секцию в скрипте линкера, --section-start не пользовался.


Переобъявил, секция попала сразу за таблицей векторов.
Как в скрипте линкера без --section-start настраивать я не умею.

Код
код
const uint8_t part_number __attribute__ ((section (".progmem.part_number")))='A';
const  unsigned long serial_number __attribute__ ((section (".progmem.serial_number"))) = 0x12345678;

маке
LDFLAGS += -Wl,--section-start=.progmem.part_number=$(PART_NUMBER_ADDRESS)
LDFLAGS += -Wl,--section-start=.progmem.serial_number=$(SERIAL_NUMBER_ADDRESS)

HEX
:100050000C9458 0041 78563412 456E7465722063D2

LST
00000054 <part_number>:
      54:    41                                                  A

  i = pgm_read_byte(&part_number);
     2f4:    e4 e5           ldi    r30, 0x54; 84
     2f6:    f0 e0           ldi    r31, 0x00; 0
     2f8:    e4 91           lpm    r30, Z+
Go to the top of the page
 
+Quote Post

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

 


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


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