From 4afca6a6808ef10a1616757b95359ffc3cc25676 Mon Sep 17 00:00:00 2001 From: qnology Date: Wed, 9 Sep 2026 18:32:02 -0700 Subject: [PATCH] Do not re-open the SPI handle on every module_init() RaspberryPi.module_init() calls self.SPI.open(0, 0) unconditionally. spidev's open() does not close an existing handle, so every call after the first leaks one /dev/spidev0.0 file descriptor. This is reachable from the documented API. Switching a panel between 4Gray and 1Gray requires calling init(mode) again, and the bundled example does exactly that: epd_3in7_test.py calls init(0), init(1), then init(0), with a single module_exit() at the end, leaking two descriptors per run. A long-running program that redraws periodically hits the process NOFILE limit. Measured on a Pi 3B refreshing an epd3in7 once a minute: 1024 descriptors held, 1012 of them spidev, after 16.7 hours. Past that the process cannot open a socket either, so unrelated network calls start failing with EINVAL. Fixed with the same Flag guard SunriseX3.module_init() already uses in this file, and reset in module_exit() so a genuine teardown still re-opens. Co-Authored-By: Claude Opus 5 --- .../python/lib/waveshare_epd/epdconfig.py | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epdconfig.py b/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epdconfig.py index b39025263..58288d894 100644 --- a/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epdconfig.py +++ b/RaspberryPi_JetsonNano/python/lib/waveshare_epd/epdconfig.py @@ -47,6 +47,7 @@ class RaspberryPi: PWR_PIN = 18 MOSI_PIN = 10 SCLK_PIN = 11 + Flag = 0 def __init__(self): import spidev @@ -139,15 +140,18 @@ def module_init(self, cleanup=False): self.DEV_SPI.DEV_Module_Init() else: - # SPI device, bus = 0, device = 0 - self.SPI.open(0, 0) - self.SPI.max_speed_hz = 4000000 - self.SPI.mode = 0b00 + if self.Flag == 0: + self.Flag = 1 + # SPI device, bus = 0, device = 0 + self.SPI.open(0, 0) + self.SPI.max_speed_hz = 4000000 + self.SPI.mode = 0b00 return 0 def module_exit(self, cleanup=False): logger.debug("spi end") self.SPI.close() + self.Flag = 0 self.GPIO_RST_PIN.off() self.GPIO_DC_PIN.off()