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

убраны debug symbols из всех *.a;

По этому поводу E.W. на avrfreaks писал типа "а что мешает самостоятельно их пострипать?" :)

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


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

Размеры проектов - 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

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


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

Ошибку  в прологе/эпилоге при использовании ISR(xxx_vect, ISR_NOBLOCK) так и не исправили :(

Проект для меги1280 на С++ в 14КБ собрался на 150 байт меньше, это хорошо.

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


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

Однако...

 

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

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


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

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, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.

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


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

А чего тут криминального?
Тут всё нормально. Вы посмотрите что из этого делают версии 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

 

Вообще, всё что не volatile, может быть "закешированно" при входе в функцию и записано перед выходом из неё или вызовом чего-либо.
И, если не зависит друг от друга, то переставлено местами (в том числе и с обращениями к volatile), и вообще выброшено.

А то я этого не знаю :-)

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


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

Однако...

Однако, дубль два.

Имеем:

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 - все нормально.

Просьба советы никогда не применять указанную опцию не давать! :)

А вначале был оч.рад, когда используя stdint.h получал утоптанные выражения целого типа. Недолго музыка играла.

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


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

Однако, дубль два.

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

 

Еще прикол. Кто нибудь знает, как избавиться от неправильного назначения регистровых пар? Например, имеем указатель на структуру, и поля в ней интенсивно используются. Сабж так любит регистры XH:XL, что поручает именно Х эту непосильную работу. В итоге, послав все к чертям, я прибил эти регистры

register volatile uint8_t xL asm("r26");
register volatile uint8_t xH asm("r27");

Компилер немедленно взялся за ум и функция изрядно похудела, т.к. пошли в ход инструкции LDD/STD

:cranky: Неужели эту фигню никогда не причешут?

А у KGP как с этим дела? (Нету времени попробовать...)

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


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

:1111493779: Ау, я что, в палате №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:

Мне повезло, что вносилась доработка в уже готовое софто.

 

Проблема имеет workaround, як кажуть кляті англійці

Для того, чтобы код выполнялся правильно, надо period объявить volatile

Такие дела.

Видимо, придется возвращаться в WinAVR-20071221 :cranky:

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


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

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

 

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

 

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 файле нету данных.

 

Обычное объявление переменных в памяти программ работает.

Совместить два аттрибута у меня не получилось.

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


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

Но ни в HEX ни в bin файле нету данных.
попробйте обозвать секцию .text.partnumber или .progmem.partnumber

Я указываю секцию в скрипте линкера, --section-start не пользовался.

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


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

Нашел серьезную багу.
Воссоздать не получается.

 

Используется два регистра, оттуда и такой подход с константами:

    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:).

 

--

 

Сделал как по ссылке.
Тоже сделал. Данные все на месте. Разница в оптимизации? Показывайте Makefile.

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


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

Попытка сделать задаром арифметическую операцию по модулю 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

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


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

аналогично, не удалось воссоздать ошибку.

проверил на готовом проекте код уменьшился, сравнил - лучше оптимизация в условиях.

правда у меня во всех проектах оптимизция равна 2.

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


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

попробйте обозвать секцию .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+

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


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

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

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

Гость
Ответить в этой теме...

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

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

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

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

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

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