I have an 8-bit microcontroller with 100 pins. Each pin belongs to a port with a unique address and each pin has a number from 0 to 7. I want to create a scheme where in the code each pin is a struct that carries the pin's port address and number with it. I have defined a `pin_t` struct in `gpio.h`.
```
/*gpio.h */
typedef enum {INPUT = 0, INPUT_PULLUP = 1, OUTPUT = 2} gpio_mode_t;
typedef enum {LOW = 0, HIGH = 1} gpio_value_t;
typedef struct
{
volatile uint8_t *const port_addr; //const pointer that points to volatile register
const uint8_t pin_number;
} pin_t;
void pin_mode(const pin_t* pin, gpio_mode_t mode);
void digital_write(const pin_t* pin, gpio_value_t value);
```
Then, I have `pins.c` in which all the pin definitions are made. The port address and pin number should not be changed anywhere else in the program.
```
/* pins.c */
#include "gpio.h"
pin_t D1 = {.port_addr = &PORTG, .pin_number = 5};
pin_t D2 = {.port_addr = &PORTE, .pin_number = 0};
/* more definitions below ...*/
```
Then I have `pins.h` that declares each pin `extern`.
```
/*pins.h */
extern pin_t D1;
extern pin_t D2;
/* more below ...*/
```
Such that I in `main.c` can do things like this
```
/* main.c */
#include "pins.h"
int main(void)
{
pin_mode(&D1, OUTPUT);
for(;;) {}
}
```
**Question 1**: As far as I understand it, declaring variables as `extern` in `pins.h` makes them visible to source files that include `pins.h`, and I need not define them again. But to be honest, I'm not sure why I need `extern` in the first place. I get a compiler error if I remove it, saying there are multiple definitions of the pins in `main.o`. And with the same logic, shouldn't the function prototypes in `gpio.h` also be `extern` for my source files to see them?
**Question 2**: Is this the appropriate way to share variables across multiple files for an embedded system?