Hallo zusammen
Auf einem Attiny412 versuche ich einen string / ein char-array zu
printen. Allerdings funktioniert das nicht, und ich weiss nicht wieso.
Mein Code ist:
Wie ihr seht, wird das Array in der Schleife nur als "\0\0\0" geprinted.
das "t" habe ich nur als delimiter mitgeschickt, damit man sieht ab wo
die Schleife fertig ist.
Kompiliert habe ich mit
N. M. schrieb:> Ich tippe Mal ins blaue und sag der Baudratenfehler ist bei 16MHz> und> 115200 zu groß.> Versuch es Mal mit 9600.
Leider nein, das hatte ich bereits getestet (und jetzt gerade
nocheinmal).
spess53 schrieb:> Ja, -3,5% sind schon ganz happig.
Hmm.. wie kommst du auf die 3.5%?
Ich komme auf 555.55.. als BAUD wert, aufgerundet auf 556.
Wenn ich das nun zurückrechne komme ich auf eine Baudrate von 115107 -
was eine Abweichung von -0.07% gibt
Wenn ich auch "mal ins Blaue tippen" darf (als Assemblerprogrammierer):
da nur der Aufruf in der Schleife nicht funktioniert, vermute ich ein
Problem mit C, vielleicht dieses 'size_t'.
S. Landolt schrieb:> Wenn ich auch "mal ins Blaue tippen" darf (als Assemblerprogrammierer):> da nur der Aufruf in der Schleife nicht funktioniert, vermute ich ein> Problem mit C, vielleicht dieses 'size_t'.
Dachte auch an ein Compiler Problem. Das 'size_t' hatte ich auch bereits
ausgetauscht durch int und int16_t - was alles nichts genützt hat. Wenn
ich 'i' über UART ausgebe mit 'USART0_sendChar((char) i + 48)' wird
schön 0, 1, 2, 3 ausgegeben...
Neuling schrieb:> wird sie gar nicht erst ausgeführt,
Ich tippe mal auf integer promotion, dann ist auch klar warum die nicht
ausgeführt wird!
Ich habe mir abgewöhnt den Compiler als Schuldigen anzusehen, weil zu
99.999% war ich immer der Dussel.
Neuling schrieb:> Angehängt findet ihr noch das binary sowie ein lst file vom kompilierten> C-Code.
Ich hab' mir nur das lst-File angeschaut. Mal abgesehen davon, dass der
Optimizer da eine ziemlich ineffiziente Arbeit abliefert, ist der
generierte Code ziemlich sicher sachlich korrekt.
Sprich: Das sollte eigentlich funktionieren. Keine Ahnung, warum's nicht
tut.
Grob zur Erklärung, was da (in dem nicht funktionierenden Bereich)
passiert:
Es wird auf dem Stack Platz für 5 Bytes geschaffen (4 Chars+NUL, also
OK), dann wird die Stringkonstante aus dem Flash dorthin kopiert,
allerdings über das SRAM-Mapping des Flash. Dann wird sie wieder
zeichenweise vom Stack geholt und an die (offensichtlich ja
funktionierende) Ausgaberoutine verfüttert.
Der Stack wurde zu Programmbegin auch korrekt initialisiert, zeigt also
in's SRAM, wie es sich gehört.
Die einzige Unsicherheit besteht IMHO darin, ob die Stringkonstante
tatsächlich an der erwarteten Stelle im SRAM-Mapping des Flash liegt.
Von anderen XMega-Erben sind ja bereits Bugs genau bei dieser Sache
bekannt...
Ein schöner Test wäre es, zwischen diesen beiden Zeilen
char hello[] = "Hi\r\n";
for (size_t i = 0; i < 4; i++) {
mal folgendes Stück Code einzufügen:
hello[0]='O';
hello[1]='o';
hello[2]='p';
hello[3]='s';
und sich dann die UART-Ausgabe anzuschauen.
Kommt das Oops, ist Mikrochip schuld.
Die Schleife ist korrekt und sollte so funktionieren. Tut sie ja auch,
sie sendet 4 Bytes, nur nicht die gewünschten. Meine Vermutung: die
Strings werden nicht korrekt ins RAM kopiert (falscher Startupcode?).
Die folgenden Einzelausgaben (hello[0] etc) werden vom Compiler
optimiert und benutzen den String gar nicht.
c-hater schrieb:> Ein schöner Test wäre es, zwischen diesen beiden Zeilen>> char hello[] = "Hi\r\n";>> for (size_t i = 0; i < 4; i++) {>> mal folgendes Stück Code einzufügen:>> hello[0]='O';> hello[1]='o';> hello[2]='p';> hello[3]='s';>> und sich dann die UART-Ausgabe anzuschauen.>> Kommt das Oops, ist Mikrochip schuld.
Tatsächlich, der Output ist dann:
1
$ cat /dev/ttyUSB0 | xxd -c 9 -g 1
2
00000000: 4f 6f 70 73 74 4f 6f 70 73 OopstOops
3
00000009: 4f 6f 70 73 74 4f 6f 70 73 OopstOops
4
00000012: 4f 6f 70 73 74 4f 6f 70 73 OopstOops
5
0000001b: 4f 6f 70 73 74 4f 6f 70 73 OopstOops
Was heisst das jetzt, respektive was genau läuft falsch?
Neuling schrieb:> Was heisst das jetzt, respektive was genau läuft falsch?
Das heißt, das du einen Hardware-Bug im Tiny412 gefunden hast. Der
allerdings in ähnlicher Form bereits vom AVR128DAxx bekannt ist...
c-hater schrieb:> Das heißt, das du einen Hardware-Bug im Tiny412 gefunden hast. Der> allerdings in ähnlicher Form bereits vom AVR128DAxx bekannt ist...
Erklär mal bitte für mich Doofi mehr. Ich weis nur, dass der AVR128 da
ein Mapping Issue hat ...
c-hater schrieb:> Das heißt, das du einen Hardware-Bug im Tiny412 gefunden hast. Der> allerdings in ähnlicher Form bereits vom AVR128DAxx bekannt ist...
Na toll, hast du eine Idee wie der umgangen werden kann? Ich meine, das
trifft dann ja auf alle Array's zu - nicht nur auf diesen String oder?
> Das heißt, das du einen Hardware-Bug im Tiny412 gefunden hast.
Das ist so früh aber eine mutige Behauptung - gibt noch genügend andere
Möglichkeiten, z.B. unpassender Startupcode.
merciMerci schrieb:> Erklär mal bitte für mich Doofi mehr. Ich weis nur, dass der AVR128 da> ein Mapping Issue hat ...
Naja, und jetzt wissen wir, dass auch der Tiny412 ein solches hat. Was
gibt es da noch groß zu erklären?
foobar schrieb:> Das ist so früh aber eine mutige Behauptung - gibt noch genügend andere> Möglichkeiten, z.B. unpassender Startupcode.
Der Startupcode ist im lst-File enthalten und macht alles richtig,
nämlich rein garnix bezüglich des Mapping. Das Map-Fenster im
SRAM-Bereich ist groß genug, dass es den gesamten Flash eines Tiny412
abbilden kann. Es gibt also keinen Grund, irgendetwas am default Mapping
zu ändern. Und übrigens auch keine Möglichkeit dafür (das ist der
einzige Unterschied zur Sachlage bei den AVR128DAxx)...
c-hater schrieb:> foobar schrieb:>>> Das ist so früh aber eine mutige Behauptung - gibt noch genügend andere>> Möglichkeiten, z.B. unpassender Startupcode.>> Der Startupcode ist im lst-File enthalten und macht alles richtig,> nämlich rein garnix bezüglich des Mapping. Das Map-Fenster im> SRAM-Bereich ist groß genug, dass es den gesamten Flash eines Tiny412> abbilden kann. Es gibt also keinen Grund, irgendetwas am default Mapping> zu ändern. Und übrigens auch keine Möglichkeit dafür (das ist der> einzige Unterschied zur Sachlage bei den AVR128DAxx)...
Hast du eine Idee, wie ich mit dem Fehler umgehen kann? Da ich mehrere
attiny412 habe wäre es schade sie wegzuschmeissen. Wäre eine Möglichkeit
immer wenn ich ein Array brauche, es mit
1
intarr[10];
2
for(inti=0;i<10;i++)
3
arr[i]=0;
zu initialisieren? Respektive überall wo möglich 'const int arr[] = {
... };' zu verwenden?
Neuling schrieb:> Na toll, hast du eine Idee wie der umgangen werden kann? Ich meine, das> trifft dann ja auf alle Array's zu - nicht nur auf diesen String oder?
Frage1:
Ja, aber die wird dir nicht gefallen: Programmiere Assembler, denn
kontrollierst du selber, wie du auf den Flash zugreifst...
Frage2:
Ja. Wird alle konstanten Daten betreffen, sofern der Compiler die
Zugriffe nicht durch Rückgriff auf andere Codevarianten wegoptimiert,
wie es ja bereits in deinem Originalcode passiert ist, bei dem zweiten
Teil der Aufgabe hat er den Zugriff auf das bereits aufwendig im SRAM
erzeugte Array durch ein paar immediate-loads ersetzt...
In dem geänderten Code konnte er das nicht mehr tun, weil wir an dem
Array rumgepfuscht haben, deswegen gibt's auch im zweiten Teil der
Ausgabe jetzt ein Oops...
>> Das ist so früh aber eine mutige Behauptung - gibt noch genügend andere>> Möglichkeiten, z.B. unpassender Startupcode.>> Der Startupcode ist im lst-File enthalten und macht alles richtig,> nämlich rein garnix bezüglich des Mapping.
Oh, sorry - hatte in das .lst gar nicht reingeschaut. Sieht tatsächlich
korrekt aus. War mir noch einfällt, wäre, dass die .rodata-Section
nicht nach 0x11e ins FLASH kopiert wurde (dann wäre aber FFs
wahrscheinlicher als die 00s). Das .hex könnte da Aufschluß geben.
Wenn das auch korrekt ist, wird's eng ;-)
Neuling schrieb:> foobar schrieb:>> Das .hex könnte da Aufschluß geben.>> Wenn das auch korrekt ist, wird's eng ;-)>> Hab das .hex angehängt. Danke für eure Hilfe :)
Das ist das Hex welches Programms? Des ursprünglichen oder das mit dem
von mir vorgeschlagenen Testcode?
Hier das mit dem aktuellen 'Atmel Studio 7' kompilierte Programm des
TOs.
Der String "Hi\r\n" - der im obigen Hex-File fehlt - ist im Datensatz
mit dem Sternchen.
c-hater schrieb:> Das ist das Hex welches Programms? Des ursprünglichen oder das mit dem> von mir vorgeschlagenen Testcode?
War das hex des ursprünglichen.
foobar schrieb:> In seinem objcopy zum Erstellen des hex-Files fehlt wohl einfach nur das> "-j .rodata":
Ja, das wars :D Danke vielmals für eure super Hilfe :)
Neuling schrieb:> foobar schrieb:>> In seinem objcopy zum Erstellen des hex-Files fehlt wohl einfach nur das>> "-j .rodata":>> Ja, das wars :D Danke vielmals für eure super Hilfe :)
OK, also doch kein Mikrochip-Bug, sondern nur eine Instanz von: Mit
Hochsprachen-Compilern (und Linkern) kann man massenhaft Probleme lösen,
die man ohne sie überhaupt nicht hätte...
c-hater schrieb:> OK, also doch kein Mikrochip-Bug, sondern nur eine Instanz von: Mit> Hochsprachen-Compilern (und Linkern) kann man massenhaft Probleme lösen,> die man ohne sie überhaupt nicht hätte...
Ja, das ist absolut so. Allerdings vereinfachen sie - sobald die
Environment stimmt - vieles. C mag ich dabei aber auch nicht besonders,
da es einfach ist mühsam zu findende Fehler einzubauen. Da hab ich
lieber Rust (ist aber für AVR nicht wirklich geeignet da LLVM fehlt).
Und die Frage wäre schnell beantwortet gewesen - hätte ich das ganze
Makefile gepostet...
Neuling schrieb:> Und die Frage wäre schnell beantwortet gewesen - hätte ich das ganze> Makefile gepostet...
Da fällt mir noch was ein: der Linker hätte doch eigentlich furchtbar
meckern müssen, ohne diese Sektion gibt es doch eine nicht auflösbare
Referenz, oder?
Also mir scheint, das sich das Gewicht verlagert, das Thema aber noch
nicht wirklich durch ist...
c-hater schrieb:> Da fällt mir noch was ein: der Linker hätte doch eigentlich furchtbar> meckern müssen, ohne diese Sektion gibt es doch eine nicht auflösbare> Referenz, oder?
Naja, gelinkt wurde ja direkt beim kompilieren, und Meldungen/Warnungen
gabs da keine...
Neuling schrieb:> c-hater schrieb:>> Da fällt mir noch was ein: der Linker hätte doch eigentlich furchtbar>> meckern müssen, ohne diese Sektion gibt es doch eine nicht auflösbare>> Referenz, oder?>> Naja, gelinkt wurde ja direkt beim kompilieren, und Meldungen/Warnungen> gabs da keine...
Eben. Das genau ist das Problem, es hätte welche geben MÜSSEN...
Es kann ja schließlich nicht sein, dass irgendwas refenziert wird, was
im Binary überhaupt nicht mehr enthalten ist.
Diese Situation muß ganz klar einen Fehler werfen. Wäre das passiert,
würde möglicherweise dieser ganze Thread überhaupt nicht existieren...
c-hater schrieb:> Es kann ja schließlich nicht sein, dass irgendwas refenziert wird, was> im Binary überhaupt nicht mehr enthalten ist.
Im binary ist es ja enthalten, nur im hex nicht (die verwendeten
optionen -j von avr-objcopy kopieren nur die angegebenen sections vom
bin ins hex).