Перейти к содержанию
    

Кто как работает с битами?

avr-gcc

 

раньше объявлял одну/несколько байтовых переменных, дефайнами называл их биты. обращаясь к биту, использовал имя переменной, и соответствующее имя бита. очевидно, вариант неудобен при наличии большого кол-ва битовых переменных, нужно же помнить какой бит в каком байте.

 

может наверняка есть какой-то более удобный метод. макрос, определяющий имя байта с флагами по имени бита, что-ли.

Изменено пользователем amost

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может наверняка есть какой-то более удобный метод. макрос, определяющий имя байта с флагами по имени бита, что-ли.

С gcc практически не работаю, но сам под ИАРом использую вот такое описание флагов в отдельном файле (см внизу)

Как это макросами развернуть - не показываю, ибо проклянете :)

На самом то деле тот метод, который используете, имеет множество достоинств. Ну включите в имя маски имя переменной, чтобы не ошибиться.

 

/*     name         var            bit   */

FLAG    (    eeprom_good                ,flags,    0x0001U )
FLAG    (    low_power_enable           ,flags,    0x0002U )
FLAG    (    factory_flag               ,flags,    0x0004U )
FLAG    (    service_calibration        ,flags, 0x0008U )
FLAG    (    remote                     ,flags, 0x0010U )
FLAG    (    show_value              ,flags, 0x0020U )
FLAG    (    blink                   ,flags, 0x0040U )
FLAG    (    missing_pulses          ,flags, 0x0080U )
FLAG    (    remote_change_enabled    ,flags, 0x0100U )
FLAG    (    booster_filled           ,flags, 0x0200U )
FLAG    (    refilling                ,flags, 0x0400U )
FLAG    (    conc_change_enable        ,flags,    0x0800U )
FLAG    (    delivery_passive        ,flags, 0x1000U )
FLAG    (    start_user_menu            ,flags, 0x2000U )
FLAG    (    process_happened           ,flags, 0x4000U )
//FLAG    (    block_booster_error        ,flags, 0x8000U )

FLAGS_VARIABLE ( flags )

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

</P><P>union char_by_bit
    {
    struct 
        {
        unsigned char D0 :1;
        unsigned char D1 :1;
        unsigned char D2 :1;
        unsigned char D3 :1;
        unsigned char D4 :1;
        unsigned char D5 :1;
        unsigned char D6 :1;
        unsigned char D7 :1;
          }bit;
    unsigned char byte;
    };    //statfl;

#define    NEW_IBUT    mode[0].bit.D0
#define    ERR_I2C        mode[0].bit.D1
#define    GET_KEY        mode[0].bit.D2

union char_by_bit mode[10];

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

avr-gcc

раньше....

Как Вам уже сказал Dog Pawlowa - так и продолжайте, только добавьте имя регистра. Типа:

#define SIS5_LIG(x)    (((x)&0x3)<<6)
#define SIS5_LIM        BIT5
#define SIS5_MCG(x)    (((x)&0x3)<<3)
#define SIS5_MCM        BIT2
#define SIS5_HIM        BIT1
#define SIS5_IIR        BIT0

......
    si_write( SIS5, SIS5_LIG(LIG_20DB)|SIS5_MCG(0)|SIS5_MCM|SIS5_HIM);    // Line Gain +20dB
    si_write( SIS6, SIS6_RXG(RXG_0DB)|SIS6_LO_ON);             // RX 0dB Line Out Active

......
void si_write( int reg, bint data )
{
    if( ( reg >= SIS1 )&&( reg <= SIS9 ) )
    {
        if( !xIsTimeout( si3000_time ) )
            vSmartDelay( 1 );
        fpga_cmd( FCMD_SI3000|FCMD_WR, (reg<<8)|(BYTE)data );
        si_reg[reg] = (BYTE)data;
        si3000_time = xGetTimeout( 1 );
    }
    else
        xprintf( "SI:Invalid REG:%2X\r", reg );
}

Проверено на собственной шкуре многими годами поисков и применения разных "извратов".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На платформах, не имеющих атомарного битового доступа к ОЗУ,

использовать битовые переменные нерационально если:

1. они volatile

2. их достаточно мало (не стоит жмотиться и выиграть аж целых 20-50 байт ОЗУ)

3. они не расположены в sfr области (см п.1).

 

Я в 99% случаев под флаги использую целую ячейку памяти (байт или даже крупнее) и в ус не дую...

 

