connectionPi在树莓派的第4版上不起作用

时间:2019-11-08 15:46:20

标签: raspberry-pi wiringpi

我有一个RPi4。

基于此link,我需要具有2.52的gpio版本才能在此设备上正常工作。

我已经做到了:

# cd /tmp
# wget https://project-downloads.drogon.net/wiringpi-latest.deb
# sudo dpkg -i wiringpi-latest.deb
# gpio -v
  gpio version: 2.46

此外,写入GPIO无效,引导后所有端口均为逻辑1。

并且git.drogon.net不可用。

如果我需要编译依赖此库的软件,该怎么办??

更新

我已按照stevieb的建议克隆了this存储库。 它还有pull请求支持PI4板。

但是即使应用了该补丁,我也无法控制PI4的输出引脚:

首先获取引脚的当前状态:

# gpio readall
 +-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |   IN | 1 |  7 || 8  | 1 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 1 | 11 || 12 | 1 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 1 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 1 | 15 || 16 | 1 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 1 | ALT0 | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 1 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 1 | 21 || 22 | 1 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 1 | 23 || 24 | 1 | ALT4 | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 1 | ALT5 | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 1 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 1 | 35 || 36 | 1 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 1 | 37 || 38 | 1 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 1 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+

然后将pin7设置为输出并检查结果:

# gpio mode 7 out
# gpio readall
 +-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |  OUT | 1 |  7 || 8  | 1 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 1 | 11 || 12 | 1 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 1 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 1 | 15 || 16 | 1 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 1 | ALT0 | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 1 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 1 | 21 || 22 | 1 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 1 | 23 || 24 | 1 | ALT4 | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 1 | ALT5 | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 1 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 1 | 35 || 36 | 1 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 1 | 37 || 38 | 1 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 1 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+

然后将0写入pin7并检查结果:

# gpio write 7 0
# gpio readall
 +-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 |     |     |    3.3v |      |   |  1 || 2  |   |      | 5v      |     |     |
 |   2 |   8 |   SDA.1 |   IN | 1 |  3 || 4  |   |      | 5v      |     |     |
 |   3 |   9 |   SCL.1 |   IN | 1 |  5 || 6  |   |      | 0v      |     |     |
 |   4 |   7 | GPIO. 7 |  OUT | 1 |  7 || 8  | 1 | IN   | TxD     | 15  | 14  |
 |     |     |      0v |      |   |  9 || 10 | 1 | IN   | RxD     | 16  | 15  |
 |  17 |   0 | GPIO. 0 |   IN | 1 | 11 || 12 | 1 | IN   | GPIO. 1 | 1   | 18  |
 |  27 |   2 | GPIO. 2 |   IN | 1 | 13 || 14 |   |      | 0v      |     |     |
 |  22 |   3 | GPIO. 3 |   IN | 1 | 15 || 16 | 1 | IN   | GPIO. 4 | 4   | 23  |
 |     |     |    3.3v |      |   | 17 || 18 | 1 | ALT0 | GPIO. 5 | 5   | 24  |
 |  10 |  12 |    MOSI |   IN | 1 | 19 || 20 |   |      | 0v      |     |     |
 |   9 |  13 |    MISO |   IN | 1 | 21 || 22 | 1 | IN   | GPIO. 6 | 6   | 25  |
 |  11 |  14 |    SCLK |   IN | 1 | 23 || 24 | 1 | ALT4 | CE0     | 10  | 8   |
 |     |     |      0v |      |   | 25 || 26 | 1 | IN   | CE1     | 11  | 7   |
 |   0 |  30 |   SDA.0 |   IN | 1 | 27 || 28 | 1 | IN   | SCL.0   | 31  | 1   |
 |   5 |  21 | GPIO.21 |   IN | 1 | 29 || 30 |   |      | 0v      |     |     |
 |   6 |  22 | GPIO.22 |   IN | 1 | 31 || 32 | 1 | ALT5 | GPIO.26 | 26  | 12  |
 |  13 |  23 | GPIO.23 |   IN | 1 | 33 || 34 |   |      | 0v      |     |     |
 |  19 |  24 | GPIO.24 |   IN | 1 | 35 || 36 | 1 | IN   | GPIO.27 | 27  | 16  |
 |  26 |  25 | GPIO.25 |   IN | 1 | 37 || 38 | 1 | IN   | GPIO.28 | 28  | 20  |
 |     |     |      0v |      |   | 39 || 40 | 1 | IN   | GPIO.29 | 29  | 21  |
 +-----+-----+---------+------+---+----++----+---+------+---------+-----+-----+
 | BCM | wPi |   Name  | Mode | V | Physical | V | Mode | Name    | wPi | BCM |
 +-----+-----+---------+------+---+---Pi 4+--+---+------+---------+-----+-----+

