timing: zu langsam bei GPIO-Zugriffen

Gast #2825128
Lesenswert?
• ▲
▼
Hallo,

ich verwende den UC3 von Atmel mit 60 MHz. Das bedeutet, dass ein Takt 
16,67ns benötigt.
Nun möchte ich den Ausgang eines GPIOs schalten und mache das durch 
Schreiben einer festen Zahl auf das entsprechende (vorher fest 
definierte) Register. Die CPU braucht also keine Adressen aus zu rechnen 
oder Bitpositionen zu verschieben. Vereinfacht schaut der Code dann in 
etwa so aus:
1
uint32_t *register_setzen   = &(port[xy].outputValueRegisterSet);
2
uint32_t *register_loeschen = &(port[xy].outputValueRegisterClear);
3

4
// start der Zeitmessung ab hier
5

6
*register_setzen   = 1;  // bit 0 setzen
7
*register_loeschen = 1;  // bit 0 löschen
8

9
// start der Zeitmessung bis hier


Eigentlich hat die CPU nicht viel zu tun und braucht nur zwei mal einen 
festen Wert laden und diesen in eine feste Registeradresse zu schreiben.
Für diese Zwei Zeilen benötigt die CPU aber ganze 284ns (und ist somit 
ein Riesen Vielfaches von den 16,67ns).

Das kann doch nicht normal sein, oder? Oder doch? Oder habe ich etwas 
falsch gemacht/gedacht?
Gast #2825221
Lesenswert?
• ▲
▼
Soweit ich weiß, habe ich überall den 60 MHz Takt dran gehängt. Aber ich 
werde das noch mal kontrollieren. ASM werde ich ebenfalls noch anschauen 
(heute Abend). Danke für die Tipps.

Was ich im Datenblatt noch gefunden habe, ist die "HSB Bus Matrix". 
Damit konnte ich bisher nie etwas anfangen.
Habe ich das richtig verstanden? Mit der HSB kann ich mich direkt mit 
dem Register verbinden und somit innerhalb eines Taktes den Registerwert 
ändern? (Ob ich nur bestimmte Adressbereiche/Module anschließen kann, 
oder auch mein gewünschtes GPIO-Register, konnte ich bis jetzt noch 
nicht raus finden.)
Gast #2825243
Lesenswert?
• ▲
▼
>Habe ich das richtig verstanden? Mit der HSB kann ich mich direkt mit
>dem Register verbinden und somit

Das wird wohl ein chip-interner Bus sein. Die Register befinden
sich im Peripherieblock.

>innerhalb eines Taktes den Registerwert
>ändern?

auf aktuellen (ARM-)Mikrocontrollern gibt es i.d.R
nicht nur einen Takt, sondern eine ganze Latte davon...

>(Ob ich nur bestimmte Adressbereiche/Module anschließen kann,
>oder auch mein gewünschtes GPIO-Register, konnte ich bis jetzt noch
>nicht raus finden.)

Das sollte Dich nicht kümmern müssen. Die Register sind
im CPU-Adressraum eingeblendet und fertig.
Gast #2825469
Lesenswert?
• ▲
▼
Bei den UC3s sind die GPIO-Register auch teilweise auf einem sogenannten 
Local-Bus verfügbar, da geht das in einem Takt. Über die HSB wird das 
wohl erheblich langsamer sein. Zeig doch mal den Assemblercode den der 
Kompiler ausgibt.
Gast #2825493
Lesenswert?
• ▲
▼
>Wie meinst du das mit dem Chip-internen Bus? Der Peripherieblock ist
>doch auch (intern) im Chip.

Was glaubst Du, wie der CPU Core mit der Peripherie spricht?

Schau' am besten in's Datenblatt oder Reference Manual (oder wie
auch immer das bei Atmel heisst.).
Da sollte die Chiparchitektur abgebildet sein.
Bei heutigen Controllern oder SOCs gibt es i.d.R
mehrere on-chip Busse.
Gast #2826312
Lesenswert?
• ▲
▼
avr32-pro schrieb:
> Zeig doch mal den Assemblercode den der
> Kompiler ausgibt.
1
    *gpio_port_clear = 1<<(CLK_PIN&0x1F);
2
80013D88  ld.w R8, R7[-8]     
3
80013D8C  movhi R9, 0x0200     
4
80013D90  st.w R8[0], R9     
5
    *gpio_port_set   = 1<<(CLK_PIN&0x1F);
6
80013D92  ld.w R8, R7[-12]     
7
80013D96  movhi R9, 0x0200     
8
80013D9A  st.w R8[0], R9


Es sind ja in der Tat nur 3  Befehle pro C-code-Zeile. Ich hätte 
allerdings schon gedacht, dass das ein 60 MHz Chip schneller umsetzt.
Gast #2826361
Lesenswert?
• ▲
▼
>Ich hätte
>allerdings schon gedacht, dass das ein 60 MHz Chip schneller umsetzt.


Dann schau' doch mal in's Datenblatt und finde heraus, mit welchem
Takt der GPIO-Block getaktet wird und wieviel Wait-States beim Programm- 
und Datenspeicherzugriff fällig sind.

Du kannst auch mit der Compileroptimierung spielen und testen,
ob schnellerer Code die Sache beschleunigt (falls Du das in einer 
Schleife laufen lassen wolltest). Nützt aber nat. nix, wenn
die Peripherie die CPU ausbremst.
Gast #2826528
Lesenswert?
• ▲
▼
Eine ganzen haufen Takte kannst du schon mal sparen wenn du das
1
80013D88  ld.w R8, R7[-8]
loswirst indem du den Blödsinn mit den gpio_port_clear/set Zeigern lässt 
und direkt die Zielregister da hin schreibst. Sohier muss er immer erst 
den Zeiger laden um dann dort hin zu schreiben.
Und noch mehr Zeit sparst du dann wenn du über den Localbus schreibst.
Gast #2826546
Lesenswert?
• ▲
▼
>Eine ganzen haufen Takte kannst du schon mal sparen wenn du das80013D88  >ld.w 
R8, R7[-8]
>
>loswirst indem du den Blödsinn mit den gpio_port_clear/set Zeigern lässt

Kannst Du die Grösse des "Haufens" quantifizieren?

Antwort schreiben

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.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.