Работа с портами пинам. Макросы, X-macro

Обсуждаем контроллеры компании Atmel.
Ответить
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн фев 16, 2026 17:30:02

Сообщение Rapra »

AQ29 писал(а): Пт июл 31, 2026 22:06:30 Эти записи, на мой взгляд, проще и нагляднее, чем на СИ. Насчёт того, что СИ проще и компактнее – вопрос.
Я ж говорю - это до тех пор, пока вы не пишите ничего сложнее дергания ног на слабеньком микроконтроллере :)
Но чем сложнее задачи и "железо", тем больше требований к возможностям языка программирования. Бывает, что даже чистый Си не справляется, приходится брать его продвинутую версию - С++.

Вот например сравнительно несложный, но показательный пример:

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

Layer1::Window::Configure(
           start, end,
           LayerPF::RGB888,
           layer.getBuf(),
           layer.getSize().x);
на вашем "вменяемом" макроассемблере вызовет бурю эмоций при реализации этого, поскольку одна функция выполняет достаточно много действий. А С/С++ умеет раскладывать действия по полочкам и не валить в одну кучу.
То есть, показанная выше функция имеет внутри себя вложенные функции:

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

static bool Configure(const PixCoord& start, const PixCoord& end,
                        LayerPF pf, uint32_t bufAddress, uint16_t linePitch)
{
    if(Window::SetPosition(start, end) == false ||
          Buffer::Configure(pf, linePitch, end - start + (PixCoord){1, 1}) == false)
        return false;

     Buffer::SetAddress(bufAddress);
     return true;
}
которые, в свою очередь, так же имеют вложенные функции:

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

static bool SetPosition(PixCoord start, PixCoord end)
{
    PixCoord firstVisiblePixel = Ltdc::Scan::GetFirstVisiblePixel();
    start += firstVisiblePixel;
    end += firstVisiblePixel;

    if(end < start || end > Ltdc::Scan::GetLastVisiblePixel())
        return false;

    lay->WHPCR = ((start.x << LTDC_LxWHPCR_WHSTPOS_Pos) & LTDC_LxWHPCR_WHSTPOS_Msk) |
                          ((end.x << LTDC_LxWHPCR_WHSPPOS_Pos) & LTDC_LxWHPCR_WHSPPOS_Msk);

     lay->WVPCR = ((start.y << LTDC_LxWVPCR_WVSTPOS_Pos) & LTDC_LxWVPCR_WVSTPOS_Msk) |
                          ((end.y << LTDC_LxWVPCR_WVSPPOS_Pos) & LTDC_LxWVPCR_WVSPPOS_Msk);

     return true;
}
которая тоже имеет вложенную функцию:

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

static PixCoord GetFirstVisiblePixel()
{
    return {(uint16_t)(((LTDC->BPCR & LTDC_BPCR_AHBP_Msk) >> LTDC_BPCR_AHBP_Pos) + 1),
            (uint16_t)(((LTDC->BPCR & LTDC_BPCR_AVBP_Msk) >> LTDC_BPCR_AVBP_Pos) + 1)};
}
И всё это сделано как раз ради уменьшения как размера текста программы, так и размера бинарника за счет повторного использования функций.

Вооот, а вы говорите, что нагляднее пины дергать на макроассеблере и присваивать V = A. Попробуйте хотябы что-то подобное, и наглядность макроассемблера быстро превратится в крутозамешанную кашу.
А на языке С/С++ вот мне пофик, какие инструкции и как там используются. Компилятор сам их подберет в соответствии с настройками компиляции и оптимизации. Это его задача и пусть он делает свою работу. А я делаю свою, более высокую работу.
Реклама
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб июл 30, 2011 21:00:24

Сообщение AQ29 »

Adrift
Как понял, РА0 – бит порта. У меня в среде уже нет встроенных битовых переменных периферийных регистров для новых МК АВР, не имеет смысла.
Их слишком много (только периферийных регистров около 550 штук), много труда для разработчика среды.
Кроме того, увеличивается время компиляции, поскольку больше время поиска переменной.
Зачем это, когда можно просто написать через регистр с точкой PORTA.5 = 1. А остальная периферия настраивается через картинку.
Откуда взялся в примере r24? Если компилятор сам выбирает, то тут возникают вопросы.

