Verständnisfrage Register zugriff

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • Einen wunderschönen guten Morgen euch allen,

    ich habe heute richtig Lust mit dem Pi an die Grenze des Möglichen zu gehen. Dazu hätte ich eine Verständnisfrage an euch.

    Und zwar habe ich die ARM Peripherien von dem BCM2835 zur Hand. Dort sehe ich die einzelnen Register vom Raspberry Pi.

    Ich möchte gerne ein Register auslesen von meinem C-Programm aus.

    Ich habe mir folgendes Register ausgesucht:

    Registername; Adresse; Beschreibung; Seitenzahl
    CLO; 0x7E003004; System timer Counter Lower 32 bits; 172

    Mein Programm zum auslesen dieses Registers sieht folgendermaßen aus:

    #include <stdio.h>
    int *pointer=0x7E003004;

    int main(void)
    {
    int systemzeit=*pointer;
    printf("aktuelle Systemzeit ist %i",systemzeit);

    return 0;
    }

    Bei diesem Code kommt folgende Fehlermeldung:
    Segmentation fault

    Wenn ich den gleichen Code mit Sudo ausführe kommt keine Fehlermeldung aber auch kein Wert.

    Kann mir bitte jemand helfen wie ich Register lesen und schreiben kann?

    Ich vermute, dass ich mir lese/schreibrechte beim Betriebssystem holen muss, aber wie?

    Vielen Dank für eure Hilfe.

    <--Heute ist ein guter Tag zum basteln-->

  • > int *pointer=0x7E003004;
    Das setzt zwar einen Pointer auf, aber der Code laeuft unter Linux.

    Unter Linux bestimmt der Kernel, welches Memory wo ist, und ob
    ein bestimmter User dort Zugriff hat.

    So also nicht !

    > Bei diesem Code kommt folgende Fehlermeldung:
    > Segmentation fault
    So sagt Linux: FINGER WEG :)

    > Ich vermute, dass ich mir lese/schreibrechte beim Betriebssystem holen muss, aber wie?
    Auf elinux.org hat's ein Musterprogramm.
    Die interessante Stelle ist: setup_io

  • Hallo Xeriox,

    die Lösung liegt in der Beschäftigung mit dem Adressoperator & und dem Indirektionsoperator *.

    Auf den Adressoperator hast Du verzichtet, somit "weiß" Dein Programm gar nicht, dass der zugewiesene Wert eine Speicheradresse darstellt.

    Beste Grüße

    Andreas

    Ich bin wirklich nicht darauf aus, Microsoft zu zerstören. Das wird nur ein völlig unbeabsichtigter Nebeneffekt sein.
    Linus Torvalds - "Vater" von Linux

    Linux is like a wigwam, no windows, no gates, but with an apache inside dancing samba, very hungry eating a yacc, a gnu and a bison.

    Einmal editiert, zuletzt von Andreas (21. Oktober 2014 um 11:14)

  • Hi,
    mal so schnell nebenbei: im Prinzip richtig gedacht ...

    Aber: wie hier schon mal angedeutet - auf den Bereich hast Du keinen Zugriff.
    Zunächst mal hat kein Prozess Zugriff auf fremden Speicher, es sei denn es handelt sich um shared memory. Dabei ist es vollkommen irrelevant, ob Du root bist oder nicht.

    Zudem dürfte das Kernel-Space sein, auf den Du da verweist ... und da kommst Du aus dem Userland zunächst mal sowieso nicht dran (Stichwort copyin/copyout ...).

    In so einem Fall verwendet man mmap() ... dadurch "spiegelst" Du sozusagen einen Speicherbereich in den Speicher Deiner Anwendung ( -> click <- ).

    Nimm vielleicht mal den Source von pigpio auseinander ... da dürfte einiges in der Richtung zu finden sein ...

    cu,
    -ds-

  • Vielen Dank für eure Antworten. Ihr habt mir sehr geholfen.

    Nur eine Frage ist offen geblieben und ich komme einfach nicht auf das Ergebnis.

    Ich nehme Bezug auf die Kampis Elektroecke. Dort wird der Offset des Adressbereiches Berechnet. Dort wird gesagt, dass dies eine einfache Rechnung wäre.

    Für mich wahrscheinlich zu einfach?!?:denker:

    Für den Anfang: Es gibt eine Physikalische Adresse und eine virtuelle Adresse der I/O Peripherien.

    Die Anfangsadresse im virtuellen Adressbereich für die I/O Peripherien ist 0xF200 0000

    Die Anfangsadresse der I/O-Peripherien im physikalischen Adressbereich liegt bei 0x2000 0000

    Der Adressbereich der GPIO-Peripherie beginnt bei 0x7E20 0000

    Nun die erste Frage: Wieso ist der Adressbereich der GPIO-Peripherie geringer als die Startadresse der I/O-Peripherie?

    Jetzt zu meiner Vermutung:
    Der Abstand zwischen der I/O-Peripherie zur GPIO-Peripherie ist im virtuellen Speicher genauso groß wie im physikalischen Speicher. Also muss die Differenz berechnet werden und im physikalischen Speicher addiert werden.

    Die Differenz zwischen der I/O-Peripherie und der GPIO-Peripherie im Virtuellen Adressraum ist die gleiche wie im physikalischen Adressraum.

    Zu meiner Rechnung:
    Logisch betrachtet wäre die Differenz zwischen der I/O-Peripherie 0xF2000000-0x7E200000 dies ergibt ein negatives Ergebnis und nicht wie auf der Seite beschrieben 0x20 0000

    Wie komme ich auf die 0x20 0000?

    <--Heute ist ein guter Tag zum basteln-->

    Einmal editiert, zuletzt von Xeriox (23. Oktober 2014 um 08:56)

  • Hat keiner eine Idee?

    Das was ich herausgefunden habe ist, dass der virtuelle Adressraum 8 bit breit ist und der physikalische Adressraum 32 bit.

    Aber warum liegt der Adressbereich der GPIO nicht in den I/O-Peripherials?

    <--Heute ist ein guter Tag zum basteln-->

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!