Байтоёбства псто
Jun. 20th, 2021 12:49 pmМеня тут жизнь заставила потрогать компилятор XC8 от майкрочипа для мелких контроллеров. Это, я вам скажу, целый отдельный мир в себе. Зато я теперь понимаю, откуда на форумах тонны говнокода с двоичными или шестнадцатиричными константами, а разбуженный внезапно ночью пикоман будет бормотать что-то типа "0xA8 в регистр 0xBB включает режим синхронизации SPI по переднему фронту". Они, мать их, похоже что учат эти константы, потому что иначе никак.
Трудности начинаются с самого начала — с доступа к периферийным регистрам. Суть в том, что нормальные люди не пытаются изобретать колёса от велосипеда и тупо перечисляют в заголовочных файлах битовые маски и смещения, что приводит к самоочевидному коду типа "CTRL_A = (1<<OPTION1) | (1<<OPTION2);"
Но это нормальные люди. Пикоманы же пытаются сделать "удобно" и делают промежуточные структуры с битовыми полями. Тот же код будет выглядеть как "CTRL_A.option1=1; CTRL_A.option2=1;", но при этом, как всегда, есть нюанс — каждый бит будет ставиться отдельной инструкцией. Семь бит — семь команд.
И вот тут мне жалко не памяти и не машинных тактов — при таком подходе упускается из виду тот простой факт, что разные биты в регистре контролируют разные части периферии, и зачастую (как правило всегда) должны быть записаны одновременно. Иначе привет разные глитчи, баги и взбрыки самых разных форм цветов и размеров, просто потому что пока мы по одному пишем остальные биты, уже инициализированная часть периферии начинает себе там что-то думать или даже действовать.
Альтернатива? Конечно есть. Можно записать целиком слово в регистр, для этого надо посмотреть в даташит, выяснить позицию нужных битов, просуммировать это всё у себя в голове и написать простую и понятную команду:
Ну, или, для эстетов
Пикоманы, как есть пикоманы.
Трудности начинаются с самого начала — с доступа к периферийным регистрам. Суть в том, что нормальные люди не пытаются изобретать колёса от велосипеда и тупо перечисляют в заголовочных файлах битовые маски и смещения, что приводит к самоочевидному коду типа "CTRL_A = (1<<OPTION1) | (1<<OPTION2);"
Но это нормальные люди. Пикоманы же пытаются сделать "удобно" и делают промежуточные структуры с битовыми полями. Тот же код будет выглядеть как "CTRL_A.option1=1; CTRL_A.option2=1;", но при этом, как всегда, есть нюанс — каждый бит будет ставиться отдельной инструкцией. Семь бит — семь команд.
И вот тут мне жалко не памяти и не машинных тактов — при таком подходе упускается из виду тот простой факт, что разные биты в регистре контролируют разные части периферии, и зачастую (как правило всегда) должны быть записаны одновременно. Иначе привет разные глитчи, баги и взбрыки самых разных форм цветов и размеров, просто потому что пока мы по одному пишем остальные биты, уже инициализированная часть периферии начинает себе там что-то думать или даже действовать.
Альтернатива? Конечно есть. Можно записать целиком слово в регистр, для этого надо посмотреть в даташит, выяснить позицию нужных битов, просуммировать это всё у себя в голове и написать простую и понятную команду:
CTRL_A = 0xA6;
Ну, или, для эстетов
CTRL_A = 0b00100010;
Пикоманы, как есть пикоманы.
no subject
Date: 2021-06-20 06:25 pm (UTC)reg_cr1 = ( SPI_CR1_BIDIMODE | SPI_CR1_BIDIOE | LCD_BYTEORDER | SPI_CR1_SSM | SPI_CR1_SSI | SPI_CR1_BAUDRATE_FPCLK_DIV_256 | SPI_CR1_MSTR | LCD_CLK_POL | LCD_CLK_PHA );Код - из проекта для stm32 на libopencm3.
no subject
Date: 2021-06-21 08:45 am (UTC)Прагматика
Date: 2021-06-21 07:04 am (UTC)А если не жить, а палкой потыкать -- поддержу, затейники разные встречаются.
Из смешного про битфилды -- стандарт любезно не настаивает на их порядке. В рамках одного компилятора конечно и хрен бы с ним, но сам подход настораживает.
Re: Прагматика
Date: 2021-06-21 09:42 am (UTC)Если для дома, для семьи, то может быть. Хотя при таком раскладе проще уже наверное sdcc взять. Если надо взаимодействовать с кем-то еще — то ну его.
Про рамки одного компилятора — ну там всегда экосистема у пиков была наособицу, они и не гнались за совместимостью с чем-то. Из забавного: там есть поддержка адресации битов, т.е. можно написать "CM1CTRL.CM1ON=1", а можно "CM1ON = 1". Последнее в хедерах выглядит примерно как
extern volatile __bit CM1ON _at(0x889); // 0x111*8+1
Что еще хуже — подобные дефиниции прозрачно приводятся компилятором к int, и если писать "как привык" (CM1CTRL |= (1<<CM1ON)), то результат будет весьма далёк от ожидаемого. Какие уж тут стандарты.
no subject
Date: 2021-06-21 07:48 am (UTC)no subject
Date: 2021-06-21 08:50 am (UTC)