Rapra
В среде не одна команда V = A, есть много других. Собственно, в тексте программы очень мало ассемблерных команд, в основном макрокоманды и функции. Да и команды типа PORTA.5 = 1 тоже обычно не бывает. Если эта команда зажигает второй светодиод, то для лучшей читаемости лучше написать макрос типа Led2_On.
Вызов из одной встроенной программы другой - это нередкая ситуация.
Например, у меня среде есть математические функции - корень, логарифм и т.д.
Функции рассчитываются на основе кусочно-линейной аппроксимации. Алгоритм простой, вначале выбирается нужный интервал, затем на основе линейной аппроксимации рассчитывается результат. Соответственно, основная программа вызывает две встроенных программы: выбор интервала и умножение. После компиляции эти программы появляются в конце программы.
Интересно, в СИ где располагаются встроенные программы.
Реклама
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн фев 16, 2026 17:30:02

Сообщение Rapra »

Да че вы со своим портом носитесь то. Я ж говорю - попробуйте что-то посложнее мигания светодиодом на старом дохленьком микроконтроллере!
Ассемблер, пусть даже и "вменяемый" макро, он давно уже изжил себя. Он просто не тянет современные микроконтроллеры и современные задачи. И бесполезно с этим спорить. Это как говорить, что кнопочный телефон круче смартфона, потому что там кнопки механические. Но кнопочный телефон - это только звонилка, и ничего более.
Вымогатель припоя
Сообщения: 587
Зарегистрирован: Вт окт 01, 2024 15:22:33

Сообщение Adrift »

AQ29 писал(а): Вс авг 02, 2026 22:18:23Как понял, РА0 – бит порта. У меня в среде уже нет встроенных битовых переменных периферийных регистров для новых МК АВР, не имеет смысла.
Их слишком много (только периферийных регистров около 550 штук), много труда для разработчика среды.
Вы себе сами эти проблемы придумали, у тех кто пользуется нормальными компиляторами все нужные определения уже есть в готовом виде, от производителей мк. И да, там файлы по несколько MB могут быть.
AQ29 писал(а):Кроме того, увеличивается время компиляции, поскольку больше время поиска переменной.
В простеньком C++ проекте для ARM, который компилируется пару секунд, с учетом стандартной библиотеки запросто может быть больше 100 тыс. строк, а ваш макроассемблер для AVR должен за доли секунды справляться, если он, конечно, грамотно написан.
AQ29 писал(а):Зачем это, когда можно просто написать через регистр с точкой PORTA.5 = 1. А остальная периферия настраивается через картинку.
Откуда взялся в примере r24? Если компилятор сам выбирает, то тут возникают вопросы.
Компилятор сам регистры выбирает, какие к нему могут быть вопросы? Вот пример, нигде явно регистры не указаны даже если вставки на ассме делать:
Спойлер

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

uint64_t umul_32_64(uint32_t u, uint32_t v)
{
	uint32_t a, b, c;

	__asm volatile("uxth %[a], %[u]\n"
				   "lsrs %[u], %[u], #16\n"
				   "lsrs %[b], %[v], #16\n"
				   "uxth %[v], %[v]\n"
				   "movs %[c], %[v]\n"
				   "muls %[v], %[a]\n"
				   "muls %[c], %[u]\n"
				   "muls %[u], %[b]\n"
				   "muls %[b], %[a]\n"
				   "lsls %[a], %[c], #16\n"
				   "lsrs %[c], %[c], #16\n"
				   "adds %[v], %[a]\n"
				   "adcs %[u], %[c]\n"
				   "lsls %[a], %[b], #16\n"
				   "lsrs %[b], %[b], #16\n"
				   "adds %[v], %[a]\n"
				   "adcs %[u], %[b]\n"
				   : [u] "+l" (u), [v] "+l" (v), [a] "=l" (a), [b] "=l" (b), [c] "=l" (c) :: "cc"
	);

	return uint64_t(u) << 32 | v;
}
AQ29 писал(а):В среде не одна команда V = A, есть много других. Собственно, в тексте программы очень мало ассемблерных команд, в основном макрокоманды и функции. Да и команды типа PORTA.5 = 1 тоже обычно не бывает. Если эта команда зажигает второй светодиод, то для лучшей читаемости лучше написать макрос типа Led2_On.
Я как бы на то и намекал, что PORTA.5 = 1 обычно никто не пишет, как и PORTA_OUTSET = &H21... А если у вас будет два определения Led1 и Led2, или макросы Led1_On/Off и Led2_On/Off, то как вы придете к записи в PORTA_OUTSET? В то же время мой код ее задействовал просто потому, что я объединил три пина и два из них оказались на одном порту.
Реклама
Эиком - электронные компоненты и радиодетали
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн фев 16, 2026 17:30:02

Сообщение Rapra »

