Как стать автором
Обновить

Комментарии 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 там стоит для того, чтобы при нулевой маске сообщить об ошибке получением отрицательного значения.
НЛО прилетело и опубликовало эту надпись здесь
Замечание верное, но все таки среди разработчиком МК не так много людей, получающих ищвращенно удовольствие от издевательства над разработчиком устройств и, как правило, порядок битов в регистре подразумевает нативный порядок байтов. Другое дело, что многие ядра поддерживают любой порядок байтов, ну так и следует выбирать такой, который не приведет к разрыву полей.
Я доброжелательно отношусь к критике, но во втором случае если бы ВЫ показали, как можно хорошо сделать при помощи битовых масок, я бы согласился, а пока что — согласится с мыслью о вредности вывода не могу.
То есть пока смею настаивать — при соблюдении должных мер предосторожности битовые поля очень удобный инструмент.
Можно перефразировать известное изречение «Битовые поля — наихудший способ, если не считать всех остальных»
НЛО прилетело и опубликовало эту надпись здесь
Я пока не видел системы, в которой одновременно есть устройства и с B и с L-endian. Если знаете такую, скажите, может, мне просто везло. И если такая есть, то какой способ можно предложить вместо превратившихся в тыкву битовых полей? Маски с пробелами и чередованием старших и младших битов?
НЛО прилетело и опубликовало эту надпись здесь
Речь шла об УДОБНОМ и обозримом способе.
НЛО прилетело и опубликовало эту надпись здесь
Вместо пары
читать регистр (read{l,w}, переворачивать (le{32,16}_to_cpu)
лучше использовать io{read,write}{8,16,32}{,be} — это более современный и рекомендованный интерфейс.
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
Пост датируется 2004 годом

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

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

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

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

а на их платформах — вполне могут быть.
НЛО прилетело и опубликовало эту надпись здесь
Ну, я так понимаю, что как раз это и должно обеспечивать совместимость между platform/pci.
НЛО прилетело и опубликовало эту надпись здесь
Будет очень интересно.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории