diff --git a/examples/gpio-interrupt.c b/examples/gpio-interrupt.c index 7ae4479..099ae69 100644 --- a/examples/gpio-interrupt.c +++ b/examples/gpio-interrupt.c @@ -1,27 +1,36 @@ /* Направляет в стандартный вывод данные полученные с параллельной 8-битной шины Raspberry Pi4. Собирать внутри папки WiringPi/examples командой make really-all. + + Использование: + ./gpio-interrupt # только stdout + ./gpio-interrupt /tmp/gpio.log # stdout + лог в файл + ./gpio-interrupt - # только лог в stdout (stderr) + Предварительные условия: - WiringPi должен быть собран из этой версии, в которую добавлена функция digitalReadPins() - ``` - make && make install - ``` - - WiringPi должен быть установлен из того deb-пакета который получен из этой версии - ``` - make debian && dpkg -i debian-template/WiringPi*.deb - ``` +make && make install + +text +- WiringPi должен быть установлен из того deb-пакета который получен из этой версии +make debian && dpkg -i debian-template/WiringPi*.deb + +text */ #include #include #include #include +#include +#include +#include #include #include /* жёлтый д0 -красный такт +красный такт чёрный д1 синий д2 зелёный д3 @@ -31,129 +40,174 @@ 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; /** Размер буфера ПППУ */ - +const size_t fifo_buffer_len = 4096U; /** Размер буфера FIFO */ struct fifo { - char *buffer; /** Буфер ПППУ */ - size_t len; /** Длина буфера ПППУ */ - size_t wri; /** Указатель записи ПППУ */ - size_t rdi; /** Указатель чтения ПППУ */ +char *buffer; /** Буфер FIFO */ +size_t len; /** Длина буфера FIFO */ +size_t wri; /** Указатель записи FIFO */ +size_t rdi; /** Указатель чтения FIFO */ }; - void fifo_reset(struct fifo* ff) { - ff->wri = 0U; - ff->rdi = 0U; +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; +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); +void fifo_uninit(struct fifo* ff) { +free(ff->buffer); +ff->buffer = NULL; +fifo_reset(ff); } - bool fifo_is_full(struct fifo *ff) { - return ((ff->wri + 1U) % ff->len) == ff->rdi; +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 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; +return (ff->len - fifo_available(ff)) > len; } - bool fifo_can_read(struct fifo *ff, size_t len) { - return fifo_available(ff) >= 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; +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; +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; -int c = 0; void isr_handle(void) { - char byte_read = 0x0f & digitalReadPins(pins, sizeof pins / sizeof pins[0]); - fifo_try_write(&isr_ff, &byte_read, 1); +char byte_read = 0x0f & digitalReadPins(pins, sizeof pins / sizeof pins[0]); +fifo_try_write(&isr_ff, &byte_read, 1); } +int main(int argc, char *argv[]) { +FILE *log_file = NULL; +const char *log_path = NULL; -int main(void) { +// Обработка аргументов командной строки +if (argc > 1) { +log_path = argv[1]; - if (!fifo_init(&isr_ff, fifo_buffer_len)) { - perror("не выполнено fifo_init()\n"); - exit(EXIT_FAILURE); - } - - if (wiringPiSetup() == -1) { - perror("не выполнено wiringPiSetup()\n"); - exit(EXIT_FAILURE); - } - - /** Сигнал записи */ - 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); - for (int i = 0; i < sizeof buffer; i ++) { - printf("%02d: %02x\n", i, buffer[i]); - } - fflush(stdout); - } - else { - usleep(10000); - } - } - return EXIT_SUCCESS; +if (strcmp(log_path, "-") == 0) { + // Логировать в stderr (чтобы не мешать stdout) + log_file = stderr; + fprintf(stderr, "=== GPIO Monitor started (logging to stderr) ===\n"); +} else { + // Открываем файл для логирования + log_file = fopen(log_path, "a"); + if (!log_file) { + perror("Ошибка открытия лог-файла"); + exit(EXIT_FAILURE); + } + fprintf(stderr, "=== GPIO Monitor started (logging to %s) ===\n", log_path); + fprintf(log_file, "\n=== Session started: %ld ===\n", (long)time(NULL)); + fflush(log_file); +} +} else { +fprintf(stderr, "=== GPIO Monitor started (stdout only) ===\n"); +} + +// Инициализация FIFO +if (!fifo_init(&isr_ff, fifo_buffer_len)) { +perror("не выполнено fifo_init()\n"); +exit(EXIT_FAILURE); +} + +// Инициализация WiringPi +if (wiringPiSetup() == -1) { +perror("не выполнено wiringPiSetup()\n"); +exit(EXIT_FAILURE); +} + +// Настройка пина записи +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); +} + +fprintf(stderr, "GPIO pins initialized, waiting for interrupts...\n"); + +char buffer[out_buffer_len]; +unsigned long total_bytes = 0; + +while (true) { +bool is_read = fifo_try_read(&isr_ff, buffer, sizeof buffer); +if (is_read) { + total_bytes += sizeof buffer; + + // Логирование в файл или stderr + if (log_file) { + fprintf(log_file, "--- Packet #%lu (%zu bytes) ---\n", + total_bytes / sizeof buffer, sizeof buffer); + for (int i = 0; i < sizeof buffer; i++) { + fprintf(log_file, " [%02d] = 0x%02x (%3d)\n", + i, (unsigned char)buffer[i], (unsigned char)buffer[i]); + } + fflush(log_file); + + // Краткая сводка на экран + fprintf(stderr, "."); // Прогресс-индикатор + if (total_bytes % (32 * 10) == 0) { + fprintf(stderr, " [%lu bytes]\n", total_bytes); + } + fflush(stderr); + } + + // Бинарные данные в stdout для Go-сервера + fwrite(buffer, 1U, sizeof buffer, stdout); + fflush(stdout); + +} else { + usleep(10000); // 10ms задержка, если данных нет +} +} + +// Очистка (теоретически недостижимо, но для порядка) +if (log_file && log_file != stderr) { +fclose(log_file); +} +fifo_uninit(&isr_ff); + +return EXIT_SUCCESS; }