Problem mit Zeigern



  • Hallo,

    eigentlich müsste doch folgendes funktionieren oder ?

    pointer ist ein Zeiger auf ein Array mit 10 Elementen.

    funktion( (pointer+2) );
    

    Sollte jetzt nicht einfach der pointer auf das 2. Element des Arrays an die Funktion übergeben werden ? Oder muss man beim Übergeben von Pointern immer das erste Element übergeben ?



  • pointer + 2 zeigt auf das dritte Element. Und die Klammern brauchst du nicht. Aber ansonsten sollte das so funktionieren.



  • Momentan schaut mein code so aus (Auch wenns euch vielleicht grad nicht viel sagt 🙂 )

    *PointerBackup     = WRITE_BUFFER_1;                                                /* Set Active command to Read into buffer */
                *(PointerBackup+1) = 0x00;                                                          /* First byte is don't care */
                *(PointerBackup+2) = (tUI8)((SPIFLS_ActivePagePosition && 0x0300)>>8);              /* Move second 6 bit into comand byte 3 */
                *(PointerBackup+3) = (tUI8)(SPIFLS_ActivePagePosition && 0x00FF);                   /* Comand Byte 4 is dont care on buffer copy */
                SPIFLS_State = SPIFLS_BUFFER_COPY_FLASH;
                IO_RWriteAsync(IO_DEVICE_SPI0,PointerBackup,(SizeBackup*SPIFLS_Conf[SPIFLS_ActiveConfig].BlockSize_u16)+5,0x00, SPIFLS_STATE_WRITE_CALLBACK);   /* Send comand over SPI */
    

    Bei der IO_RWriteAsync übergebe ich den Pointer PointerBackup. Das ganze Funktioniert wunderbar, solange ich es so lasse wie es ist, wenn ich aber beim Parameter unten (Pointer+1) mache funktioniert die Funktion dahinter nicht mehr.

    An Grenzüberschreitungen kann es nicht liegen, der Pointer hat hinten ein paar Elemente zuviel.



  • Tom555 schrieb:

    *(PointerBackup+1) = 0x00;

    Einfacher: PointerBackup[1] = 0x00;

    wenn ich aber beim Parameter unten (Pointer+1) mache funktioniert die Funktion dahinter nicht mehr.

    Was soll denn Pointer+1 bewirken?



  • Kann es sein, daß ab "Pointer+1" nicht die Daten stehen, die deine Funktion erwartet?

    (btw, es wäre wirklich eine Hilfe, wenn du die Parameter aufschlüsseln könntest, die du da an IO_RWriteAsync() übergibst)



  • Es ist so, das ich einen gewissen Buffer vorhalten muss, in den man an die Stelle der ersten 5 Bytes ein Kommando einfügen kann. Das dumme ist nur, das beim schreiben das Kommando nur 4 Bytes braucht, beim lesen aber 5 Bytes. Jetzt wollt ich es dem User so einfach wie möglich machen, das er immer 5 Bytes freilässt, und ich schreib das Kommando dann eben so rein das es passt.

    Also übergebe ich bei Lesekomando pointer und bei schreibkomando pointer+1.

    @CStoll
    Ich habe schon mit dem Debugger durchgesteppt. Die Parameter stehen wirklich da wo sie sein sollen.

    Die Parameter sind einfach beim schreiben Byte1 Kommando, Byte 2+3+4 Adresse.
    Beim Lesen ist es dasselbe, nur das ich halt noch zusätzlich ein 5. Byte mitschicken muss.

    Das ganze ist ein Zugriff auf einen extern über SPI Bus angebundenen Flash Speicher.

    Beim



  • Bei der Write-Funktion wird doch eine Länge mitgegeben. Bei Pointer+1 ist der Buffer natürlich ein Byte kürzer (und hinter der Länge steht immernoch +5)... Da vielleicht?



  • Nein, die Länge stimmt schon, ich hab den Buffer vorsichtshalber auch noch etwas länger gemacht. Also er kommt definitiv nicht drüber.



  • Tom555 schrieb:

    Also übergebe ich bei Lesekomando pointer und bei schreibkomando pointer+1.

    Dann solltest du beim Schreibkommando aber auch das WRITE_BUFFER_1 in Pointer[1] eintragen 😉
    (btw, die Bit-Manipulationen stimmen nicht ganz mit den Kommentaren dahinter überein)

    Die Parameter sind einfach beim schreiben Byte1 Kommando, Byte 2+3+4 Adresse.
    Beim Lesen ist es dasselbe, nur das ich halt noch zusätzlich ein 5. Byte mitschicken muss.

    Da ist deine Zeiger-Bastelei aber überflüssig:

    cc xx xx xx 00
    ^p
       ^p+1
    

    Das zusätzliche Byte für den Lesebefehl steht am Ende des Puffers und stört den Schreibbefehl (vermutlich) gar nicht - wenn du aber pointer+1 dort übergibst, deutet er das erste Byte der Adresse als Befehl (mit etwas Glück bricht er ohne weitere Aktionen ab, aber wahrscheinlicher macht er Dummheiten).



  • Die 00 Dahinter würde ganz sicher stören, das SPI Interface ist da Teilweise sehr pingelig :).

    Die kommentare stimmen nicht, das ist wahr, ich hab die beim Paste and Copy einfach mit rüber gezogen und noch nicht geändert.

    *(pointer+1) = WRITE_BUFFER_1; ist richtig, sorry hab den falschen code schnippsel reinkopiert oben. Aber das Problem bleibt.



  • Tom555 schrieb:

    Die 00 Dahinter würde ganz sicher stören, das SPI Interface ist da Teilweise sehr pingelig :).

    Wenn du dir schon über die 00 Sorgen machen mußt, dann solltest du die Belegung deines Arrays nicht so lasch angehen (was du da erzählst, klingt eher nach "packen wir mal den Wert in das Feld - wird schon passen" :D).

    Die Aufteilung der Daten ist doch für LEsen und Schreiben identisch (abgesehen von dem zusätzlichen Byte am Ende), richtig? Also kannst du die Daten auch identisch aufbauen und passt nur den Größenparameter daran an, welcher Befehl übergeben wird.
    (die Funktion kann ohnehin nicht feststellen, wozu der Speicher HINTER dem zugewiesenen Bereich genutzt wird)



  • Geht leider nicht so einfach, weil das SPI Interface, alles komplett als EINEN Buffer braucht.

    ich geb dir mal ein Beispiel

    10 00 00 00 55 55 55 55 55 55 55 55

    So wäre jetzt :

    10 Kommando
    00
    00 Alle Adressen Null, also ganz an den Anfang schreiben
    00
    55 Alle 55 Bytes sind Daten

    wenn ich jetzt den Pointer bei einem Lesekomando hätte würde es so aussehen

    11 Lesekomando
    00
    00 3 Adressbytes
    00
    00 <--- Zusätzliches Byte
    55
    55 Daten

    Wenn ich den Buffer jetzt bei Lesen und schreiben gleich lasse, schreibt er mir jedesmal das Zusätzliche Byte mit in den Flash. Das will ich aber nicht.



  • nimm doch zwei buffers, dann kommt nichts durcheinander



  • Ich muss den Buffer inklusive Kommando aber als einen einzigen Bytestrom übergeben, sonst funktioniert das Kommando nicht.



  • Dann verwende doch einen Puffer für's Lesen und einen Puffer für's Schreiben 😉



  • Dummerweise ist das bei SPI nicht möglich, da dort genau während ich mein Zeug raustakte gleichzeitig die Antwort reingetaktet wird. Das ist leider Hardwaremäßig so in diesem Bus. Mir wäre es auch lieber das Teil würde warten bis es alles hat und dann antworten.



  • Tom555 schrieb:

    Dummerweise ist das bei SPI nicht möglich, da dort genau während ich mein Zeug raustakte gleichzeitig die Antwort reingetaktet wird. Das ist leider Hardwaremäßig so in diesem Bus. Mir wäre es auch lieber das Teil würde warten bis es alles hat und dann antworten.

    das ist aber eher ein softwareproblem. natürlich kann man eine spi schnittstelle so schreiben, dass die empfangenen daten in einem anderen puffer landen als dem, den man senden möchte. beschreib doch mal deine umgebung, also welchen controller, welche libraries, compiler etc. benutzt du?



  • Ich habs gefunden.

    Steinigt mich, ich hab in einer ganz anderen Funktion weiter unten ein Datenbyte falsch umkopiert und so hat er immer ein Byte zu wenig abgeschickt. Ich könnt gegen die Mauer rennen. Sowas sucht man dann stundenlang.

    Danke denjenigen die sich das angeschaut haben.

    @net
    Ja man kann das schon so machen, ist aber bei HIS standardisierten Treibern eher unpraktisch weil man da die Schnittstellen vorgegeben kriegt. Und da is leider nur ein Buffer vorgesehen.



  • Tom555 schrieb:

    @net
    Ja man kann das schon so machen, ist aber bei HIS standardisierten Treibern eher unpraktisch weil man da die Schnittstellen vorgegeben kriegt. Und da is leider nur ein Buffer vorgesehen.

    also wenn ich mir deine 'IO_RWriteAsync' angucke, dann sieht man schon, dass man der einen pointer und die anzahl der daten übergeben kann, die man versenden will. was ist der letzte parameter? (sieht aus wie eine callback-function/completion routine etc.). ich wette es gibt auch eine dazugehörige IO_RReadAsync, der du auch die adresse eines buffers geben kannst...und der kann sicherlich ein anderer sein, als der, den IO_RWriteAsync bekommen hat, oder?



  • Man kann der Funktion übergeben :

    address --> pointer auf datenbuffer
    size --> anzahl der Blöcke
    location--> Startblock

    Die Blöcke sind frei definierbar.

    Read und Write ind den RWriteAsync und RReadAsync funktionen unterscheiden sich lediglich darin, das der RWrite einen schreibjob auf das Externe Flash startet und der RReadAsync einen Lesejob. Dieser wird dann im Hintergrund von Interrupts abgearbeitet.

    Den Aufruf IO_RWriteAsync den du meinst, hat unser Kunde geschrieben, das heisst für mich Finger weg und Hinnehmen so wie es ist. Das ist ein Aufruf der HIS IO Library. Das dahinter ist tatsächlich eine Callback, die aufgerufen werden soll, wenn der Befehl fertig ist.



  • so hab ich mir das vorgestellt. also muss man nach dem aufruf der funktion den buffer in ruhe lassen, bis die callback angesprungen wurde. das ist an sich nichts, was stress machen sollte. während die 'write'-funktion brav den buffer versendet, kannst du sicherlich mit der 'read'-funktion arbeiten (das 'async' im namen veranlasst mich zu der annahme). d.h. während 'write' aktiv ist, sollte die read-funktion natürlich mit einem anderen buffer arbeiten, sonst gibts datensalat.


Anmelden zum Antworten