Котуинко

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18544
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

Re: Котуинко

Сообщение ARV »

ARV, кстати, а что вы имели ввиду под "подразумевающимися фичами" бесконечного цикла for(;;) ?
Бесконечный цикл иногда удобная штука же....
У меня иногда получается, что проще выйти из бесконечного цикла через break, нежели возиться с флагом, который проверять потом в do {} while
Правда, for(;;) для бесконечности никогда не применяла... В основном while(1) {}


а вас не удивляет, что for(;;) - это бесконечный цикл, а while() - это ошибка синтаксиса? т.е. пустой операнд ;; в условии цикла for трактуется, как true, в то время как пустой операнд в условии цикла while недопустим? это я и называю фичами стандарта, когда тут играем, тут не играем, а тут рыбу заворачивали... я такое не использую в целях гигиены.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Котуинко

Сообщение Just_Fluffy »

BOB51 писал(а): (тот же GCC хоть для аврстудио, хоть для адуринки) имеется множество заголовочных файлов описания ресурсов АВРок... Те же заголовочники *.h с теми же #define плюс редко, но встречающимися комментариями...
Найдите там хоть один, нарушающий те правила, что я в самом начале указал (однострочный простой комментарий после #define до конца строки).

Седьмая студия: (ПрограмФайлс)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\avr\include\avr\iom165.h
Строка 366:

Код: Выделить всё

#define OCD     7   // The datasheet defines this but IMO it should be OCDR7.
То же саме в iom165p.h - строка 368

Да, я допускаю, что это исключение, поскольку я нашла такой дефайн только в трех файлах - два этих и еще в util\delay.h, строка 49:

Код: Выделить всё

#define F_CPU 1000000UL  // 1 MHz
но оно там в блоке комментария, как пример.

Т.е. авторы заголовочников старались следовать самому старому стандарту, где // нету. Но в каком то месте провтыкали.
И раз за все года это не поправили, значит проблем нету и оно работает. Или никто не компилит в режиме совместимости C89/C90...
Белая и Пушистая
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Седьмая студия вообще то уже давно в "микрочип студио" превратилась.
8)
Но те монстры весьма избыточны и довольно тяжелы для простых компов по требуемым для нормальной работы ресурсам.
Проекты с простым комментарием после #define работают, но лучше таки иметь перестраховку.
Спокойнее будет насчет исключения теоретически вероятных ошибок.
(Тех ошибок и без того в достатке попадается).
8)
Кстати... на один вариант проблем с "разнообразием стандартов" я уже нарвался при работе в ардуино IDE с МК от LGT...
Похоже именно из за разнотипных подходов к написанию от разработчиков.
Ранее уже тут обсуждался сей момент - но тогда особо никто внимания не обратил...
(viewtopic.php?p=4766580#p4766580)
пришлось самому "методом научного тыка" исправлять...
Не факт, что правильно, но таки работает (образец с другой платформы списал)...
:(
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Котуинко

Сообщение Just_Fluffy »

Это смотря когда скачивать. У меня она еще атмел студия. И прекрасно работает на старом 11-летнем ноуте.
Белая и Пушистая
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Простое очередное обновление превращает атмел студии в микрочипов. Обновление, а не скачивание.
Это еще до "всяко блокировок" - позже обновления уже не выполнялись.
А сегодня и ардуино уже "недоступно" (если без "ухищрений").
8)
Аватара пользователя
Just_Fluffy
Вымогатель припоя
Сообщения: 532
Зарегистрирован: Ср июн 29, 2022 16:25:45

Re: Котуинко

Сообщение Just_Fluffy »

BOB51, 1. не вижу смысла обновлять, оно и так работает. Равно как и десятка винда с продленными на 4 года обновлениями.
2. про недоступность - мое мнение не будет совпадать с мнением администрации, поэтому промолчу. Мне - доступно.
Белая и Пушистая
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Обновления добавили новые семейства МК.
Но смысла при отсутствии таковых в наличии особо нету.
Касательно доступности - речь о доступе без всяких заморочек.
Остальное не считается (хотя и существует) .
В микрочип студии похоже постарались от GCC уйти в пользу микрощипьего варианта...
:roll:
А для пенсионной забавки мне и старой 4.19 да АВРкиных платформ в ардуино 1.8.19 достаточно.
8)
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Пока делать нечего слепил из подручных средств полевичек "нижнего ключа" для прикладных адуриньих тестов...
СпойлерИзображение