Судя по синтаксису PORTA_OUTSET = &H21 - возможно, это BASCOM-AVR. В любом случае, это чрезвычайно устаревший инструмент, давно изживший себя. Разумеется, это ни коим боком не ассемблер, а диалект языка Basic.
Впрочем, если человек привык, то даже морально устаревший инструмент ему будет казаться идеалом совершенства. Вот только не стоит навязывать другим эти "древние окаменелости мамонта" :)
Реклама
Вымогатель припоя
Сообщения: 587
Зарегистрирован: Вт окт 01, 2024 15:22:33

Сообщение Adrift »

Rapra писал(а): Пн авг 03, 2026 15:17:09Судя по синтаксису PORTA_OUTSET = &H21 - возможно, это BASCOM-AVR.
Так AQ29 же C не знает, там видимо и сам ассемблер, если он есть, на бейсике написан, отсюда и заимствованный синтаксис )
Реклама
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб июл 30, 2011 21:00:24

Сообщение AQ29 »

Adrift писал(а): Пн авг 03, 2026 00:33:13 Компилятор сам регистры выбирает, какие к нему могут быть вопросы?
Например, такой вопрос. Проверенную программу немного изменили, например, вставили вашу строчку. Распределение регистров изменилось, где-нибудь в узком по времени месте из-за этого возникла ошибка. Получается, надо опять всё тестировать?
Adrift писал(а): Пн авг 03, 2026 00:33:13 Я как бы на то и намекал, что PORTA.5 = 1 обычно никто не пишет, как и PORTA_OUTSET = &H21... А если у вас будет два определения Led1 и Led2, или макросы Led1_On/Off и Led2_On/Off, то как вы придете к записи в PORTA_OUTSET? В то же время мой код ее задействовал просто потому, что я объединил три пина и два из них оказались на одном порту.
Макросы создаются просто, например, для Led1_On, если светодиод на 5 бите порта и включается единицей:
Public Mac Led1_On
PORTA_OUTSET = &H20
End Mac
Public – видимость макроса. Макрос может быть глобальный или модульный.
В СИ, наверно, тоже есть аналогичное.

Насчёт наличия битовых переменных периферии в среде. Понятно, что влияние на время компиляции мало.
Переменных в среде сейчас нет, потому что, практически, не нужны.
Кстати, запись с точкой более информативна, по цвету слова можно определить, к какой памяти (РОН, SRAM и т.д.) относится бит.
Rapra писал(а): Вс авг 02, 2026 23:21:57 Да че вы со своим портом носитесь то. Я ж говорю - попробуйте что-то посложнее мигания светодиодом на старом дохленьком микроконтроллере!
Ассемблер, пусть даже и "вменяемый" макро, он давно уже изжил себя. Он просто не тянет современные микроконтроллеры и современные задачи. И бесполезно с этим спорить.
Тема то как называется – «Работа с портами».
Новые МК АВР гораздо лучше «старых дохленьких», так что во многих случаях предпочтительнее. Кстати, похоже здесь на форуме мало кто их использует. А вы новые МК АВР применяете?
Обычный ассемблер, действительно, из прошлого века. Хотя вчера читал пост, для небольших МК всё-таки пишут. Наверно, СИ тут не катит, а получше ничего нет.

BASCOM-AVR не знаю.
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн фев 16, 2026 17:30:02

Сообщение Rapra »

AQ29 писал(а): Ср авг 05, 2026 21:25:01 вы новые МК АВР применяете?
Нет. И не буду. Вообще с AVR давно не имею дела. В том числе и по их ценовой политике в соотношении "возможности/цена"
AQ29 писал(а): Ср авг 05, 2026 21:25:01 , СИ тут не катит, а получше ничего нет.
С и тем более С++ - очень даже катит. С++ сейчас получил вполне хорошее распространение, в том числе и благодаря Ардуине.
AQ29 писал(а): Ср авг 05, 2026 21:25:01 BASCOM-AVR не знаю.
Так вы расскажите, что именно используете? Это что-то сверхсекретное чтоль? Как называется? А то вы показываете куски текста, но не говорите, что это это вообще такое.
AQ29 писал(а): Ср авг 05, 2026 21:25:01 Например, такой вопрос. Проверенную программу немного изменили, например, вставили вашу строчку. Распределение регистров изменилось, где-нибудь в узком по времени месте из-за этого возникла ошибка. Получается, надо опять всё тестировать?
Именно поэтому язык С/С++ предпочтительнее ассемблеров, в том числе и "вменяемых".
Ассемблеры, в том числе и макроассемблеры - давно устаревшая тема по причине всех этих недостатков.
Вымогатель припоя
Сообщения: 587
Зарегистрирован: Вт окт 01, 2024 15:22:33

Сообщение Adrift »

AQ29 писал(а): Ср авг 05, 2026 21:25:01Например, такой вопрос. Проверенную программу немного изменили, например, вставили вашу строчку. Распределение регистров изменилось, где-нибудь в узком по времени месте из-за этого возникла ошибка. Получается, надо опять всё тестировать?
Не пишите так чтобы из-за перераспределения регистров возникали ошибки. Или напишите критически важный фрагмент на ассме, а остальные 99% кода на C/C++.
AQ29 писал(а):Макросы создаются просто, например, для Led1_On, если светодиод на 5 бите порта и включается единицей:
Public Mac Led1_On
PORTA_OUTSET = &H20
End Mac
Public – видимость макроса. Макрос может быть глобальный или модульный.
В СИ, наверно, тоже есть аналогичное.
Да не об этом речь вообще... Вызовите вы свой Led1_On и сгенерится LDI+STS - 6 байт, а если нужно сразу два или три светодиода зажечь, то напишите еще макросы, вызовите их последовательно и получите 12 или 18 байт. Как имея Led1_On и Led2_On сгенерить PORTA_OUTSET = &H21? Еще один макрос написать? А для трех светодиодов еще 4 макроса только для On? ) На C++ вообще макросы писать не нужно и для одного светодиода сгенерит SBI - 2 байта, для двух светодиодов - SBI+SBI - 4 байта и только для трех будет LDI+STS - 6 байт.
AQ29 писал(а):Новые МК АВР гораздо лучше «старых дохленьких», так что во многих случаях предпочтительнее.
А какой у вас выбор? Со своим ассмом только со старых дохленьких на новые дохленькие AVR переехать и получится ) Периферию чуть подтянули, а производительность осталась 20-ти летней давности...
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб июл 30, 2011 21:00:24

Сообщение AQ29 »

Rapra писал(а): Чт авг 06, 2026 04:47:21 Вообще с AVR давно не имею дела. В том числе и по их ценовой политике в соотношении "возможности/цена"
В Чипдипе одно время продавали новый Attiny по цене около 34 рублей. 32 килобайта, полно всяких возможностей типа программируемой логики, коммутатор для аппаратного соединения периферии и т.д. При такой цене, наверно, один из лучших МК в этой категории. Сейчас, правда, пропали по такой цене.
Rapra писал(а): Чт авг 06, 2026 04:47:21 Так вы расскажите, что именно используете? Это что-то сверхсекретное чтоль? Как называется? А то вы показываете куски текста, но не говорите, что это вообще такое.
Пока в разработке, так что ни у кого нет. Не собирался обсуждать среду, но затянуло.
Народ неявно подбрасывает всякие идеи. Например, здесь Adrift написал о применении готовых файлов с параметрами периферийных регистров МК. Мельком посмотрел. Не понравилось, что файл «раздут», правда, толком не разбирался, но, скорее всего, можно использовать с доработкой.
Adrift писал(а): Чт авг 06, 2026 09:34:30 Не пишите так чтобы из-за перераспределения регистров возникали ошибки. Или напишите критически важный фрагмент на ассме, а остальные 99% кода на C/C++.
Писать без возникновения ошибок – хорошее пожелание, но оно из разряда: надо быть здоровым и богатым.
В ассемблере при небольшой правке тоже можно получить скрытые ошибки, но вероятность гораздо меньше.
Плохо представляю, как в СИ проверяют программу после правок. Скажем, ответственная программа, тестировали полгода, и что, после небольших правок опять тестировать полгода? Неизвестно, что там изменилось при перераспределении регистров, да ещё оптимизатор что наделал.
Были случаи, из-за дефектов программы погибали пациенты.
Adrift писал(а): Чт авг 06, 2026 09:34:30 Вызовите вы свой Led1_On и сгенерится LDI+STS - 6 байт, а если нужно сразу два или три светодиода зажечь, то напишите еще макросы, вызовите их последовательно и получите 12 или 18 байт. Как имея Led1_On и Led2_On сгенерить PORTA_OUTSET = &H21? Еще один макрос написать?
Макросы пишет разработчик согласно своему усмотрению.
Создать ещё один макрос – не проблема. Для ускорения скопировал макрос, вставил нужные строчки, изменил название – это по времени пара минут, вот и есть нужный макрос. А можно без макроса просто команды написать, причём в одну строчку с разделением двоеточием.
Никогда не озадачивался количеством макросов.
Будет в программе 10 или 30 макросов, какая разница, это не увеличивает код.
Обычно вначале работы создаётся макрос Port_Set, где прописываются все параметры портов (вход/выход, значения выходов). Затем указанные макросы и всякая мелочь типа звонок пикнул, светодиод моргнул. Потом посложнее, например, вывод на индикатор и т.д., но тут уже лучше Sub.
Макрос удобнее вашей строчки.
Во-первых, светодиод может зажигаться нулём. Тогда вам, наверно, придётся писать комментарии, хоть и есть слово set, но это будет гашение.
Кроме того, что-то может включаться единицей, а что-то нолём, в вашем случае их не объединить.
Во-вторых, макрос имеет видимость, для сложных программ это удобно.
Кстати, в СИ есть видимость макросов?
Adrift писал(а): Чт авг 06, 2026 09:34:30 А какой у вас выбор? Со своим ассмом только со старых дохленьких на новые дохленькие AVR переехать и получится ) Периферию чуть подтянули, а производительность осталась 20-ти летней давности...
Тут да, пока работа только с АВР. Но у АВР широкий ассортимент, на ближайшие годы хватит, а позже, возможно, такая среда появится и для других МК.
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн фев 16, 2026 17:30:02

