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
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
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.
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.
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 ?
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 | }
|
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
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.