C pointer for operations

I play with GPIO access on a raspberry Pi, so, of course, the memory is involved.

The idea is that I have a base address: gpios. Depending on what I want to do, I will get to some address beyond this base address and change some bits.

volatile uint32_t* gpios;

In this example, I want to read the boolean value of a pin. There are two registers for this, the first at the address (gpios + GPIO_INPUT_READ_OFFSET)for the first 32 gpios, and the second at the address (gpios + GPIO_INPUT_READ_OFFSET + 4)for the remaining gpios.

I always wrote operations like this:

volatile uint32_t* input = (uint32_t*)
    ((uint32_t)gpios + GPIO_INPUT_READ_OFFSET + 4*(gpio/32));

With gpiojust being the gpio number being processed in the current function.

But I thought, and if I'm not mistaken, it would be quite possible to write like this:

volatile uint32_t* input = gpios + GPIO_INPUT_READ_OFFSET/4 + (gpio/32);

Due to shenanigans pointers.

I like both, but I can’t say what should be preferred over the other.

" " ?

+4
1

IMO C . RPi , GPIO:

0x7E20 0000 | GPFSEL0 GPIO Function Select 0 | 32 | R/W
0x7E20 0004 | GPFSEL1 GPIO Function Select 1 | 32 | R/W
0x7E20 0008 | GPFSEL2 GPIO Function Select 2 | 32 | R/W
0x7E20 000C | GPFSEL3 GPIO Function Select 3 | 32 | R/W
0x7E20 0010 | GPFSEL4 GPIO Function Select 4 | 32 | R/W
0x7E20 0014 | GPFSEL5 GPIO Function Select 5 | 32 | R/W
0x7E20 0018 | - Reserved                     | -  | -
0x7E20 001C | GPSET0 GPIO Pin Output Set 0   | 32 | W
0x7E20 0020 | GPSET1 GPIO Pin Output Set 1   | 32 | W
0x7E20 0024 | - Reserved                     | -  | -
0x7E20 0028 | GPCLR0 GPIO Pin Output Clear 0 | 32 | W
0x7E20 002C | GPCLR1 GPIO Pin Output Clear 1 | 32 | W 
0x7E20 0030 | - Reserved                     | -  | -
0x7E20 0034 | GPLEV0 GPIO Pin Level 0        | 32 | R
0x7E20 0038 | GPLEV1 GPIO Pin Level 1        | 32 | R
....

, , :

typedef struct {
    volatile       uint32_t gpfsel0;
    volatile       uint32_t gpfsel1;
    volatile       uint32_t gpfsel2;
    volatile       uint32_t gpfsel3;
    volatile       uint32_t gpfsel4;
    volatile       uint32_t gpfsel5;
    volatile       uint32_t : 32;
    volatile       uint32_t gpset0;
    volatile       uint32_t gpset1;
    volatile       uint32_t : 32;
    volatile       uint32_t gpclr0;
    volatile       uint32_t gpclr1;
    volatile       uint32_t : 32;
    volatile const uint32_t gplev0;
    volatile const uint32_t gplev1;
    ....
} RPiGpio;

RPiGpio / :

RPiGpio* rPiGpio = (RPiGpio*)(0x7E200000);

rPiGpio->gpclr1 = 0x0001;
uint32_t pins = rPiGpio->gplev0;

GPIO

, gpio, , , , , :

// Change this
typedef struct {
    ....
    volatile const uint32_t gplev0;
    volatile const uint32_t gplev1;
    ....
} RPiGpio;

// To this
typedef struct {
    ....
    volatile const uint32_t gplev[2];
    ....
} RPiGpio;

// Read a pin
bool isPinHigh(unsigned pinNum)
{
    const RPiGpio* rPiGpio = (const RPiGpio*)(0x7E200000);

    return rPiGpio->gplev[pinNum / 32] & (1 << (pinNum % 32));
}

pinNum - GPIO 0-63 ( , Pi, gpio 0 gpio 63).

pinNum / 32 (0 1).

1 << (pinNum % 32) .

& , .

:

. , . volatile , , . Volatile , .

volatile const. (, , , ).

uint32_t : 32;, 32- . - , , .

+3

Source: https://habr.com/ru/post/1653416/


All Articles