Что то много у народа вопросов на данную тему, а конкретно перепроверить особо нечем ...
:solder:
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Слепил простейший ленивый тест для того ключа на полевичке
https://img.radiokot.ru/files/20529/3zar064p98.GIF
Спойлер

Код: Выделить всё

/*        test290126
 *    тестовый макет - игрушка
 *    управляемый с помощью переменного резистора вентилятор
 */
 
//----------

/*         motor (D9)
 *  вывод управления ключем мотора вентилятора
 *  режим цифровой выход output
 *  активный уровень = 1
 */
#define motor 9

/*       varu (A7)
 * вывод приема данных с движка потенциометра
 * режим  - аналоговый вход
 * диапазон входного напряжения 0 - +5В(или +3В)
 */
#define varu A7

/*      Wled  (D14)
 * вывод подключения индикаторного светодиода
 * отображающего нестабильное состояние (перемещение)
 * движка потенциометра
 * режим цифровой выход output
 * активное состояние = 1
 */
#define Wled 14

volatile int tmp; // байт хранения предыдущих данных АЦП
int tmp1; // текущее значение от АЦП
volatile byte flag; // флаг "данные защелкнуты"


//----------

void setup() {
  // put your setup code here, to run once:

   // настройка выводов
 digitalWrite(motor, LOW); digitalWrite(Wled, LOW);
 pinMode(motor, OUTPUT); pinMode(Wled, OUTPUT); pinMode(varu, INPUT);
 analogReference(DEFAULT); tmp = 0;

}


void loop() {
  // put your main code here, to run repeatedly:

 tmp1 = analogRead(varu);
 tmp1 = (tmp1 >> 2);
  if(tmp != tmp1){tmp = tmp1; digitalWrite(Wled, HIGH); flag = 0;}
   else {
    if(!flag)
     {
      if(tmp <= 76){analogWrite(motor, 0);}
      else{analogWrite(motor, tmp);}
      digitalWrite(Wled, LOW); flag = 1;
     }
    }
 delay(100);
}

:sleep:
Аватара пользователя
главный колбасист
Это не хвост, это антенна
Сообщения: 1319
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край
Контактная информация:

Re: Котуинко

Сообщение главный колбасист »

Читаю Катупитию,Бентли. Вот страница 168 Может тупития это я, но не пойму откуда тройки взялись вместо иксов.
Вложения
катупития.txt
(1.56 КБ) 21 скачивание
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Там просто очепятка.
Вместо y=cube(x)
должно быть y=cube(3)
очепятки и от "цензуры" порой специально вводили - чтоб самообразованием народ не мог заниматься и шпионы не разобрались.
8)
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

ОЧЕРЕДНЫЕ ПЕЧАЛЬНЫЕ РАЗМЫШЛЕНИЯ НА ТЕМУ АРДУИНО ...
Навеяно этими темами:
https://radiokot.ru/forum/viewtopic.php?f=66&t=200578
и больше этой
https://radiokot.ru/forum/viewtopic.php?f=66&t=200625
Ранее для АВР платформ при загрузке через программатор (по SPI) было принято, что прошивка фузов и бутлоадера идет при запуске
"инструменты -> записать загрузчик"
А прошивка программ делается при
"скетч -> загрузить через программатор"...
Однако при разборе случая с аттини13 под платформой MicroCore v2.5.1 от MCUdude появилось нечто новое и неожиданное...
Выполнение опции
"инструменты -> записать загрузчик"
вызывает вот такую ошибку:
Спойлер

Код: Выделить всё

D:\Arduino\portable\packages\MicroCore\tools\avrdude\8.0-arduino.1/bin/avrdude -CD:\Arduino\portable\packages\MicroCore\tools\avrdude\8.0-arduino.1/etc/avrdude.conf -v -pattiny13a -cstk500v1 -B32 -PCOM5 -b19200 -e -Ulock:w:0xff:m -Uhfuse:w:0xfb:m -Ulfuse:w:0b00111010:m 
Avrdude version 8.0-arduino.1
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