您可以看到每个引脚都处于逻辑状态1。用电压表对其进行测量也可以确认这一点。 有谁知道如何修改connectionPiPi库以能够正确设置输出值?

谢谢

4 个答案:

答案 0 :(得分:0)

Gordon abandoned前一段时间是connectionPi的开放源代码端,并且完全删除了对其的访问。

自那时以来,我已经多次与他联系,但尚未收到任何回复。我什至要求获得对他所做更改的付费访问权,以便我自己的包装器软件可以继续工作。

显然,您必须有权访问旧版本的源代码并自行对其进行修改。 v2.46的this 'fork'可以作为更改的基础。

答案 1 :(得分:0)

按照戈登在this link中所说的做,它再次起作用:

cd /tmp
wget https://project-downloads.drogon.net/wiringpi-latest.deb
sudo dpkg -i wiringpi-latest.deb

答案 2 :(得分:0)

Raspberry 4的connectionPi版本2.52(以及等效的GPIO shell命令)有很大帮助,但不能正确实现pullUpDnControl()。结果,输入引脚无法设置为使用内部上拉/下拉电阻。

使用GPIO / BCM引脚26进行了测试

sudo raspi-gpio get | grep "GPIO 26"

shell命令。

试图通过以下方式设置上拉/下拉:

pullUpDnControl(26, PUD_DOWN);

pullUpDnControl(26, PUD_UP);

wiringPiSetupGpio();

在C中进行WiringPi设置。

使用“ raspi-gpio” shell命令未报告更改。

由于这个问题对我来说是静态安装失败,所以我没有完全放弃connectionPi,而是实施了一个解决方案。由于我无法使等效的GPIO shell命令正常工作(出于相同的原因(因为它是connectioningPi套件的一部分)),但是Python得以维护并正常工作,因此我将等效的Python引脚设置代码嵌入C中,并认为它可能对某人有用(使connectionPi通过Raspberry Pi 4正常工作)。

对于那些可能会觉得有用的人,这里是测试代码。 3-LED Cylon。 LED的一端接地(电阻缓冲(200OHM)),另一端则连接到不同的引脚(16、20和21)。一端接地,另一端26号。按下开关时,Cylon显示屏会变成3个LED的眩光,直到释放开关为止。引脚号在BCM系列中,由外壳程序命令“ gpio readall”显示。

/* 3-LED Cylon testbed. Embedded Python GPIO pin setup code
 * as a workaround to wiringPi v2.52 pullUpDnControl() bug.
 * Send setup code to Python's stdin, as a short-lived child process.
 * Sends Python equivalent to pullUpDnControl(26, PUD_UP); keeping
 * the pin number (26) as a C #define.
 * Use as needed.
 * Alen Shapiro June 2020
 */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wiringPi.h>

/* on */
#define FIX_GPIO    1   // replace pullUpDnControl on Raspberry Pi 4. Use Python as GPIO in the shell fails too */

#define MICRO_SLEEP (100*1000) /* 100 microseconds */
#define LOW         0
#define HIGH        1

     /*   BCM: gpio -g // wPi // Phys: gpio -1 */
#define LED1        16 // 27  // 36
#define LED2        20 // 28  // 38
#define LED3        21 // 29  // 40
#define PRESS       26 // 25  // 37

#if defined(FIX_GPIO)
struct fixGPIO {
    char *pyLine;
    int pin;
} fixGPIO[] = { // feed a three-argument fprintf() to popen() (so #define pins can be passed (one per line))
    { "import RPi.GPIO as GPIO\n", 0},
    { "GPIO.setmode(GPIO.BCM)\n", 0},
    { "GPIO.setwarnings(False)\n", 0},
    { "GPIO.setup(%d, GPIO.IN, pull_up_down=GPIO.PUD_UP)\n", PRESS},
    { (char *)NULL, 0}
};
FILE *pythonStream;
#endif /* defined(FIX_GPIO) */

