Конкретный код, который вы разместили, не имеет особого смысла.Но в общем случае вы должны сделать что-то вроде этого, чтобы обрабатывать несколько аппаратных периферийных устройств на одном чипе:
#define PORTF 0x40025000ul
...
#define GPIO_PORT_DATA(base) (*((volatile unsigned long *)(base + 0x3FCul)))
#define GPIO_PORT_DIR(base) (*((volatile unsigned long *)(base + 0x400ul)))
#define GPIO_PORT_DEN(base) (*((volatile unsigned long *)(base + 0x51Cul)))
Учитывая, что все периферийные устройства имеют одинаковое отображение памяти, теперь вы можете написать один драйверкоторый может обрабатывать несколько периферийных устройств.GPIO может быть не лучшим примером, так как написание слоев абстракции поверх GPIO обычно просто добавляет беспорядок.Но теоретически у нас мог бы быть этот драйвер:
void gpio_set (volatile unsigned long* port, uint8_t pin);
...
gpio_set (PORTF, 5);
Где gpio
не знает, с каким конкретным портом он работает, он выполняет ту же самую работу независимо от доступа к макросам.
Это распространенный способ написания драйверов для таких вещей, как SPI, UART, CAN, ADC и т. Д., Где у вас может быть несколько идентичных периферийных устройств на кристалле и вы хотите, чтобы один и тот же код обрабатывал их все, без повторения кода.
Недостатком является незначительная часть накладных расходов на выполнение, поскольку адрес должен вычисляться во время выполнения.