mirror of
https://github.com/EmbedDevIOT/obsidian-vault-.git
synced 2026-11-06 03:53:26 +03:00
vault backup: 2026-03-04 21:27:43
This commit is contained in:
@@ -1,71 +1,29 @@
|
|||||||
#include <iostream> // вывод сообщений
|
#include <libgpiod>
|
||||||
#include <fcntl.h> // открытие файлов
|
|
||||||
#include <sys/mman.h> // mmap и munmap
|
|
||||||
#include <unistd.h> // usleep и close
|
|
||||||
#include <cstring> // perror
|
|
||||||
#include <cstdint> // для uint32_t
|
|
||||||
|
|
||||||
/*
|
void main() {
|
||||||
1. Userspace драйвер GPIO.
|
struct gpiod_chip *chip;
|
||||||
Управление GPIO Raspberry Pi через mmap обеспечивает прямой доступ к регистрам периферии,
|
struct gpiod_line *line;
|
||||||
минуя медленные системные вызовы. Это реализуется через открытие /dev/mem,
|
int req, value;
|
||||||
мапирование базового адреса GPIO
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define GPIO_BASE 0x3F200000 // физический адрес начала блока регистров GPIO на SoC BCM2835
|
chip = gpiod_chip_open("/dev/gpiochip0");
|
||||||
#define BLOCK_SIZE 4096 // Размер отображ. памяти Регистры GPIO занимают 41 байт, но мы отображаем целую страницу для простоты.
|
if (!chip)
|
||||||
#define TIME_SLEEP 500000 // Время задержки в микросекундах
|
return -1;
|
||||||
|
|
||||||
int main() {
|
line = gpiod_chip_get_line(chip, 3);
|
||||||
// открытие спец.файла физической памяти. Флаги - чтение и запись + отключение кэширования
|
if (!line) {
|
||||||
int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
|
gpiod_chip_close(chip);
|
||||||
// Если не удалось открыть - вывод ошибки
|
return -1;
|
||||||
if (mem_fd < 0) {
|
|
||||||
perror("open");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
req = gpiod_line_request_input(line, "gpio_state");
|
||||||
Отображение памяти регистров в виртуальное адресное пространство
|
if (req) {
|
||||||
mmap создаёт отображение физической памяти, начиная с адреса GPIO_BASE, размером BLOCK_SIZE, в виртуальную память процесса.
|
gpiod_chip_close(chip);
|
||||||
NULL – ядро само выбирает адрес для отображения.
|
return -1;
|
||||||
BLOCK_SIZE – количество байт.
|
|
||||||
PROT_READ | PROT_WRITE – разрешено чтение и запись.
|
|
||||||
MAP_SHARED – изменения видны другим процессам и синхронизируются с файлом (важно для доступа к реальной памяти).
|
|
||||||
mem_fd – файловый дескриптор /dev/mem.
|
|
||||||
GPIO_BASE – смещение в файле (физический адрес).
|
|
||||||
*/
|
|
||||||
void* gpio_map = mmap(
|
|
||||||
NULL,
|
|
||||||
BLOCK_SIZE,
|
|
||||||
PROT_READ | PROT_WRITE,
|
|
||||||
MAP_SHARED,
|
|
||||||
mem_fd,
|
|
||||||
GPIO_BASE
|
|
||||||
);
|
|
||||||
|
|
||||||
if (gpio_map == MAP_FAILED) {
|
|
||||||
perror("mmap");
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Указатель приводится к типу volatile uint32_t*, чтобы:
|
value = gpiod_line_get_value(line);
|
||||||
// Обращаться к памяти 32-битными словами.
|
|
||||||
// volatile запрещает компилятору оптимизировать обращения, т.к. значения регистров могут меняться аппаратно.
|
|
||||||
volatile uint32_t* gpio = (volatile uint32_t*)gpio_map;
|
|
||||||
|
|
||||||
// GPIO17 = бит 21 в GPFSEL1
|
printf("GPIO value is: %d\n", value);
|
||||||
gpio[1] &= ~(7 << 21); // очистить
|
|
||||||
gpio[1] |= (1 << 21); // output
|
|
||||||
|
|
||||||
while (true) {
|
gpiod_chip_close(chip);
|
||||||
gpio[7] = (1 << 17); // set
|
|
||||||
usleep(TIME_SLEEP);
|
|
||||||
gpio[10] = (1 << 17); // clear
|
|
||||||
usleep(TIME_SLEEP);
|
|
||||||
}
|
}
|
||||||
// освобождение ресурсов, при выходе
|
|
||||||
munmap(gpio_map, BLOCK_SIZE);
|
|
||||||
close(mem_fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user