#c #gcc #bit-fields
#c #gcc #битовые поля
Вопрос:
Мой код нравится ниже, но после компиляции gcc вывод этой процедуры всегда «не соответствует».
Кажется, что RXC_SLOT всегда имеет 8-битную ширину в этом коде, а не 6. Почему?
#include <stdint.h>
#include <stdio.h>
typedef struct _RX_CONROL_t {
union {
struct {
//32'b{RESERVED12, RX_ABORT, RXC_RECEIVE, RXC_SOURCE_PORT, RXC_SLOT}
//32'b{ 20bit, 1bit, 1bit, 4bit, 6bit}
uint8_t RXC_SLOT : 6;
uint8_t RXC_SOURCE_PORT : 4;
uint8_t RXC_RECEIVE : 1;
uint8_t RX_ABORT : 1;
uint32_t RESERVED12 : 20;
};
uint32_t VALUE32;
};
} RX_CONROL_t;
int main(void) {
RX_CONROL_t rx_control = {.VALUE32 = 0};
rx_control.RXC_SLOT = 3;
rx_control.RXC_SOURCE_PORT = 2;
rx_control.RXC_RECEIVE = 1;
rx_control.RX_ABORT = 0;
//32'b{RESERVED12, RX_ABORT, RXC_RECEIVE, RXC_SOURCE_PORT, RXC_SLOT}
//32'b{ 20'd0, 1'd0, 1'b1, 4'd2, 6'd3} == 32'h00000483
if(rx_control.VALUE32 == 0x00000483) {
printf("matchn");
return 0;
}
else {
printf("unmatch rx_control.VALUE32 is %xn", rx_control.VALUE32); //FIXME: rx_control.VALUE32 is 1203 (why?)
printf("%x %x %x %x %xn", rx_control.RXC_SLOT, rx_control.RXC_SOURCE_PORT, rx_control.RXC_RECEIVE, rx_control.RX_ABORT, rx_control.RESERVED12);
return 1;
}
}
Комментарии:
1. Потому что вы сказали, что это
uint8_t
. Попробуйте сделать этоuint32_t
. Или, возможно, используйте битовые маски вместо битовых полей.2. @n.’местоимения’m.спасибо, но RXC_SOURCE_PORT, RXC_RECEIVE, RX_ABORT имеют правильную разрядность. Неправильная разрядность RXC_SLOT переводит другие поля в более высокое положение. Изначально я думал, потому что ‘RXC_SLOT RXC_SOURCE_PORT’ имеет ширину 6 4 = 10 бит, которая превышает границу uint8_t, поэтому компилятор запускает новую область для RXC_SOURCE_PORT .
3. Поскольку
uint32_t
битовые поля должны храниться отдельно отuint8_t
битовых полей, в первых 4 битовых полях передuint32_t
битовым полем есть 4 бита заполнения. Создайте их всеuint32_t
, и они смогут использовать один и тот же блок хранения.4. uint32_t работает хорошо, спасибо!!
5. Вы в принципе правы: 6 4 бита не вписываются в ваш
uint8_t
, и поэтому второе поле помещается в следующий элемент типаuint8_t
. Битовые поля обычно не хранятся в границах unterlying типа. Но, конечно, поскольку они в любом случае определены реализацией, я не был бы слишком удивлен, если бы это сделал компилятор…