What is the purpose of bitshifting by 0 - c

I am reviewing the open source AMD GPU drivers for Linux. I noticed something I haven't seen before, and I would like to know the purpose. On line 1441 of the sid.h file, there are a series of defines that are integers being bitshifted left by 0. Wouldn't this just result in the original integer being operated on?
Here is an excerpt and a link to the head
#define VGT_EVENT_INITIATOR 0xA2A4
#define SAMPLE_STREAMOUTSTATS1 (1 << 0)
#define SAMPLE_STREAMOUTSTATS2 (2 << 0)
#define SAMPLE_STREAMOUTSTATS3 (3 << 0)
https://github.com/torvalds/linux/blob/master/drivers/gpu/drm/amd/amdgpu/sid.h#L1441
Also, I am learning to access the performance counter registers of AMD GPUs in order to calculate the GPU load. Any tips on that would be appreciated as well.

Things like that could be done just for the sake of consistency (not necessarily applicable to your specific case). For example, I can describe a set of single-bit flags as
#define FLAG_1 0x01
#define FLAG_2 0x02
#define FLAG_3 0x04
#define FLAG_4 0x08
or as
#define FLAG_1 (1u << 0)
#define FLAG_2 (1u << 1)
#define FLAG_3 (1u << 2)
#define FLAG_4 (1u << 3)
In the first line of the latter approach I did not have to shift by 0. But it just looks more consistent that way and emphasizes the fact that FLAG_1 has the same nature as the rest of the flags. And 0 acts as a placeholder for a different value, if I some day decide to change it.
You can actually see exactly that in the linked code with shift by 0 in the definitions of DYN_OR_EN and DYN_RR_EN macros.
The approach can be extended to multi-bit fields within a word, like in the following (contrived) example
// Bits 0-3 - lower counter, bits 4-7 - upper counter
#define LOWER_0 (0u << 0)
#define LOWER_1 (1u << 0)
#define LOWER_2 (2u << 0)
#define LOWER_3 (3u << 0)
#define UPPER_0 (0u << 4)
#define UPPER_1 (1u << 4)
#define UPPER_2 (2u << 4)
#define UPPER_3 (3u << 4)
unsigned packed_counters = LOWER_2 + UPPER_3; /* or `LOWER_2 | UPPER_3` */
Again, shifts by 0 bits are present purely for visual consistency. As well as shifts of 0 values.
You can actually see exactly that in the linked code with shift by 0 in the definitions of LC_XMIT_N_FTS and LC_XMIT_N_FTS_MASK macros.

Related

GPIO Output Register Bit value not updating