System wide configuration file is D:\Arduino\portable\packages\MicroCore\tools\avrdude\8.0-arduino.1\etc\avrdude.conf

Using port            : COM5
Using programmer      : stk500v1
Setting baud rate     : 19200
Setting bit clk period: 32.0 us

Error: cannot get into sync
Error: cannot set Parm_STK_SCK_DURATION
Error: unable to open port COM5 for programmer stk500v1

Avrdude done.  Thank you.
Ошибка при записи загрузчика.

Это при условии, что программатор ардуиноISP подключен к ПК и правильно определен как СОМ5
В то же время, и при сохранении того же подключения, выполнение опции
"скетч -> загрузить через программатор"
мало того, что прекрасно выполняется, так еще и содержит добавку в виде записи фуз битов для заданной в проекте конфигурации МК!...
Вот такой отчет IDE:
Спойлер

Код: Выделить всё

Скетч использует 704 байт (68%) памяти устройства. Всего доступно 1024 байт.
Глобальные переменные используют 18 байт (28%) динамической памяти, оставляя 46 байт для локальных переменных. Максимум: 64 байт.
D:\Arduino\portable\packages\MicroCore\tools\avrdude\8.0-arduino.1/bin/avrdude -CD:\Arduino\portable\packages\MicroCore\tools\avrdude\8.0-arduino.1/etc/avrdude.conf -v -pattiny13a -cstk500v1 -PCOM5 -b19200 -Uhfuse:w:0xfb:m -Ulfuse:w:0b00111010:m -Uflash:w:C:\Users\9532~1\AppData\Local\Temp\arduino_build_595068/tn13gat.ino.hex:i 
Avrdude version 8.0-arduino.1
Copyright see https://github.com/avrdudes/avrdude/blob/main/AUTHORS

System wide configuration file is D:\Arduino\portable\packages\MicroCore\tools\avrdude\8.0-arduino.1\etc\avrdude.conf

Using port            : COM5
Using programmer      : stk500v1
Setting baud rate     : 19200
AVR part              : ATtiny13A
Programming modes     : SPM, ISP, HVSP, debugWIRE
Programmer type       : STK500
Description           : Atmel STK500 v1
HW Version            : 2
FW Version            : 1.18
Topcard               : Unknown
Vtarget               : 0.0 V
Varef                 : 0.0 V
Oscillator            : Off
SCK period            : 0.0 us
XTAL frequency        : 7.372800 MHz

AVR device initialized and ready to accept instructions
Device signature = 1E 90 07 (ATtiny13, ATtiny13A)
Auto-erasing chip as flash memory needs programming (-U flash:w:...)
specify the -D option to disable this feature
Erased chip

Processing -U hfuse:w:0xfb:m
Reading 1 byte for hfuse from input file 0xfb
in 1 section [0, 0]
Writing 1 byte (0xFB) to hfuse, 1 byte written, 1 verified

Processing -U lfuse:w:0b00111010:m
Reading 1 byte for lfuse from input file 0b00111010
in 1 section [0, 0]
Writing 1 byte (0x3A) to lfuse, 1 byte written, 1 verified

Processing -U flash:w:C:\Users\9532~1\AppData\Local\Temp\arduino_build_595068/tn13gat.ino.hex:i
Reading 704 bytes for flash from input file tn13gat.ino.hex
in 1 section [0, 0x2bf]: 22 pages and 0 pad bytes
Writing 704 bytes to flash
Writing | ################################################## | 100% 1.44s
Reading | ################################################## | 100% 0.59s
704 bytes of flash verified

Avrdude done.  Thank you.
Причем одни платформы могут работать по старым правилам (та же DIY ATtiny версии 2023.4.19-gcc7.3 к примеру), а другие уже по новым - в зависимости от версий установленных в IDE платформ (и , вероятно, версий самой IDE)...
Так что при работе через программатор по SPI необходимо быть весьма внимательным и осторожным...
В вышеприведенном примере использовалась тестовая игрушка по схеме
https://img.radiokot.ru/files/20529/3zktmtki1p.GIF
и с этой программой
Спойлер