int
main(void) {
    int i;

    wiringPiSetupGpio();
    //wiringPiSetupPhys();

    printf("Raspberry Pi 4 - direct Cylon Test\n");
    pinMode(LED1, OUTPUT);
    pinMode(LED2, OUTPUT);
    pinMode(LED3, OUTPUT);
    pinMode(PRESS, INPUT);
#if defined(FIX_GPIO)
    if((pythonStream=popen("python", "w")) == NULL) {
        fprintf(stderr, "Can't run python to set pin mode\n");
        exit(1);
    }
    for(i=0 ; fixGPIO[i].pyLine ; i++)
        fprintf(pythonStream, fixGPIO[i].pyLine, fixGPIO[i].pin);
    pclose(pythonStream);
#else /* defined(FIX_GPIO) */
    pullUpDnControl(PRESS, PUD_UP); /* fails on RPi-4 (as does shell GPIO) */
#endif /* defined(FIX_GPIO) */

    while(1) {
        if(digitalRead(PRESS) == LOW) { // Glaring Cylon
            digitalWrite(LED1, HIGH);
            digitalWrite(LED2, HIGH);
            digitalWrite(LED3, HIGH);
            usleep(MICRO_SLEEP);
        }
        else { // Happy Cylon
            digitalWrite(LED1, HIGH);
            digitalWrite(LED2, LOW);
            digitalWrite(LED3, LOW);
            usleep(MICRO_SLEEP);

            digitalWrite(LED1, LOW);
            digitalWrite(LED2, HIGH);
            //digitalWrite(LED3, LOW);
            usleep(MICRO_SLEEP);

            //digitalWrite(LED1, LOW);
            digitalWrite(LED2, LOW);
            digitalWrite(LED3, HIGH);
            usleep(MICRO_SLEEP);

            //digitalWrite(LED1, LOW);
            digitalWrite(LED2, HIGH);
            digitalWrite(LED3, LOW);
            usleep(MICRO_SLEEP);
        }
    }
}

使用此Makefile编译:

CC=gcc
CLIBS= -lwiringPi

cylon: cylon.o
    $(CC) -o cylon cylon.o $(CLIBS)

下面是运行中的Cylon测试台的简短实况照片,请忽略仅用于监控GPIO引脚电压的Arduino(感谢加拿大的John):

https://imgur.com/a/mlpr7Gr

ASIDE:Gordon ...很抱歉,您被高斯曲线的下端(真是一条尾巴,老实说)所吸引,希望您能从另一端走出来完好无损。

答案 3 :(得分:0)

虽然 WiringPi 已停产,但有一个非官方补丁(开源很难杀死,其他人会继续)。

经过测试,应用后 GPIO 在我的 RaspberryPi4 上运行良好。

补丁:

diff -ruN wiringPi/wiringPi.c wiringPi/wiringPi.c
--- wiringPi/wiringPi.c
+++ wiringPi/wiringPi.c
@@ -215,6 +215,7 @@ volatile unsigned int *_wiringPiTimerIrqRaw ;
 
 #define    GPIO_PERI_BASE_OLD  0x20000000
 #define    GPIO_PERI_BASE_NEW  0x3F000000
+#define    GPIO_PERI_BASE_RP4  0xFE000000
 
 static volatile unsigned int piGpioBase = 0 ;
 
@@ -547,6 +548,10 @@ static uint8_t gpioToPUDCLK [] =
   39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,39,
 } ;
 
+#define PULLUPDN_OFFSET_2711_0      57
+#define PULLUPDN_OFFSET_2711_1      58
+#define PULLUPDN_OFFSET_2711_2      59
+#define PULLUPDN_OFFSET_2711_3      60
 
 // gpioToPwmALT
 // the ALT value to put a GPIO pin into PWM mode
@@ -814,7 +819,7 @@ int piGpioLayout (void)
 
   for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
     *c = 0 ;
-  
+
   if (wiringPiDebug)
     printf ("piGpioLayout: Revision string: %s\n", line) ;
 
@@ -883,7 +888,7 @@ int piBoardRev (void)
  * So the distinction between boards that I can see is:
  *
  *     0000 - Error
- *     0001 - Not used 
+ *     0001 - Not used
  *
  * Original Pi boards:
  *     0002 - Model B,  Rev 1,   256MB, Egoman
@@ -955,6 +960,30 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
   if ((cpuFd = fopen ("/proc/cpuinfo", "r")) == NULL)
     piGpioLayoutOops ("Unable to open /proc/cpuinfo") ;
 