I just started learning about embedded systems and I'm having a bit of trouble with correctly setting up the led pin on my stm32f746ng-discovery board. I am not sure if I am not typecasting correctly or have the wrong address for the pin however, I do believe I have addressed everything correctly and I'm not seeing a value change for the GPIO output data register in the watch window which leads me to believe there might be an issue with my code.
To define the registers and their respective addresses this is the approach I took:
//Referring to STM32F746xx Memory Map and Register Boundary Addresses:
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_OFFSET (0x00020000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + AHB1PERIPH_OFFSET)
#define GPIOI_OFFSET (0x2000UL)
#define GPIOI_BASE (AHB1PERIPH_BASE + GPIOI_OFFSET)
#define RCC_OFFSET (0x3800UL)
#define RCC_BASE (AHB1PERIPH_BASE + RCC_OFFSET)
#define RCC_AHB1EN_R_OFFSET (0x30UL)
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + RCC_AHB1EN_R_OFFSET)) //register
#define MODE_R_OFFSET (0x00UL)
#define GPIOI_MODE_R (*(volatile unsigned int *)(GPIOI_BASE + MODE_R_OFFSET)) //register
#define OD_R_OFFSET (0x14UL)
#define GPIOI_OD_R (*(volatile unsigned int *)(GPIOI_BASE + OD_R_OFFSET)) //register
#define GPIOIEN (1U << 0)
#define PIN_1 (1U << 1)
#define LED_PIN PIN_1
The above hex addresses I located from the stm32f746xx datasheet's memory map/table and RM0385 reference manual for the stm32f74xxx.
The code below is the main function where I try to change the bit value of the GPIOI_OD_R register:
int main(void)
{
/* 1. Enable clock access for GPIOI.*/
/* 1.1 I use the OR operator to only change the first bit instead of the whole 32bit chain. */
RCC_AHB1EN_R |= GPIOIEN;
/* 2. Sets PIN_1 as output.*/
GPIOI_MODE_R |= (1U << 2);
GPIOI_MODE_R &=~(1U << 3);
while(1)
{
/* 3. Sets PIN_1 high */
GPIOI_OD_R |= LED_PIN;
}
}
The problem that I am having is that the bit value for the GPIOI_OD_R register is not updating correctly and gets set to 00 instead of 01 which is the required value for the GPIOI Pin_1 (LED) to be set to the general-purpose output mode.
The above parameters I got from the RM0385 reference manual for the stm32f74xxx which can be seen in the image below:
However, when running the code the GPIOI_MODE_R and the GPIOI_OD_R bit values do not change which can be seen in the image below:
I need the values of the registers to be correct to set the LED PIN high on my stm32f746ng-discovery board.
I tried combining the GPIOI_MODE_R setting operation into a single one: GPIOI_MODE_R = (GPIOI_MODE_R | (1U << 2)) & ~(1U << 3) however that causes the program to loose connection with the debugger.
I am using the STM32CubeIDE with the following MCU GCC Compiler Settings:
Thanks in advance and if have referenced something incorrectly please excuse me im new to embedded systems.
I found the issue and realised that I was addressing the wrong bit value for the GPIOIEN. Instead of looking at the bit address for GPIOIEN with:#define GPIOIEN (1U << 8) I was making the mistake to look at the bit address for GPIOAEN with:#define GPIOIEN (1U << 0).
A super silly mistake from my side however I think it might be a mistake that many beginners like myself may make. The only advice that I can give from what I experienced and the process it took to solve the issue is to try and be extra accurate and properly focus when reading through the various board's references manuals and datasheets. When it comes to solving the issue I would say it is important to stay consistent with your code which makes it much easier during the debugging process because I followed this methodology I was able to trace each srep of my code and compare what I expected the values to be versus what I was actually getting.
The final code solution I have attached below:
//Referring to STM32F746xx Memory Map and Register Boundary Addresses:
#define PERIPH_BASE (0x40000000UL)
#define AHB1PERIPH_OFFSET (0x00020000UL)
#define AHB1PERIPH_BASE (PERIPH_BASE + AHB1PERIPH_OFFSET)
#define GPIOI_OFFSET (0x2000UL)
#define GPIOI_BASE (AHB1PERIPH_BASE + GPIOI_OFFSET)
#define RCC_OFFSET (0x3800UL)
#define RCC_BASE (AHB1PERIPH_BASE + RCC_OFFSET)
#define RCC_AHB1EN_R_OFFSET (0x30UL)
#define RCC_AHB1EN_R (*(volatile unsigned int *)(RCC_BASE + RCC_AHB1EN_R_OFFSET))
#define MODE_R_OFFSET (0x00UL)
#define GPIOI_MODE_R (*(volatile unsigned int *)(GPIOI_BASE + MODE_R_OFFSET))
#define OD_R_OFFSET (0x14UL)
#define GPIOI_OD_R (*(volatile unsigned int *)(GPIOI_BASE + OD_R_OFFSET))
#define GPIOIEN (1U << 8) // updated from (1U << 0)
#define PIN_1 (1U << 1)
#define LED_PIN PIN_1
int main(void)
{
/* 1. Enable clock access for GPIOI.*/
/* 1.1 I use the OR operator to only change the first bit instead of the whole 32bit chain. */
RCC_AHB1EN_R |= GPIOIEN;
/* 2. Sets PIN_1 as output.*/
GPIOI_MODE_R |= (1U << 2);
GPIOI_MODE_R &=~(1U << 3);
while(1)
{
/* 3. Sets PIN_1 high */
GPIOI_OD_R |= LED_PIN;
}
}

Most correct way for bit checking in C

