Hey,
folgendes Problem, ich darf bei der STM HAL nur Buffer an die SPI
übergeben welche mit einer geraden Adresse anfangen. Ansonsten landet
man im HardFault.
Ist eine ziemlich dämliche Sache aber nun gut, nicht zu ändern.
daher muss ich überprüfen ob die an meine Funktion übergeben Adresse des
Sende-Buffers um eine geradzahlige handelt.
mit dem Code
1
voidmyFunktion(char*sendBuf)
2
{
3
if((sendBuf%2)!=0)
4
{
5
//Abbruch, Fehlerbehandlung
6
}
7
}
bekomme ich folgende Fehlermeldung
"invalid operands to binary % (have 'char *' and 'int')"
meine Q&D Lösung sieht jetzt erst mal so aus:
1
voidmyFunktion(char*sendBuf)
2
{
3
if((((uint32_t)sendBuf)%2)!=0)
4
{
5
//Abbruch, Fehlerbehandlung
6
}
7
}
allerdings gefällt mir der Cast auf 32bit nicht. was ist wenn ich den
code auf eine andere Platform portiere auf dem die Adressen nicht
32bittig sind?
ok bei einem Vergleich auf gerade/ungerade würden auch ein 8bit
(eigentlich sogar nur das letzte Bit) Wert reichen, aber es ist eher die
Frage nach dem "wie mach ich das richtig"
@ HaaanSoul
Es scheint mir ratsamer an der Ursache anzusetzen, als die Folgen zu
vermeiden.
Woher bekommst Du denn eigentlich möglicherweise ungerade (unaligned)
Adressen?
HaaanSoul schrieb:> allerdings gefällt mir der Cast auf 32bit nicht. was ist wenn ich den> code auf eine andere Platform portiere auf dem die Adressen nicht> 32bittig sind?
Dafür gibt uintptr_t
HaaanSoul schrieb:> was ist wenn ich den> code auf eine andere Platform portiere auf dem die Adressen nicht> 32bittig sind?
Dann wird die Einschränkung vermutlich auch eine andere sein.
Theor schrieb:> Es scheint mir ratsamer an der Ursache anzusetzen, als die Folgen zu> vermeiden.>> Woher bekommst Du denn eigentlich möglicherweise ungerade (unaligned)> Adressen?
Hallo,
Die Adresse bekomme ich übergeben, woher die genau stammt kann ich zum
jetzigen Zeitpunkt nicht sagen, da es ein Softwaremodul wird welches
universell eingesetzt werden kann.
kurzes Beispiel wie das passieren kann
jemand implementiert mein Modul und benutzt es so
1
staticchar[20]myBuf;
2
fillBuf(myBuf);// hier einfach mal als Beispiel wie der Buffer gefüllt wird
3
myFunktion(myBuf)
soweit ok, nun kommt derjeneige auf den Gedanken das es sich bei dem
ersten Byte um ein Steuerzeichen handelt welches nicht mit übergeben
werden soll, also benutzt er den folgenden Code
1
staticchar[20]myBuf;
2
fillBuf(myBuf);
3
myFunktion(&myBuf[1])
und schon knallt es bei der Übergabe an die HAL Spi Funktion.
Da fange ich das lieber ab und gebe eine Rückmeldung, was nicht passt.
Die alternative wäre den ganzen Buffer in eine zweite Variable zu
kopieren, was aber auf kleinen µC eine riesen Platzverschwendung währe.
HaaanSoul schrieb:> und schon knallt es bei der Übergabe an die HAL Spi Funktion.
Welche Art von Daten werden da überhaupt übergeben und warum sind die
statisch?
> Da fange ich das lieber ab und gebe eine Rückmeldung, was nicht passt.> Die alternative wäre den ganzen Buffer in eine zweite Variable zu> kopieren, was aber auf kleinen µC eine riesen Platzverschwendung währe.
Das wäre nicht wirklich tragisch, jeder STM32 hat genug RAM, aber es
wäre nur ein Workaround und keine Lösung des Problems.
>folgendes Problem, ich darf bei der STM HAL nur Buffer an die SPI>übergeben welche mit einer geraden Adresse anfangen. Ansonsten landet>man im HardFault.
Ich habe mit HAL SPI noch nie gearbeitet, das hier halte ich aber für
Quatsch.
Die HAl Funktion erwartet einen Pointer auf einen Buffer? Vom welchen
Typ Buffer?
Poste bitte die komplette Funktion.
Wahrscheinlich müsst du statt sendBuf (char *)sendBuf übergeben....
+ und - machen bei Pointern was ganz anderes als bei einem Int.
Eine Funktion % auf einen Pointer kenne ich nicht.
Von daher ist Dein Cast genau richtig.
Ob du das auf 32, 8 oder 16 Bit castest oder uintptr_t, ist erstmal
egal, solange es unsigned ist.
Von daher: Alles richtig, Weitermachen!
HaaanSoul schrieb:> Theor schrieb:>> Es scheint mir ratsamer an der Ursache anzusetzen, als die Folgen zu>> vermeiden.>>>> Woher bekommst Du denn eigentlich möglicherweise ungerade (unaligned)>> Adressen?>> Hallo,>> Die Adresse bekomme ich übergeben, woher die genau stammt kann ich zum> jetzigen Zeitpunkt nicht sagen, da es ein Softwaremodul wird welches> universell eingesetzt werden kann.>> kurzes Beispiel wie das passieren kann> jemand implementiert mein Modul und benutzt es so>
1
>staticchar[20]myBuf;
2
>fillBuf(myBuf);// hier einfach mal als Beispiel wie der Buffer gefüllt
3
>wird
4
>myFunktion(myBuf)
5
>
>> soweit ok, nun kommt derjeneige auf den Gedanken das es sich bei dem> ersten Byte um ein Steuerzeichen handelt welches nicht mit übergeben> werden soll, also benutzt er den folgenden Code>
1
>staticchar[20]myBuf;
2
>fillBuf(myBuf);
3
>myFunktion(&myBuf[1])
4
>
>> und schon knallt es bei der Übergabe an die HAL Spi Funktion.> Da fange ich das lieber ab und gebe eine Rückmeldung, was nicht passt.> Die alternative wäre den ganzen Buffer in eine zweite Variable zu> kopieren, was aber auf kleinen µC eine riesen Platzverschwendung währe.
Hm. Sowas Ähnliches dachte ich mir schon.
Man könnte es auch einfach bei dem Hardfault belassen. Der Anwender
Deiner Bibliothek müsste da ja sowieso beim Testen drauf stossen. Mir
täte es um die Laufzeit leid. Naja. Ansichtssache.
Neben uintptr_t gibt (oder gab?) es dann noch ptrdiff_t.
Da ja das SPI Bytes ausgeben kann, sollte das HAL-SPI aber auch jede
Byteadresse verarbeiten können.
Die beste Lösung wäre daher, den Bug im HAL-SPI zu reparieren.
zu dem besagten HardFault.
Was mir in dem Zusammenhang auch noch nicht klar ist, mann kann die SPI
auf bis zu 16Bits stellen, die HAL-Funktion erwartet aber einen *uint8_t
Theor schrieb:> Man könnte es auch einfach bei dem Hardfault belassen. Der Anwender> Deiner Bibliothek müsste da ja sowieso beim Testen drauf stossen. Mir> täte es um die Laufzeit leid. Naja. Ansichtssache.
Die Laufzeit ist an der Stelle nicht so entscheidend, das Problem beim
belassen wäre ja dann das der Nutzer erst mal wieder herausfinden müsste
das es an der Adresse liegt, ist nicht ganz so offensichtlich.
Da wäre im einfachsten Fall eine while(1){//Du musst eine gerade
Adressen übergeben} aus meiner Sicht noch sinnvoller.
A. F. schrieb:> Das wäre nicht wirklich tragisch, jeder STM32 hat genug RAM, aber es> wäre nur ein Workaround und keine Lösung des Problems.
der von mir verwendete µC hat nur 6kb RAM, also mit reichlich Speicher
ist da nicht, wenn mann z.B. einen Buffer von 1k vorhält welchen man
senden möchte...
HaaanSoul schrieb:> while(1){//Du musst eine gerade> Adressen übergeben} aus meiner Sicht noch sinnvoller.
Hast Du denn eine Art stderr implementiert? Für solche Fälle ist das
vorhandensein von assert() und error() schon eine feine Sache, dass man
nicht erst mit dem Debugger nach dem Problem suchen muss (oder damit
deutlich schneller ist).
Walter T. schrieb:> Hast Du denn eine Art stderr implementiert? Für solche Fälle ist das> vorhandensein von assert() und error() schon eine feine Sache, dass man> nicht erst mit dem Debugger nach dem Problem suchen muss (oder damit> deutlich schneller ist).
In diesem speziellen Fall sieht die Fehlerbehandlung noch etwas anders
aus, was hier aber wirklich zu weit führen würde, es ging mir ja
hauptsächlich um die Überprüfung gerade/ungerade :)
Grundsätzlich gebe ich dir da aber auf jeden Fall recht.
Theor schrieb:> Man könnte es auch einfach bei dem Hardfault belassen. Der Anwender> Deiner Bibliothek müsste da ja sowieso beim Testen drauf stossen. Mir> täte es um die Laufzeit leid. Naja. Ansichtssache.
Ehrlich gesagt: Nein. Ein korrektes Funktionieren der Software steht an
erster Stelle. Danach erst kommen Laufzeitoptimierungen. Für nicht
genutzte Rechenzeit gibt es kein Geld zurück. ;-)
Auf jeden Fall gehört so ein Bug in den Release Notes zu der
SW-Bibliothek dokumentiert.