Hallo! Da habe ich ein altes Board gefunden, auf das ich irgendwann einen Atmega8A gelötet hatte, und wollte "mal eben" testen, ob's noch funktioniert. "Mal eben" ist jetzt zwei Tage her und ich bin ausreichend frustriert, um hier nachzufragen: m8a_Pin-Test.c funktioniert, m8a_Pin-Test2.c funktioniert nicht. Warum? Hintergrund: Ich hatte die Idee einen Array für die Port-Pins anzulegen und in der Timer-ISR über die einzelnen Pins zu gehen und jeweils einen auf Output, low zu stellen und alle anderen auf Input mit pull-up. Aber nichts tat sich. Nun kann man sich ja mit Pointern beim Dereferenzieren ins Knie schießen, besonders, wenn der Compiler auf die Idee kommt, den Array im Flash zu belassen. Testweise habe ich den Array mal mit "const PinDesc PROGMEM..." absichtlich im Flash gelassen und von dort mit pgm_read_word() ausgelesen. Das funktioniert, und die Pins werden wie erwartet getoggelt. Dann habe ich die "Array im RAM"-Version (m8a_Pin-Test2.c) so umgestrickt, dass sie fast genau der "Array im Flash"-Version (m8a_Pin-Test.c) entspricht - sie funktioniert trotzdem nicht. Die ISR wird aufgerufen, das ist es nicht. Der Array liegt in der .data section, sollte von __do_copy_data ins RAM kopiert worden sein und hat da offenbar auch einen von 0 verschiedenen Inhalt. Also muss der wohl den falschen Typ haben - aber wie? Ich seh's nicht. Und sowohl in simulavr als auch in simavr funktioniert die "Array im RAM"-Version.
Oh, vergessen: Ich nutze avr-gcc 14.1 aus eclipse mit:
1 | gcc -mmcu=${DEVICE} -DF_CPU=16000000UL -I/Pfad/zu/avr-gcc-14.1.0-x64-linux/avr/include -Os -Wall -c -fmessage-length=0 -ffunction-sections -fdata-sections |
Was genau funktioniert denn nicht? Die Pins werden nicht geschaltet? Hast du mal versucht... * die erzeugte Programmdatei zu disassemblieren und beide Versionen zu vergleichen, ob die Daten dort sind bzw. abgelegt werden, wo sie sein sollen? * die Daten zu Beginn des Programms seriell auszugeben und zu vergleichen? (Wobei mit Daten das Array der Pin-Adressen gemeint ist.)
Manuel H. schrieb: > Was genau funktioniert denn nicht? Die Pins werden nicht geschaltet? Genau. Es rühren sich nur die "zum Debuggen" ohne Zugriff auf den Array getoggelten PB0 und PD2. > Hast du mal versucht... > > * die erzeugte Programmdatei zu disassemblieren und beide Versionen zu > vergleichen, ob die Daten dort sind bzw. abgelegt werden, wo sie sein > sollen? Ja. Bei der Flash-Version liegt das Array in .text, bei der RAM-Version in .data. Der Inhalt scheint identisch. > * die Daten zu Beginn des Programms seriell auszugeben und zu > vergleichen? Das kommt morgen, wenn ich wieder zu Hause bin. Ich habe gerade keinen USB-seriell-Adapter bei mir. Aber in m8a_Pin-Test2.c wird der Inhalt des Arrays geprüft. Wenn da nichts drin wäre, würde PD2 nicht getoggelt. Wird er aber.
Da optimiert der compiler wohl was weg. Probier mal beim Schreiben des Registers den Zeiger volatile zu machen, nicht das Register: uint8_t * volatile ddr = (uint8_t*) ddrAddr; uint8_t * volatile port = (uint8_t*) ddrPort;
Wann immer man anfängt, Typecasts zu schreiben, sollte man sich Gedanken machen, ob sie wirklich nötig sind. Warum kann deine Tabelle nicht gleich mit den korrekten Zieltypen arbeiten? Im Anhang mal mein Vorschlag. Compiliert zumindest ohne Warnungen, und der erzeugte Code sah mir auf den ersten Blick plausibel aus.
Ich habe mal alle 3 Versionen kompiliert (mein GCC ist allerdings Version 15.2). Wegoptimiert wird da allerdings nichts - die Befehle zum Setzen der Register sind vorhanden. Das hätte mich auch gewundert, weil es dann in simulavr / simavr auch nichts hätte tun sollen.
Manuel H. schrieb: > (mein GCC ist allerdings Version 15.2) Meiner ist 15.1 in der Arduino IDE Jörg W. schrieb: > Im Anhang mal mein Vorschlag. Diesen habe ich verwendet. Habe keinen m8a da, drum einen m328p verwendet. Einzige Änderung im Programm: // TIMSK |= (1 << OCIE1A); TIMSK1 |= (1 << OCIE1A); Es sind nur 12 LED an den Pins, aber die zirkulieren schön durch.
:
Bearbeitet durch User
Sorry, bei mir ist es gestern etwas spät geworden. Daher erst jetzt meine Meldung. Zunächst das TL;DR: Problem gelöst. Es ist doch immer wieder schön, wie kreativ man sich mit einer IDE ins Knie schießen kann. Vielen Dank für Eure Anteilnahme. ;-) Lange Version: Jörg W. schrieb: > Wann immer man anfängt, Typecasts zu schreiben, sollte man sich Gedanken > machen, ob sie wirklich nötig sind. Ja, alles richtig. Am Anfang hatte ich ja auch:
1 | typedef struct { |
2 | volatile uint8_t *ddr; |
3 | volatile uint8_t *port; |
4 | uint8_t mask; |
5 | } PinDesc; |
6 | |
7 | PinDesc testPins[] = { |
8 | // PORTB (exclude PB6, PB7)
|
9 | { &DDRB, &PORTB, _BV(PB0) }, ... |
und dann in der ISR:
1 | const PinDesc *pin = &testPins[currentPin]; |
2 | ...
|
3 | *(pin->ddr) |= pin->mask; // DDRx = 1 → output |
4 | *(pin->port) &= ~pin->mask; // PORTx = 0 → drive low |
Aber nachdem das nicht ging aber in der Flash-Version schon, habe ich die Unterschiede zwischen den Source-Dateien minimiert, um im diff nur noch das Wesentliche zu sehen. Nun habe ich versucht, die Daten per UART auszugeben - und bin gleich vor eine Wand gelaufen. Wenn ich in eine Firmware eine UART-Routine einbaue, dann lasse ich die auch gleich beim Start Name und Version der Anwendung ausgeben. Aber es kam nur x-mal 0xFF. Weiteres Probieren ergab: Ein Register konnte ich auslesen und per UART ausgeben. Ebenso Bytes aus dem Flash, die per PROGMEM angelegt und per pgm_read_byte() gelesen wurden. Aber ein string literal? Nope. Nada. Harald schrieb: > Da optimiert der compiler wohl was weg. Nee, wie (fast) immer der User. Dieses Laptop benutze ich nur selten und eigentlich nie zum programmieren. Aber irgendwann hatte ich da Eclipse und avr-gcc installiert, wohl nur halbseiden eingerichtet und offenbar nie benutzt. Aus unerfindlichen Gründen stand bei "Post-build Steps":
1 | avr-size ${ProjName} ;avr-objcopy -O ihex -j text ${ProjName} ${ProjName}.hex |
Irgendwer muss da an meinem Laptop gewesen sein... ;-)
Np R. schrieb: > Irgendwer muss da an meinem Laptop gewesen sein... ;-) Ah, der Finder des Fehlers bekommt ein goldenes Manual von "objcopy" als Finderlohn. :-) ps: Lass das blöde iHex-File einfach weg. Brauchste nicht, braucht keiner. Nimm das ELF-File.
:
Bearbeitet durch Moderator
Jörg W. schrieb: > Lass das blöde iHex-File einfach weg. Brauchste nicht, braucht > keiner. Nimm das ELF-File. avr-libc Doku sagt:
1 | Generating Intel Hex Files |
2 | ========================== |
3 | |
4 | We have a binary of the application, but how do we get it into the |
5 | processor? Most (if not all) programmers will not accept a GNU |
6 | executable as an input file, so we need to do a little more processing. |
7 | The next step is to extract portions of the binary and save the |
8 | information into .hex files. |
https://avrdudes.github.io/avr-libc/avr-libc-user-manual/group__demo__project.html
Johann L. schrieb: > Most (if not all) programmers will not accept a GNU > executable as an input file Das ist wohl nicht mehr aktuell. "Some programmers ..." würde passen.
Johann L. schrieb: > Ach. Wenn sich hier einer mit AVRdude auskennt, dann ist es doch wohl unser Jörg Wunsch! Oder zweifelst du das an?
Arduino F. schrieb: > Johann L. schrieb: >> Ach. > > Wenn sich hier einer mit AVRdude auskennt, dann ist es doch wohl unser > Jörg Wunsch! > > Oder zweifelst du das an? Wo hab ich denn irgendwas angezweifelt? Außer der Aktualität der Doku.
Johann L. schrieb: > Außer der Aktualität der Doku. Da hast du völlig Recht. Man könnte das natürlich noch drin lassen, aber halt in deutlich abgeschwächter Form …
Johann L. schrieb: > Ist von 2002 Noch von Ted Roth. Der hatte dann aus persönlichen Gründen sehr schnell aufgegeben.
Jörg W. schrieb: > Johann L. schrieb: >> Außer der Aktualität der Doku. > > Da hast du völlig Recht. > > Man könnte das natürlich noch drin lassen, aber halt in deutlich > abgeschwächter Form … Das Beispiel auf avrdude anzupassen fänd ich ganz schon, mit Target wie "make flash". Das "aktuelle" Makefile erstellt ja nur die Binaries, ohne was damit zu machen. Oder Targets "flash-elf" "flash-hex" etc. Falls da noch Zeit ist bis zur nächsten Release.
:
Bearbeitet durch User
Johann L. schrieb: > Das Beispiel auf avrdude anzupassen fänd ich ganz schon, mit Target wie > "make flash". Stimmt. Mache ich ja für mich selbst auch so. ;-) Auch müssten die Codebeispiele mal überarbeitet werden, einen STK500 hat ja heute kaum noch jemand. Allerdings hatte der natürlich mit seinen 8 LEDs und 8 Tasten schön viel Hardware zum Spielen gleich an Bord.
Jörg W. schrieb: > Auch müssten die Codebeispiele mal überarbeitet werden, Immerhin scheinen die examples noch zu compilieren — zumindest "demo", das ja beim Build generiert wird. Aber Zeug wie SIGNAL und avr/signal.h ist auch schon etwas angestaubt. > einen STK500 hat ja heute kaum noch jemand. Da kann ich mit meinen selbstgebastelten Programmern und Boeards nicht mitreden... Sollte aber doch fast egal sein, solange man LED-Ports etc. anpassen kann. Ist denn schon absehbar wann es eine neue libc Version gibt?
Johann L. schrieb: > Ist denn schon absehbar wann es eine neue libc Version gibt? September? Könnte realistisch sein, und die genannten Dinge noch davor machbar.
Jörg W. schrieb: > September? Klingt gut. Paar Fragen hab ich aber noch. Welchen Kanal nehm ich denn da am besten? Ich will ja hier nicht alles zuspammen...
:
Bearbeitet durch User
Johann L. schrieb: > Welchen Kanal nehm ich denn da am besten? Ich hab dir endlich mal eine Mail geschrieben. ;-)
Jörg W. schrieb: > einen STK500 hat > ja heute kaum noch jemand. Allerdings hatte der natürlich mit seinen 8 > LEDs und 8 Tasten schön viel Hardware zum Spielen gleich an Bord. Ich war früher gerne auf den Seminaren der Halbleiterhersteller. Da bekam man in der Regel auch Eval-Boards usw. Mittags gab es ein reichliches Buffet und am Abend konnte man sich mit den Entwicklern bei einem Glas Wein noch unterhalten. Diese Zeiten sind leider lange vorbei. Ich habe noch das erste STK für AT90S1200/2313/8515. Da saß ein AT89C2051 als Programmer drauf. Dann gab es das STK300 mit ATmega103, leider ohne Programmer-µC. Das mußte man an den LPT-Port anschließen, habe ich daher nie benutzt. Und dann das originale STK500 mit AT90S1200 und AT90S8535. Der AT90S1200 war nur für Firmware-Updates zuständig, da die AVRs alle noch keinen Bootloader unterstützten. Somit konnte man das STK500 auch nicht aussperren.
Jörg W. schrieb: > ps: Lass das blöde iHex-File einfach weg. Brauchste nicht, braucht > keiner. Nimm das ELF-File. Och, das iHex bleibt für immer. Z.B. der Galep-5 kann gar kein ELF. Bei Leiterplatten bleibt das Gerber ja auch für immer.
Peter D. schrieb: > Och, das iHex bleibt für immer. > Z.B. der Galep-5 kann gar kein ELF. Auch der wird in Rente gehen. Für AVRs (über die wir hier reden) hat(te) der sowieso keine so herausragende Bedeutung. > Bei Leiterplatten bleibt das Gerber ja auch für immer. Keineswegs, es gibt inzwischen einige (viele?) Fertiger, die ODB++ unterstützen, und Gerber hat sich zumindest mit X2 weiterentwickelt. Ja, ist nicht wie ELF, es sind immer noch Einzeldateien, die ein Zip drum herum brauchen.
Jörg W. schrieb: > Keineswegs, es gibt inzwischen einige (viele?) Fertiger, die ODB++ > unterstützen Hab mal geschaut, im Altium OutputJob gibt es die Option ODB++ Files, da weiß ich aber nicht was man da alles konfigurieren muß. Es entsteht ein Zip mit 53 Dateien und 37 Ordnern, 4MB (1MB Zip). Also deutlich mehr Schrunz, als bei Gerber/NC Drill. Ich müßte mal den Fertiger fragen, ob der daran überhaupt Interesse hat und was er davon wirklich braucht. Es ist immer viel Arbeit, etwas bewährtes durch was neues zu ersetzen. Der bisherige OutputJob wurde schon viele Jahre nicht mehr angefaßt, sondern immer nur in neue Projekte kopiert.
:
Bearbeitet durch User
Peter D. schrieb: > Also deutlich mehr Schrunz, als bei Gerber/NC Drill. Anders gesagt: deutlich klarer im Detail. Bei den einzelnen Gerberdateien brauchte es ja fast immer irgendeine Form der Nebenabsprache, damit der Empfänger sich auch sicher sein kann, dass er sie genau so verwendet, wie der Absender sie meinte – ob nun in Form einer separaten Beschreibungsdatei oder einer Namenskonvention. > Ich müßte mal den Fertiger fragen, ob der daran überhaupt Interesse hat > und was er davon wirklich braucht. Ich habe es letztens bei Aisler mal benutzt (auch aus Altium heraus), das hat auf Anhieb und völlig aufwandsarm für mich klaglos funktioniert. Aber das ist jetzt hier genug OT. Es ging ja darum, dass der TE sich selbst beim Produzieren der iHex-Datei ins Knie geschossen hatte, was ihm bei direkter Verwendung der ELF-Datei gar nicht hätte passieren können.
Jörg W. schrieb: > bei direkter Verwendung der ELF-Datei In der AVR Abteilung der Arduino IDE wird die Bootloader .hex mit der Anwendung .hex verschmolzen, was ein recht trivialer Vorgang ist. Wie macht man das bei einer .elf am einfachsten?
Arduino F. schrieb: > In der AVR Abteilung der Arduino IDE wird die Bootloader .hex mit der > Anwendung .hex verschmolzen, was ein recht trivialer Vorgang ist. Wofür das? Wenn du einen Bootloader hast, überschreibt der sich eh nicht selbst. Ansonsten kann man den sicher als separate Objektdatei mit eigener section dazu linken.
Jörg W. schrieb: > Wofür das? Wenn du einen Bootloader hast, überschreibt der sich eh nicht > selbst. Bei einem Upload per ISP ist der Bootloader außen vor. Bei einem Chip Erase ist auch der Bootloader weg. Das EEPROM lässt sich nicht aus/über dem verwendeten Optiboot beschreiben. Es ist in manchen Situationen schlicht praktisch Bootloader, EEPROM und Anwendung in einem Rutsch zu schreiben. Ansonsten: Das "Warum das so gemacht wird?" kann ich nicht beantworten, denn ist nicht auf meinem Mist gewachsen. Ist vor über 10 Jahren so gebaut worden. Jörg W. schrieb: > Ansonsten kann man den sicher als separate Objektdatei mit eigener > section dazu linken. Der Bootloader liegt als .hex und als Quellcode vor. Ein übersetzen des Bootloaders ist in der IDE nicht vorgesehen, auch wenn die Toolchain vollständig vorliegt. Wobei ich meine, dass make fehlt, bin mir da aber nicht sicher. So wie ich das sehe wäre dafür ein tiefgreifender Umbau des Arduinobuilders nötig. Eine AVR Extrawurst, die bei den anderen µC Typen dann zu Seiteneffekten führen könnte. Nein, ich erwarte nicht, dass das jemand umbaut. Und ich sehe mich dazu nicht in der Lage. Darum auch meine Frage nach "einfach". Deine Antwort interpretiere ich so: Nein! Nicht einfach.
Arduino F. schrieb: > Nein! Nicht einfach. Naja, irgendwas müsstest du in jedem Falle dafür machen. Wenn man Umbauten kategorisch ausschließt, dann kann man auch nie etwas ändern. Den Bootloader gleich mit zu compilieren (und ihm eine eigene section zu spendieren), wäre durchaus keine unelegante Lösung. Hätte auch den Vorteil, dass ihn sich jemand einfach lokal ändern kann, falls er dafür Bedarf hat. Man kann ja auch weiter Hexfiles nehmen, wenn man das unbedingt will. Ist ja nur, dass des TE's Fehler mit dem ELF-File gar nicht erst passiert wäre.
Jörg W. schrieb: > Naja, irgendwas müsstest du in jedem Falle dafür machen. Es gibt Eingriffsmöglichkeiten! https://docs.arduino.cc/arduino-cli/platform-specification/ https://docs.arduino.cc/arduino-cli/sketch-build-process/ Jörg W. schrieb: > Wenn man Umbauten kategorisch ausschließt, Es ist erstmal nur für mich ausgeschlossen den Builder zu ändern.
Arduino F. schrieb: > Es ist in manchen Situationen schlicht praktisch Bootloader, EEPROM und > Anwendung in einem Rutsch zu schreiben. Ich mache das in einer Batch, die den Programmer (atprogram.exe) dreimal aufruft. Im ersten Aufruf erfolgt das Löschen und Fusebits setzen.
1 | @echo off & setlocal |
2 | path=%path%;"C:\Program Files (x86)\Atmel\Studio\7.0\atbackend |
3 | :cls |
4 | for /f "delims=" %%s in ('dir /B /OD .\Binfiles\bl*.hex') do set binf=%binp%%%s |
5 | echo Program %binf% |
6 | echo. |
7 | atprogram.exe -t avrispmk2 -i ISP -d AT90CAN128 program -c -fl -f Binfiles\%binf% --verify write -fs --values FFD0FD --verify |
8 | for /f "delims=" %%s in ('dir /B /OD .\Binfiles\module*.hex') do set binf=%binp%%%s |
9 | echo Program %binf% |
10 | echo. |
11 | atprogram.exe -t avrispmk2 -i ISP -d AT90CAN128 program -ee -f Binfiles\bootstart_eep.hex --verify |
12 | atprogram.exe -t avrispmk2 -i ISP -d AT90CAN128 program -fl -f Binfiles\%binf% --verify |
13 | pause |
Peter D. schrieb: > Ich mache das in einer Batch In Arduino, in der betreffenden platform.local.txt
1 | # Upload with Programemr
|
2 | # brennt Anwendung, Bootloader und *.eep Datei
|
3 | # aendert keine Fuses
|
4 | tools.avrdude.program.pattern="{cmd.path}" "-C{config.path}" {program.verbose} {program.verify} -p{build.mcu} -c{protocol} {program.extra_params} "-Uflash:w:{build.path}/{build.project_name}.with_bootloader.hex:i" "-Ueeprom:w:{build.path}/{build.project_name}.eep:i" |
Prinzipiell könntest du auch das Hexfile für den Bootloader separat noch mit angeben, halt als ein zweites -Uflash:w:… Das (default) chip erase wird ja nur einmal am Anfang gemacht. Dann kannst du für Application Flash+EEPROM das ELF-File direkt nehmen und für den Bootloader das Hexfile hinterher schieben. Muss man gar nichts erst vorab mergen. ;-) Habe ich jetzt nicht probiert, aber sollte funktionieren.
Jörg W. schrieb: > Muss man gar nichts erst vorab mergen. ;-) OK... Das mergen ist eigentlich kein Problem. Denn das macht der Arduino Builder automatisch. Es wird eine Anwendung.eep, eine Anwendung.hex und eine Anwendung.with_bootloader.hex erzeugt. Wüsste auch nicht wie man das abschalten/ändern kann. Jörg W. schrieb: > Habe ich jetzt nicht probiert, Werde ich mal testen.
:
Bearbeitet durch User
Arduino F. schrieb: > Wüsste auch nicht wie man das abschalten/ändern kann. Das ist, was ich meine: irgendwas muss man natürlich ändern, wenn man was ändern will. Die Erzeugung dieser drei Dateien ist eigentlich überflüssig.
Arduino F. schrieb: > Bei einem Upload per ISP ist der Bootloader außen vor. Bei einem Chip > Erase ist auch der Bootloader weg. > Das EEPROM lässt sich nicht aus/über dem verwendeten Optiboot > beschreiben. Hallo? Es geht um eine Anleitung für EINSTEIGER und auch nicht um Arduino oder was auch immer.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.