I reading a book "Linux Kernel. Development. Third Edition." by Robert Love.
And in softirq section it's comment next piece of code:
u32 pending;
pending = local_softirq_pending();
if (pending) {
struct softirq_action *h;
/* reset the pending bitmask */
set_softirq_pending(0);
h = softirq_vec;
do {
if (pending & 1) /* STEP 4 */
h->action(h);
h++;
pending >>= 1;
} while (pending);
}
He discribe step by step what happens and most unclear step for me is 4:
If the first bit in pending is set, h->action(h) is called
I have following code to check if bit set like in book:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define BIT_SET(n) ((1) << (n))
#define BIT_CLEAR(n) ~((1) << (n))
int main(void)
{
unsigned char bits = 0x0;
bits |= BIT_SET(1);
if (bits & (1 << 1))
printf("TEST CHECK SET 1\n");
if (bits & 1)
printf("TEST CHECK SET 2\n");
bits &= BIT_CLEAR(1);
if (!(bits >> 1) & 1UL)
printf("BITS UNSET\n");
return 0;
}
compiled with:
gcc main.c -O0 -Wall -Wextra -Werror.
I always check if bit set with this one:
if (bits & (1 << n))
And my code make output like this:
TEST CHECK SET 1
BITS UNSET
Why if (bits & 1) statment is not work?:
So from several option which should I use and what exactly last one check?
if (bit & (1 << n))
if ((bit >> n) & 1)
if (bit & n)
I always check if bit set with this one: if (bits & (1 << n))
This checks n-th bit in place; the code from the book, however, shifts the bit into the least-significant-bit position prior to making the check with bits & 1. In other words, by the time the code reaches the if (bits & 1) the value of bits has already been shifted such that the bit of interest is in 1-s position.
This is similar to your other check
if ((bit >> n) & 1)
except (bit >> n) part is done by performing bit >>= 1 operation n times in a loop.
Note that in order for this code to work correctly bit must be unsigned.
So from several option which should I use and what exactly last one check?
You misinterpreted the last check: it's not checking bit n, it's checking bit against the entire bit pattern of n's binary representation.

Most efficient way to check if flags are set in an integer

I have 11 flags defined as:
#define F1 1
#define F2 2
#define F3 3
#define F4 4
...
#define F11 11
In some function I then create an integer which can include either of those flags, for example:
int a = (1 << F1) | (1 << F5) | (1 << F11) | (1 << F8);
This then gets passed into a function which needs to decode which flags are set in order to set specific bits in specific registers. So my question is, what is the most efficient way to check which flags are set. Right now I have 11 if's like:
void foo(int a)
{
if ((a & (1 << F1)) >> F1) {
// Set bit 5 in register A.
}
if ((a & (1 << F2)) >> F2) {
// Set bit 3 in register V.
}
if ((a & (1 << F3)) >> F3) {
// Set bit 2 in register H.
}
if ((a & (1 << F4)) >> F4) {
// Set bit 1 in register V.
}
// And so on, for all 11 flags.
}
P.S.
This is for an 8-bit microcontroller.
Just use:
typedef enum{
FLAG1 = 1, // or 0x01
FLAG2 = 2,
FLAG3 = 4,
...
FLAG8 = 0x80
} flags;
Then in main just check
if(value & FLAGN)
In C there is no diffrence between 1 and any other number in if statement. It just check if is zero or non-zero number.
And setting is the same:
value = FLAG1 | FLAG2 | FLAG8;
You can also use defines ofc.
And for claryfication, max number of flags for N bit type is N. So you need to have larger type (if compiller supports bigger datatypes) like uint16_t.
C's if statement and logical operators do not make a difference between 1 and other non-zeros (although logical operators produce 1 for true). Therefore, there is no difference between (a & (1 << F3)) >> F3 and a & (1 << F3) in the context of a logical expression: if one evaluates to true, so does the other one, and vice versa. Hence, this should work:
if (a & (1 << F1)) {
// Set bit 5 in register A.
}
Note: I assume you didn't mean to write #define F11 1024, but rather #define F11 10, because you use your Fs as the second operand of <<.

What does "#Define BLABLABLA (1 << 2) mean? [duplicate]

This question already has answers here:
What does '<<' mean in C?
(5 answers)
Closed 9 years ago.
I am reviewing some C code, and found a header file full of defines of the style:
#define BLABLABLABLA (1 << 2)
#define XXXXXXXXXXXX (1 << 3)
#define YYYYYYYYYYYY (1 << 4)
What do they mean? What do they do?
<< is the shift operator in C.
So you define BLABLABLABLABLA by a zero value with a binary 1 shifted by 2 digits to the left.
The resulting value is then :
...00000100
You would normally do this do mask things.
So, say you have one status byte where every bit is a flag.
And if the 3rd bit is set, this means BLABLABLABLABLA, you would do :
int blablaFlag = statusByte & BLABLABLABLABLA;
If this is greater 0, your flag was set.
These defines can be used when storing information (flags) in bits:
#define HAS_SOMETHING (1 << 2)
#define HAS_ANOTHER (1 << 3)
int flags = 0;
if (has_something())
flags |= HAS_SOMETHING;
if (has_another())
flags |= HAS_ANOTHER;
// ... later:
if (flags & HAS_SOMETHING)
do_something();
Using a macro preprocessor directive to set or unset these flags makes the code way more readable than this would:
if (flags & 4) // 4 is 1 lsh 2
do_something();
They are a way of defining constants, using the C preprocessor. So each time you use XXXXXXXXXXXX in your code it will be replaced with 1 << 2 by the preprocessor.
#define simply means that whenever BLABLABLABLA is seen, it's replaced with (1 << 2).
So if you write int x=BLABLABLABLA;, it's as if you wrote int x=(1 << 2);.
<< is the shift left operator.
<< and >> are shift operators, they work on a binary scale.
42 is written 42 in decimal and 101010 in binary.
When you use the operators :
The binary representation of 42 is : 101010
42 << 1 : 101010 is "shifted" to the left, becoming 1010100, thus 84.
42 >> 1 : 101010 is "shifted" to the right, becoming 10101, thus 21.
This is used for flags for readability purposes : It's easier to read 1 << 1, 1 << 2, 1 << 3 than 1, 2, 4.

