From 9d8910af0ae3bbbf64ad50d75e1f7eb83c0a01a5 Mon Sep 17 00:00:00 2001 From: sasha80 Date: Fri, 17 Apr 2026 15:42:14 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=BA=D0=B0.=20=D0=A4=D1=83=D0=BD=D0=BA=D1=86=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=87=D1=82=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=B0=D1=80=D0=B0=D0=BB=D0=BB=D0=B5=D0=BB=D1=8C=D0=BD?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=BE=D1=80=D1=82=D0=B0.=20=D0=9F?= =?UTF-8?q?=D1=80=D0=B8=D0=BC=D0=B5=D1=80=20=D0=B2=20=D0=BA=D0=BE=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BE=D0=BC=20=D0=B4=D0=B0=D0=BD=D0=BD=D1=8B=D0=B5?= =?UTF-8?q?=20=D1=81=20=D0=BF=D0=B0=D1=80=D0=B0=D0=BB=D0=BB=D0=B5=D0=BB?= =?UTF-8?q?=D1=8C=D0=BD=D0=BE=D0=B9=20=D1=88=D0=B8=D0=BD=D1=8B=20=D0=BD?= =?UTF-8?q?=D0=B0=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D1=8F=D1=8E=D1=82=D1=81?= =?UTF-8?q?=D1=8F=20=D0=B2=20stdout?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 4 +- examples/Makefile | 2 +- examples/gpio-interrupt.c | 217 ++++++++++++++++++++++---------------- wiringPi/wiringPi.c | 28 +++++ wiringPi/wiringPi.h | 1 + 5 files changed, 159 insertions(+), 93 deletions(-) diff --git a/.gitignore b/.gitignore index 6a46b85..5b2e83d 100755 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,6 @@ lib*.so.* debian-template/wiringPi debian-template/wiringpi-*.deb gpio/gpio -.idea/ +/.idea/ +/.vscode/ +/debian-template/ diff --git a/examples/Makefile b/examples/Makefile index d43c963..4cb96ef 100755 --- a/examples/Makefile +++ b/examples/Makefile @@ -27,7 +27,7 @@ Q ?= @ endif #DEBUG = -g -O0 -DEBUG = -O3 +DEBUG = -O0 -g CC ?= gcc INCLUDE = -I/usr/local/include CFLAGS = $(DEBUG) -Wall $(INCLUDE) -Winline -pipe $(EXTRA_CFLAGS) diff --git a/examples/gpio-interrupt.c b/examples/gpio-interrupt.c index a078616..fa3028c 100755 --- a/examples/gpio-interrupt.c +++ b/examples/gpio-interrupt.c @@ -1,113 +1,148 @@ -/* Demonstration C GPIO interrupt handling routine for Raspberry Pi - -This is a modified code found at https://github.com/phil-lavin/raspberry-pi-gpio-interrupt - -The program displays a notice whenever you: - -turn on the Raspberry Pi's pin 11 (apply 3.3V), - -turn the pin off. - -This routine uses wiringPi library (follow the installation instructions at wiringpi.com), -and should be compiled with a command: - -gcc source_filename -o executable_filename -lwiringPi - -You must have root privileges to run it - I don't know any workaround yet: - -sudo ./executable_filename - -Then the program displays a notice whenever you turn the GPIO pin 11 on and off. -It runs as an infinite loop and you can cancel it by pressing ctrl-C. +/* Направляет в стандартный вывод данные полученные с + параллельной 8-битной шины Raspberry Pi4. Собирать внутри папки WiringPi/examples + командой make really-all. + Предварительные условия: + - WiringPi должен быть собран из этой версии, в которую добавлена функция digitalReadPins() + ``` + make && make install + ``` + - WiringPi должен быть установлен из того deb-пакета который получен из этой версии + ``` + make debian && dpkg -i debian-template/WiringPi*.deb + ``` */ #include +#include #include #include #include #include -// Which GPIO pin we're using. For this program we'll use physical pin numbers. -#define PIN 27 -// How much time a change must be since the last in order to count as a change -// (in microseconds); allows to avoid generating interrupts on contact bouncing etc. -#define IGNORE_CHANGE_BELOW_USEC 10000 - -// Current state of the pin -static volatile int state; - -// Time of last change -struct timeval last_change; +unsigned int wr_pin = 27; /** Вывод для сигнала записи */ +unsigned int pins[] = { 21, 7, 6, 5, 25, 24, 23, 22 }; /** Выводы для данных */ +const size_t out_buffer_len = 32U; /** Размер выходного буфера */ +const size_t fifo_buffer_len = 4096U; /** Размер буфера ПППУ */ -// Handler for interrupt -void handle(void) { - struct timeval now; - static __uint64_t cnt; - unsigned long diff; - //gettimeofday(&now, NULL); - state = digitalRead(PIN); - printf("-->%d %d\n", ++cnt, state); - return; +struct fifo { + char *buffer; /** Буфер ПППУ */ + size_t len; /** Длина буфера ПППУ */ + size_t wri; /** Указатель записи ПППУ */ + size_t rdi; /** Указатель чтения ПППУ */ +}; - // Time difference in microseconds - diff = (now.tv_sec * 1000000 + now.tv_usec) - (last_change.tv_sec * 1000000 + last_change.tv_usec); - // Filter any changes in intervals shorter than diff (like contact bouncing etc.): - /* - if (diff > IGNORE_CHANGE_BELOW_USEC) { - - // Check whether the last state was on or off: - if (state) { - // Print info to console: - printf("Input goes off\n"); - // You can add some code to do when input goes off here... - } - else { - // Print info to console: - printf("Input goes on\n"); - // Add code to do when input goes on here... - } - - // Change the "state" variable value: - state = !state; - } - */ - // Store the time for last state change: - last_change = now; +void fifo_reset(struct fifo* ff) { + ff->wri = 0U; + ff->rdi = 0U; } + +bool fifo_init(struct fifo* ff, size_t len) { + ff->buffer = malloc(len); + ff->len = len; + fifo_reset(ff); + return ff->buffer != NULL; +} + + +void fifo_uninit(struct fifo* ff, size_t len) { + free(ff->buffer); + ff->buffer = NULL; + fifo_reset(ff); +} + + +bool fifo_is_full(struct fifo *ff) { + return ((ff->wri + 1U) % ff->len) == ff->rdi; +} + + +size_t fifo_available(struct fifo *ff) { + bool v = ff->wri >= ff->rdi; + return (ff->wri - ff->rdi) * v + (ff->wri + ff->len - ff->rdi) * (!v); +} + + +bool fifo_can_write(struct fifo *ff, size_t len) { + return (ff->len - fifo_available(ff)) > len; +} + + +bool fifo_can_read(struct fifo *ff, size_t len) { + return fifo_available(ff) >= len; +} + + +bool fifo_try_read(struct fifo *ff, char* buffer, size_t len) { + if (!fifo_can_read(ff, len)) { + return false; + } + memcpy(buffer, &ff->buffer[ff->rdi], len); + ff->rdi = (ff->rdi + len) % ff->len; + return true; +} + + +bool fifo_try_write(struct fifo *ff, char* buffer, size_t len) { + if (!fifo_can_write(ff, len)) { + return false; + } + memcpy(&ff->buffer[ff->wri], buffer, len); + ff->wri = (ff->wri + len) % ff->len; + return true; +} + + +static struct fifo isr_ff; + + +void isr_handle(void) { + char byte_read = digitalReadPins(pins, sizeof pins / sizeof pins[0]); + fifo_try_write(&isr_ff, &byte_read, 1); +} + + int main(void) { - // Init -- use the physical pin number on RPi P1 connector - if (wiringPiSetup() == -1) - { - printf("ошибка wiringPiSetup()\n"); - exit(1); + + if (!fifo_init(&isr_ff, fifo_buffer_len)) { + perror("не выполнено fifo_init()\n"); + exit(EXIT_FAILURE); } - // Set pin to input in case it's not - pinMode(PIN, INPUT); - pullUpDnControl(PIN, PUD_UP); - - // Time now - gettimeofday(&last_change, NULL); - - // Bind to interrupt - wiringPiISR(PIN, INT_EDGE_RISING, &handle); - - // Get initial state of pin - state = digitalRead(PIN); - - // Feedback for user that the program has started, depending on input state: - if (state) { - printf("Started! Initial state is on\n"); - } - else { - printf("Started! Initial state is off\n"); + if (wiringPiSetup() == -1) { + perror("не выполнено wiringPiSetup()\n"); + exit(EXIT_FAILURE); } - // Waste time but not CPU - for (;;) { - sleep(1); - state = digitalRead(PIN); + /** Сигнал записи */ + pinMode(wr_pin, INPUT); + pullUpDnControl(wr_pin, PUD_UP); + + /** Шина данных 8 бит */ + for (unsigned int i = 0; i < (sizeof pins / sizeof pins[0]); i ++) { + unsigned int pin = pins[i]; + pinMode(pin, INPUT); + pullUpDnControl(pin, PUD_UP); } + + int rc = wiringPiISR(wr_pin, INT_EDGE_RISING, &isr_handle); + if (rc != 0) { + perror("не выполнено wiringPiISR()\n"); + exit(EXIT_FAILURE); + } + char buffer [out_buffer_len]; + while (true) { + bool is_read = fifo_try_read(&isr_ff, buffer, sizeof buffer); + if (is_read) { + fwrite(buffer, 1U, sizeof buffer, stdout); + fflush(stdout); + } + else { + usleep(10000); + } + } + return EXIT_SUCCESS; } diff --git a/wiringPi/wiringPi.c b/wiringPi/wiringPi.c index d387d1a..a9ba72d 100755 --- a/wiringPi/wiringPi.c +++ b/wiringPi/wiringPi.c @@ -2585,6 +2585,34 @@ unsigned int digitalReadByte (void) } +unsigned int digitalReadPins(unsigned int *pins, unsigned int count) +{ + uint32_t i, x ; + uint32_t raw ; + uint32_t data = 0 ; + + FailOnModel5("digitalReadPins"); + + if (wiringPiMode == WPI_MODE_GPIO_SYS) + { + return 0; + } + else + { + raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins + data = 0; + for (i = 0 ; i < count ; ++ i) + { + uint32_t pin = pins[i] ; + x = pinToGpio [pin & 63]; + data |= ((raw & (1 << x)) > 0) << i; + } + } + return data; +} + + + /* * digitalWriteByte2: * digitalReadByte2: diff --git a/wiringPi/wiringPi.h b/wiringPi/wiringPi.h index 07cd258..38a4d73 100755 --- a/wiringPi/wiringPi.h +++ b/wiringPi/wiringPi.h @@ -288,6 +288,7 @@ extern void pwmSetMode (int mode) ; extern void pwmSetRange (unsigned int range) ; extern void pwmSetClock (int divisor) ; extern void gpioClockSet (int pin, int freq) ; +extern unsigned int digitalReadPins (unsigned int *pins, unsigned int count) ; extern unsigned int digitalReadByte (void) ; extern unsigned int digitalReadByte2 (void) ; extern void digitalWriteByte (int value) ;