vault backup: 2026-04-08 20:55:42

This commit is contained in:
2026-04-08 20:55:42 +03:00
parent 908a3fd11f
commit fbe3622ced
2 changed files with 0 additions and 0 deletions
+182
View File
@@ -0,0 +1,182 @@
#linux #GPIO #i2c #spi #hardware #userspase #libgpiod
Контроль и управление периферией в Linux
https://habr.com/ru/articles/520488/
---
Устройства в Linux представлены в виде файлов и живут в системной директории: `/dev`
Например :
- Устройства i2c
`/dev/i2c-0`
`/dev/i2c-1`
- Последовательные порты (Виртуальная консоль)
`/dev/ttyUSB0`
- SPI устройства
`/dev/spidev*`
## GPIO Driver
Полезная информация:
https://devdotnet.org/post/rabota-s-gpio-v-linux-chast-6-biblioteka-libgpiod/
Способы управления:
1. Userspace driver -прямое управление
2. Libgpiod - управление через библиотеку (API для Python и C/C++)
3. Python library
#### User Space
Прямой доступ к регистрам, минуя медленные системные вызовы.
Посредством открытия `/dev/mem` и мапирование базового адреса GPIO.
==Подводные камни:==
1. Обход GPIO Subsystem
2. Нет контроля конкуренции (может управлять несколько процессов)
3. Можно сломать драйвер
4. Нет безопасности
Пример работы с GPIO
```cpp title:userspace_gpio_control.cpp
#include <iostream> // вывод сообщений
#include <fcntl.h> // открытие файлов
#include <sys/mman.h> // mmap и munmap
#include <unistd.h> // usleep и close
#include <cstring> // perror
#include <cstdint> // для uint32_t
/*
1. Userspace драйвер GPIO.
Управление GPIO Raspberry Pi через mmap обеспечивает прямой доступ к регистрам периферии,
минуя медленные системные вызовы. Это реализуется через открытие /dev/mem,
мапирование базового адреса GPIO
*/
#define GPIO_BASE 0x3F200000 // физический адрес начала блока регистров GPIO на SoC BCM2835
#define BLOCK_SIZE 4096 // Размер отображ. памяти Регистры GPIO занимают 41 байт, но мы отображаем целую страницу для простоты.
#define TIME_SLEEP 500000 // Время задержки в микросекундах
int main() {
// открытие спец.файла физической памяти. Флаги - чтение и запись + отключение кэширования
int mem_fd = open("/dev/mem", O_RDWR | O_SYNC);
// Если не удалось открыть - вывод ошибки
if (mem_fd < 0) {
perror("open");
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;
}
// Указатель приводится к типу volatile uint32_t*, чтобы:
// Обращаться к памяти 32-битными словами.
// volatile запрещает компилятору оптимизировать обращения, т.к. значения регистров могут меняться аппаратно.
volatile uint32_t* gpio = (volatile uint32_t*)gpio_map;
// 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);
}
```
---
#### libgpiod - library control
Library General Purpose Input/Output device - Библиотека и набор утилит в Linux для управления пинами GPIO (ввод/вывод общего назначения) через символьные устройства (`/dev/gpiochip*`) или контроллеры GPIO
Состав библиотеки:
- **gpiodetect**
- **gpioinfo**
- **gpioset**
- **gpioget**
Установка:
``` bash
sudo apt-get update
sudo apt-get install -y libgpiod-dev libgpiod-doc gpiod
```
Проверка корректности установки:
``` bash
pkg-config --cflags --libs libgpiod
```
Компиляция:
``` bash
g++ -o gpio_control gpio_control.cpp -lgpiod
```
Пример работы с GPIO
``` cpp title:libgpiod_control.cpp
```
---
## I2C Bus. Integrates
Представление:
- `/sys/bus/i2c/devices/` - управление конфигурацией устройств через драйверы ядра
- `/dev/i2c-0` - прямой доступ к шине через userspace
По умолчанию шина отключена.
Включить можно следующими способами:
1 - Через raspi - config
``` bash
sudo raspi-config
```
2 - корректировкой `/boot/firmware/config.txt`
раскомментировать параметр `dtparam=i2c_arm=on`
Затем в устройство должно появиться в `/dev` как `i2c-1`
Набор утилит для работы с шиной i2c: `i2c-tools`
Установка:
```bash
sudo apt-get install i2c-tools
```
Состав библиотеки:
- **i2cdetect**
- **i2cdump**
- **i2cget**
- **i2cset**
## SPI
E
Команды для работы:
```bash
```
## Commands
Система:
`vcgencmd get_config int` - параметры, которые передает GPU
`cat /etc/os-release` - просмотр версии системы