I2C-Takt-DTC kann nicht geändert werden

I2C-Takt-DTC kann nicht geändert werden

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:

  1. So überprüfen Sie die Taktfrequenz von i2c auf RPI 4B mit Ubuntu 22.04 (NICHT Raspbian)
  2. 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:

  1. hat einen Raspberry Pi mit Ubuntu
  2. 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 :-)

verwandte Informationen