Was bedeutet eigentlich @ SIGNAL_UPDATE ?
Dieses Macro ist hier definiert und beinhaltet offenbar ... nix!
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dht0008a/CJAHGJEF.html
Warum hängt sich meine Kiste auf? - Ein Fehler in den
Assembler-Routinen?
Ich hoffe, das ist alles so verständlich erklärt, und es kann mir jemand
helfen.
Danke und Gruß Peter
Peter schrieb:> CMP r0, #1 /* Store successful - test if incremented from> zero */
Muss hier nicht r1 stehen? r0 ist doch der Pointer...
Peter schrieb:> Da sich die Funktion x_semaphore aufhängt
Definiere "aufhängen"...
Peter schrieb:> Was bedeutet eigentlich @ SIGNAL_UPDATE ?
Das ist wohl zur Synchronisation mehrerer Prozessoren (gibts nicht beim
STM32) und Threads gedacht.
Soll das ein Spinlock werden oder ein blockierender Semaphore via
Scheduler?
Im zweiten Fall musst du in der x_semaphore_dec bei SIGNAL_UPDATE den
Scheduler bitten den Thread blockieren zu lassen. In der x_semaphore_inc
musst du dem Scheduler mitteilen, andere wartende Threads aufzuwecken.
Aber deine Logik ist falsch, muss es nicht sein:
1
CMP r1, #1 /* Store successful - test if incremented from
2
zero */
3
DMB /* Required before releasing protected resource */
4
BHI 2 /* If initial value was 0, signal update */
5
SIGNAL_UPDATE /* Signal waiting processors or processes */
6
2:
7
BX lr
Wenn der Semaphor-Wert nach dem Inkrementieren echt-größer 1 ist, ("BHI"
für unsigned, "GE" ist signed), war er also vorher echt-größer 0, somit
kann es keinen wartenden Prozess geben und man muss niemanden aufwecken.
Ansonsten braucht es halt SIGNAL_UPDATE.
Hallo Niklas,
danke für die Denkanstöße.
Niklas G. schrieb:> Definiere "aufhängen"...
Die test_assert() Funktion wird nicht mehr aufgerufen.
Niklas G. schrieb:> Soll das ein Spinlock werden oder ein blockierender Semaphore via> Scheduler?
Ein Spinlock (Mutex?) - auch wenn semaphore dran steht. Ich muss das
noch ändern.
Folgendes funktioniert:
1
.section.text.x_semaphore_inc
2
x_semaphore_inc:
3
1:LDREXr1,[r0]
4
ADDr1,#1/* Increment temporary copy */
5
STREXr2,r1,[r0]/* Attempt Store-Exclusive */
6
CMPr2,#0/* Check if Store-Exclusive succeeded */
7
BNE1/* Store failed - retry immediately */
8
CMPr0,#1/* Store successful - test if incremented from
9
zero */
10
DMB/* Required before releasing protected resource */
11
// BGE 2 /* If initial value wasn't 0, signal update */
12
BXlr
13
14
2:/* Signal waiting processors or processes */
15
@SIGNAL_UPDATE
16
BXlr
Wenn ich
1
BGE2
wieder einfüge, dann hängt sich die Kiste auf.
Mal abgesehen davon, dass ich mir das in meinem Fall sparen kann, wüsste
ich doch gerne, was da schief läuft?
Gruß Peter
Peter schrieb:> Folgendes funktioniert:
Du hast ja immer noch r0 statt r1 drin.
Peter schrieb:> wüsste> ich doch gerne, was da schief läuft?
Dann steppe doch mal im Debugger jede Anweisung einzeln durch und schau
wie die Endlosschleife zustande kommt.
Peter schrieb:> Wenn ich BGE 2>> wieder einfüge, dann hängt sich die Kiste auf.
Welchen Assembler nutzt du überhaupt? Beim GNU Assembler musst du "bge
2f" (forwards) schreiben. Sonst springt er an Adresse 2, und nicht an
das nächste Label 2! Das Gleiche gilt für das "bne", hier muss es "bne
1b" (backwards) heißen.
Niklas G. schrieb:> Du hast ja immer noch r0 statt r1 drin.
Das stimmt schon so:
LDREX r1, [r0] -> Lade Addresse nach r1
ADD r1, #1 -> Erhöhe den Wert in r1 um 1
STREX r2, r1, [r0] -> Schreibe r1 in einem Ruck zurück nach r0
CMP r2, #0 -> Hat das so funktioniert mit dem Rückschreiben?
BNE 1 -> Nein, da in r2 eine 0 steht - also nochmal.
CMP r0, #1 -> War vorher der Wert 0?
usw. ...
Niklas G. schrieb:> Welchen Assembler nutzt du überhaupt?
Den von ARM. Das mit den Sprüngen stimmt.
Gruß Peter
Niklas G. schrieb:> In r0 steht die Adresse der Semaphor. Also Vermutlich 0x2001... . Das> ist immer größer 1. Also kannst du das "CMP" weglassen und statt "BGE"> einfach "B" schreiben.
Du hast recht. Ich habs geändert.