Forum: Mikrocontroller und Digitale Elektronik ARM Cortex M3 LPC1768 Bit toggeln mit XOR


von Ruprecht (Gast)


Angehängte Dateien:

Lesenswert?

Mahlzeit,

ich habe ein Problem mit XOR unter Keil MDK-ARM 3.80a mit einem Cortex
LPC1768.
Ich würde gerne in dem Register LPC_GPIO1->FIOPIN das Bit 28 toggeln.
LPC_GPIO1->FIOPIN ^=  (1<<28); -> funktioniert leider nicht.
LPC_GPIO1->FIOPIN &= ~(1<<28); -> löschen geht aber
LPC_GPIO1->FIOPIN |=  (1<<28); -> setzen geht auch

Im Anhang seht ihr noch den passenden AssemblerCode zu den obigen drei
Zeilen. Für mich sieht das eigentlich alles i.O. aus.

Jemand eine Idee?

von (prx) A. K. (prx)


Lesenswert?

Da stimmt einiges nicht. Bist du sicher, dass Disassembly und Quellcode 
synchron sind? Dass der Disassembly-Code tatsächlich zum gezeigten 
Quellcode gehört?

Beispielsweise fängt der Interrupt-Handler mit einem Return an. Wenn 
0x31C tatsächlich der Einstieg in den Interrupt-Handler ist, dann ist 
der Rest hinter dem Befehl "BX lr" nur Makulatur.

Und dieser Rest ist ebenfalls kompletter Bockmist.

von Michael G. (graf)


Lesenswert?

Kann es sein, das die register nicht richtig definiert sind, vermutlich 
fehlt da ein sehr sehr wichtiges schlüsselwort "volatile"? oder das der 
code zu stark optimiert wird vom kompiler?

hast du die register selber definiert, oder sind die von kail definiert 
worden? (code posten wenn du es selber gemacht hast)

für die erste operation wird ein ldr durchgeführt, aber kein str.
Das ergebnis wird nicht in die HW zurückgeschrieben. für die 2. 
operation wird wieder ausgelesen, und das ergebnis auch wieder 
zurückgeschrieben.

für die 3. Operation, dein xor, wird der startwert von der 2. bzw 1. 
operation genommen, und verknüpft und auf die hw zurückgeschrieben.

Ich vermute, das daher das komische verhalten herkommt, das du 
beobachtest.

das heist, wen bei deimen xor die led wieder ausgehen sollte, aber 
anbleibt, könnte das durchaus zu dem ASM code passen. wenn vorher die 
LED aus war.

von (prx) A. K. (prx)


Lesenswert?

Michael Graf schrieb:

> für die erste operation wird ein ldr durchgeführt, aber kein str.

Yep, aber ein PC-relativer LDR, womit totsicher nicht der Port 
angesprochen wird.

von Michael G. (graf)


Lesenswert?

Das müsste doch eigentlich ein THAMB 2 Befehlssatz sein, von daher weiss 
ich nicht, wie die genau addressieren.
Beim ARM Befehlssatz wird normalerweiserelativ addresiert. zumindest hab 
ich so komische relative sachen zum pc schon öfter gesehen.

ok die ziehlposition sieht etwas komisch aus. 0x0000051C sieht nicht 
nach hw aus, eher nach selbst definierter datenstruktur. daher 
warscheinlich der volatile fehler.

von (prx) A. K. (prx)


Lesenswert?

Michael Graf schrieb:

> Beim ARM Befehlssatz wird normalerweiserelativ addresiert. zumindest hab
> ich so komische relative sachen zum pc schon öfter gesehen.

Klar, aber was rauskommt wenn man zum Wert des PC 508 addiert steht ja 
rechts daneben. Nämlich 0x51C. Und das liegt definitiv nicht im 
I/O-Bereich, dazu muss ich nichtmal ins Datasheet schauen.

> nach hw aus, eher nach selbst definierter datenstruktur.

Yep, das könnte die Ursache sein. Aber dafür gibt's bei den CM3 das 
CMSIS, muss man anders als bei den ARM7 nicht mehr selber machen.

von Marcus H. (mharnisch) Benutzerseite


Lesenswert?

Also das BX lr gehört sicher noch zur vorherigen Funktion. Die Zuordnung 
von Assembler Instruktionen zu C Code hat seine Grenzen. Insbesondere 
wenn Optimierung im Spiel ist.

Die PC-relative Adressierung greift mit Sicherheit auf die Adresse des 
Registers zu. Stichwort: literal pool. Wenn wir mal einen größeren 
Ausschnitt des Programms sehen könnten (inklusive des pools), dann wäre 
das sicherlich hilfreich. Außerdem verwirrt die gemischte Darstellung 
mehr als sie hilft, den Code zu verstehen. Haben wir ja bereits gemerkt 
:-)

Bei diesem Zugriff scheint aber etwas schiefzugehen. Es scheint als 
würde eine Stufe der Indirektion vergessen. Vorausgesetzt, es handelt 
sich bei den Strukturen tatsächlich um die entsprechenden GPIO, bzw. SCB 
Register. Bei mir heißen die etwas anders (MDK ARM 3.70).

Gruß
Marcus
http://www.doulos.com/arm/

von (prx) A. K. (prx)


Lesenswert?

Marcus Harnisch schrieb:

> Die PC-relative Adressierung greift mit Sicherheit auf die Adresse des
> Registers zu. Stichwort: literal pool.

Gib mit mal einen Tip, wie du einen C Compiler dazu bringst, eine 
Adresse mit |= zu verzieren, ohne dass er dich mit Fehler abwirft.

Würde mich aber auch sehr interessieren, wie er den Compiler dazu 
dressiert hat, einen derart schrägen Code zu produzieren.

von (prx) A. K. (prx)


Lesenswert?

Marcus Harnisch schrieb:

> Also das BX lr gehört sicher noch zur vorherigen Funktion. Die Zuordnung
> von Assembler Instruktionen zu C Code hat seine Grenzen. Insbesondere
> wenn Optimierung im Spiel ist.

Wohl wahr. Aber die exakte Funktionsadresse sollte eigentlich schon 
kennen, egal wie super er optimiert. Nö, ich glaube da erst einmal 
garnix mehr, das ist einfach zu hirnrissig was da steht.

von Ruprecht (Gast)


Lesenswert?

So, es gibt neue Erkenntnisse!

Wie Marcus schon richtig festgestellt hat, gehört das Return BX lr zu 
vorigen Funktion. Synchronität sucht man wohl vergebens.
Scheinbar ist es die Laufzeit der ISR die hier Probleme macht.

void EINT0_IRQHandler(void)
{
    LPC_GPIO1->FIOPIN ^=  (1<<28);
    LPC_SC->EXTINT    |=  (1<<1);
}

Verlängere ich die Laufzeit der ISR durch eine Countervariable, die ich 
einfach hochzähle...

void EINT0_IRQHandler(void)
{
    LPC_GPIO1->FIOPIN ^=  (1<<28);
    LPC_SC->EXTINT    |=  (1<<1);
    irq_counter++;
}

funktioniert das Toggeln.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.