Pull to refresh

Comments 28

Очень хорошо, что вы описываете подобные тонкости и хитрости, для меня, как для начинающего на этом поприще, очень интересно и полезно читать вас!
так для этого и начал делать посты с упором на то, почему надо именно так )
Спасибо за добрые слова
Посмотрите исходники (желательно старого) ядра Linux в arch/arm/, там таких тонкостей — половина.
в первом листинге:
#define IO_STATUS_CMD_BIT 0x28

в 10-чной это будет 40, а не 28. Как я понял сдвинуть то вы на 28 собирались
Точно в десятичной, спасибо.
Легко написать макрос, который из битовой маски сделает битовую маску с единственным младшим битом

#define LOWBIT(MASK) ((((MASK)-1)  <<1 ) & (MASK))
#define LOWBIT(MASK) (~(MASK << 1) & (MASK))

Первая реализация просто неправильная: при MASK = 0x3 она даёт 0 вместо 1.
Вторая не работает с битовыми полями в которых есть разрывы: при MASK = 0x5 она даёт 0x5 вместо 1.

Идиома в данном случае — #define LOWBIT(MASK) (-(MASK) & MASK)
совершенно верно когда переносил руками ошибся в первом макросе должно быть ~(MASK-1) & MASK, спасибо, исправляю
Ну и прерывистые битовые поля я не рассматривал, поскольку с ними что делать вообще непонятно.
труднее (у меня не получилось), макрос выделяющий номер младшего бита


Простейшее решение:
#define LOWBITIDX(MASK) ((LOWBIT(MASK) > 0x1) + (LOWBIT(MASK) > 0x2) + (LOWBIT(MASK) > 0x4) + (LOWBIT(MASK) > 0x8) +… )

Больше битовых трюков: см. www.hackersdelight.org/
этот метод я конечно нашел, но речь то идет о красивых решениях ))
а не в переборных, а этот можно и упростить, если работать по байтам, но коряво до ужаса
Что тут некрасивого? Получается константа времени компиляции. Ну или вот, более короткое решение:

#define LOWBITIDX(MASK) LOWBITIDX32(MASK)

#define LOWBITIDX32(MASK) ((MASK) >= (1 << 16) ? LOWBITIDX16(MASK >> 16) + 16 : LOWBITIDX16(MASK))
#define LOWBITIDX16(MASK) ((MASK) >= (1 << 8) ? LOWBITIDX8(MASK >> 8) + 8 : LOWBITIDX8(MASK))
#define LOWBITIDX8(MASK) ((MASK) >= (1 << 4) ? LOWBITIDX4(MASK >> 4) + 4 : LOWBITIDX4(MASK))
#define LOWBITIDX4(MASK) ((MASK) >= (1 << 2) ? LOWBITIDX2(MASK >> 2) + 2 : LOWBITIDX2(MASK))
#define LOWBITIDX2(MASK) ((MASK) >= (1 << 1) ? LOWBITIDX1(MASK >> 1) + 1 : LOWBITIDX1(MASK))
#define LOWBITIDX1(MASK) ((MASK) >= 0x1 ? 0 : -1)
А вот такое решение я не увидел.
Неплохо, совсем неплохо и битовая природа хорошо видна и наращиваемость очевидна. И в моем стиле попробую прокомментировать последнюю строку: -1 там стоит для того, чтобы при нулевой маске сообщить об ошибке получением отрицательного значения.
UFO just landed and posted this here
Замечание верное, но все таки среди разработчиком МК не так много людей, получающих ищвращенно удовольствие от издевательства над разработчиком устройств и, как правило, порядок битов в регистре подразумевает нативный порядок байтов. Другое дело, что многие ядра поддерживают любой порядок байтов, ну так и следует выбирать такой, который не приведет к разрыву полей.
Я доброжелательно отношусь к критике, но во втором случае если бы ВЫ показали, как можно хорошо сделать при помощи битовых масок, я бы согласился, а пока что — согласится с мыслью о вредности вывода не могу.
То есть пока смею настаивать — при соблюдении должных мер предосторожности битовые поля очень удобный инструмент.
Можно перефразировать известное изречение «Битовые поля — наихудший способ, если не считать всех остальных»
UFO just landed and posted this here
Я пока не видел системы, в которой одновременно есть устройства и с B и с L-endian. Если знаете такую, скажите, может, мне просто везло. И если такая есть, то какой способ можно предложить вместо превратившихся в тыкву битовых полей? Маски с пробелами и чередованием старших и младших битов?
UFO just landed and posted this here
Речь шла об УДОБНОМ и обозримом способе.
UFO just landed and posted this here
Вместо пары
читать регистр (read{l,w}, переворачивать (le{32,16}_to_cpu)
лучше использовать io{read,write}{8,16,32}{,be} — это более современный и рекомендованный интерфейс.
UFO just landed and posted this here
UFO just landed and posted this here
Пост датируется 2004 годом

С тех пор вышли новые книги/написаны новые письма утверждающие обратное?

Хотите пример свежее: вот.

Ну и на наших target-платформах нету

а немного раньше
я могу сказать по опыту, что разработчики SoC-ов очень любят лицензировать чужие блоки

а на их платформах — вполне могут быть.
UFO just landed and posted this here
Ну, я так понимаю, что как раз это и должно обеспечивать совместимость между platform/pci.
UFO just landed and posted this here
Будет очень интересно.
Sign up to leave a comment.

Articles