Код: Выделить всё

/*
 * проект  - игрушка 
 * регулируемый звуковой генератор
 *       tn13gat.ino
 */

// Ugtv вывод подключения движка потенциометра
// задатчика частоты аналоговый вход АЦП1 (A1)
#define Ugtv A1
// TgOut вывод подключения выхода на телефонный капсуль
// выход (D0), пассивное состояние = 0
#define TgOut 0
// ZxLED вывод подключения индикатора
// нестабильности входных данных
// выход (D4), активный уровень = 1
#define ZxLED 4
// константа интервала времени для шага опроса АЦП (mS)
#define tms 45
// константа устранения шумов движка
#define zum 0xFFF0
volatile unsigned long tmpMs0; // РВХ контроля интервала опроса АЦП
unsigned long tmpMs1; // РВХ текущего значения времени в mS
volatile unsigned int tmp0; // РВХ предыдущих данных АЦП
unsigned int tmp1; // РВХ текущего результата АЦП
volatile byte flag; // триггер блокировки повторного включения текущей tonе

//-----------------------------------------------------------------------

void setup() {
  // put your setup code here, to run once:
   digitalWrite(TgOut, LOW); digitalWrite(ZxLED, LOW);
   pinMode(Ugtv, INPUT); pinMode(TgOut, OUTPUT); pinMode(ZxLED, OUTPUT);
   analogReference(DEFAULT);
}

//-----------------------------------------------------------------------

void loop() {
  // put your main code here, to run repeatedly:
  tmpMs1 = millis();
  
  if((tmpMs1 - tmpMs0) >= tms)
  {
   
    tmpMs0 = tmpMs1;
    tmp1 = analogRead(Ugtv);
    tmp1 = tmp1 & zum; // нормирование данных
    if(tmp0 == tmp1)
     {
      if(!flag)
       {
         digitalWrite(ZxLED, LOW); // выключить ZxLED
        // включить звук на TgOut с частотой равной данным от потенциометра
        tone(TgOut, tmp0); flag = 1;
       }
     }
    else{
      digitalWrite(ZxLED, HIGH);// включить индикатор ZxLED
      noTone(TgOut);// отключить звук на TgOut
      tmp0 = tmp1;// перезапись значения из tmp1 в tmp0
      flag = 0;
     }
    
  }
}

//-----------------------------------------------------------------------

:tea:
:beer:
Аватара пользователя
главный колбасист
Это не хвост, это антенна
Сообщения: 1319
Зарегистрирован: Чт авг 21, 2014 11:11:48
Откуда: краснодарский край
Контактная информация:

Re: Котуинко

Сообщение главный колбасист »

https://vrtp.ru/index.php?showtopic=357 ... ntry993563
Ардуино.нас снова поимели. :))
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Нанка в комплекте с JDY40 ??
8)
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Предложил одному котейкину проверить его предположение практикой
https://radiokot.ru/forum/viewtopic.php ... 4#p4790174
А в ответ -"...
https://radiokot.ru/forum/viewtopic.php ... 8#p4790178
"...
К сожалению, давно не пишу для АВР, поэтому показать в сравнении на АВР не могу. Но могу привести пример для любимого многими нынче STM32 :)..."
Так любой вариант программы только на единой базе проверить можно.
:wink:
Тем более мне пока те АРМы особо не требовались. Может "не доросли задачи", а может отсутствие свободно-бесплатных компиляторов (включая ассемблер) для стародохлых ПК не слишком нравится.
Плюс необходимость детального изучения огроменных даташитов (без практического приложения/применения).
Разве что попробовал под адуринкой чуток да и забросил... Тудыть же и ESPшки - но у них другое - надо по сетевым технологиям и соответствующим компиляторам приличный объём перечитать (ежли чего своего нашкрябать, а не примерами баловаться).
:dont_know:
8)
Да вот ещё:
https://radiokot.ru/forum/viewtopic.php ... 8#p4790188
Хотелось только замечание сделать:
чтобы оценить результат работы с МК под ассемблером необходимо до мелочей знать документацию на тот МК и его систему команд.
Ежли работу с компилятором (ассемблер и/или Си или еще какой ЯВУ) освоить достаточно легко, то изучение документации современных "систем на кристалле" при скоростях "устаревания" моделей/типов тех МК делает подход к работе под ассемблером практически весьма затратным.
Работа с АРМ и "системами на кристалле" принуждает к переходу на различные варианты применения ЯВУ (языков высокого уровня).
Но одновременно с тем и создает полную зависимость разработчика устройств от авторов сред разработки, что не всегда учитывается "на перспективу".
:beer:
Последний раз редактировалось BOB51 Вт фев 17, 2026 19:47:14, всего редактировалось 1 раз.
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Котуинко

