Forum: Compiler & IDEs Funktion in RAM kopieren, Renesas M16C


von Sebastian H. (feuerreiter)


Lesenswert?

Hallo Ihr,
ich stehe vor dem Problem, einen M16C per Software flashen zu müssen, da 
der PIN der den µC normalerweise in den Flash Modus setzt nicht 
zugänglich ist. Dafür muss ich eine Funktion, die dann nach 
Initialisierung eines Flahs Vorganges das Löschen des Roms und dann auch 
das Wiederbeschreiben durchführt, in den RAM kopieren.
Leider bin ich noch nicht ganz so versiert in C und benötige einige 
Hilfestellungen, bei dem Kopiervorgang der Funktion. Als Compiler nehme 
ich den IAR Embedded Workbench.

Eine erste lauffähige Version macht folgendes:

1. Ich deklariere die Funktion, die später den Flash Vorgang durchführen 
soll und verweise mit einem Pointer (ptr1) auf den Anfang der Funktion.
3. Ich reserviere mir mit malloc einen Speicher im RAM, ptr2 ist der 
Pointer, der auf das erste Byte des alloziierten Speichers verweist
4. Der Kopiervorgang
5. Umbiegen des Zeigers ptr1 auf ptr2, damit der Controller weiß, dass 
er die Funktion aus dem RAM ausführen soll
6. Starten der BootLoader Funktion

Hier der Code, solltet Ihr irgendwas finden, was man so eigentlich gar 
nicht macht, wäre es gut, Ihr würdet das kommentieren.
1
        void (*ptr1) (void);  //Function pointer
2
        ptr1= BootloaderFunction;  /*set ptr1 to the beginning of the bootloader
3
                                function in Rom */
4
5
        void* ptr2;          //undeclared pointer
6
7
        ptr2 = malloc(500); //reserves 500 bytes in Ram, beginning with the address of ptr2
8
9
        memcpy((void *)ptr2, (void *) ptr1, 500); //copies 500bytes from ptr1 to ptr2
10
11
        ptr1 = (void (*)(void))ptr2; // ptr1 gets the address of ptr2
12
13
        (*ptr1)(); //call the bootloader function via the new ptr1

Die Funktion läuft, und wird auch definitiv aus dem RAM ausgeführt 
allerdings mit einigen Warnungen, durch die relativ abenteuerliche 
Pointer Umwandlung:
- Warning[Ta012]: Pointer conversion with possible loss of data.
- Warning[Pe1053]: conversion from integer to smaller pointer

Des weiteren ich bin mir nicht sicher, ob dieser Code auch definitiv 
immer funktioniert, deswegen folgende Fragen:

- Ich setze ptr1 auf den Anfang der Funktion und kopiere dann dieses 
Byte und die nachfolgenden 500 in den RAM. Kann ich mir sicher sein, 
dass eine Funktion ohne Lücken im ROM abgelegt wird? Bei mir ist das 
jetzt zwar so, kann ich aber sicherstellen, dass das immer so ist?

- Die feste Länge von 500 Byte ist natürlich sehr gewagt definiert. 
Lieber wäre mir, genau den benötigten Speicherbereicht zu kopieren. 
Leider gibt sizeof nicht die Länge von Funktionen aus. Welche 
Möglichkeiten bleiben, den Speicherumfang der Funktion zu ermitteln? 
Eventuell eine leere Dummy Funktion, die genau hinter meiner BootLoader 
Funktion liegt "anpointern" und dann die beiden Pointer subtrahieren? 
Wie kann ich in diesem Falle sicherstellen, dass die Funktion genau 
hinter meiner jetzigen Funktion im Rom liegt?

- Ich habe jetzt des öfteren gelesen, dass Lösungen darauf basieren, 
dass die zu kopierende Funkktion in ein Segment geschrieben wird und 
dann ds Segment kopiert wird. Hier scheitere ich an vielen Dingen:

1. Ist die Lösung viel besser als meine jetzige ohne die Zuhilfenahme 
von Segmenten? Wo liegen die Vorteile?
2. Ich möchte das Segment natürlich nur so groß wie nötig machen, und 
bin jetzt wieder bei dem Punkt, wie viel Speicher eigtl. meine Funktion 
benötigt
3. Kann ich das Segment dann genau so ansprechen, wie ich vorher meine 
Funktion angesprochen habe?

Vielen Dank auf jeden Fall für alle Hilfen und Grüße aus Dresden


Sebastian

von StinkyWinky (Gast)


Lesenswert?

Den Speicherbedarf einer Funktion sieht man im Map-File.
Die Lösung mit dem Segment hat den Vorteil, dass man mit einer 
Fehlermeldung belohnt wird, falls die Funktion grösser als vorgesehen 
werden sollte.

von Sebastian H. (feuerreiter)


Lesenswert?

Hallo,
vielen Dank für die schnelle Hilfe

Deine Lösung beinhaltet also, dass ich mir im MAP File ansehe, wie gross 
die Funktion ist, und dann genau diesen Wert bei Malloc und Memcpy 
eintrage, richtig?

Der Segmentvorteil würde sich dann auch relativieren, da ich Malloc und 
Memcpy die tatsächliche Größe der Funktion übergeben kann.

Lieber wäre mir dennoch eine Version, die das Programm veranlasst, sich 
selbst die Größe der Funktion zu errechnen, um das Ganze dynamisch zu 
halten.

Gibt es dafür Lösungen?


Grüße

von StinkyWinky (Gast)


Lesenswert?

Die Idee mit der Dummy-Funktion ist nicht so schlecht. Die Reihenfolge 
im Speicher wird sich zwar je nach Compiler/Linker ergeben, aber: Wenn 
Du im oben erwähnten Segment nur den Loader und die Dummy-Funktion hast, 
könntest Du immerhin prüfen, ob die Adresse der Dummy-Funktion grösser 
ist als die des Loaders und eine Fehlerbehandlung implementieren.

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
Noch kein Account? Hier anmelden.