Сообщение Rapra »

AQ29 писал(а): Вс авг 09, 2026 13:34:53 Пока в разработке, так что ни у кого нет. Не собирался обсуждать среду, но затянуло.
Ааа, самопал... Ну тогда фигня, даже не обсуждаемо :) Хосспидя, я так и предпологал, что чето там не так, поскольку на существующие макроассемблеры не совсем похоже. И слово "вменяемый" тут вообще никак не подходит. Обычный набор макросов в проприетарном стиле. Применимость - нулевая, полезность и преимущества - крайне спорные, если не сказать нулевые. Имеет ценность только для автора.
Макросы - это вообще очень устаревшая тема, пережиток прошлого. В современных языках от макросов вообще отказываются ввиду их неповоротливости. Например, в С++ вместо макросов - constexpr, consteval.
А то, что вы подразумеваете под макросами, в С/С++ называется функциями. Причем, функции более предпочтительны, поскольку имеют входные и выходные параметры, которые могут изменяться во время работы.
Пример функции:

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

int Sum(int a, int b)
{
   return a + b;
}

c1 = Sum(2, 3);
c2 = Sum(c1, 10);
c3 = Sum(c1, c2);
То есть, функция Sum принимает не только заданные при написании константы, но и изменяющиеся во время работы переменные.

AQ29 писал(а): Вс авг 09, 2026 13:34:53 Кстати, в СИ есть видимость макросов?
Есть. Но как я уже говорил, макросы в современных языках считаются устаревшим делом и не рекомендуются для новых разработок. Чтобы вы там ни говорили, как бы вы там не убеждали, но такова реальность. Макросы уже давно стали пережитком прошлого и в современной продвинутой практике фактически не применяются.
Остались только динозавры типа вас, которые так и не смогли идти не то чтобы в ногу со временем, но хотябы не слишком отставать.
AQ29 писал(а): Вс авг 09, 2026 13:34:53 придётся писать комментарии, хоть и есть слово set, но это будет гашение.
Вы просто не знакомы с современными языками, поэтому даже и не представляете, с помощью чего это реализуется :) "Видишь суслика? - Нет. - А он есть!" :)
RedLed::On(); GreenLed::Off(); PowerLed::Toggle(); и при этом без разницы, как подключен светодиод, ибо при его описании можно задать, инвертируется выход или нет. using RedLed = Pin<GpioA::Pin3, Polarity::Invert>; using GreenLed = Pin<GpioD::Pin14, Polarity::Normal>
AQ29 писал(а): Вс авг 09, 2026 13:34:53 В ассемблере при небольшой правке тоже можно получить скрытые ошибки, но вероятность гораздо меньше.
Скорее, наоборот. В ассемблере, в силу его привязанности к железу, даже небольшие правки могут иметь большую вероятность повреждения работы кода.
А в языке Си компилятор сам всё устаканит на уровне размещения кода и используемых инструкций. Поэтому, вносить правки на Си гораздо легче, чем на ассемблере. Это давно известный факт, подтвержденный многими годами работы многих программистов.
AQ29 писал(а): Вс авг 09, 2026 13:34:53 Плохо представляю, как в СИ проверяют программу после правок. ... тестировали полгода, и что, после небольших правок опять тестировать полгода
По полгода никто не тестирует. Полгода рынок ждать не будет. Все куда проще. Если в проге есть ошибка, она проявит себя сразу же, а не через полгода. Нужно просто знать, как правильно тестировать.
При правильном тестировании не надо ждать, когда какая-то ошибка проявит себя при случайном стечении обстоятельств. Нужно как раз при тесте и вызвать все возможные обстоятельства.

