Easyelectronics.ru

Электроника для всех
Текущее время: 25 фев 2018, 05:02

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 107 ]  На страницу Пред.  1, 2, 3, 4, 5  След.
Автор Сообщение
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 04 дек 2017, 12:21 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 316
К вопросам оптимизации и целесообразности оной, на примере смежной сферы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 04 дек 2017, 13:02 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2361
Откуда: Санкт-Петербург
Может, разделить тему (хорошо бы "технически", если есть такая возможность)? Продолжим про "раньше трава была зеленее" в Валгалле :-)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 04 дек 2017, 22:03 
Старожил

Зарегистрирован: 02 июл 2010, 23:41
Сообщения: 376
demiurg1978 писал(а):
Я тоже когда-то возмущался выхлопом. "Да у меня волосы дыбом встают от выхлопа компилятора". Ридико Л.И. на это ответил. "У меня тоже волосы дыбом вставали, я их быстренько причесал и все нормально." :)

Похоже, пишущих на СИ для МК «причесали».
Сказали: Смиритесь, вам и так сойдёт.
Думаю, макроассемблер лучше подходит для МК: написание программ, наверно, соизмеримо, а отладка проще, код короче.
Только кто будет развивать макроассемблер?
По идее, это должны делать производители МК, но:
Sphynx55 писал(а):
Да просто одни люди стараются делают замечательные, быстрые процессоры, выжимают все из мегагерц и миллиампер, а потом ваяется код на си и все старания уходят в никуда. Перфекционист во мне возмущен.
Это как переносить воду в дырявом ведре, и чтобы доносить больше воды, предлагается не заклеить дыры а взять дырявое ведро большего размера.

«Дырявое ведро» большего размера стоит дороже, вот производителям МК и хорошо, они получат большую прибыль.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 04 дек 2017, 22:29 
Старожил

Зарегистрирован: 25 фев 2011, 18:45
Сообщения: 3435
Откуда: Новосибирск
Alexandr_1 писал(а):
...

Никто нас не причесывал. Я тоже когда-то был ярым поклонником ассемблера AVR. Проекты становились сложнее и сложнее. Когда наступила пора создания меню, тут начались проблемы. Указатель на указатель на указатель. Проще застрелиться.
Главный фактор при создании проекта - целесообразность. Скорость создания проектов. Когда я перешел на си и более-менее его освоил, скорость создания проектов возросла в разы.
Поэтому, когда встает вопрос, полгода уйдет на проект или месяц - выбор однозначен.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 10 дек 2017, 22:50 
Старожил

Зарегистрирован: 02 июл 2010, 23:41
Сообщения: 376
demiurg1978 писал(а):
Никто нас не причесывал. Я тоже когда-то был ярым поклонником ассемблера AVR. Проекты становились сложнее и сложнее. Когда наступила пора создания меню, тут начались проблемы. Указатель на указатель на указатель. Проще застрелиться…

Вы пишите про обычный ассемблер, это, на мой взгляд, прошлый век.
Макроассемблер намного выше по уровню.
Делал меню на макроассемблере - это простая, даже можно сказать, банальная задача.
Как я понял, у Sphynx55 свежий, «непричёсанный» взгляд на СИ.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 13 янв 2018, 21:21 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
Добрый вечер. Пока разбирался почему
uint8_t temp;
eeprom_seq_read_start((uint16_t)(temp<<8)+0);

в функцию в качестве адреса всегда передается 0,
а так
eeprom_seq_read_start((uint16_t)(temp<<8)+1);
адрес будет равен 256*temp+1, случайно наткнулся на это:
mc_file.size=(eeprom_seq_read_byte()<<8);
mc_file.size+=eeprom_seq_read_byte();

занимает 16 команд
Show

mc_file.size=(eeprom_seq_read_byte()<<8)+eeprom_seq_read_byte();
занимает 14 команд
Show

И финалист
mc_file.size=(eeprom_seq_read_byte()<<8)|eeprom_seq_read_byte();
занимает 13 команд.
Show

На ассемблере я бы сделал так:

CALL 0x000004C8
MOVW R30,R12
STD Z+1,R24
CALL 0x000004C8
MOVW R30,R12
STD Z+0,R24

Всего 6 команд !!!!!!
Как все-таки правильно объединять байты в слова средствами С, чтоб не было этой жути ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 13 янв 2018, 23:02 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Включите оптимизацию и будет вам счастье. Компиляторы из двух uint8_t запросто один uint16_t собирают простой пересылкой регистров.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 13 янв 2018, 23:39 
Старожил
Аватара пользователя

