Forum: Mikrocontroller und Digitale Elektronik Registerbereich als array of structs betrachten


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Bewertung
0 lesenswert
nicht lesenswert
Hallo,

beim STM32 befindet sich z.B. ein Registersatz mit dem Type 
USB_OTG_INEndpointTypeDef für jeden In Enpoint ab offset 0x900 im 
Bereich der OTG Register.

Ich hatte versucht, diese Struktur als ein Array of structs 
anzusprechen:
1
USB_OTG_INEndpointTypeDef **in = (USB_OTG_INEndpointTypeDef **)(usbd_dev->driver->base_address +                                                               USB_OTG_IN_ENDPOINT_BASE);
und mit
1
in[i]->DIEPCTL
 anzusprechen. Leider geht das schief und
1
 &in[i]
 ist der Inhalt von DIEPCTL der i.ten Struktur.
Verwendet wurde arm-none-eabi-gcc (GNU Tools for ARM Embedded Processors 
6-2017-q2-update) 6.3.1 20170620

Der Zugriff auf eine einzelne Struktur funktioniert wie erwertet:
1
USB_OTG_INEndpointTypeDef *in = (USB_OTG_INEndpointTypeDef *)(usbd_dev->driver->base_address +                                                               USB_OTG_IN_ENDPOINT_BASE);
2
in->DIEPCTL

Ist ein array of structs mit dem Zuweisen einer Adresse nicht erlaubt? 
Bei meiner Suche im Web meine ich Hinweise darauf gefunden zu haben. 
Oder wird ein bestimmter C Standard gebraucht?

: Bearbeitet durch User
von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Du nutzt ja einen Doppel Pointer?! Variante 2 sollte auch automatisch 
für mehrere Register gehen. Ein Array ist in C ja fast das gleiche wie 
ein Pointer. Du musst nur dafür sorgen, dass die Größe des Element Typs 
dem Abstand zwischen zwei Registern gleichen Typs entspricht.

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Bewertung
0 lesenswert
nicht lesenswert
Bitte ein Codebeispiel. Ich habe schon tausende Möglichkeiten 
durchprobiert.

von Dr. Sommer (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Genau so wie du es geschrieben hast:
1
__IO USB_OTG_INEndpointTypeDef *in = (__IO USB_OTG_INEndpointTypeDef*) (usbd_dev->driver->base_address + USB_OTG_IN_ENDPOINT_BASE);
2
3
in[0].DIEPCTL = 42;
4
in[1].DIEPTSIZ = 21;

Beim Zugriff auf "in[i].DIEPCTL" wird auf die Adresse "in + 
sizeof(USB_OTG_INEndpointTypeDef)*i" zugegriffen. Da 
USB_OTG_INEndpointTypeDef praktischerweise so definiert ist dass es 32 
Bytes groß ist, und der Abstand zwischen DIEPCTL0 und DIEPCTL1 genau 32 
Bytes ist, kommt das so genau hin. In C++ könnte man das noch etwas 
verbessern:
1
__IO USB_OTG_INEndpointTypeDef (&in)[3] = *reinterpret_cast<__IO USB_OTG_INEndpointTypeDef (*) [3]> (usbd_dev->driver->base_address + USB_OTG_IN_ENDPOINT_BASE);
2
in[0].DIEPCTL = 42;
3
in[1].DIEPTSIZ = 21;

Dann ist die Arraygröße Teil des Typs und leichter ersichtlich. Leider 
warnt der GCC auch hier nicht, wenn der Array-Index zu groß wird...

von Uwe B. (Firma: TU Darmstadt) (uwebonnes)


Bewertung
0 lesenswert
nicht lesenswert
Danke, so gehts!

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.