Forum: Mikrocontroller und Digitale Elektronik Funktion an bestimmte Flash Addresse speichern


von Andi (Gast)


Lesenswert?

Hi,

habe leider nichts in der Suche gefunden. Folgendes Problem:

Habe einen Bootloader und eine Funktion, die zu einer bestimmten 
Registeraddresse springt und dort soll sich meine eigentliche 
Applikation befinden. Nun weiss ich aber nicht wie ich meine Funktion an 
diese bestimmte Stelle speichere/bringe..bei 0x8003000 soll sie sich 
sich dann befinden. Aktuell ist da leider nichts :-)

Ich hoffe die Loesung ist einfach und unkompliziert :-)

von Thomas (Gast)


Lesenswert?

Was verwendetst du als Toolchain? Mit den GNU Tools siehts ca. so aus im 
Linkerfile:
1
MEMORY
2
{  
3
  /* without bootloader */
4
   /*FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 64K*/
5
  /* with bootloader */
6
   FLASH (rx) : ORIGIN = 0x08003000, LENGTH = 48K
7
   
8
   SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 10K
9
}

Damit erzeugt der Linker Code, welcher bei 0x08003000 startet. Den 
Adressen nach zu urteilen würde ich mal sagen, du arbeitest mit einem 
Cortex, dh da steht zu Beginn kein ausführbarer Code, sondern nur die 
Vektoren mit den Adressen für Stackpointer, Main und allen anderen ISR. 
Man kann also nich direkt zu dieser Adressen springen, sondern muss sich 
von der zweiten Speicherstelle der Applikation (0x08003000+4) die 
Adresse von main holen und dann dorthin springen.
Weiters solltest du beachten das du beim Umschalten von Bootloader zur 
Applikation die Startadresse der Vektortabelle für die Applikation setzt 
(0x08003000) sonst würden die ISR welche der Bootloader gesetzt hat 
angesprungen (0x08000000)

von Andi (Gast)


Lesenswert?

Vielen Dank erstmal für die schnelle Antwort.

Ich benutze Keil uVision 4.6 damit wohl GNU. Und ja es ist ein Cortex 
M3.

Der bootloader Code liegt bei 0x08000000 und ist ca 10kByte gross. D.h. 
ab Addresse 0x08003000 kann die Applikation abgespeichert werden. Ich 
muss wohl ein Scatter file erstellen ? Was mir dann meine eigentliche 
"main"- funktion auf 08003000 mapped?

von Andi (Gast)


Lesenswert?

mein Scatter file sieht von anfang an so aus:

LR_IROM1 0x08000000 0x00020000  {    ; load region size_region
  ER_IROM1 0x08000000 0x00020000  {  ; load address = execution address
   *.o (RESET, +First)
   *(InRoot$$Sections)
   .ANY (+RO)
  }
  RW_IRAM1 0x20000000 0x00005000  {  ; RW data
   .ANY (+RW +ZI)
  }
}

wie muss ich das veraendern? hab einiges probiert, hat aber nicht 
geholfen.

meine funktion nenn ich einfach newmain

von StinkyWinky (Gast)


Lesenswert?

Ich würde bei den Projekt-Optionen für den Linker bei "R/O Base" anstatt 
0x0 einfach 0x2800 eingeben.
Dann beim Flashen den selben Offset benützen.

von Andi (Gast)


Lesenswert?

So einfach geht das leider nicht. Die bootloader main ist bei 0x08000000 
abgelegt. Wenn der MC resetet soll er auch diese durchlaufen. Innherhalb 
dieser main wird dann ein Sprung auf die Applikation durchgefuehrt. Wo 
die Applikation liegt kann ich selbst bestimmen, default ist sie aber 
bei 0x08003000, da der Bootloader eben 10kbyte gross ist.

Ich muss nur einfach meine Funktion "newmain" auf 0x08003000 flashen. 
Dann waere ich schon ein grosses Stück weiter...

von Andi (Gast)


Lesenswert?

Also es ist einfacher als ich dachte.. korrigiert mich wenn ich mich 
irre bitte..

erstmal oeffnet man das Bootloader project und flasht das device. Nun 
ist der code im speicher auf 080000000 - 08003000.

Nun startet man das eigentliche Applikations project und definiert dort 
den Speicher von 08003000 - xxxxx, so dass das Bootloader programm nicht 
angerührt wird.

somit startet das Programm im Bootloader.. aber wechselt dann, je 
nachdem wie man es implementiert hat, zur Applikation und verbleibt 
dort.

von StinkyWinky (Gast)


Lesenswert?

Na also, geht doch!

von Mr.T (Gast)


Lesenswert?

Den Sprung vom Bootloader zur Applikation kannst Du z.B. so machen:
1
extern void WarmStart(const uint32_t inWarmStartAddress_U32)
2
{
3
  typedef void (*tFunction)(void);
4
  tFunction  JumpToApplication;
5
  uint32_t  myJumpAddress_U32;
6
7
  myJumpAddress_U32 = (*(volatile uint32_t*) (inWarmStartAddress_U32 + sizeof(uint32_t)));
8
  JumpToApplication = (tFunction) myJumpAddress_U32;
9
  __MSR_MSP(*(volatile uint32_t*) inWarmStartAddress_U32);
10
  JumpToApplication();
11
}

__MSR_MSP ist ein asm Ausdruck für:
1
;*******************************************************************************
2
; Function Name  : __MSR_MSP
3
; Description    : Assembler function for the MSR instruction.
4
; Input          : - r0 : Main Stack new value.
5
; Return         : None
6
;*******************************************************************************
7
__MSR_MSP
8
9
    MSR MSP, r0 ; set Main Stack value
10
    BX r14

inWarmStartAddress_U32 wäre bei Dir dann 0x08003000.

von StinkyWinky (Gast)


Lesenswert?

Vor dem JumpToApplication() würde ich aber noch prüfen, ob dort 
tatsächlich eine Applikation vorhanden ist oder nicht..
1
/*
2
* The application is assumed to be valid if:
3
* - the first location is a valid stack pointer (it must reside in SRAM,
4
* and must have a value of 0x2xxx.xxxx)
5
* - the second location is a valid reset handler address (it must reside
6
* in flash, and must have a value of 0x000x.xxxx, and the value must be odd).
7
*
8
* If either of these tests fail, then the application is assumed to be invalid.
9
*/

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.