Для этого, безотносительно языка программирования, пишутся так называемые unit-тесты. Это концепция проверки на правильность функционирования, на соответствие результата выполнения юнита ожидаемому от него результату. А так же на "поломатость" некоторой единицы программы (юнита, модуля) после внесения изменений.

На примере гипотетического юнита, возвращающего сумму двух 16-битных чисел со знаком: проверяют, что во всем диапазоне входных чисел возвращается то, что ожидается. То есть, проверяется поведение на специфических, характерных условиях: 2 + 3 = 5, -2 + 3 = 1, 2 + (-3) = -1, 0 + 0 = 0, 32000 + 1000 = 32767 (сложение с насыщением по 16-битному знаковому), и то же в отрицательную сторону.
Таким образом проверяется, что сложение положительных и отрицательных чисел работает верно, а так же при переполнении разрядной сетки возвращается максимально возможное в этой разрядности число.

А для проверки внесенных в готовый юнит изменений есть регрессионные тесты - проверка на деградацию (поломку) кода. Новая версия сравнивается со старой и обнаруживается расхождение поведения.
Для проведения этих проверок есть специальные утилиты генерации и запуска тестов, поэтому проверки на деградацию выполняются автоматически. С конкретным языком программирования юнит-тесты не связаны. Юнит-тестирование - это часть работы. И после внесения изменений запускаются ранее написанные юнит-тесты, они сразу же покажут поломку, если таковая имеется.
AQ29 писал(а): Вс авг 09, 2026 13:34:53 Для ускорения скопировал макрос, вставил нужные строчки, изменил название – это
...это крайне вредный принцип работы. Копипасты - вредны в программировании. Если вам что-то приходится копипастить, значит, вы неверно организовали работу. Почему? А потому что если потом вам пришлось отредактировать (добавить, убавить, улучшить) один фрагмент, то эти изменения придется вручную так же копипастить и во все остальные места, куда было раньше скопипащено. Постоянные правки в разных местах одного и того же сильно замедляют работу и вносят потенциальные ошибки.
Именно из-за таких копипаст ваше тестирование затягивается на полгода. Вместо того, чтобы оттестировать один юнит в одном месте, вам приходится тестировать каждое скопированное вхождение этого юнита во всех местах.
Из-за неверной концепции вы сами себе усложнили задачу.
Поэтому еще раз повторю - копипасты - зло и вред!
Прорезались зубы
Сообщения: 238
Зарегистрирован: Сб июл 30, 2011 21:00:24

Сообщение AQ29 »

Rapra писал(а): Вс авг 09, 2026 14:07:26 Макросы - это вообще очень устаревшая тема, пережиток прошлого. В современных языках от макросов вообще отказываются ввиду их неповоротливости. Например, в С++ вместо макросов - constexpr, consteval.
А то, что вы подразумеваете под макросами, в С/С++ называется функциями. Причем, функции более предпочтительны, поскольку имеют входные и выходные параметры, которые могут изменяться во время работы.
За что вы так макросы-то, ведь они ни в чём не виноваты.
Я макроассемблер не знаю, может, мы по-разному определяем макросы.
У меня макрос просто вставляет строчки текста в программу. А функции вызывают программу.
Соответственно, разные области применения.
Макрос обычно небольшой. В примере, скажем, после компиляции будет одна ассемблерная команда. А если переименовать этот макрос в Sub, из-за вызова подпрограммы будет три команды, в три раза хуже.
Естественно, в этой ситуации макрос гораздо лучше.
Если однократный вызов, тоже можно применить макрос с большим текстом. Например, установка портов Port_Set в начале программы.

