From c935b90866a1fda5cbdaaeb0d053e9909a4cb621 Mon Sep 17 00:00:00 2001 From: embeddev Date: Wed, 4 Mar 2026 21:27:43 +0300 Subject: [PATCH] vault backup: 2026-03-04 21:27:43 --- Linux/Programm/GPIO Kernel control.md | 82 +++++++-------------------- 1 file changed, 20 insertions(+), 62 deletions(-) diff --git a/Linux/Programm/GPIO Kernel control.md b/Linux/Programm/GPIO Kernel control.md index 95547c7..ded6062 100644 --- a/Linux/Programm/GPIO Kernel control.md +++ b/Linux/Programm/GPIO Kernel control.md @@ -1,71 +1,29 @@ -#include // вывод сообщений -#include // открытие файлов -#include // mmap и munmap -#include // usleep и close -#include // perror -#include // для uint32_t +#include -/* -1. Userspace драйвер GPIO. -Управление GPIO Raspberry Pi через mmap обеспечивает прямой доступ к регистрам периферии, -минуя медленные системные вызовы. Это реализуется через открытие /dev/mem, -мапирование базового адреса GPIO -*/ +void main() { + struct gpiod_chip *chip; + struct gpiod_line *line; + int req, value; -#define GPIO_BASE 0x3F200000 // физический адрес начала блока регистров GPIO на SoC BCM2835 -#define BLOCK_SIZE 4096 // Размер отображ. памяти Регистры GPIO занимают 41 байт, но мы отображаем целую страницу для простоты. -#define TIME_SLEEP 500000 // Время задержки в микросекундах + chip = gpiod_chip_open("/dev/gpiochip0"); + if (!chip) + return -1; -int main() { - // открытие спец.файла физической памяти. Флаги - чтение и запись + отключение кэширования - int mem_fd = open("/dev/mem", O_RDWR | O_SYNC); - // Если не удалось открыть - вывод ошибки - if (mem_fd < 0) { - perror("open"); - return 1; + line = gpiod_chip_get_line(chip, 3); + if (!line) { + gpiod_chip_close(chip); + return -1; } - /* - Отображение памяти регистров в виртуальное адресное пространство - mmap создаёт отображение физической памяти, начиная с адреса GPIO_BASE, размером BLOCK_SIZE, в виртуальную память процесса. - NULL – ядро само выбирает адрес для отображения. - 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; + req = gpiod_line_request_input(line, "gpio_state"); + if (req) { + gpiod_chip_close(chip); + return -1; } - // Указатель приводится к типу volatile uint32_t*, чтобы: - // Обращаться к памяти 32-битными словами. - // volatile запрещает компилятору оптимизировать обращения, т.к. значения регистров могут меняться аппаратно. - volatile uint32_t* gpio = (volatile uint32_t*)gpio_map; + value = gpiod_line_get_value(line); - // GPIO17 = бит 21 в GPFSEL1 - gpio[1] &= ~(7 << 21); // очистить - gpio[1] |= (1 << 21); // output - - while (true) { - gpio[7] = (1 << 17); // set - usleep(TIME_SLEEP); - gpio[10] = (1 << 17); // clear - usleep(TIME_SLEEP); - } - // освобождение ресурсов, при выходе - munmap(gpio_map, BLOCK_SIZE); - close(mem_fd); -} + printf("GPIO value is: %d\n", value); + gpiod_chip_close(chip); +} \ No newline at end of file