
Guten Tag liebe Freunde,
Das Ziel: -> I2C-Taktfrequenz auf 400kHz ändern
Die Motivation: -> Ich versuche, Adafruit BNO085 über i2c zu verwenden, und es gibt bekannte Probleme mit der RPI-I2C-Taktverlängerung. (Dies ist ein bekannter Fehler, der seit 2012 besteht. Yeah!)
Was ich versucht habe: Ich habe gut zwei Tage damit verbracht, mich in dieses Thema einzulesen und mehrfach versucht, die I2C-Taktfrequenz auf meinem Raspberry Pi 4b mit Ubuntu 22.04 Server (headless) zu ändern.
da ich kein Rasbian verwende, kann ich NICHT einfach eine Zeile in meiner Boot-Konfigurationsdatei bearbeiten. Vielmehr muss ich eine Gerätebaumdatei disassemblieren, ändern und neu kompilieren.
Habe dieses Tutorial befolgt: Aktivieren Sie SPI und I2C auf Ubuntu 20.04 Raspberry Pi
Auf diese Datei angewendet:
/boot/dtbs/5.15.0-1033-raspi/bcm2711-rpi-4-b.dtb
habe diesen Befehl zum Disassemblieren verwendet:
dtc -I dtb -O dts -o bcm2711-rpi-4-b.dts /boot/dtbs/5.15.0-1033-raspi/bcm2711-rpi-4-b.dtb
Dann habe ich diese Bereiche in dieser .dts (Device-Tree-Source) geändert.
in den folgenden beiden Codeteilen habe ich ersetzt
clock-frequency = <0x186a0>; // 100000
mit
clock-frequency = <0x61a80>; // 400000
Block 1
i2c@7e205000 {
compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c";
reg = <0x7e205000 0x200>;
interrupts = <0x00 0x75 0x04>;
clocks = <0x08 0x14>;
#address-cells = <0x01>;
#size-cells = <0x00>;
status = "disabled";
#clock-frequency = <0x186a0>; // 100000
clock-frequency = <0x61a80>; // 400000
phandle = <0x10>;
};
und auch Block 2
i2c@7e804000 {
compatible = "brcm,bcm2711-i2c\0brcm,bcm2835-i2c";
reg = <0x7e804000 0x1000>;
interrupts = <0x00 0x75 0x04>;
clocks = <0x08 0x14>;
#address-cells = <0x01>;
#size-cells = <0x00>;
status = "disabled";
pinctrl-names = "default";
pinctrl-0 = <0x18>;
#clock-frequency = <0x186a0>; // 100000
clock-frequency = <0x61a80>; // 400000
phandle = <0x36>;
};
Weiter unten habe ich folgenden Codeblock geändert:
#i2c1_baudrate = "\0\0\06clock-frequency:0"; // modified this
i2c1_baudrate = "\0\0\06clock-frequency:400000"; // modified this
Hier das gesamteüberschreibtBlock
__overrides__ {
cam0-pwdn-ctrl;
cam0-pwdn;
cam0-led-ctrl;
cam0-led;
krnbt = "\0\0\00status";
krnbt_baudrate = "\0\0\00max-speed:0";
cache_line_size;
uart0 = "\0\0\01status";
uart1 = "\0\0\02status";
i2s = "\0\0\03status";
spi = "\0\0\04status";
i2c0 = [00 00 00 10 73 74 61 74 75 73 00 00 00 00 35 73 74 61 74 75 73 00];
i2c1 = "\0\0\06status";
i2c0_baudrate = [00 00 00 10 63 6c 6f 63 6b 2d 66 72 65 71 75 65 6e 63 79 3a 30 00]; // left this alone
#i2c1_baudrate = "\0\0\06clock-frequency:0"; // modified this
i2c1_baudrate = "\0\0\06clock-frequency:400000"; // modified this
audio = "\0\0\07status";
watchdog = "\0\0\08status";
random = "\0\0\09status";
sd_overclock = "\0\0\0:brcm,overclock-50:0";
sd_force_pio = "\0\0\0:brcm,force-pio?";
sd_pio_limit = "\0\0\0:brcm,pio-limit:0";
sd_debug = "\0\0\0:brcm,debug";
sdio_overclock = "\0\0\0;brcm,overclock-50:0\0\0\0\0<brcm,overclock-50:0";
axiperf = "\0\0\0=status";
arm_freq;
act_led_gpio = "\0\0\0>gpios:4";
act_led_activelow = "\0\0\0>gpios:8";
act_led_trigger = "\0\0\0>linux,default-trigger";
pwr_led_gpio = "\0\0\0?gpios:4";
pwr_led_activelow = "\0\0\0?gpios:8";
pwr_led_trigger = "\0\0\0?linux,default-trigger";
eth_led0 = "\0\0\0/led-modes:0";
eth_led1 = "\0\0\0/led-modes:4";
sd_poll_once = "\0\0\0@non-removable?";
spi_dma4 = <0x34 0x646d6173 0x3a303d00 0x41 0x34 0x646d6173 0x3a383d00 0x41>;
};
danach habe ich die .dts-Datei mit diesem Befehl wieder in .dtb zurückkompiliert:
dtc -I dts -O dtb -o bcm2711-rpi-4-b.dtb bcm2711-rpi-4-b.dts
und habe die Datei dann wieder in das Verzeichnis kopiert, in dem sie ursprünglich gefunden wurde, und die vorhandene Datei überschrieben. Natürlich habe ich ein Backup.
sudo cp bcm2711-rpi-4-b.dtb /boot/dtbs/5.15.0-1033-raspi/bcm2711-rpi-4-b.dtb
Aber es funktioniert immer noch nicht. Beim Ausführen der Python-Testdatei von Adafruit erhalte ich den folgenden Fehler:
python3 imu_v2.py
********** Packet *************
DBG:: HEADER:
DBG:: Data Len: 17
DBG:: Channel: CONTROL (2)
DBG:: ** UNKNOWN Report Type **: 0x7c
DBG:: Sequence number: 19
DBG:: Data:
DBG:: [0x04] 0x7C 0x05 0x00 0x00
DBG:: [0x08] 0x00 0x50 0xC3 0x00
DBG:: [0x0C] 0x00 0x00 0x00 0x00
DBG:: [0x10] 0x00 0x00 0x00 0x00
DBG:: [0x14] 0x00
*******************************
Traceback (most recent call last):
File "/home/administrator/Documents/raspberrypi_software/python/src/imu_v2.py", line 19, in <module>
bno.enable_feature(BNO_REPORT_ROTATION_VECTOR)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 999, in enable_feature
self._process_available_packets(max_packets=10)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 803, in _process_available_packets
self._handle_packet(new_packet)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 863, in _handle_packet
raise error
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 858, in _handle_packet
_separate_batch(packet, self._packet_slices)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 373, in _separate_batch
required_bytes = _report_length(report_id)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 362, in _report_length
return _AVAIL_SENSOR_REPORTS[report_id][2]
KeyError: 124
Dies ist das Programm, das ich ausführen möchte. Laut der Adafruit-Dokumentation muss dafür die I2C-Taktfrequenz 400 kHz betragen.
import time
import board
import busio
from adafruit_bno08x import (
BNO_REPORT_ACCELEROMETER,
BNO_REPORT_GYROSCOPE,
BNO_REPORT_MAGNETOMETER,
BNO_REPORT_ROTATION_VECTOR,
)
from adafruit_bno08x.i2c import BNO08X_I2C
i2c = busio.I2C(board.SCL, board.SDA, frequency=400000)
#i2c = busio.I2C(board.SCL, board.SDA, frequency=100000)
bno = BNO08X_I2C(i2c)
bno.enable_feature(BNO_REPORT_ACCELEROMETER)
bno.enable_feature(BNO_REPORT_GYROSCOPE)
bno.enable_feature(BNO_REPORT_MAGNETOMETER)
bno.enable_feature(BNO_REPORT_ROTATION_VECTOR)
while True:
time.sleep(0.5)
imu_data = {}
accel_x, accel_y, accel_z = bno.acceleration # pylint:disable=no-member
imu_data["linear_acceleration"] = {"x": accel_x, "y": accel_y, "z": accel_z}
gyro_x, gyro_y, gyro_z = bno.gyro # pylint:disable=no-member
imu_data["angular_velocity"] = {"x": gyro_x, "y": gyro_y, "z": gyro_z}
mag_x, mag_y, mag_z = bno.magnetic # pylint:disable=no-member
imu_data["magnetic_field"] = {"x": mag_x, "y": mag_y, "z": mag_z}
quat_i, quat_j, quat_k, quat_real = bno.quaternion # pylint:disable=no-member
imu_data["orientation"] = {"x": quat_i, "y": quat_j, "z": quat_k, "w": quat_real}
# Populate the 3x3 covariance matrices with zeros (assuming no covariance)
imu_data["orientation_covariance"] = [0.0] * 9
imu_data["angular_velocity_covariance"] = [0.0] * 9
imu_data["linear_acceleration_covariance"] = [0.0] * 9
print(imu_data)
print("")
Und ja, ich habe es sowohl mit 100.000 als auch mit 400.000 versucht, wie Sie im Skript sehen können.
Und hier die Ausgabe, die es erzeugt, bevor es abstürzt und eine Fehlerspur erzeugt, die weiter unten zu finden ist. Bitte beachten Sie, dass die Ausgabe aufgrund sich wiederholender Informationen stark redigiert ist. Läuft normalerweise etwa 10-15 Sekunden, bevor es abstürzt. Könnte ein Puffer gefüllt sein?
administrator@hostname:~/Documents/raspberrypi_software/python/src$ python3 imu_v2.py
{'linear_acceleration': {'x': 0.3046875, 'y': -0.11328125, 'z': 9.578125}, 'angular_velocity': {'x': 0.001953125, 'y': 0.0, 'z': 0.0}, 'magnetic_field': {'x': -4.0, 'y': -9.5625, 'z': 54.4375}, 'orientation': {'x': -0.005615234375, 'y': -0.01409912109375, 'z': 0.0001220703125, 'w': 0.9998779296875}, 'orientation_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'angular_velocity_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'linear_acceleration_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}
{'linear_acceleration': {'x': 0.26953125, 'y': -0.11328125, 'z': 9.58203125}, 'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}, 'magnetic_field': {'x': -4.75, 'y': -11.375, 'z': 49.75}, 'orientation': {'x': -0.00567626953125, 'y': -0.01416015625, 'z': 6.103515625e-05, 'w': 0.9998779296875}, 'orientation_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'angular_velocity_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'linear_acceleration_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}
<data ommited>
Large chunk of data ommited due to character limit
</data ommited>
{'linear_acceleration': {'x': 0.3046875, 'y': -0.15234375, 'z': 9.578125}, 'angular_velocity': {'x': 0.0, 'y': 0.0, 'z': 0.0}, 'magnetic_field': {'x': -4.0, 'y': -9.9375, 'z': 54.1875}, 'orientation': {'x': -0.0064697265625, 'y': -0.015380859375, 'z': -6.103515625e-05, 'w': 0.9998779296875}, 'orientation_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'angular_velocity_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], 'linear_acceleration_covariance': [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]}
Und schließlich die Fehlerspur, die 10–15 Sekunden nach der obigen Ausgabe erscheint:
********** Packet *************
DBG:: HEADER:
DBG:: Data Len: 191
DBG:: Channel: INPUT_SENSOR_REPORTS (3)
DBG:: Report Type: BASE_TIMESTAMP (0xfb)
DBG:: Sensor Report Type: ACCELEROMETER(0x1)
DBG:: Sequence number: 87
DBG:: Data:
DBG:: [0x04] 0xFB 0xFB 0x12 0x00
DBG:: [0x08] 0x00 0x01 0xE1 0x02
DBG:: [0x0C] 0x00 0x45 0x00 0xE3
DBG:: [0x10] 0xFF 0x95 0x09 0x03
DBG:: [0x14] 0xD1 0x00 0x16 0xB4
DBG:: [0x18] 0xFF 0x56 0xFF 0x44
DBG:: [0x1C] 0x03 0x05 0xD0 0x00
DBG:: [0x20] 0x7A 0x99 0xFF 0x00
DBG:: [0x24] 0xFF 0x00 0x00 0x7E
DBG:: [0x28] 0xBF 0x44 0x32 0x01
DBG:: [0x2C] 0xE2 0x06 0x3D 0x4E
DBG:: [0x30] 0x00 0xE3 0xFF 0x94
DBG:: [0x34] 0x09 0x02 0xD2 0x04
DBG:: [0x38] 0x3F 0x00 0x00 0x00
DBG:: [0x3C] 0x00 0x00 0x00 0x03
DBG:: [0x40] 0xD2 0x08 0x0B 0xBA
DBG:: [0x44] 0xFF 0x56 0xFF 0x2B
DBG:: [0x48] 0x03 0x05 0xD1 0x08
DBG:: [0x4C] 0x6F 0x98 0xFF 0x00
DBG:: [0x50] 0xFF 0x00 0x00 0xFE
DBG:: [0x54] 0x3F 0x44 0x32 0x01
DBG:: [0x58] 0xE3 0x0A 0x78 0x4E
DBG:: [0x5C] 0x00 0xD9 0xFF 0x94
DBG:: [0x60] 0x09 0x02 0xD3 0x0C
DBG:: [0x64] 0x37 0x00 0x00 0x00
DBG:: [0x68] 0x00 0x00 0x00 0x01
DBG:: [0x6C] 0xE4 0x0E 0xB6 0x45
DBG:: [0x70] 0x00 0xE3 0xFF 0x95
DBG:: [0x74] 0x09 0x03 0xD3 0x10
DBG:: [0x78] 0x00 0xBA 0xFF 0x5B
DBG:: [0x7C] 0xFF 0x38 0x03 0x05
DBG:: [0x80] 0xD2 0x10 0x63 0x98
DBG:: [0x84] 0xFF 0x00 0xFF 0x00
DBG:: [0x88] 0x00 0xFE 0x3F 0x44
DBG:: [0x8C] 0x32 0x01 0xE5 0x12
DBG:: [0x90] 0xF7 0x4E 0x00 0xE3
DBG:: [0x94] 0xFF 0x8A 0x09 0x02
DBG:: [0x98] 0xD4 0x14 0x2C 0x00
DBG:: [0x9C] 0x00 0x00 0x00 0x00
DBG:: [0xA0] 0x00 0x03 0xD4 0x14
DBG:: [0xA4] 0xF4 0xB4 0xFF 0x5B
DBG:: [0xA8] 0xFF 0xB1 0x03 0x01
DBG:: [0xAC] 0xE6 0x1A 0x36 0x4E
DBG:: [0xB0] 0x00 0xE3 0xFF 0x94
DBG:: [0xB4] 0x04 0xFF 0xFF 0xFF
DBG:: [0xB8] 0xFF 0xFF 0xFF 0xFF
DBG:: [0xBC] 0xFF 0xFF 0xFF 0xFF
DBG:: [0xC0] 0xFF 0xFF 0xFF
*******************************
Traceback (most recent call last):
File "/home/administrator/Documents/raspberrypi_software/python/src/imu_v2.py", line 26, in <module>
accel_x, accel_y, accel_z = bno.acceleration # pylint:disable=no-member
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 598, in acceleration
self._process_available_packets()
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 803, in _process_available_packets
self._handle_packet(new_packet)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 863, in _handle_packet
raise error
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 858, in _handle_packet
_separate_batch(packet, self._packet_slices)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 373, in _separate_batch
required_bytes = _report_length(report_id)
File "/home/administrator/.local/lib/python3.10/site-packages/adafruit_bno08x/__init__.py", line 364, in _report_length
return _REPORT_LENGTHS[report_id]
KeyError: 255
Ich bin mir nicht sicher, was ich übersehe. An diesem Punkt bin ich mir immer noch nicht sicher, ob mein Bus tatsächlich die Taktfrequenz geändert hat. Weiß jemand:
- So überprüfen Sie die Taktfrequenz von i2c auf RPI 4B mit Ubuntu 22.04 (NICHT Raspbian)
- was fehlt mir, was stimmt hier nicht?
Antwort1
Ich konnte dieses Problem lösen und wollte die Lösung für alle anderen posten, die:
- hat einen Raspberry Pi mit Ubuntu
- muss die I2C-Taktrate ändern (von 100000 auf 400000)
Nach diesem Ausflug in die Welt der DTS und DTB wurde entschieden, einfach DT-Overlays zu verwenden.
Zuerst habe ich eine neue Datei "i2c1-frequency-overlay.dts" erstellt
// i2c1-frequency-overlay.dts
/dts-v1/;
/plugin/;
/ {
compatible = "brcm,bcm2711";
fragment@0 {
target = <&i2c1>;
__overlay__ {
clock-frequency = <400000>; // Set your desired frequency here (e.g., 400 kHz)
};
};
};
Zweitens habe ich diese Datei kompiliert mit:
dtc -I dts -O dtb -o i2c1-frequency-overlay.dtbo i2c1-frequency-overlay.dts
Dadurch wurde die dtb-Datei erstellt
i2c1-frequency-overlay.dtbo
welches dann nach /boot/firmware/overlays/ kopiert wurde
sudo cp i2c1-frequency-overlay.dtbo /boot/firmware/overlays/
Als nächstes habe ich /boot/firmware/config.txt geändert
sudo nano /boot/firmware/config.txt
und fügte Folgendes hinzu:
# Added below to change i2c frequency from 100kHz [default] to 400kHz [fast mode]
dtparam=i2c_arm_baudrate=400000
dtoverlay=i2c1-frequency-overlay
Letzter Schritt: Neustart
sudo reboot
Nur um zu überprüfen, ob die I2C-Taktfrequenz aktualisiert wurde:
// this did not work:
cat /sys/class/i2c-adapter/i2c-1/of_node/clock-frequency
habe noch etwas recherchiert und folgendes herausgefunden
// but this worked
echo 0x$(xxd /sys/class/i2c-adapter/i2c-1/of_node/clock-frequency | cut -f 2,3 -d ' ' --output-delimiter='') | xargs printf "%d\n"
-bash: warning: command substitution: ignored null byte in input
400000
-> dies bestätigt, dass der Bus bei 400 kHz ist :-)