У меня есть, конечно, и функции, называются Sub, как же без них. Есть и входные, и выходные параметры. Входные могут быть числами и переменными. Всё, как полагается, может быть, даже несколько больше.
Выходных переменных может быть несколько. Например, в вашем примере выходными переменными могут быть сумма и разность аргументов а и b.
В программе значительное большинство по понятным причинам – это Sub.
Rapra писал(а): Вс авг 09, 2026 14:07:26 И слово "вменяемый" тут вообще никак не подходит.
Это согласен. Предлагаю такое название АВУ – ассемблер высокого уровня.
Rapra писал(а): Вс авг 09, 2026 14:07:26 По полгода никто не тестирует. Полгода рынок ждать не будет. Все куда проще. Если в проге есть ошибка, она проявит себя сразу же, а не через полгода. Нужно просто знать, как правильно тестировать.
При правильном тестировании не надо ждать, когда какая-то ошибка проявит себя при случайном стечении обстоятельств. Нужно как раз при тесте и вызвать все возможные обстоятельства.
При испытаниях «вызвать все возможные обстоятельства» может только идеальный разработчик. А простым смертным для серьёзного оборудования приходится проводить опытную эксплуатацию, лучше длительно.
Похоже, вы пишите о простых случаях, когда при дефекте программы нет тяжёлых последствий.
Так не пойдёт для серьёзного оборудования, отказ которого может привести к тяжёлым последствиям.
Пример из поста на форуме. Аппарат искусственной вентиляции лёгких, тяжёлый больной, медсестра нажала на пульте кнопку, пошла перезагрузка, на это время вентиляция прекратилась, больной умер. Провели бы хорошую опытную эксплуатацию, такого бы не было.
Проводившие опытную эксплуатацию могли бы много чего рассказать, и трагичного, и комичного. Я тоже сталкивался.
Rapra писал(а): Вс авг 09, 2026 14:07:26 ...это крайне вредный принцип работы. Копипасты - вредны в программировании. Если вам что-то приходится копипастить, значит, вы неверно организовали работу.
Макросы небольшие, какие там проблемы. Приведённые примеры со светодиодами, скажем, какой-нибудь не загорелся, найти ошибку просто.
Большие Sub обычно не копирую. Если нужна копия с небольшими изменениями, лучше для этого Sub ввести входной параметр, при разных значениях которого запускаются разные варианты.
Ошибки обычно отыскиваются легко, в среде есть отладчик реального времени.
Вымогатель припоя
Сообщения: 587
Зарегистрирован: Вт окт 01, 2024 15:22:33

Сообщение Adrift »

AQ29 писал(а): Вт авг 11, 2026 23:03:34Похоже, вы пишите о простых случаях, когда при дефекте программы нет тяжёлых последствий.
Так не пойдёт для серьёзного оборудования, отказ которого может привести к тяжёлым последствиям.
Пример из поста на форуме. Аппарат искусственной вентиляции лёгких, тяжёлый больной, медсестра нажала на пульте кнопку, пошла перезагрузка, на это время вентиляция прекратилась, больной умер. Провели бы хорошую опытную эксплуатацию, такого бы не было.
Смотрите, заходите на сайт ARM, например, находите там "Arm Compiler for Embedded FuSa" и читаете:
Arm Compiler for Embedded FuSa is a qualified C/C++ toolchain that has been assessed by safety-accredited certification body, TÜV SÜD. The qualified toolchain is suitable for developing embedded software for safety markets including automotive, industrial, medical, railways, and aviation.

Arm Compiler for Embedded FuSa is qualified for developing software that meets the highest level of safety integrity for the following standards:

IEC 61508 (Industrial) – SIL 3
ISO 26262 (Automotive) – ASIL D
EN 50716 (Railways) – SIL 4
IEC 62304 (Medical) – Class C

For other safety standards, many of which have been derived from IEC 61508, the Qualification Kit provides the key information required by end-users need to perform Tool Validation.
А какая сертификация у вашего ассемблера высокого уровня который пишется уже десяток лет и никак до дойдет до стадии когда его можно продемонстрировать широкой общественности? Так он еще и только для AVR, где даже контроля четности SRAM нет )
Вымогатель припоя
Сообщения: 651
Зарегистрирован: Пн фев 16, 2026 17:30:02

Сообщение Rapra »

AQ29 писал(а): Вт авг 11, 2026 23:03:34 Я макроассемблер не знаю, может, мы по-разному определяем макросы.
Интересно, что вы вообще тогда знаете?
Обычно люди сначала учатся, изучают тему, и только потом начинают что-то своё творить. В противном случае, когда что-то делаете, ничего не зная, можете наворотить всяких бед. Представьте, что вас будет оперировать хирург, который ничего не знает, но сам изобрел свою методику хирургических операций и имеет какое-то свое собственное представление об внутрянке человека. Страшно даже представить, что натворит такой хЕрург.
AQ29 писал(а): Вт авг 11, 2026 23:03:34 Предлагаю такое название АВУ – ассемблер высокого уровня.
Ясно. В общем, вы изобрели велосипед на квадратных колесах. Серьезно.
AQ29 писал(а): Вт авг 11, 2026 23:03:34 Всё, как полагается, может быть, даже несколько больше.
Откуда вы знаете, "как полагается и даже больше", если вы не знаете других языков программирования? Ведь чтобы создать что-то новое, нужно знать все то, что уже существует. Иначе получаете просто очередной велосипед на квадратных колесах.

Вот в вашем "языке" есть например полиморфизм? Ааа, вы даже такого слова то вряд ли слышали :)
Как реализуется он в С++ на примере той же функции суммирования:

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

template<typename T>
T Sum(T a, T b)
{
   return a + b;
}
И в эту функцию можно передать как простые числа - знаковые и беззнаковые, так и составные структуры чисел. Например, координаты точки на плоскости, описываемые двумя числами:

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

