Closed dingyifei closed 5 years ago
Did you compile it yourself? Afaik, the packages have binaries that aren’t 64bit
I followed the procedure in http://wiringpi.com/download-and-install/
compiled WiringPi by clone and run the build script. I didn't compile the rpi.gpio-common... isn't rpi.gpio a python program?
The RPi.GPIO isn't pre-installed in the image, I ran apt install rpi.gpio
and installed it manually.
The rpi.gpio-common, python3-rpi.gpio, and python-rpi.gpio are all arm64 package base on apt search rpi.gpio result
ah you're right - it looks like the 64bit package doesn't actually pass the check for RPI for some reason.
Can you give me the output of /proc/cpuinfo on yours?
Keep in mind, the RPi Foundation does not support running the RPi in 64bit mode at all, so we're gonna have to do a little leg work. This will likely have to be passed on to a debian bug as we (in kali) don't modify the package from Debian at all, but lets do the troubleshooting before we do so.
The raspberry pi I'm using is Raspberry Pi 3 B+
(the one with higher clock speed cpu and metal shielding on the processor)
I tested the kali-linux-2018.4-rpi3-nexmon.img
and it is working fine
Here are the cat /proc/cpuinfo
output:
root@kali:~# cat /proc/cpuinfo
processor : 0
BogoMIPS : 38.40
Features : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 1
BogoMIPS : 38.40
Features : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 2
BogoMIPS : 38.40
Features : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 3
BogoMIPS : 38.40
Features : fp asimd evtstrm crc32 cpuid
CPU implementer : 0x41
CPU architecture: 8
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
Right - Basically what we're looking at is https://sourceforge.net/p/raspberry-gpio-python/code/ci/default/tree/source/c_gpio.c - and seeing if we can massage it to see that we're an RPi - since I'm guessing we lack the Hardware: line in 64bit that is in 32bit.
Seems like the 64 bit build don't have some cpu features and the model name
I get some completely different cpuinfo from the 32 bit kali cat /proc/cpuinfo
:
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 1
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 2
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
processor : 3
model name : ARMv7 Processor rev 4 (v7l)
BogoMIPS : 38.40
Features : half thumb fastmult vfp edsp neon vfpv3 tls vfpv4 idiva idivt vfpd32 lpae evtstrm crc32
CPU implementer : 0x41
CPU architecture: 7
CPU variant : 0x0
CPU part : 0xd03
CPU revision : 4
Hardware : BCM2835
Revision : a020d3
Serial : 000000004be218c8
Right, in 32bit, it has the Hardware/Revision/Serial stanza.
And the rpi.gpio package looks for that to tell if it's on an RPi or not.
As far as I know, there's no way to have the Hardware/Revision/Serial stanza in arm64, at least, not without someone patching the kernel to add it.
Im looking at the source code form https://pypi.org/project/RPi.GPIO/
maybe just set the value in it to BCM2835?
you could hack it locally to always return true, yes, but unfortunately, that won't work for a debian package, since it can be installed on any (arm64) system.
I get it to work LOL The following are the modified \RPi.GPIO-0.6.5\source\cpuinfo.c
/*
Copyright (c) 2012-2016 Ben Croston
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "cpuinfo.h"
int get_rpi_info(rpi_info *info)
{
FILE *fp;
char buffer[1024];
char hardware[1024];
char revision[1024];
char *rev;
int found = 0;
int len;
char fake_revision[1024] = "a020d3";
char fake_hardware[1024] = "BCM2835";
found = 1;
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
return -1;
while (!feof(fp) && fgets(buffer, sizeof(buffer), fp))
{
sscanf(buffer, "Hardware : %s", fake_hardware);
if (strcmp(fake_hardware, "BCM2708") == 0 ||
strcmp(fake_hardware, "BCM2709") == 0 ||
strcmp(fake_hardware, "BCM2835") == 0 ||
strcmp(fake_hardware, "BCM2836") == 0 ||
strcmp(fake_hardware, "BCM2837") == 0)
{
found = 1;
}
sscanf(buffer, "Revision : %s", fake_revision);
}
fclose(fp);
if (!found)
return -1;
if ((len = strlen(fake_revision)) == 0)
return -1;
if (len >= 6 && strtol((char[]){fake_revision[len - 6], 0}, NULL, 16) & 8)
{
// new scheme
//info->rev = revision[len-1]-'0';
strcpy(info->revision, fake_revision);
switch (fake_revision[len - 2])
{
case '0':
info->type = "Model A";
info->p1_revision = 2;
break;
case '1':
info->type = "Model B";
info->p1_revision = 2;
break;
case '2':
info->type = "Model A+";
info->p1_revision = 3;
break;
case '3':
info->type = "Model B+";
info->p1_revision = 3;
break;
case '4':
info->type = "Pi 2 Model B";
info->p1_revision = 3;
break;
case '5':
info->type = "Alpha";
info->p1_revision = 3;
break;
case '6':
info->type = "Compute";
info->p1_revision = 0;
break;
case '8':
info->type = "Pi 3 Model B";
info->p1_revision = 3;
break;
case '9':
info->type = "Zero";
info->p1_revision = 3;
break;
default:
info->type = "Unknown";
info->p1_revision = 3;
break;
}
switch (fake_revision[len - 4])
{
case '0':
info->processor = "BCM2835";
break;
case '1':
info->processor = "BCM2836";
break;
case '2':
info->processor = "BCM2837";
break;
default:
info->processor = "Unknown";
break;
}
switch (fake_revision[len - 5])
{
case '0':
info->manufacturer = "Sony";
break;
case '1':
info->manufacturer = "Egoman";
break;
case '2':
info->manufacturer = "Embest";
break;
case '4':
info->manufacturer = "Embest";
break;
default:
info->manufacturer = "Unknown";
break;
}
switch (strtol((char[]){fake_revision[len - 6], 0}, NULL, 16) & 7)
{
case 0:
info->ram = "256M";
break;
case 1:
info->ram = "512M";
break;
case 2:
info->ram = "1024M";
break;
default:
info->ram = "Unknown";
break;
}
}
else
{
// old scheme
info->ram = "Unknown";
info->manufacturer = "Unknown";
info->processor = "Unknown";
info->type = "Unknown";
strcpy(info->revision, fake_revision);
// get last four characters (ignore preceeding 1000 for overvolt)
if (len > 4)
rev = (char *)&fake_revision + len - 4;
else
rev = fake_revision;
if ((strcmp(rev, "0002") == 0) ||
(strcmp(rev, "0003") == 0))
{
info->type = "Model B";
info->p1_revision = 1;
info->ram = "256M";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0004") == 0)
{
info->type = "Model B";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Sony";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0005") == 0)
{
info->type = "Model B";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Qisda";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0006") == 0)
{
info->type = "Model B";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Egoman";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0007") == 0)
{
info->type = "Model A";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Egoman";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0008") == 0)
{
info->type = "Model A";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Sony";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0009") == 0)
{
info->type = "Model A";
info->p1_revision = 2;
info->ram = "256M";
info->manufacturer = "Qisda";
info->processor = "BCM2835";
}
else if (strcmp(rev, "000d") == 0)
{
info->type = "Model B";
info->p1_revision = 2;
info->ram = "512M";
info->manufacturer = "Egoman";
info->processor = "BCM2835";
}
else if (strcmp(rev, "000e") == 0)
{
info->type = "Model B";
info->p1_revision = 2;
info->ram = "512M";
info->manufacturer = "Sony";
info->processor = "BCM2835";
}
else if (strcmp(rev, "000f") == 0)
{
info->type = "Model B";
info->p1_revision = 2;
info->ram = "512M";
info->manufacturer = "Qisda";
info->processor = "BCM2835";
}
else if ((strcmp(rev, "0011") == 0) ||
(strcmp(rev, "0014") == 0))
{
info->type = "Compute Module";
info->p1_revision = 0;
info->ram = "512M";
info->processor = "BCM2835";
}
else if (strcmp(rev, "0012") == 0)
{
info->type = "Model A+";
info->p1_revision = 3;
info->ram = "256M";
info->processor = "BCM2835";
}
else if ((strcmp(rev, "0010") == 0) ||
(strcmp(rev, "0013") == 0))
{
info->type = "Model B+";
info->p1_revision = 3;
info->ram = "512M";
info->processor = "BCM2835";
}
else
{ // don't know - assume revision 3 p1 connector
info->p1_revision = 3;
}
}
return 0;
}
/*
32 bits
NEW 23: will be 1 for the new scheme, 0 for the old scheme
MEMSIZE 20: 0=256M 1=512M 2=1G
MANUFACTURER 16: 0=SONY 1=EGOMAN
PROCESSOR 12: 0=2835 1=2836
TYPE 04: 0=MODELA 1=MODELB 2=MODELA+ 3=MODELB+ 4=Pi2 MODEL B 5=ALPHA 6=CM
REV 00: 0=REV0 1=REV1 2=REV2
pi2 = 1<<23 | 2<<20 | 1<<12 | 4<<4 = 0xa01040
--------------------
SRRR MMMM PPPP TTTT TTTT VVVV
S scheme (0=old, 1=new)
R RAM (0=256, 1=512, 2=1024)
M manufacturer (0='SONY',1='EGOMAN',2='EMBEST',3='UNKNOWN',4='EMBEST')
P processor (0=2835, 1=2836 2=2837)
T type (0='A', 1='B', 2='A+', 3='B+', 4='Pi 2 B', 5='Alpha', 6='Compute Module')
V revision (0-15)
*/
Also I had modified the /gpiozero/pins/local.py
from __future__ import (
unicode_literals,
absolute_import,
print_function,
division,
)
str = type('')
import io
import warnings
from collections import defaultdict
from threading import Lock
try:
from spidev import SpiDev
except ImportError:
SpiDev = None
from . import SPI
from .pi import PiFactory, PiPin, SPI_HARDWARE_PINS
from .spi import SPISoftwareBus
from ..devices import Device, SharedMixin
from ..output_devices import OutputDevice
from ..exc import DeviceClosed, PinUnknownPi, SPIInvalidClockMode
class LocalPiFactory(PiFactory):
"""
Abstract base class representing pins attached locally to a Pi. This forms
the base class for local-only pin interfaces
(:class:`~gpiozero.pins.rpigpio.RPiGPIOPin`,
:class:`~gpiozero.pins.rpio.RPIOPin`, and
:class:`~gpiozero.pins.native.NativePin`).
"""
pins = {}
_reservations = defaultdict(list)
_res_lock = Lock()
def __init__(self):
super(LocalPiFactory, self).__init__()
self.spi_classes = {
('hardware', 'exclusive'): LocalPiHardwareSPI,
('hardware', 'shared'): LocalPiHardwareSPIShared,
('software', 'exclusive'): LocalPiSoftwareSPI,
('software', 'shared'): LocalPiSoftwareSPIShared,
}
# Override the reservations and pins dict to be this class' attributes.
# This is a bit of a dirty hack, but ensures that anyone evil enough to
# mix pin implementations doesn't try and control the same pin with
# different backends
self.pins = LocalPiFactory.pins
self._reservations = LocalPiFactory._reservations
self._res_lock = LocalPiFactory._res_lock
def _get_revision(self):
# Cache the result as we can reasonably assume it won't change during
# runtime (this is LocalPin after all; descendents that deal with
# remote Pis should inherit from Pin instead)
with io.open('/proc/cpuinfo', 'r') as f:
for line in f:
line = "Revision : a020d3"
revision = line.split(':')[1].strip().lower()
overvolted = revision.startswith('100')
if overvolted:
revision = revision[-4:]
return revision
raise PinUnknownPi('unable to locate Pi revision in /proc/cpuinfo')
class LocalPiPin(PiPin):
"""
Abstract base class representing a multi-function GPIO pin attached to the
local Raspberry Pi.
"""
pass
class LocalPiHardwareSPI(SPI, Device):
def __init__(self, factory, port, device):
self._port = port
self._device = device
self._interface = None
if SpiDev is None:
raise ImportError('failed to import spidev')
super(LocalPiHardwareSPI, self).__init__()
pins = SPI_HARDWARE_PINS[port]
self.pin_factory.reserve_pins(
self,
pins['clock'],
pins['mosi'],
pins['miso'],
pins['select'][device]
)
self._interface = SpiDev()
self._interface.open(port, device)
self._interface.max_speed_hz = 500000
def close(self):
if getattr(self, '_interface', None):
self._interface.close()
self._interface = None
self.pin_factory.release_all(self)
super(LocalPiHardwareSPI, self).close()
@property
def closed(self):
return self._interface is None
def __repr__(self):
try:
self._check_open()
return 'SPI(port=%d, device=%d)' % (self._port, self._device)
except DeviceClosed:
return 'SPI(closed)'
def transfer(self, data):
"""
Writes data (a list of integer words where each word is assumed to have
:attr:`bits_per_word` bits or less) to the SPI interface, and reads an
equivalent number of words, returning them as a list of integers.
"""
return self._interface.xfer2(data)
def _get_clock_mode(self):
return self._interface.mode
def _set_clock_mode(self, value):
self._interface.mode = value
def _get_lsb_first(self):
return self._interface.lsbfirst
def _set_lsb_first(self, value):
self._interface.lsbfirst = bool(value)
def _get_select_high(self):
return self._interface.cshigh
def _set_select_high(self, value):
self._interface.cshigh = bool(value)
def _get_bits_per_word(self):
return self._interface.bits_per_word
def _set_bits_per_word(self, value):
self._interface.bits_per_word = value
class LocalPiSoftwareSPI(SPI, OutputDevice):
def __init__(self, factory, clock_pin, mosi_pin, miso_pin, select_pin):
self._bus = None
super(LocalPiSoftwareSPI, self).__init__(select_pin, active_high=False)
try:
self._clock_phase = False
self._lsb_first = False
self._bits_per_word = 8
self._bus = SPISoftwareBus(clock_pin, mosi_pin, miso_pin)
except:
self.close()
raise
def _conflicts_with(self, other):
# XXX Need to refine this
return not (
isinstance(other, LocalPiSoftwareSPI) and
(self.pin.number != other.pin.number)
)
def close(self):
if getattr(self, '_bus', None):
self._bus.close()
self._bus = None
super(LocalPiSoftwareSPI, self).close()
@property
def closed(self):
return self._bus is None
def __repr__(self):
try:
self._check_open()
return 'SPI(clock_pin=%d, mosi_pin=%d, miso_pin=%d, select_pin=%d)' % (
self._bus.clock.pin.number,
self._bus.mosi.pin.number,
self._bus.miso.pin.number,
self.pin.number)
except DeviceClosed:
return 'SPI(closed)'
def transfer(self, data):
with self._bus.lock:
self.on()
try:
return self._bus.transfer(
data, self._clock_phase, self._lsb_first, self._bits_per_word)
finally:
self.off()
def _get_clock_mode(self):
with self._bus.lock:
return (not self._bus.clock.active_high) << 1 | self._clock_phase
def _set_clock_mode(self, value):
if not (0 <= value < 4):
raise SPIInvalidClockMode("%d is not a valid clock mode" % value)
with self._bus.lock:
self._bus.clock.active_high = not (value & 2)
self._clock_phase = bool(value & 1)
def _get_lsb_first(self):
return self._lsb_first
def _set_lsb_first(self, value):
self._lsb_first = bool(value)
def _get_bits_per_word(self):
return self._bits_per_word
def _set_bits_per_word(self, value):
if value < 1:
raise ValueError('bits_per_word must be positive')
self._bits_per_word = int(value)
def _get_select_high(self):
return self.active_high
def _set_select_high(self, value):
with self._bus.lock:
self.active_high = value
self.off()
class LocalPiHardwareSPIShared(SharedMixin, LocalPiHardwareSPI):
@classmethod
def _shared_key(cls, factory, port, device):
return (port, device)
class LocalPiSoftwareSPIShared(SharedMixin, LocalPiSoftwareSPI):
@classmethod
def _shared_key(cls, factory, clock_pin, mosi_pin, miso_pin, select_pin):
return (select_pin,)
The RPi.GPIO is not working on Kali Linux RaspberryPi 3 64bit 2018.4a I install the image download from https://www.offensive-security.com/kali-linux-arm-images/ and when I try to import RPi.GPIO on python 3.7.1 and python3.6, I receive the following error:
Already tried reinstall RPi.GPIO I tried install wiringpi and when I use
gpio readall
I get the following error:Here are the
cat /proc/cpuinfo