vault backup: 2026-05-01 17:07:28
This commit is contained in:
@@ -1,373 +0,0 @@
|
||||
#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 Output from userspace
|
||||
```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
|
||||
```
|
||||
|
||||
##### Example GPIO Output
|
||||
``` cpp title:libgpiod_control.cpp
|
||||
#include <gpiod.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GPIO_CHIP "gpiochip0"
|
||||
#define GPIO_PIN 17
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct gpiod_chip *chip;
|
||||
struct gpiod_line *line;
|
||||
int ret;
|
||||
// Open the GPIO chip
|
||||
chip = gpiod_chip_open_by_name(GPIO_CHIP);
|
||||
if (!chip) {
|
||||
perror("gpiod_chip_open_by_name");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Get the GPIO line
|
||||
line = gpiod_chip_get_line(chip, GPIO_PIN);
|
||||
if (!line) {
|
||||
perror("gpiod_chip_get_line");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Request the line as output
|
||||
ret = gpiod_line_request_output(line, "gpio-control", 0);
|
||||
if (ret < 0) {
|
||||
perror("gpiod_line_request_output");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 50; i++){
|
||||
// Set GPIO to HIGH
|
||||
ret = gpiod_line_set_value(line, 1);
|
||||
if (ret < 0) {
|
||||
perror("gpiod_line_set_value");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("GPIO 17 set to HIGH\n");
|
||||
sleep(2);
|
||||
|
||||
// Set GPIO to LOW
|
||||
ret = gpiod_line_set_value(line, 0);
|
||||
if (ret < 0) {
|
||||
perror("gpiod_line_set_value");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("GPIO 17 set to LOW\n");
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
// Release resources
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
Запуск программы (находясь в папке)
|
||||
``` bash
|
||||
./gpio_control
|
||||
```
|
||||
|
||||
##### Example GPIO Input
|
||||
```c
|
||||
|
||||
#include <gpiod.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
const char* chipname = "gpiochip0";
|
||||
unsigned int line_num = 27;
|
||||
|
||||
gpiod_chip* chip = gpiod_chip_open_by_name(chipname);
|
||||
if (!chip) {
|
||||
perror("chip open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
gpiod_line* line = gpiod_chip_get_line(chip, line_num);
|
||||
if (!line) {
|
||||
perror("get line");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Запрос линии как input с событием
|
||||
if(gpiod_line_request_falling_edge_events(line,"button") < 0) {
|
||||
perror("request events");
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Waiting for button press..." << std::endl;
|
||||
|
||||
while (true) {
|
||||
int ret = gpiod_line_event_wait(line, NULL);
|
||||
if (ret < 0) {
|
||||
perror("event wait");
|
||||
break;
|
||||
}
|
||||
if (ret == 1) {
|
||||
struct gpiod_line_event event;
|
||||
gpiod_line_event_read(line, &event);
|
||||
std::cout << "Button pressed!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
gpiod_line_release(line);
|
||||
gpiod_chip_close(chip);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Запуск компиляции
|
||||
```bash
|
||||
g++ -std=c++11 gpio_button.cpp -lgpiod -o gpio_button
|
||||
```
|
||||
|
||||
##### Example GPIO Led Button Contol
|
||||
Пример управления светодиодом по кнопке.
|
||||
```c++
|
||||
#include <gpiod.h>
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GPIO_CHIP "gpiochip0"
|
||||
#define LED_PIN 17
|
||||
#define BUTTON_PIN 27
|
||||
|
||||
// Function Prototype
|
||||
int system_init();
|
||||
int button_control();
|
||||
// int led_controller();
|
||||
|
||||
// General Function
|
||||
int main() {
|
||||
button_control();
|
||||
}
|
||||
|
||||
|
||||
int button_control (){
|
||||
// value`s to led control
|
||||
int led;
|
||||
bool led_state = false;
|
||||
|
||||
gpiod_chip* chip = gpiod_chip_open_by_name(GPIO_CHIP);
|
||||
if (!chip) {
|
||||
perror("chip open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
gpiod_line* button_line = gpiod_chip_get_line(chip, BUTTON_PIN);
|
||||
if (!button_line) {
|
||||
perror("get line");
|
||||
return 1;
|
||||
}
|
||||
|
||||
gpiod_line* led_line = gpiod_chip_get_line(chip, LED_PIN);
|
||||
if (!led_line) {
|
||||
perror("get led line");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Request the line as output
|
||||
led = gpiod_line_request_output(led_line, "gpio-control", 0);
|
||||
if (led < 0) {
|
||||
perror("gpiod_line_request_output");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Запрос линии как input с событием
|
||||
if (gpiod_line_request_falling_edge_events(button_line, "button") < 0) {
|
||||
perror("request events");
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::cout << "Waiting for button press..." << std::endl;
|
||||
|
||||
while (true) {
|
||||
int ret = gpiod_line_event_wait(button_line, NULL);
|
||||
if (ret < 0) {
|
||||
perror("event wait");
|
||||
break;
|
||||
}
|
||||
|
||||
if (ret == 1) {
|
||||
struct gpiod_line_event event;
|
||||
gpiod_line_event_read(button_line, &event);
|
||||
std::cout << "Button pressed!" << std::endl;
|
||||
led_state = !led_state;
|
||||
|
||||
if(led_state){
|
||||
// Set GPIO LED to HIGH
|
||||
led = gpiod_line_set_value(led_line, 1);
|
||||
if (led < 0) {
|
||||
perror("gpiod_line_set_value");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GPIO 17 set to HIGH\n");
|
||||
}
|
||||
else{
|
||||
// Set GPIO to LOW
|
||||
led = gpiod_line_set_value(led_line, 0);
|
||||
if (led < 0) {
|
||||
perror("gpiod_line_set_value");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
printf("GPIO 17 set to LOW\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
gpiod_line_release(button_line);
|
||||
gpiod_chip_close(chip);
|
||||
return 0;
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
Запуск компиляции
|
||||
```bash
|
||||
g++ -std=c++11 gpio_button.cpp -lgpiod -o gpio_button
|
||||
```
|
||||
@@ -1,52 +0,0 @@
|
||||
#DeviceTree #Boot #Linux
|
||||
## Hardware starting. Процесс запуска и инициализации
|
||||
Далее описан процесс запуска и инициализации оборудования следующих уровней:
|
||||
Firmware layer
|
||||
Hardware descriptional layer
|
||||
kernal initialization stage
|
||||
|
||||
1. Power On
|
||||
2. Starting GPU on SoC
|
||||
3. ROM внутри Video Core начинает выполнение.
|
||||
4. GPU читает SD карту (загружаются)
|
||||
Файлы расположены в `/boot или /firmware/boot`
|
||||
1. ==bootcode.bin== - FirstStage Bootloader.
|
||||
Он инициализирует SDRAM и загружает прошивку start.elf
|
||||
2. ==start.elf== - Second Stage Bootloader
|
||||
Инициализирует систему и загружает ядро линукс, управляет памятью
|
||||
3. ==config.txt== - файл конфигурации
|
||||
Основной конфигурационный файл системы, считываемый GPU используемый для настройки оборудования
|
||||
4. ==cmdline.txt==
|
||||
файл конфигурации, передаваемый ядру линукс при загрузке
|
||||
5. ==device tree== - подгружается дерево устройств. (файлы *dtb)
|
||||
Передается в kernel. Хранятся в каталоге boot / firmware / overlays
|
||||
5. Только после этого GPU включает ARM CPU
|
||||
6. ARM начинает выполнение linux kernal
|
||||
|
||||
## Device tree - Описание аппаратной конфигурации.
|
||||
[Device Tree wiki](https://www.altlinux.org/Device_Tree)
|
||||
Device Tree — это **описание аппаратной конфигурации конкретной платы**.
|
||||
Применяется GPU до запуска ядра.
|
||||
Device Tree Overlays - фрагмент device tree, или слой абстракции который:
|
||||
добавляет новое устройство
|
||||
включает отключенный контроллер
|
||||
меняет параметры существующего узла
|
||||
|
||||
Пример изменения конфигурации DT без перекомпиляции ядра
|
||||
Открыть config.txt и добавить `dtoverlay=i2c-rtc,ds3231`
|
||||
|
||||
Что происходит:
|
||||
1. GPU загрузит основной DTB
|
||||
2. GPU применит overlay
|
||||
3. GPU передаст модифицированный DT ядру
|
||||
4. Ядро увидит новое устройство
|
||||
5. Драйвер RTC автоматически загрузится
|
||||
|
||||
Если удалить узел устройства (например SPI) из Device Tree то ядро просто не создаст SPI контроллер.
|
||||
|
||||
[[Linux - Commands]]
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,306 +0,0 @@
|
||||
#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 Output from userspace
|
||||
```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
|
||||
```
|
||||
|
||||
##### Example GPIO Output
|
||||
``` cpp title:libgpiod_control.cpp
|
||||
#include <gpiod.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define GPIO_CHIP "gpiochip0"
|
||||
#define GPIO_PIN 17
|
||||
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
struct gpiod_chip *chip;
|
||||
struct gpiod_line *line;
|
||||
int ret;
|
||||
// Open the GPIO chip
|
||||
chip = gpiod_chip_open_by_name(GPIO_CHIP);
|
||||
if (!chip) {
|
||||
perror("gpiod_chip_open_by_name");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Get the GPIO line
|
||||
line = gpiod_chip_get_line(chip, GPIO_PIN);
|
||||
if (!line) {
|
||||
perror("gpiod_chip_get_line");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
// Request the line as output
|
||||
ret = gpiod_line_request_output(line, "gpio-control", 0);
|
||||
if (ret < 0) {
|
||||
perror("gpiod_line_request_output");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 50; i++){
|
||||
// Set GPIO to HIGH
|
||||
ret = gpiod_line_set_value(line, 1);
|
||||
if (ret < 0) {
|
||||
perror("gpiod_line_set_value");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("GPIO 17 set to HIGH\n");
|
||||
sleep(2);
|
||||
|
||||
// Set GPIO to LOW
|
||||
ret = gpiod_line_set_value(line, 0);
|
||||
if (ret < 0) {
|
||||
perror("gpiod_line_set_value");
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
printf("GPIO 17 set to LOW\n");
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
// Release resources
|
||||
gpiod_chip_close(chip);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
```
|
||||
|
||||
Запуск программы (находясь в папке)
|
||||
``` bash
|
||||
./gpio_control
|
||||
```
|
||||
|
||||
##### Example GPIO Input
|
||||
```c
|
||||
|
||||
#include <gpiod.h>
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
const char* chipname = "gpiochip0";
|
||||
unsigned int line_num = 27;
|
||||
|
||||
gpiod_chip* chip = gpiod_chip_open_by_name(chipname);
|
||||
if (!chip) {
|
||||
perror("chip open");
|
||||
return 1;
|
||||
}
|
||||
|
||||
gpiod_line* line = gpiod_chip_get_line(chip, line_num);
|
||||
if (!line) {
|
||||
perror("get line");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Запрос линии как input с событием
|
||||
if(gpiod_line_request_falling_edge_events(line,"button") < 0) {
|
||||
perror("request events");
|
||||
return 1;
|
||||
}
|
||||
std::cout << "Waiting for button press..." << std::endl;
|
||||
|
||||
while (true) {
|
||||
int ret = gpiod_line_event_wait(line, NULL);
|
||||
if (ret < 0) {
|
||||
perror("event wait");
|
||||
break;
|
||||
}
|
||||
if (ret == 1) {
|
||||
struct gpiod_line_event event;
|
||||
gpiod_line_event_read(line, &event);
|
||||
std::cout << "Button pressed!" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
gpiod_line_release(line);
|
||||
gpiod_chip_close(chip);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
Запуск компиляции
|
||||
```bash
|
||||
g++ -std=c++11 gpio_button.cpp -lgpiod -o gpio_button
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 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
|
||||
|
||||
Команды для работы:
|
||||
```bash
|
||||
|
||||
```
|
||||
|
||||
|
||||
## Commands
|
||||
Система:
|
||||
`vcgencmd get_config int` - параметры, которые передает GPU
|
||||
`cat /etc/os-release` - просмотр версии системы
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user