Зарегистрирован: 28 дек 2011, 11:24
Сообщения: 3539
Откуда: г. Липецк
Ассемблер это не табличка с командами, это направление мысли.
Ассемблерщиков всячески норовят пнуть, в частности сишники. Ну и хай с ними. Можно и на С изобразить, на ассемблере выходит изящнее. Запасаюсь попкорном...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 13 янв 2018, 23:50 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
VladislavS писал(а):
Включите оптимизацию и будет вам счастье. Компиляторы из двух uint8_t запросто один uint16_t собирают простой пересылкой регистров.

Сейчас почитаю как включить.
Вообще не понятно, почему он всегда старается использовать Z для адресации.
Никакого динамического выделения памяти тут нет.
mc_file.size всегда будет по одному адресу.
CALL 0x000004C8
STS mc_file.size+1,R24
CALL 0x000004C8
STS mc_file.size,R24

По факту нужно всего 4 команды.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 00:35 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Sphynx55 писал(а):
Вообще не понятно, почему он всегда старается использовать Z для адресации.

Вот уж глупости. Переменные в зависимости от их типа и использования могут храниться в сегментах данных, стеке, регистрах, битах регистра, EEPROM и Flash. И для всех применяются соответствующие типы адресации. Если вы не в курсах про типы переменных в С/С++ и не знаете как их эффективно использовать, то это ваши проблемы.

Sphynx55 писал(а):
Сейчас почитаю как включить.

