Hallo, ich habe gerade ein kleines Tesprogramm in Asembler für einen PIC18F2550 geschrieben, das auch funktioniert. Ein paar Variablen habe ich ab 0x020 deklariert. Vor dem Hauptprogramm habe ich dann ORG 0x000 hingeschrieben. Nun will ich den Bootloader von sprut benutzen. Der 'Bootblock' belegt den Anfang de Speichers (ab 0x000). Ich darf mein Programm laut sprut erst bei 0x800 starten lassen. Ich habe meinen Code dann einfach ORG 0x800 und die Variablen habe ich ab 0x820 deklariert. Leider hängt sich das Programm offenbar auf, sowie die erste Variable benutzt werden soll. Was mache ich denn falsch? Ich muss gestehen, dass ich eigentlich auch gar nicht verstehe, wieso die erste Variante ohne Bootloader so korrekt ist. Denn: Der Programmcode wird ab 0x000 in den Speicher geschrieben. Möglicherweise ist der aber so lang, dass er bis zu 0x020 oder darüber hinaus reicht. Das weiß ich doch gar nicht. Wäre es nicht sinnvoll die Variablen vor dem Start des Programmcodes zu platzieren? (Ein entsprechender Test ließ sich allerdings gar nicht erst compilieren...) Kann mir jemand die Nutzung von Speicher für Programm und Variablen mal bitte etwas erklären? Viele Grüße, Stefan.
Stefan schrieb: > Hallo, > > ich habe gerade ein kleines Tesprogramm in Asembler für einen PIC18F2550 > geschrieben, das auch funktioniert. > Ein paar Variablen habe ich ab 0x020 deklariert. > Vor dem Hauptprogramm habe ich dann ORG 0x000 hingeschrieben. > > Nun will ich den Bootloader von sprut benutzen. Der 'Bootblock' belegt > den Anfang de Speichers (ab 0x000). Ich darf mein Programm laut sprut > erst bei 0x800 starten lassen. > > Ich habe meinen Code dann einfach ORG 0x800 und die Variablen habe ich > ab 0x820 deklariert. Hi 0x000000 ist der Anfang des Bootblocks im Flash und 0x0007FF das Ende daher muss das Programm bei 0x000800 anfangen ab da beginnt der Erste Block für das Programm. 0x800 != 0x000800 > Leider hängt sich das Programm offenbar auf, sowie die erste Variable > benutzt werden soll. > kenne jetzt grade nicht die reg von den Gpio beim 2550 aber es solte ab 0x000 zu deklarieren sein nicht wie beim 16f ab 0x020 > Viele Grüße, > Stefan.
K. J. schrieb:
> 0x800 != 0x000800
Wer (welches Tool) erkennt denn hier auf Ungleichheit? 800 Hex sollte
doch 800 Hex sein - egal wie viele Nullen zwischen dem x und der 800
stehen.
Gruß,
Bernd
Hallo, Variablen kannst du ab der Adresse 0x000 deklarieren. Diese Adresse bezieht sich auf den Datenspeicher/RAM, und hat nichts mit dem Programmspeicher zu tun, in welchem dein Programm bzw. auch der Bootloader steht. 0x800 und 0x000800 ist meiner Meinung nach auch das gleiche. Gruß Flo
> Variablen kannst du ab der Adresse 0x000 deklarieren. Diese Adresse > bezieht sich auf den Datenspeicher/RAM, und hat nichts mit dem > Programmspeicher zu tun Dem Stimme ich nur halb zu. Durch die Harvard-Architektur ist der Datenspeicher und der Programmspeicher getrennt. Also kannst du die Variable weiterhin mit den alten Adressen benutzen. Du musst nur wissen, welche Adressen der Bootloader benutzt. Da dieser wohl nicht mehr ausgeführt werden soll (außer nach einem Neustart/Reset) kannst du diese aber auch überschreiben. Im PIC18F2550 ist der Speicher wieder in Bänke unterteilt. Die Befehle haben deswegen noch ein Parameter, welcher bestimmt ob in die SFRs (Special Function Registers, das sind die Register wie PORTA, TRISA, SSPCON1, STATUS, etc.) oder in die GPRs (General Purpose Registers, alle Register zur freien Verwendung) geschrieben oder gelesen werden soll. Die Bank setzt du mit einem MOVWF BSR, a oder mit MOVLB k, wobei k eine Konstante ist und a = 0 definiert ist. Mit a = 1 schreibst du in die GPR und mit a = 0 eben in die SFRs, darunter in das BSR. Grob könnte man sagen, dass BSR die Entsprechung der Segmentregister von einem 80386 kompatiblen Prozessor ist, falls dir das etwas sagt. Da die Bytes 0x00-0x5F in Bank 0 und die Bytes 0x60-0xFF in Bank 15 die SFRs sind, solltest du einfach zu Beginn die Bank auf 1 setzen und kannst dann die Variablen auch bei 0 beginnen lassen. Ich hoffe, ich konnte dir etwas helfen. =) Viele Grüße Sebastian
Bernd O. schrieb: > K. J. schrieb: > >> 0x800 != 0x000800 > > Wer (welches Tool) erkennt denn hier auf Ungleichheit? 800 Hex sollte > doch 800 Hex sein - egal wie viele Nullen zwischen dem x und der 800 > stehen. > > Gruß, > Bernd GPASM z.b. wen man 0x800 schreibt macht GPASM daraus 0x800000 in Vergleich zu 0x000800 ist des ne ganz andere Adresse.
K. J. schrieb: > Bernd O. schrieb: >> K. J. schrieb: >> >>> 0x800 != 0x000800 >> >> Wer (welches Tool) erkennt denn hier auf Ungleichheit? 800 Hex sollte >> doch 800 Hex sein - egal wie viele Nullen zwischen dem x und der 800 >> stehen. >> > GPASM z.b. wen man 0x800 schreibt macht GPASM daraus 0x800000 in > Vergleich zu 0x000800 ist des ne ganz andere Adresse. Das ist ja ein krankes Tool. Was wird denn aus 0x8? auch 0x800000? Dass Assembler nicht sonderlich portabel ist, ist ja bekannt, aber sowas nervt doch nur - oder hat das auch einen Vorteil? Wenn sich die Architektur weiterentwickelt, dann wird aus den heute korrekten 0x800000 später mal 0x80000000 - oder wie? Ich hatte früher auch ein paar Jahre PICs in Assembler programmiert (MPASM) mit diversen 16Cxxx, kann mich aber nicht an ein solches unerwartetes Verhalten erinnern. Vielleicht hätte es mich früher aber auch nicht gestört...
Also wen man weis passt es und es ist synaktisch auch korrekt wen man ne 6hex lange Speicher Adresse hat gibt man halt nicht 0x800 an ebenso wen du ne 2 hex breite gibst ja auch nicht 0x2 an sondern 0x02 ob des dan von links nach rechts oder von rechts nach links aufgefüllt wird ist halt Sache des Interpreters.
Nunja, wir Menschen mit unserem Dezimalen Zahlensystem lassen auch nur führende Nullen weg. Mir wäre neu wenn 80 = 80000 sein soll XD
K. J. schrieb: > Also wen man weis passt es und es ist synaktisch auch korrekt wen man ne > 6hex lange Speicher Adresse hat gibt man halt nicht 0x800 an ebenso wen > du ne 2 hex breite gibst ja auch nicht 0x2 an sondern 0x02 Warum sollte ich das tun? Wenn ich den Wert 2 schreiben will, dann schreibe ich 2 und nicht 0002 oder 00000002. Sowas macht man eigentlich nur wenn mehrere Variablen untereinander stehen und man mit den einstelligen Werten das Bild nicht versauen will. > ob des dan > von links nach rechts oder von rechts nach links aufgefüllt wird ist > halt Sache des Interpreters. Natürlich, man kann alles festlegen beispielsweise, dass rot nun grün ist und links hier rechts bedeutet. Mit schöner Regelmäßigkeit geht das dann aber auch schief - eben weil es unintuitiv ist. Mathematisch ist eben 0x800 == 0x000800. Wenn ein Assembler hier aus der Reihe tanzt und meint, dass 0x800 == 0x800000 wäre, somit also 2048 das gleiche wäre wie 8388608, führt das zu Problemen. Spätestens wenn man mehr Makrofähigkeit braucht als der Assembler liefern kann und zu einer separaten Makrosprache greift wird's aufwändig und Fehlerträchtig. Gruß, Bernd
Sebastian Hepp schrieb: > Nunja, wir Menschen mit unserem Dezimalen Zahlensystem lassen auch nur > führende Nullen weg. Wir Menschen (und die allermeisten unserer Rechentools - von solchen exotischen Ausnahmen wie diesem Assembler mal abgesehen) lassen in jedem Zahlensystem, auch im Hexadezimalsystem, führende Nullen weg, eben weil sie insignifikant sind. Aus diesem Grund ist eben 0x2 das gleiche wie 0x02 oder 0x0002, genauso wie 1234 == 01234 ist. Alles andere wäre fatal. Stell Dir vor, Du hast eine Konstante von sagen wir mal 0x20. Wenn Dein Tool (Assembler) je nachdem, in welche Variable Du die Konstante schreiben willst mal 0x20, mal 0x2000 oder mal 0x20000000 daraus macht erhöht das die Fehlerwahrscheinlichkeit enorm. Darum bin ich mir auch relativ sicher, dass diese obskure Sonderregel nur für Addressen gilt und nicht für sonstige Arithmetik mit diesem Assembler. > Mir wäre neu wenn 80 = 80000 sein soll XD Mir auch, aber für diesen (ominösen) Assembler scheint das normal zu sein, denn der macht genau das. Gruß, Bernd
Bernd O. schrieb: > > Ich hatte früher auch ein paar Jahre PICs in Assembler programmiert > (MPASM) mit diversen 16Cxxx, kann mich aber nicht an ein solches > unerwartetes Verhalten erinnern. > Das macht der MPASM auch heute noch nicht so. Mann kann führende Nullen durchaus weg lassen. Notfalls füllt der Assembler die führenden Nullen automatisch auf. Ich hab mir allerdings auch angewöhnt Bytes zweistellig und Adressen vierstellig (Bei PIC16F) zu schreiben. Sven
Ok, vielen Dank für die zahlreichen Antworten. Leider habe ich in der Woche momentan zu wenig Zeit, aber ich werde spätestens Freitag abend mit diesen Informationen nochmal im Datenblatt lesen. Das Umschalten der Bänke kannte ich beim 18F2550 nicht. Das werde ich mir mal ansehen. Was die Zahlen angeht, also MPLab behandelt auch 0x20 wie 0x0020. Zumindest ist mir aufgrund dieser Schreibweisenunterschiede noch kein Fehler aufgefallen. Aber auch das teste ich sicherheitshalber am Wo-Ende. Ich sage dann nochmal Bescheid, ob und vor allem wie es dann mit dem Bootloader funktioniert. Viele Grüße, Stefan.
Du musst dir halt immer vor Augen halten, dass du bei den µC in der Harvard Architektur bist. Das heist Daten-, Programm- und Eprom- Speicher sind völlig getrennt voneinender. Alle diese drei Speicherbereiche fangen bei 0x0000 an und gehen bis zu ihrem Maximum (hängt vom Typ des µC ab). Dein Programm liegt im Flashspeicher und kann nur von hier aus ausgeführt werden. Nichtflüchtige Daten kannst du im EPROM speichern (bei vielen Typen auch im Flash, aber dass ist eher eine nützliche Beigabe und sollte aufgrund der maximalen Schreibzyklen des Flash nicht überbeansprucht werden). Und deine Variablen legst du im RAM an. Die 18F können bis zu 16 RAM-Bänke a 256 Bytes haben. Nun gibt es noch einen mit Access-RAM bezeichneten gesonderten Speicherbereich. Dieser Access-RAM setzt sich aus den Bytes 0x0000 - 0x005F von Bank 0 und den Bytes 0x0060 - 0x00FF der Bank 15 zusammen. In diesem zweiten Bereich liegen auch die Statusregister (SFR) welche praktisch in den Access-RAM gespiegelt werden. Damit ist es nun möglich ohne die Bank umzuschalten die ersten 128 Userdatenbytes und die Statusbytes über den Access-RAM anzusprechen. Benötigst du mehr wie 128 Bytes, geht die Bankumschalterei wieder los, so wie halt schon bei den 16F... Viel Spaß noch Sven
Also, ich habe jetzt noch mal getestet und komme zu einem seltsamen Ergebnis. Gut ist erstmal, dass das Programm sowohl mit als auch ohne Bootloader läuft, wenn ich als Startadresse 0x0800 eingebe (0x800 habe ich noch nicht getestet) und die Variablen ab 0x60 definiere (war noch vom letzten Test auf diesem Wert). Komisch ist aber, dass die Takfrequenz offenbar wesentlich höher ist, wenn ich das ganze über den Bootloader laufen lasse. Beide male wird der gleiche 4MHz Resonator verwendet und für den Bootloader habe ich die 4MHz Variante gewählt. Allerdings muss ich bei Bootloaderbenutzung meine Wartescheifen extrem vergrößern. Es scheint, als würde der PIC mit mehr als 20 MHz laufen. Kann das überhaupt sein? Kann irgendeine Einstellung im Bootloader den PIC schneller machen, obwohl nur einen 4MHz Resonator angeschlossen ist? Ich vermute sogar, dass mein Programm auch vorher schon mit dem Bootloader lief - allerdings so schnell, dass ich es gar nicht mitbekommen habe... Wie seht ihr dieses Problem?
>Es scheint, als würde der PIC mit mehr >als 20 MHz laufen. >Kann das überhaupt sein? Kann irgendeine Einstellung im Bootloader den >PIC schneller machen, obwohl nur einen 4MHz Resonator angeschlossen ist? Im Bootloader wohl kaum. Wahrscheinlicher ist das das ConfigWord auf HSPLL eingestellt ist. Dann bekommst du auch mehr als 4MHz.
Die 18F haben einen internen PLL. Damit lässt sich die Taktfrequenz des Prozessors intern vervielfachen. Der µC leitet daraus intern seinen USB Takt von 96 MHz ab. Der Takt für den Prozessor kann über entsprechende Vorteiler auf bis zu 48 MHz geschraubt werden. Es ist also durchaus denkbar, dass dein Programm mit der 10fachen Geschwindigkeit läuft. Zu den Variablen: Die solltest du gerade nicht ab 0x0060 definieren, zumindest nicht in Bank0. Definiere deine Variablen ab 0x0000 und greife über den Access-RAM darauf zu. Den Zugriff auf den Access-RAM steuerst du im Befehl (a=0 oder 1). Wenn du am Anfang mit dem Access RAM arbeitest sparst du dir die Bankumschalterrei. Beachte aber, dass deine Uservariablen dann im Bereich 0x0000 bis 0x005F liegen und ab 0x0060 die Special Funktion Register (SFR) kommen. Wenn du deine Variablen allerdings ab 0x0060 anlegst, könnte es durchaus sein, dass du Probleme bekommst. Sven
Hallo , ich denke die Interrupt Vektoren müssen auch umgelegt werden. Desweiteren kann es sein, dass im Linker-Script Platz für den Bootloader reserviert werden muß. Ansonsten, wie schon oben gesagt, ist es eine beliebte Falle über 0x5f mit den Variablen zu gehen. ;*********************************************************************** ******* STARTUP CODE 0x0000 bra RVReset HI_INT_VECTOR CODE 0x0008 bra RVIntH ; Re-map Interrupt vector ; _V_INT_LOW CODE 0x0018 bra RVIntL ; Re-map Interrupt vector ;************************************************************** ; ;************************************************************** PROG1 CODE org 0x800 RVReset goto start org 0x808 RVIntH goto IntVector_high org 0x818 RVIntL goto IntVector_low
Vieleicht sind Pic's einfach nur sinnlos!`?
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.