+  char buffer[12] ;
+  const char *ranges_file = "/proc/device-tree/soc/ranges" ;
+  int info_fd = open(ranges_file, O_RDONLY) ;
+
+  if (info_fd < 0) {
+    fprintf(stderr, "cannot open: %s", ranges_file) ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  ssize_t n = read(info_fd, buffer, sizeof(buffer)) ;
+  close(info_fd) ;
+
+  if (n < 8) {
+    fprintf(stderr, "cannot read base address: %s", ranges_file) ;
+    exit (EXIT_FAILURE) ;
+  }
+
+  uint32_t gpio_base =  (buffer[4] << 24) + (buffer[5] << 16) + (buffer[6] << 8) + (buffer[7] << 0) ;
+
+  if (!gpio_base)
+  {
+    gpio_base = (buffer[8] << 24) + (buffer[9] << 16) + (buffer[10] << 8) + (buffer[11] << 0) ;
+  }
+
   while (fgets (line, 120, cpuFd) != NULL)
     if (strncmp (line, "Revision", 8) == 0)
       break ;
@@ -968,7 +997,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
 
   for (c = &line [strlen (line) - 1] ; (*c == '\n') || (*c == '\r') ; --c)
     *c = 0 ;
-  
+
   if (wiringPiDebug)
     printf ("piBoardId: Revision string: %s\n", line) ;
 
@@ -1007,7 +1036,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
     bMfg      = (revision & (0x0F << 16)) >> 16 ;
     bMem      = (revision & (0x07 << 20)) >> 20 ;
     bWarranty = (revision & (0x03 << 24)) != 0 ;
-    
+
     *model    = bType ;
     *rev      = bRev ;
     *mem      = bMem ;
@@ -1034,7 +1063,7 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
 // If longer than 4, we'll assume it's been overvolted
 
     *warranty = strlen (c) > 4 ;
-  
+
 // Extract last 4 characters:
 
     c = c + strlen (c) - 4 ;
@@ -1073,8 +1102,11 @@ void piBoardId (int *model, int *rev, int *mem, int *maker, int *warranty)
 
     else                              { *model = 0           ; *rev = 0              ; *mem =   0 ; *maker = 0 ;               }
   }
+  if (gpio_base == GPIO_PERI_BASE_RP4) {
+    *model = PI_MODEL_4;
+  }
 }
