Reading a header file, which implements the mapping of I/O devices for a microcontroller, I stumbled about the following code snippet:
typedef union{
unsigned char Byte;
struct
{
unsigned char BIT0 :1;
unsigned char BIT1 :1;
...
unsigned char BIT7 :1;
}Bits;
}COP;
extern volatile COP _COP #(0x0000 + 0x000000006FUL);
I cannot make any sense of the last line since I do not know the # Operator.
Related
I have following problem: In my code example, the too_long_CommandFrameStruct shows a size of 5, wheras all members added together have the size of 4. If I change the position of the union member to be first (like in shorter_CommandFrameStruct), the size is, like expected, 4.
Why does this happen and how can I prevent this? I'd like to have the order of the struct members as-is, because the struct gets byte-by-byte written to a (4-byte long) SPI buffer frame.
With the 5-byte long struct I have problems, because a nibble gets added between the unsigned int crc member and the union Commands cmdData. This nibble is probably causing the struct to grow to 4.5 and thus 5 bytes.
The code can be executed in an online compiler, like e.g. https://www.tutorialspoint.com/compile_c_online.php
#include <stdio.h>
#include <stddef.h>
union UnspecificFrame_t
{
unsigned short RegValue;
struct /* Single Bits */
{
unsigned bit0 :1;
unsigned bit1 :1;
unsigned bit2 :1;
unsigned bit3 :1;
unsigned bit4 :1;
unsigned bit5 :1;
unsigned bit6 :1;
unsigned bit7 :1;
unsigned bit8 :1;
unsigned bit9 :1;
unsigned bit10 :1;
unsigned bit11 :1;
unsigned bit12 :1;
unsigned bit13 :1;
unsigned bit14 :1;
unsigned bit15 :1;
} __attribute__((packed, aligned(1))) Bits;
};
union Commands
{
union UnspecificFrame_t unSpecFrame;
};
/* This one should be 4 bytes long, but actually is 5 bites long */
struct too_long_CommandFrameStruct
{
unsigned int crc :4;
union Commands cmdData;
unsigned int cmdType :4;
unsigned int id :8;
}__attribute__((packed, aligned(1))) too_long_CommandFrameStruct_t;
/* When switching the first members, the size is right */
struct shorter_CommandFrameStruct
{
union Commands cmdData;
unsigned int crc :4;
unsigned int cmdType :4;
unsigned int id :8;
}__attribute__((packed, aligned(1))) shorter_CommandFrameStruct_t;
int main()
{
printf("why is this size: %d\n", sizeof(too_long_CommandFrameStruct_t)); // returns 5
printf("and this one size: %d?\n", sizeof(shorter_CommandFrameStruct_t)); // returns 4
return 0;
}
In C, objects other than bit-fields are represented with whole numbers of bytes. And the members of a structure are required to be in order in memory in the same order they are declared in the structure.
When unsigned int crc :4;, it does not have to fill a full byte, because it is a bit-field, but it does have to be inside one or more bytes that are used for it. Then union Commands cmdData follows that and takes two bytes. Then unsigned int cmdType :4; and unsigned int id :8; require 12 more bits, so that requires at least two bytes (presuming bytes are eight bits, as is common). So declaring the members requires at least five bytes.
Note that alignment is not even consider in the above; five bytes are required simply because you need one byte, then two, then two more.
When union Commands cmdData is first, it requires two bytes. Then the three bit-fields that follow it take 4+4+8 = 16 bits, which only need two more bytes. So the total is four bytes.
I have a bit-field structure "struct errors" of size 1 byte and I am using its data using a mask "ERR_MASK" as shown in below code.
My requirement is that if the type of the structure is changed, the mask need to be adapted accordingly.
Since I am importing this structure type from another component or module (file1.h in below code),
I want to define a copy of this structure type "struct copy_errors" in my source file (file2.c in below code) and check if it has got changed with original type in file1.h,
If there is a mismatch, I want to throw an compilation error from file2.c. Can anyone tell me how do I achieve this? Or is there any other way to do this?
Note: I don't want to access "struct errors" with its elements.
/*file1.h*/
struct errors
{
unsigned char err0 :1;
unsigned char err1 :1;
unsigned char err2 :1;
unsigned char err3 :1;
unsigned char err4 :1;
unsigned char err5 :1;
unsigned char reserved1 :1;
unsigned char reserved2 :1;
};
/*file2.c*/
#include "file1.h"
#define ERR_MASK 0xFCU
struct copy_errors
{
unsigned char err0 :1;
unsigned char err1 :1;
unsigned char err2 :1;
unsigned char err3 :1;
unsigned char err4 :1;
unsigned char err5 :1;
unsigned char reserved1 :1;
unsigned char reserved2 :1;
};
bool function(struct err*)
{
bool ret=0;
unsigned char * err_ptr;
err_ptr = (unsigned char *) err;
if (((*err_ptr) & ERR_MASK) != 0U)
{
ret = 1;
}
return ret;
}
C doesn't support anything equivalent. If you have a tool chain that supports custom build events, you could introduce a pre-build step calling e. g. a python script (or any other language you prefer). This script then would:
load the header file
iterate over all lines until it finds the structure in question
check for all known members in desired order (i. e. no members replaced)
finally check, if end of structure is reached (i. e. no new members added)
If your tool chain stops, if the pre-build task fails, you are out already (just return 0 on success and anything else on failure), otherwise you could create a simple C-File, empty on success and containing an #error directive on failure.
Within your C code, you could additionally assure that the size of your struct matches:
#define CONCATENATE(X, Y) CONCATENATE_(X, Y)
#define CONCATENATE_(X, Y) X##Y
#define STATIC_ASSERT(CONDITION) \
typedef int(CONCATENATE(_static_assert_, __LINE__))[(CONDITION)? 1 : -1]
STATIC_ASSERT(sizeof(struct errors) == sizeof(unsigned char));
The macro is defined to be re-usable, as is, though, might produce additional warnings if used within function body (because of unused local type).
Admittedly this is a very silly question, but one that I was thinking about the other day. Sometimes in source I see registers defined like so:
union
{
uint8_t byte;
struct
{
uint8_t bit1 :1;
uint8_t bit2 :1;
uint8_t bit3_4 :2;
uint8_t rsvd :4;
} bitfield;
} SomeReg_t;
Other times I see just a standard struct:
struct
{
uint8_t bit1 :1;
uint8_t bit2 :1;
uint8_t bit3_4 :2;
uint8_t rsvd :4;
} SomeReg_t;
I wrote a quick example to show what I mean:
https://onlinegdb.com/r1H3Xuqe4
The question is, in regard to bitfields, what are the differences in these two definitions. When would you use one vs the other for bitfields.
It is easy to explain
Union is handy if you want to read or assign the whole byte as well.
for example
typedef union
{
uint8_t byte;
struct
{
uint8_t bit1 :1;
uint8_t bit2 :1;
uint8_t bit3_4 :2;
uint8_t rsvd :4;
} bitfield;
} SomeReg_t;
SomeReg_t reg;
reg.bitfield.bit1 = 1;
/*...*/
printf("The reg value is %hhx\n", reg.byte);
reg.byte = ReadFormPeriph();
if(reg.bitfield.rsvd == 0b1011)
{
/* do something */
}
I am somewhat new to C in regards to structures, unions and bitfields and need help. Below is the SLPH_CONTROL which will "control" the bits in the destination of DRVCONF0 and DRVCONF1. After the code snippet I will explain what I need.
/* SLPH_CONTROL **********************************************/
typedef union
{
struct
{
unsigned int SH0_BIT0 :1;
unsigned int SH0_BIT1 :1;
};
uint8 SLPH_CONTROL_byte;
} SLPH_CONTROL;
SLPH_CONTROL my_SLPH_CONTROL;
/* DRVCONF0 **********************************************/
typedef union
{
struct
{
unsigned int DF0_BIT0 :1;
unsigned int DF0_BIT1 :1;
unsigned int DF0_BIT2 :1;
unsigned int DF0_BIT3 :1;
unsigned int DF0_BIT4 :1;
};
uint8 DRVCONF0_byte;
} DRVCONF0;
DRVCONF0 my_DRVCONF0;
/* DRVCONF0 **********************************************/
typedef union
{
struct
{
unsigned int DF1_BIT0 :1;
unsigned int DF1_BIT1 :1;
unsigned int DF1_BIT2 :1;
unsigned int DF1_BIT3 :1;
unsigned int DF1_BIT4 :1;
};
uint8 DRVCONF1_byte;
} DRVCONF1;
DRVCONF1 my_DRVCONF1;
Now with the code above I want to link or copy data from and to like so:
SH0_BIT0:1 to DF0_BIT4:1;
SH1_BIT1:1 to DF1_BIT0:1;
Is there a way to do this? I am really lost and looked everywhere online for a solution to this. Any suggestions are welcome!!!
Thanks,
Eric
Maybe this is possible on special embedded H/W (I don't know) but not on a regular PC with standard C.
Bit fields describe individual bits in one or more consecutive bytes. Actually, bytes are addressable but bits are not. The read/write access to bits is internally solved by bit-wise operations (like in C expressed with &, |, ^, ~).
my_DRVCONF0 and my_DRVCONF1 are individual variables in your sample. Thus, it's even not granted that they will be allocated/stored in consecutive memory. (They definitely will not if some kind of word-alignment is enabled.)
You probably have to make the control more sophisticated (e.g. providing pairs of address and bit index) to do what's intended.
I am currently writing code for a PIC micro-controller and I would like to structure some of my code using a uint8_t as a "state counter" for a part of my code. This involves a lot of bitwise operations. What I'd like to do is create a struct for this uint8_t in a similar vein to the SFR bits structs that are within the header flies, I have included an example of one from the header file that I'm using below.
The header file allows access to the bits within the SFR using a notation similar to accessing elements within a struct, eg U1STAbits.UTXBF and as a uint16_t this is what I'd like to implement in my code as it will allow me to use a switch statement as the main structure of my code.
#define U1STA U1STA
extern volatile unsigned int U1STA __attribute__((__sfr__));
__extension__ typedef struct tagU1STABITS {
union {
struct {
unsigned URXDA:1;
unsigned OERR:1;
unsigned FERR:1;
unsigned PERR:1;
unsigned RIDLE:1;
unsigned ADDEN:1;
unsigned URXISEL:2;
unsigned TRMT:1;
unsigned UTXBF:1;
unsigned UTXEN:1;
unsigned UTXBRK:1;
unsigned :1;
unsigned UTXISEL0:1;
unsigned UTXINV:1;
unsigned UTXISEL1:1;
};
struct {
unsigned :6;
unsigned URXISEL0:1;
unsigned URXISEL1:1;
};
};
} U1STABITS;
extern volatile U1STABITS U1STAbits __attribute__((__sfr__));
Update:
I have made a potential solution based from this:
typedef struct {
union {
struct{
unsigned breakDetected :1;
unsigned overrunError :1;
unsigned framingError :1;
unsigned startDetected :1;
unsigned dmxMode :1;
unsigned rdmMode :1;
};
uint8_t UartFlags;
};
} UartFlagsBits;
UartFlagsBits uartFlags;
By defining a union between a bitfield struct and a uint8_t I am able to access the bitfield as a number to perform actions on the whole bitfield as suggested by Alex.
typedef struct {
union {
struct{
uint8_t breakDetected :1;
uint8_t overrunError :1;
uint8_t framingError :1;
uint8_t startDetected :1;
uint8_t dmxMode :1;
uint8_t rdmMode :1;
};
uint8_t UartFlags;
};
} UartFlagsBits;
UartFlagsBits uartFlags;