А выводов то не разобравшись понаделали... :(


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 08:30 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
VladislavS писал(а):
Sphynx55 писал(а):
Вообще не понятно, почему он всегда старается использовать Z для адресации.

Вот уж глупости. Переменные в зависимости от их типа и использования могут храниться в сегментах данных, стеке, регистрах, битах регистра, EEPROM и Flash. И для всех применяются соответствующие типы адресации. Если вы не в курсах про типы переменных в С/С++ и не знаете как их эффективно использовать, то это ваши проблемы.

Sphynx55 писал(а):
Сейчас почитаю как включить.

А выводов то не разобравшись понаделали... :(


Вы про что ? Сегментации ОЗУ в AVR нет. Переменную в EEPROM и Flash объявить нельзя (с надстройкой PROGMEM вроде как можно использовать только pgm_read_byte). Я разбираюсь с си чуть больше месяца, объясните пожалуйста какой тип переменной мне нужен чтоб эффективно ее использовать, и сгенерился нормальный код.
Если даже переменная будет в регистрах (или даже в стеке) то код на ассемблере все равно укладывается в 4 команды.
Пока что только факты, то что увидел своими глазами.
Или я делаю что-то не так, или GCC AVR писали левой пяткой на отцепись, и так сойдет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 08:58 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
По умолчанию стояла оптимизация -О1 размер кода ~4.6Кб
С оптимизацией -О2 код стал занимать 4,4Кб а с -О3 8,0Кб.
Вот во что превращается кусок кода
Код:
mc_file.size=(eeprom_seq_read_byte()<<8)|eeprom_seq_read_byte();

000004AF  CALL 0x0000038E      Call subroutine
000004B1  MOV R9,R24      Copy register
000004B2  CALL 0x0000038E      Call subroutine
000004B4  MOV R18,R9      Copy register
000004B5  LDI R19,0x00      Load immediate
000004B6  MOV R19,R18      Copy register
000004B7  CLR R18      Clear Register
000004B8  OR R18,R24      Logical OR
000004B9  STS 0x013C,R19      Store direct to data space
000004BB  STS 0x013B,R18      Store direct to data space

Используются команды STS, уже хорошо. Но все равно остается бессмысленная манипуляция с регистрами.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 09:32 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
Код:
uint8_t *t_ptr = &mc_file.size;
*t_ptr = eeprom_seq_read_byte();
*(t_ptr+1) = eeprom_seq_read_byte();

Через заднее место, но зато какой результат !!!
Код:
*t_ptr = eeprom_seq_read_byte();
000004FE  CALL 0x000003F5      Call subroutine
00000500  STS 0x013B,R24      Store direct to data space
*(t_ptr+1) = eeprom_seq_read_byte();
00000502  CALL 0x000003F5      Call subroutine
00000504  STS 0x013C,R24      Store direct to data space


Напутал с порядком, правильно так:
Код:
uint8_t *t_ptr = &mc_file.size;
*(t_ptr+1) = eeprom_seq_read_byte();
*t_ptr = eeprom_seq_read_byte();


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 11:47 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Не порите чушь, ей от этого больно. Если честно, по приведённым двум строчкам кода приходится только гадать что вы хотите и какого типа переменные используете. Давайте усложним задачу компилятору. Разместим две 32-битных переменных, одну в EEPROM, другую во FLASH. Функция будет выдавать логический результат их сравнения. По этому результату будем дёргать бит в регистре.

Код:
#include <ioavr.h>
#include <stdint.h>
#include <intrinsics.h>

#define DATA PORTB_Bit0

volatile const __flash uint32_t flash_x = 0x12345678;
__no_init __eeprom uint32_t ee_x;

bool SetBit(uint32_t a, uint32_t b)
{
  return (a==b)?true:false;
}

int main()
{
  if(SetBit(ee_x,flash_x)) DATA=1; else DATA=0;
 
  for(;;);
}

Для начала я немного связал руки компилятору, объявив flash_x с модификатором volatile, иначе не будет видно как он с ней работает. Получаем такой ASM:
Show

Вообще, на коротких примерах с высоким уровнем оптимизации очень трудно примеры делать. Убираю модификатор volatile. Результат:
Show

Компилятор, конечно же, упростил поставленную мной задачу, но главное результат остался тем же. И если это будут не целые числа, а структуры или даже классы, то ничего не изменится. Чем сложнее код, тем больше преимущество компилятора над человеком. Пока вы будете считать команды на ASM, я буду применять виртуальные методы, конструкторы копирования и т.д. и т.п. и считать количество выполненных проектов.

PS: Компилятор в моём примере не GCC. Я из IAR-овской секты. Наверняка GCC не хуже справится, только синтаксис чуть другой будет.

PPS:Кстати, а сколько у вас на ASM времени уйдёт, чтобы в моём примере 32-битные переменные заменить на 64-битные? У меня секунд 10. Результат:
Код:
volatile const __flash uint64_t flash_x = 0x1234567890;
__no_init __eeprom uint64_t ee_x;
bool SetBit(uint64_t a, uint64_t b);

ASM:
Show


Последний раз редактировалось VladislavS 14 янв 2018, 12:04, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 12:04 
Старожил

Зарегистрирован: 25 фев 2011, 18:45
Сообщения: 3435
Откуда: Новосибирск
Изначально неравное сравнение. IAR и AVR-Toolchain к примеру. IAR изначально сотрудничал с Atmel.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 12:05 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
Не понимаю к чему ваши примеры. У меня AVR Studio и GCC, он не понимает __flash;
У меня не получается нормально склеить из 2ух uint8_t один uint16_t.
Простой способ uint16_t=(uint8_t<<8)|uint8_t; дает слишком плохой код.
Код:
uint8_t *t_ptr = &mc_file.size;
*t_ptr = eeprom_seq_read_byte();
*(t_ptr+1) = eeprom_seq_read_byte();

Дает хороший код, но очень неудобно все это писать и можно легко ошибиться.
Так как правильно их объединить ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 12:19 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
demiurg1978 писал(а):
Изначально неравное сравнение. IAR и AVR-Toolchain к примеру. IAR изначально сотрудничал с Atmel.

Я давно не интересовался сравнением компиляторов. Последний раз когда я это делал, то разница была в пределах погрешности. И сравнивать надо на больших проектах, когда все ресурсы заняты. А на примерах когда всё в регистры укладывается как-то бессмысленно сравнивать.

В моём примере заменил оптимизацию с High->Size на High->Speed и компилятор заинлайнил мою функцию:
Show

Что будет без volatile даже выкладывать не буду - это как раз пример-колибри, неспортивно :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 12:48 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Sphynx55 писал(а):
Не понимаю к чему ваши примеры.

Я показываю как к разным типам переменных компилятор по разному адресуется.

Sphynx55 писал(а):
У меня AVR Studio и GCC, он не понимает __flash;

Там это как-то по другому объявляется. У AVR есть FLASH и размещать в ней данные компилятор должен уметь.

Sphynx55 писал(а):
У меня не получается нормально склеить из 2ух uint8_t один uint16_t.

Вы не чувствуете разницы между переменной типа uint16_t и элементом структуры типа uint16_t? Привели бы хотя бы определение структуры.

Sphynx55 писал(а):
Простой способ uint16_t=(uint8_t<<8)|uint8_t; дает слишком плохой код.

Этот способ, как и uint16_t=(uint8_t<<8)+uint8_t, всегда давал простую пересылку двух байт.

Sphynx55 писал(а):
Дает хороший код, но очень неудобно все это писать и можно легко ошибиться.

По сравнению с ASM? :)

Sphynx55 писал(а):
Так как правильно их объединить ?

mc_file.size=(eeprom_seq_read_byte()<<8)+eeprom_seq_read_byte();
И не парить себе мозги.


Последний раз редактировалось VladislavS 14 янв 2018, 13:04, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:00 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
Вы наверно не читали но mc_file.size=(eeprom_seq_read_byte()<<8)+eeprom_seq_read_byte();
не дает простую пересылку 2ух байт а дает во это:
Show

Может я что-то не так объявил. В какую сторону копать ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:04 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Смотрите, попытался максимально воссоздать ваш пример
Код:
#include <ioavr.h>
#include <stdint.h>

#define DATA PORTB_Bit0

extern uint8_t eeprom_seq_read_byte(void);

typedef struct
{
  uint8_t a;
  uint16_t size;
  uint8_t b;
} MY_FILE;

int main()
{
  MY_FILE mc_file;
  mc_file.size = (eeprom_seq_read_byte()<<8)|eeprom_seq_read_byte();

  if(mc_file.size==0x1234) DATA=1; else DATA=0; 
  for(;;);
}

Оптимизация High->Size:
Show

Никакого ужас-ужас не вижу. Если GCC так не умеет, то я уж не знаю....

PS: Манипуляцию с DATA в пример вношу, чтобы от значения переменной mc_file зависело что-то volatile, иначе компилятор беспощадно выкинет код примера как ничего не делающий :)