- 
+
 
 
 /*
@@ -1205,6 +1237,10 @@ void pwmSetRange (unsigned int range)
 void pwmSetClock (int divisor)
 {
   uint32_t pwm_control ;
+
+  if(piGpioBase == GPIO_PERI_BASE_RP4) {
+    divisor = 540*divisor/192;
+  }
   divisor &= 4095 ;
 
   if ((wiringPiMode == WPI_MODE_PINS) || (wiringPiMode == WPI_MODE_PHYS) || (wiringPiMode == WPI_MODE_GPIO))
@@ -1260,7 +1296,7 @@ void gpioClockSet (int pin, int freq)
     pin = physToGpio [pin] ;
   else if (wiringPiMode != WPI_MODE_GPIO)
     return ;
-  
+
   divi = 19200000 / freq ;
   divr = 19200000 % freq ;
   divf = (int)((double)divr * 4096.0 / 19200000.0) ;
@@ -1504,11 +1540,31 @@ void pullUpDnControl (int pin, int pud)
     else if (wiringPiMode != WPI_MODE_GPIO)
       return ;
 
-    *(gpio + GPPUD)              = pud & 3 ;       delayMicroseconds (5) ;
-    *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;   delayMicroseconds (5) ;
-    
-    *(gpio + GPPUD)              = 0 ;         delayMicroseconds (5) ;
-    *(gpio + gpioToPUDCLK [pin]) = 0 ;         delayMicroseconds (5) ;
+    // Check GPIO register
+    int is2711 = *(gpio + PULLUPDN_OFFSET_2711_3) != 0x6770696f;
+    if(is2711) {
+        // Pi 4 Pull-up/down method
+        int pullreg = PULLUPDN_OFFSET_2711_0 + (pin >> 4);
+        int pullshift = (pin & 0xf) << 1;
+        unsigned int pullbits;
+        unsigned int pull = 0; // Turn PUD off by default
+        if (pud == PUD_UP) {
+            pull = 1;
+        } else if (pud == PUD_DOWN) {
+            pull = 2;
+        }
+        pullbits = *(gpio + pullreg);
+        pullbits &= ~(3 << pullshift);
+        pullbits |= (pull << pullshift);
+        *(gpio + pullreg) = pullbits;
+    } else {
+        // Legacy Pull-up/down method
+        *(gpio + GPPUD)              = pud & 3 ;       delayMicroseconds (5) ;
+        *(gpio + gpioToPUDCLK [pin]) = 1 << (pin & 31) ;   delayMicroseconds (5) ;
+
+        *(gpio + GPPUD)              = 0 ;         delayMicroseconds (5) ;
+        *(gpio + gpioToPUDCLK [pin]) = 0 ;         delayMicroseconds (5) ;
+    }
   }
   else                     // Extension module
   {
@@ -1680,7 +1736,7 @@ void pwmWrite (int pin, int value)
 
 /*
  * analogRead:
- * Read the analog value of a given Pin. 
+ * Read the analog value of a given Pin.
  * There is no on-board Pi analog hardware,
  * so this needs to go to a new node.
  *********************************************************************************
@@ -1699,7 +1755,7 @@ int analogRead (int pin)
 
 /*
  * analogWrite:
- * Write the analog value to the given Pin. 
+ * Write the analog value to the given Pin.
  * There is no on-board Pi analog hardware,
  * so this needs to go to a new node.
  *********************************************************************************
@@ -1748,7 +1804,7 @@ void pwmToneWrite (int pin, int freq)
  * Write an 8-bit byte to the first 8 GPIO pins - try to do it as
  * fast as possible.
  * However it still needs 2 operations to set the bits, so any external
- * hardware must not rely on seeing a change as there will be a change 
+ * hardware must not rely on seeing a change as there will be a change
  * to set the outputs bits to zero, then another change to set the 1's
  * Reading is just bit fiddling.
  * These are wiringPi pin numbers 0..7, or BCM_GPIO pin numbers
@@ -1804,7 +1860,7 @@ unsigned int digitalReadByte (void)
       data = (data << 1) | x ;
     }
   }
-  else 
+  else
   {
     raw = *(gpio + gpioToGPLEV [0]) ; // First bank for these pins
     for (pin = 0 ; pin < 8 ; ++pin)
@@ -1861,7 +1917,7 @@ unsigned int digitalReadByte2 (void)
       data = (data << 1) | x ;
     }
   }
-  else 
+  else
     data = ((*(gpio + gpioToGPLEV [0])) >> 20) & 0xFF ; // First bank for these pins
 
   return data ;
@@ -2265,6 +2321,9 @@ int wiringPiSetup (void)
     case PI_MODEL_ZERO:    case PI_MODEL_ZERO_W:
       piGpioBase = GPIO_PERI_BASE_OLD ;
       break ;
+  case PI_MODEL_4:
+      piGpioBase = GPIO_PERI_BASE_RP4 ;
+      break ;
 
     default:
       piGpioBase = GPIO_PERI_BASE_NEW ;
@@ -2273,7 +2332,7 @@ int wiringPiSetup (void)
 
 // Open the master /dev/ memory control device
 // Device strategy: December 2016:
-// Try /dev/mem. If that fails, then 
+// Try /dev/mem. If that fails, then
 // try /dev/gpiomem. If that fails then game over.
 
   if ((fd = open ("/dev/mem", O_RDWR | O_SYNC | O_CLOEXEC)) < 0)
@@ -2311,13 +2370,13 @@ int wiringPiSetup (void)
   pwm = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PWM) ;
   if (pwm == MAP_FAILED)
     return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (PWM) failed: %s\n", strerror (errno)) ;
- 
+
 // Clock control (needed for PWM)
 
   clk = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_CLOCK_BASE) ;
   if (clk == MAP_FAILED)
     return wiringPiFailure (WPI_ALMOST, "wiringPiSetup: mmap (CLOCK) failed: %s\n", strerror (errno)) ;
- 
+
 // The drive pads
 
   pads = (uint32_t *)mmap(0, BLOCK_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, fd, GPIO_PADS) ;
@@ -2437,7 +2496,7 @@ int wiringPiSetupSys (void)
 
 // Open and scan the directory, looking for exported GPIOs, and pre-open
 // the 'value' interface to speed things up for later
-  
+
   for (pin = 0 ; pin < 64 ; ++pin)
   {
     sprintf (fName, "/sys/class/gpio/gpio%d/value", pin) ;
diff -ruN wiringPi/wiringPi.h wiringPi/wiringPi.h
--- wiringPi/wiringPi.h
+++ wiringPi/wiringPi.h
@@ -100,6 +100,7 @@
 #define    PI_MODEL_CM3        10
 #define    PI_MODEL_ZERO_W     12
 #define    PI_MODEL_3P         13
+#define    PI_MODEL_4          14
 
 #define    PI_VERSION_1        0
 #define    PI_VERSION_1_1      1
<块引用>

注意补丁应该在 Wiring-Pi 根目录内执行(在它的 wiringPi 子目录之外)。

此外,这是我在 other answer 上的 RaspberryPi.StackExchange.com 的副本,与 https://github.com/WiringPi/WiringPi 无关(尽管他们也可以自由应用此内容)。