A C preprocessor macro to pack bitfields into a byte?

I'm getting into micro-controller hacking and while I'm very comfortable with bitwise operators and talking right to the hardware, I'm finding the resulting code very verbose and boilerplate. The higher level programmer in me wants to find an effective but efficient way to clean it up.
For instance, there's a lot of setting flags in registers:
/* Provided by the compiler */
#define SPIE 7
#define SPE 6
#define DORD 5
#define MSTR 5
#define CPOL 4
#define CPHA 3
void init_spi() {
SPCR = (1 << SPE) | (1 << SPIE) | (1 << MSTR) | (1 << SPI2X);
}
Thankfully there are macros that hide actual port IO operations (the left hand side), so it looks like a simple assignment. But all that syntax to me is messy.
Requirements are:
it only has to handle up to 8 bits,
the bit positions must be able to be passed in any order, and
should only require set bits to be passed.
The syntax I'd like is:
SPCR = bits(SPE, SPIE, MSTR, SPI2X);
The best I've come up with so far is a combo macro/function:
#define bits(...) __pack_bits(__VA_ARGS__, -1)
uint8_t __pack_bits(uint8_t bit, ...) {
uint8_t result = 0;
va_list args;
va_start(args, bit);
result |= (uint8_t) (1 << bit);
for (;;) {
bit = (uint8_t) va_arg(args, int);
if (bit > 7)
break;
result |= (uint8_t) (1 << bit);
}
}
This compiles to 32 bytes on my particular architecure and takes 61-345 cycles to execute (depends on how many bits were passed).
Ideally this should be done in preprocessor since the result is a constant, and the output machine instructions shouldbe just an assignment of an 8 bit value to a register.
Can this be done any better?
Yea, redefine the macros ABC as 1 << ABC, and you simplify that. ORing together bit masks is a very common idiom that anyone will recognize. Getting the shift positions out of your face will help a lot.
Your code goes from
#define SPIE 7
#define SPE 6
#define DORD 5
#define MSTR 5
#define CPOL 4
#define CPHA 3
void init_spi() {
SPCR = (1 << SPE) | (1 << SPIE) | (1 << MSTR) | (1 << SPI2X);
}
to this
#define BIT(n) (1 << (n))
#define SPIE BIT(7)
#define SPE BIT(6)
#define DORD BIT(5)
#define MSTR BIT(5)
#define CPOL BIT(4)
#define CPHA BIT(3)
void init_spi() {
SPCR = SPE | SPIE | MSTR | SPI2X;
}
This suggestion does assume that the bit-field definitions are used many times more than there are definitions of them.
I feel like there might be some way to use variadic macros for this, but I can't figure on anything that could easily be used as an expression. Consider, however, creating an array literal inside a function generating your constant:
#define BITS(name, ...) \
char name() { \
char[] bits = { __VA_ARGS__ }; \
char byte = 0, i; \
for (i = 0; i < sizeof(bits); ++i) byte |= (1 << bits[i]); \
return byte; }
/* Define the bit-mask function for this purpose */
BITS(SPCR_BITS, SPE, SPIE, MSTR, SPI2X)
void init_spi() {
SPCR = SPCR_BITS();
}
If your compiler is good, it will see that the entire function is constant at compile-time, and inline the resultant value.
Why not create your own definitions in addition to the pre-defined ones...
#define BIT_TO_MASK(n) (1 << (n))
#define SPIE_MASK BIT_TO_MASK(SPIE)
#define SPE_MASK BIT_TO_MASK(SPE)
#define DORD_MASK BIT_TO_MASK(DORD)
#define MSTR_MASK BIT_TO_MASK(MSTR)
#define CPOL_MASK BIT_TO_MASK(CPOL)
#define CPHA_MASK BIT_TO_MASK(CPHA)
void init_spi() {
SPCR = SPE_MASK | SPIE_MASK | MSTR_MASK | SPI2X_MASK;
}

Resources