Последний раз редактировалось VladislavS 14 янв 2018, 13:47, всего редактировалось 2 раз(а).

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:07 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
Пример не совсем корректный, mc_file у вас даже не сохраняется,
так как используется только 1 раз для сравнения if(mc_file.size==0x1234) DATA=1; else DATA=0;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:15 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Sphynx55 писал(а):
Пример не совсем корректный, mc_file у вас даже не сохраняется,

Да не вопрос, давайте выкрутим компилятору руки запретив оптимизировать mc_file .
Код:
#include <stdint.h>

#define DATA PORTB_Bit0

extern uint8_t eeprom_seq_read_byte(void);

typedef struct
{
  uint8_t a;
  uint16_t size;
  uint8_t b;
} MY_FILE;

volatile MY_FILE mc_file;

int main()
{
 
  mc_file.size = (eeprom_seq_read_byte()<<8)|eeprom_seq_read_byte();

  if(mc_file.size==0x1234) DATA=1; else DATA=0; 
  for(;;);
}

Все та же байтовая пересылка только в другое место.
Код:
//   17 int main()
main:
//   18 {
        ST      -Y, R25
//   19   
//   20   mc_file.size = (eeprom_seq_read_byte()<<8)|eeprom_seq_read_byte();
        RCALL   ??eeprom_seq_read_byte
        MOV     R25, R16
        RCALL   ??eeprom_seq_read_byte
        STS     (mc_file + 1), R16
        STS     (mc_file + 2), R25
//   21
//   22   if(mc_file.size==0x1234) DATA=1; else DATA=0; 
        LDS     R16, (mc_file + 1)
        LDS     R17, (mc_file + 2)
        CPI     R16, 52
        SBCI    R17, 18
        BRNE    ??main_0
        SBI     0x18, 0x00
        RJMP    ??main_1
??main_0:
        CBI     0x18, 0x00
//   23   for(;;);
??main_1:
        RJMP    ??main_1
        REQUIRE _A_PORTB
//   24 }


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:19 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
А можете оставить оптимизацию, но передать mc_file во внешнюю функцию ? В любом случае код уже выглядит лучше чем на GCC.
Уже приятно что используются RCALL и RJMP.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:36 
Заглядывает иногда

Зарегистрирован: 13 янв 2018, 21:36
Сообщения: 34
Sphynx55 писал(а):
А можете оставить оптимизацию, но передать mc_file во внешнюю функцию ?

Кхм... Не приучен передавать структуры в функции. Давайте так. Сначала я передам во внешнюю функцию только mc_file.size. Затем адрес структуры mc_file. А потом всю структуру.

1. Передаю mc_file.size
Show

2. Передаю адрес mc_file
Show

3. Передаю всю mc_file
Show

4. Ну и для общности, передаю всю mc_file сделав её volatile
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AVR Studio
СообщениеДобавлено: 14 янв 2018, 13:44 
Заглядывает иногда

Зарегистрирован: 19 июн 2013, 08:23
Сообщения: 57
Большое спасибо. Код выглядит достойно. В ближайшее время попробую IAR, посмотрим что у меня получится.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 107 ]  На страницу Пред.  1, 2, 3, 4, 5  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB