Forum: Mikrocontroller und Digitale Elektronik Cortex-M4 Anfängerfragen


von Michael Hefner (Gast)


Lesenswert?

Hallo,

ich programmiere seit einem Jahr uC von Microchip und möchte nun in die 
32bit Welt eintauchen. Dazu habe ich mir das neue Discoveryboard von STM 
mit dem stm32F429 geholt. Als IDE habe ich mir die Keil uVision 
V5.0.5.15 installiert. Nun habe ich mir mal ein Beispiel angeschaut und 
frage mich wozu die unzähligen startup files gut sind ? Ich bin es von 
Microchip gewohnt, einfach die Headerdatei für meinen uC einzubinden, 
dann die Clock einzustellen und loszulegen. Ist das hier nicht mehr 
möglich ? Außer den Startupfiles sind unter dem Reiter Device noch c 
Filse für DMA,EXIT,FSMC,GPIO eingebunden. Gibt es irgendwo ein gutes 
Tutorial für Einsteiger in die 32bit Welt mit uVision 5 ?

Michael

von Ingo (Gast)


Lesenswert?

Die Frage ist doch, warum der Kern soviel Wasserkopf mitsich trägt!?
Ich finde da greifen einem dir IDEs noch nicht ausreichend unter die 
Arme. Hab's damals aber auch so hinbekommen, aber bis der Kern erstmal 
so funktioniert wie man will dauert es...



Ingo

von Guest (Gast)


Lesenswert?

Michael Hefner schrieb:
> ich programmiere seit einem Jahr uC von Microchip und möchte nun in die
> 32bit Welt eintauchen. Dazu habe ich mir das neue Discoveryboard von STM
> mit dem stm32F429 geholt. Als IDE habe ich mir die Keil uVision
> V5.0.5.15 installiert. Nun habe ich mir mal ein Beispiel angeschaut und
> frage mich wozu die unzähligen startup files gut sind ? Ich bin es von
> Microchip gewohnt, einfach die Headerdatei für meinen uC einzubinden,
> dann die Clock einzustellen und loszulegen. Ist das hier nicht mehr
> möglich ? Außer den Startupfiles sind unter dem Reiter Device noch c
> Filse für DMA,EXIT,FSMC,GPIO eingebunden. Gibt es irgendwo ein gutes
> Tutorial für Einsteiger in die 32bit Welt mit uVision 5 ?

Das ist bei deinem PIC und auch bei den AVRs genauso. Startup routinen 
brauchts überall, wenn man C macht. Irgendwie müssen ja zB die Variablen 
aus .data initialisiert werden. Oder .bss gecleared. Bei C++ wirds noch 
komplizierter, da müssen auch noch statische Klassen initialisiert 
werden und so späßchen. Bei den AVRs versteckt sich das eben in der AVR 
Libc, bei PIC weiß ich nicht. Die anderen Files wie DMA, FSMC, GPIO sind 
libs für eben diese gleichnamigen Hardware Module damit du als 
Programmierer nicht jedes Register manuell beschreiben/lesen musst 
insbesondere was DMA ist solltest du dir anschauen, ist verdammt 
praktisch. Was EXIT ist weiß ich auf Anhieb nicht.

Der richtige Hobbybastler greift übrigens weder auf Keil noch auf die 
ST-Periph Lib zurück, sondern baut sich einen gcc-arm-none-eabi, nutzt 
für das grobe Zeug open source Libs (LibOpenCM3) und schreibt den rest 
selbst, sonst lernt man ja nix dabei. Außerdem ist es oft einfacher 
Teile einer Lib selber neu zu schreiben als zu verstehen was sich der 
ursprüngliche Programmierer vielleicht dabei gedacht hat und was er 
versemmelt hat.

von Guest (Gast)


Lesenswert?

Ingo schrieb:
> Die Frage ist doch, warum der Kern soviel Wasserkopf mitsich trägt!?
> Ich finde da greifen einem dir IDEs noch nicht ausreichend unter die
> Arme. Hab's damals aber auch so hinbekommen, aber bis der Kern erstmal
> so funktioniert wie man will dauert es...

Der Wasserkopf bei den Cortex M* hält sich stark in grenzen. Vergleich 
mal die Startup Routinen mit denen eines ARM9 oder eines Cortex A8. Da 
sind Welten dazwischen.

von Michael Hefner (Gast)


Angehängte Dateien:

Lesenswert?

ok, wenn ich alles aus meinem Projekt rausschmeisse bis auf meine main.c 
und dort dann meine Clock konfiguriere wird es mir nicht gelingen den uC 
zum laufen zu bekommen ? In den startup files wird weitaus mehr als nur 
die Clock konfiguriert ?

von Ingo (Gast)


Lesenswert?

So ist es...

von klausr (Gast)


Lesenswert?

Michael Hefner schrieb:
> In den startup files wird weitaus mehr als nur
> die Clock konfiguriert ?

So arg viel macht der Startup-code nicht. Neben der Initialisierung der 
Vektor-Tabelle (die hier nicht zu sehen ist) ist es hauptsächlich 
folgendes:
1
/*----------Default_Reset_Handler---------------------------------------------*/
2
void Default_Reset_Handler(void)
3
{
4
  /* Initialize data and bss */
5
  unsigned long *pulSrc, *pulDest;
6
7
  /* Copy the data segment initializers from FLASH to SRAM */
8
  pulSrc   = &_sidata;
9
  pulDest  = &_sdata;
10
11
  //for(pulDest = &_sdata; pulDest < &_edata;)
12
  while(pulDest < &_edata)
13
  {
14
    *(pulDest++) = *(pulSrc++);
15
  }
16
17
  /* Zero fill the bss segment. This is done with inline assembly since this
18
     will clear the value of pulDest if it is not kept in a register. */
19
  __asm("ldr     r0, =_sbss");
20
    __asm("ldr     r1, =_ebss");
21
    __asm("mov     r2, #0");
22
    __asm(".thumb_func");
23
    __asm("zero_loop:");
24
    __asm("cmp     r0, r1");
25
    __asm("it      lt");
26
    __asm("strlt   r2, [r0], #4");
27
    __asm("blt     zero_loop");
28
29
    /* Relocate Vector Table */
30
  #if(VECT_TAB_SRAM == 1)
31
      SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET;
32
  #else
33
      SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET;
34
  #endif
35
36
  /* Enable FPU */
37
  #if(USE_FPU == 1)
38
        SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));
39
  #endif
40
41
    /* Set to maximum Speed from PLL driven by HSI Oscillator */
42
  #if(USE_MAX_SPEED == 1)
43
    RCC_PLLConfig(RCC_PLLSource_HSI, 8, 168, 2, 7);
44
    RCC_PLLCmd(ENABLE);
45
    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) != SET);
46
47
    FLASH_SetLatency(FLASH_Latency_5);
48
49
    RCC_HCLKConfig(RCC_SYSCLK_Div1);
50
    RCC_PCLK1Config(RCC_HCLK_Div4);
51
    RCC_PCLK2Config(RCC_HCLK_Div2);
52
53
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
54
  #endif
55
56
  #if(USE_D_I_CACHE == 1)
57
    FLASH_InstructionCacheCmd(ENABLE);
58
    FLASH_DataCacheCmd(ENABLE);
59
  #endif
60
61
  #if(USE_PREFETCH_BUFFER == 1)
62
    FLASH_PrefetchBufferCmd(ENABLE);
63
  #endif
64
65
66
  /* Call the application's entry point. */
67
  main();
68
}

von Dr. Sommer (Gast)


Lesenswert?

Guest schrieb:
> nutzt
> für das grobe Zeug open source Libs (LibOpenCM3)
Weil die alle Nachteile der StdPeriphal Library übernommen hat, 
unvollständig und kommerziell nicht nutzbar ist? Klingt... sinnvoll.

klausr schrieb:
> __asm("ldr     r0, =_sbss");
>     __asm("ldr     r1, =_ebss");
>     __asm("mov     r2, #0");
Und dann beten dass der Optimizer nicht auf die Idee kommt die 
Anweisungen anders zu sortieren oder gar komplett rauszuwerfen weil sie 
sinnlos sind für ihn? Entweder:
 * Überall volatile dranschreiben
 * Ein einzigen asm-Block machen, volatile dranschreiben (am 
einfachsten)
 * In/Out-Constraints angeben

von Guest (Gast)


Lesenswert?

Was auch viele nicht wissen: Neben echtem Code wie dem Startup Code 
braucht es auch noch andere Sachen, wie zB ein linker script, das dem 
linker sagt wo hin er was linken soll und von wo es dann ausgeführt 
wird. Das hat seine ganz eigene Syntax und versteckt sich auch irgendwo 
in der Lib. Genauso wie beim AVR natürlich. Verwunderlich dass so viele 
meinen auf dem AVR läuft NUR der eigene Code, das ist nur bei assembler 
so.

von Dr. Sommer (Gast)


Lesenswert?

Guest schrieb:
> Verwunderlich dass so viele
> meinen auf dem AVR läuft NUR der eigene Code, das ist nur bei assembler
> so.
Nö, auch da spielen Linkerscripte mit, aber die "laufen" natürlich nicht 
auf der Zielplattform ;-)

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.