int c = Sum(50, 40);
CoordXY point = Sum({10, 30}, {50, 20});
То есть, одно имя, одна реализация функции, но с работает с разными типами переменных.
А у вас такое возможно? Судя по написанному, полиморфизм у вас образуется методом копипасты с редактированием. Ну вот, а это - одна из критичных ошибок в парадигме программирования. И с такой концепцией гораздо выше шанс угрохать поцыента под ИВЛ из-за какой-то ошибки при копипасте.
AQ29 писал(а): Вт авг 11, 2026 23:03:34 При испытаниях «вызвать все возможные обстоятельства» может только идеальный разработчик. А простым смертным для серьёзного оборудования приходится проводить опытную эксплуатацию, лучше длительно.
Почему же? Я ж объяснил принцип юнит-тестирования на примере простой суммы двух чисел. И хотите сказать, что эту сумму может протестировать только идеальный программист, а все остальные будут по полгода тестить её? Я ж ранее приводил пример тестирования.
AQ29 писал(а): Вт авг 11, 2026 23:03:34 Похоже, вы пишите о простых случаях, когда при дефекте программы нет тяжёлых последствий.
А вы думаете, что вы один тут Дартаньян, а все остальные мелочь пузатая? :)) Вы сильно заблуждаетесь. Опять же потому, что не интересуетесь тем, что происходит вне вашего микромирка.
Похоже, что вы просто не поняли принципа юнит-тестирования, который очень распространен за пределами вашего микромира. Юнит - это единица, одна программная единица. Из таких юнитов складывается сколь угодно сложная и гиперответственная программа. И тестируют от частного к общему, а не сразу целиком всю программу по полгода.
А вопросы аппаратного тестирования устройства не входят в компетенцию программного тестирования. Это вопрос другой. Программисту дается набор входных и выходных данных, и на этой основе он и пишет программу и тестирует ее. Тестирование аппаратной части - это задача других разработчиков
AQ29 писал(а): Вт авг 11, 2026 23:03:34 медсестра нажала на пульте кнопку, пошла перезагрузка, на это время вентиляция прекратилась, Провели бы хорошую опытную эксплуатацию, такого бы не было.
Опытная эксплуатация прибора с кривой программой стоит очень дорого.
Поэтому и производится юнит-тестирование программы, что при нажатии кнопки не происходит зависание и перезагрузка! Опытной эксплуатации тут не нужно. Достаточно программисту протестировать свой код так, чтобы нажатие кнопки отрабатывалось без сбоев, даже если кнопка хреновая и генерирует тыщщу импульсов вместо одного. (на самом деле, все механические кнопки генерируют несколько импульсов, а не один).
Задача программиста - получив на входе серию импульсов, определить, что это нажатие/отпускание кнопки, ну и обеспечить соответствующее поведение программы.
А представьте, что вам сделали готовый медицинский прибор со всеми наворотами, вы в него загружаете свою программу и начинаете тестить. И прибор начинает глючить на каждом шаге. И вы гадаете - толи это программная ошибка, то ли это аппаратная проблема. Например, хреновая кнопка. А вы такого не ожидали, и начинаете править свою программу, вместо того, чтобы сказать - на моей стороне все норм, это у вас аппаратный косяк. И так на каждом шагу. Каждый программный глюк вы будете ловить на готовом приборе стоимостью овердофига денег. И вы не уверены, программный это косяк или аппаратный. И так - полгода подряд "опытной эксплуатации".
AQ29 писал(а): Вт авг 11, 2026 23:03:34 Макросы небольшие, какие там проблемы. Приведённые примеры со светодиодами, скажем, какой-нибудь не загорелся, найти ошибку просто.
Это вы говорите о простом случае, когда визуально видно незагоревшийся светодиод. Но если вы копипастите много раз один макрос, имеющий ошибку, то вам придется в каждом месте, куда вы его скопировали, исправить эту ошибку. А это рутинная операция, и рутинные операции как раз и подвержены ошибкам из-за невнимательности. Это в простой программе легко и просто обнаружить ошибку. А представьте себе программу, управляющую каким-нить ИВЛ с полутора десятками клапанов, моторчиков и тп. По вашей методике, это нужно собрать весь ИВЛ, запустить его, и проверить каждый клапан. Причем, если какой-то клапан не сработал, будет неясно - косяк в программе или косяк с самим клапаном или его цепью управления.

Так что ваша методика тестирования - ущербная, она не дает представления о источнике неисправности. Вот что значит - что-то делать, не имея профильных знаний!
Ответить

Вернуться в «AVR»