Оптимизация ресурсов ОЗУ не должна быть самоцелью...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я в 99% случаев под флаги использую целую ячейку памяти (байт или даже крупнее) и в ус не дую...

Ну и зря, в тех-же 99 случаях флаги не используются отдельно, а "кучкуются" и лазить за каждым флагом в память, вместо работы с этими флагами в единожды загруженном одном регистре это уже не только растраты памяти, но и производительности. Естественно, случаи бывают разными. И железо бывает разным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Естественно, случаи бывают разными. И железо бывает разным.

А если флагов под сотню? Никаких регистров не хватит.

Или, к примеру, у MSP430 нет битовых команд. Забавно иногда смотреть, как выкручивается компилятор, доставая бит из середины, к примеру, четырьмя сдвигами подряд и переходом по флагу

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Или, к примеру, у MSP430 нет битовых команд. Забавно иногда смотреть, как выкручивается компилятор, доставая бит из середины, к примеру, четырьмя сдвигами подряд и переходом по флагу
По этой причине я для MSP430 не использую битовых переменных. Работаю с битовыми масками.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А если флагов под сотню? Никаких регистров не хватит.

Вы хоть поняли, о чем речь-то идет? Количество флагов к количеству регистров регистров у контроллера отношения не имеет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы хоть поняли, о чем речь-то идет? Количество флагов к количеству регистров регистров у контроллера отношения не имеет.

 

Я не телепат но похоже он имел в виду тот факт что у авр работа с регистрами не некоторых командах идет быстрее чем с памятью.

 

Я при переносе проекта на STM32 с avr решил не извращаться и все флаги просто байтовые сделал. Правда их не много - 30шт всего.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я не телепат но похоже он имел...

Так зачем, то, что "он имел", Вы переносите на то, что писал я :(. Причем в том числе и по помянутой Вами причине, следует использовать битовые маски в большинстве случаев.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вы хоть поняли, о чем речь-то идет?

Перечитал ещё раз. Теперь понял.

 

По этой причине я для MSP430 не использую битовых переменных. Работаю с битовыми масками.

А компиляторы нынче умные шибко пошли. Он и с маской может то же самое сделать, если посчитает, что это "дешевле" по времени или размеру

В общем, я к такому выводу пришёл, на основании своих наблюдений, что нет особой разницы, как писать.

Компилятор сам не дурак, решит, где удобнее маску наложить, где подвигать, а где битовые команды (если они есть) использовать.

Таким образом, надо писать так, как удобнее.

Вот ещё бы научить компилятор, чтобы группировал множество битов в одной команде...

Ну то есть чтобы вместо восьми битовых команд для одного, скажем, порта I/O формировал сразу общую байтовую маску.

Но это надо какое-то расширение языка в сторону HDL, например, объединить группу операторов в некий "квант", который можно выполнять одновременно

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ну и зря, в тех-же 99 случаях флаги не используются отдельно, а "кучкуются" и лазить за каждым флагом в память, вместо работы с этими флагами в единожды загруженном одном регистре это уже не только растраты памяти, но и производительности. Естественно, случаи бывают разными. И железо бывает разным.

Конечно, они могут и кучковаться, а могут и нет. Это меня даже не сильно заботит.

Меня во всей этой ситуации всегда напрягала необходимость использования критической секции.

И даже если они (флаги) обрабатываются пачками по 3-5 штук ещё не известно что будет оптимальнее прочитать 3-5 байт из ОЗУ или вкрячить критичекую секцию, добавив при этом лишнюю латентность (пусть даже и копеечную).

Мне всегда ближе наиболее простой вариант. И код не засорён лишними временными промежуточными переменными.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

И даже если они (флаги) обрабатываются пачками по 3-5 штук ещё не известно что будет оптимальнее прочитать 3-5 байт из ОЗУ или вкрячить критичекую секцию, добавив при этом лишнюю латентность (пусть даже и копеечную).

А зачем приплетать всуе слова "критическая секция". Эта сущность в общем случае совершенно отдельная. Если Вы не задумываясь щедрой рукой разбрасываете volatile да critical, и знаете только одну систему команд, то это не значит, что все должны следовать Вашему "примеру" и разбрасываться ресурсами :(.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гость MALLOY2
Я при переносе проекта на STM32 с avr решил не извращаться и все флаги просто байтовые сделал. Правда их не много - 30шт всего.

 

Совершенно зря, у Cortex есть фича упрощающая работу с битами называется она "Bit Banding"

Все ваши флаги можно было упаковать в одно слово, а там работай хоть через маски хоть через Bit Banding.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...