Сообщение Rapra »

А что я мог еще ответить, если я действительно НЕ пишу для АВР :) Последний раз, когда я держал АВР в руках, как раз примерно совпадает с годом вашей регистрации на этом форуме :) Ну и что вы от меня хотите то?
Да, меня в то время тоже не очень обрадовали тысячестраничные доки на тогдашний STM32F100. Ну а че делать то, нужда заставила, напрягся и освоил.
В прочем, я никого не заставляю и не убеждаю никуда переходить и менять привычное.

Добавлено after 4 minutes 12 seconds:
Скетчи для Ардуины же никогда не были быстрыми, поскольку в них использовался максимально унифицированный подход, жертвуя производительностью ради единообразия и упрощения программной части.

Добавлено after 6 minutes 9 seconds:
Поэтому при сравнении сгенерированного из Ардуино-скетчей асмового кода с асмом, написанным человеком, Ардуино-скетч будет проигрывать и в производительности, и в размере кода. Потому как написаны на Си неоптимально, избыточно.
Это вы еще не бывали на форумах ардуинщиков. Вы бы смеялись от их проблем, как они, не понимая разницы между аппаратным и программным I2C, пытаются состыковать различные скетчи в один кусок, именуемый "программой"
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

Так там есть и проект GCC в авр студии...
:wink:
Но ежли у меня для АВРок ленивый пример - попробуйте у себя соответственно сделать и чистый ассемблер и СИ - только вот где для АРМов компилятор ассемблера "в чистом виде" раскопать... Все среды под минимум Си вроде ...
Помимо того еще и заставлять изучать документацию в избыточном объёме (я что то не замечал проектов для АРМ под ассемблером - хотя бы для примера) как то это не в моем стиле...
:roll:
Но поскольку у нас разные базовые МК - смысл вступать в спор абсолютно теряется (зачем бы АРМовцу лезть в споры с оценками в тему с АВР?).
8)
Ардуино - всего лишь ИНСТРУМЕНТ (один из многих), коим просто надо корректно пользоваться.
:wink:
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Котуинко

Сообщение Rapra »

Хорошо, позднее попробую привести пример на СТМ.

Компилятор ассемблера уже встроен в среде разработки. Из стареньких и бесплатных можете поискать Atollic. Ранее это была официальная бесплатная среда разработки для АРМ. Позднее её перекупили ST Microelectronics, а затем трансформировали в новый продукт CubeIDE.
Аватара пользователя
BOB51
Друг Кота
Сообщения: 15539
Зарегистрирован: Вт мар 16, 2010 22:02:27
Откуда: ДОНЕЦК

Re: Котуинко

Сообщение BOB51 »

У меня подход к ассемблеру слишком старомодный.
8)
С другой стороны как раз именно ардуиноIDE может рассматриваться как наиболее удачное средство для работ с различными семействами МК.
К сожалению с недавних пор сайт ардуино перешел в разряд "подсанкционных", что ограничивает перспективы использования определенным набором того, что можно хранить в архивной форме (с возможностью быстрого восстановления).
Что будет более перспективным на будущее - предсказать довольно сложно (может простая палка-копалка к примеру :roll: ).
Пока что наиболее удачны платформы на основе АВРок под ардуино IDE по представленному перечню МК, возможностям самостоятельного изготовления железа программатора и возможностям компилятора плюс широкая доступность в продаже.
Опять же что будет дальше - удел шаманов.
С меня на крайний случай и MCS51/INTEL8080/Z80 под ассемблером (с листочками бумаги и карандашиком в качестве компилятора) возможностей хватит (даже ежли другого не будет).
:hunger:
:beer:
Rapra
Грызет канифоль
Сообщения: 259
Зарегистрирован: Пн фев 16, 2026 17:30:02

Re: Котуинко

Сообщение Rapra »

Ардуина попала под ссанкции? Хм. Походу, это уже наши тормозят. Есть немало примеров, когда доступ к безобидным материалам закрывают с нашей стороны по формальным признакам, находя какие-то древние и неактуальные материалы, в которых чето там "усматривают". Очень у нас уж любят всё запрещать из-за собственного страха.
А что будет дальше - да и так примерно понятно, запретят всё забугорное (в первый раз чтоль?) и принудительно влепят какой-нить условный Миландр по цене десять тысяч шкурок енотов за штучку. И покупать разрешат только при наличии справки из комендатуры. Да у них уже несколько лет так и сделано.

Касательно затронутой темы Асм/Си.
Сделал вот такой синтетический пример на Си. Вычисление среднего арифметического в массиве чисел. Функция Average() вызывает функцию Sum() для подсчета суммы элементов и этот результат делит на число элементов в массиве.
Спойлер

Код: Выделить всё

int Sum(int const* array, uint32_t n)
{
    int result = 0;
    while(n--)
    result += *array++;
    return result;
}

int Average(int const* array, uint32_t n)
{
    return Sum(array, n) / n;
}

int array[50];

int main()
{
    volatile int avr;
    avr = Average(array, 50);
При компиляции без оптимизации (параметр -O0) получается вот такой ассемблерный листинг, и он довольно длинный
Спойлер

Код: Выделить всё

int Sum(int const* array, uint32_t n)
{
 800014c:	b480      	push	{r7}
 800014e:	b085      	sub	sp, #20
 8000150:	af00      	add	r7, sp, #0
 8000152:	6078      	str	r0, [r7, #4]
 8000154:	6039      	str	r1, [r7, #0]
	int result = 0;
 8000156:	2300      	movs	r3, #0
 8000158:	60fb      	str	r3, [r7, #12]
	while(n--)
 800015a:	683b      	ldr	r3, [r7, #0]
 800015c:	1e5a      	subs	r2, r3, #1
 800015e:	603a      	str	r2, [r7, #0]
 8000160:	2b00      	cmp	r3, #0
 8000162:	bf14      	ite	ne
 8000164:	2301      	movne	r3, #1
 8000166:	2300      	moveq	r3, #0
 8000168:	b2db      	uxtb	r3, r3
 800016a:	2b00      	cmp	r3, #0
 800016c:	d007      	beq.n	800017e <_Z3SumPKim+0x32>
		result += *array++;
 800016e:	687b      	ldr	r3, [r7, #4]
 8000170:	1d1a      	adds	r2, r3, #4
 8000172:	607a      	str	r2, [r7, #4]
 8000174:	681b      	ldr	r3, [r3, #0]
 8000176:	68fa      	ldr	r2, [r7, #12]
 8000178:	4413      	add	r3, r2
 800017a:	60fb      	str	r3, [r7, #12]
	while(n--)
 800017c:	e7ed      	b.n	800015a <_Z3SumPKim+0xe>
	return result;
 800017e:	68fb      	ldr	r3, [r7, #12]
}
 8000180:	4618      	mov	r0, r3
 8000182:	3714      	adds	r7, #20
 8000184:	46bd      	mov	sp, r7
 8000186:	bc80      	pop	{r7}
 8000188:	4770      	bx	lr

0800018a <_Z7AveragePKim>:

int Average(int const* array, const uint32_t n)
{
 800018a:	b580      	push	{r7, lr}
 800018c:	b082      	sub	sp, #8
 800018e:	af00      	add	r7, sp, #0
 8000190:	6078      	str	r0, [r7, #4]
 8000192:	6039      	str	r1, [r7, #0]
	return Sum(array, n) / n;
 8000194:	6839      	ldr	r1, [r7, #0]
 8000196:	6878      	ldr	r0, [r7, #4]
 8000198:	f7ff ffd8 	bl	800014c <_Z3SumPKim>
 800019c:	4603      	mov	r3, r0
 800019e:	461a      	mov	r2, r3
 80001a0:	683b      	ldr	r3, [r7, #0]
 80001a2:	fbb2 f3f3 	udiv	r3, r2, r3
}
 80001a6:	4618      	mov	r0, r3
 80001a8:	3708      	adds	r7, #8
 80001aa:	46bd      	mov	sp, r7
 80001ac:	bd80      	pop	{r7, pc}
	...

080001b0 <main>:
int main()
{
	volatile int avr;
	avr = Average(array, 50);
 80001b6:	2132      	movs	r1, #50	; 0x32
 80001b8:	4802      	ldr	r0, [pc, #8]	; (80001c4 <main+0x14>)
 80001ba:	f7ff ffe6 	bl	800018a <_Z7AveragePKim>
 80001be:	4603      	mov	r3, r0
 80001c0:	607b      	str	r3, [r7, #4]
Подробно каждую строчку описывать не буду, это долго. Скажу лишь что здесь при генерации компилятор использовал самый простой и избыточный шаблон, сохраняя все вызовы функций вместе с передачей параметров через стек и самые простые алгоритмы математики и логики, даже несмотря на более оптимальный сишный код. Кароч, компилятор исполняет роль тупого студента.

Ладно. Теперь включаем оптимизацию компиляции на уровень -O3 и получаем:
Спойлер

Код: Выделить всё

 800014c:	2200      	movs	r2, #0
 800014e:	4b07      	ldr	r3, [pc, #28]	; (800016c <main+0x20>)
 8000152:	f103 00c8 	add.w	r0, r3, #200	; 0xc8

 8000156:	f853 1b04 	ldr.w	r1, [r3], #4
 800015a:	4283      	cmp	r3, r0
 800015c:	440a      	add	r2, r1
 800015e:	d1fa      	bne.n	8000156 <main+0xa>

 8000160:	4b03      	ldr	r3, [pc, #12]	; (8000170 <main+0x24>)
 8000162:	fba3 2302 	umull	r2, r3, r3, r2
 8000166:	091b      	lsrs	r3, r3, #4
 8000168:	9301      	str	r3, [sp, #4]
Здесь уже задействуются более эффективные шаблоны. При этом вызовы функций Average и Sum с их накладными расходами полностью исчезают. Компилятор учитывает короткую сишную запись while(n--) и *array++ и применяет соответствующие совмещенные инструкции.
Первые три строчки задают начальные условия, следующие четыре строчки выполняют суммирование элементв и последние четыре строки выполняют деление суммы на число элементов и сохренение результата в ОЗУ.

Таким образом, при включении оптимизации компилятора на выходе генерируется фактически то же самое, как если бы вы писали это вручную на ассемблере. Возможно, кому-то покажется быстрее написать этот текст на ассемблере. Конкретно этот пример несложен и на ассемблере писать даже меньше букв, чем на Си.
Но чтобы писать такой же эффективный код на ассемблере в рамках всей программы, нужно помимо логики приложения всегда держать в голове логику и ограничения инструкций, помнить все их варианты и ограничения параметров. А во-вторых, изменение такого текста под изменившиеся условия будет выполнить намного сложнее.
В разных сериях ядра АРМ используется разный набор инструкций. В лучшем случае, если замените Cortex M3 на Cortex M7 вы просто ограничитесь базовым набором, не используя специфические для M7 инструкции. А вот при обратном переходе, если использовали расширенный набор для M7, придется убирать их и искать упрощенный эквивалент на наборе M3.
В противовес этому, когда пишите на Си, один и тот же код без изменений будет работать на любом Кортексе. Я не имею ввиду аппаратные различия периферии, а вот такую прикладную задачу.

Как-то так.
Ответить

Вернуться в «Разные вопросы по МК»