Forum: Mikrocontroller und Digitale Elektronik LPC17xx (Cortex M3) mit FreeRTOS


von peter_w. (Gast)


Lesenswert?

Hey,

ich möchte auf einem NXP LPC1768 das FreeRTOS Betriebssystem zum Laufen 
bekommen. Ich arbeite mit Sourcery G++ Lite und Eclipse.

Meine erste Inbetriebnahme des Microcontrollers habe ich ohne FreeRTOS 
durchgeführt, um einfach mal Startup- und Linker-Files auf Funktion zu 
testen (da ich bisher keine Erfahrung damit habe). Habe also ein 
einfaches LED-blinky mittels Timer geschreiben und die UART0 in Betrieb 
genommen. Das hat alles soweit ohne Probleme funktioniert.

Nun wollte ich wie gesagt FreeRTOS integrieren. Es gibt ja einige 
Demoprogramme vom Betriebssystemhersteller selbst. Ich habe aber kein 
Rowly oder RedSuit Board. Deswegen habe ich dieses Demoprojekt von 
FreeRTOS dahingehend verändert, dass es nur 2 Tasks gibt, die jeweils 
eine LED mit unterschiedlicher Frequenz blinken lassen (bzw. einen GPIO 
Pin toggln). Das Problem ist, dass immer sobald das Betriebssystem 
übernehmen soll, nämlich nach dem SVC Call in den Hard Fault Handler 
gesprungen wird. Normalerweise sollte ja der SVC Handler ausgeführt 
werden, oder? Ich habe gelesen, dass angeblich 8 Registerwerte auf den 
Stack gepusht werden, im Falle eines Hard Faults? Aber ich kann nirgends 
finden wie ich diese Registerwerte interpretieren kann. Könnt ihr mir 
weiterhelfen?

Mit freundlichen Grüßen
peter

von Jürgen (jliegner)


Lesenswert?

freeRTOS benutzt und initialisiert den Cortex-M3 Systick-Handler. Ist 
das im Startupcode richtig gesetzt? Das passiert bei mir im 
cr_startup_lpc176x.c und sieht so aus:
1
  // freertos Vectoren 
2
  vPortSVCHandler,
3
  DebugMon_Handler,
4
  0,
5
  xPortPendSVHandler,
6
  xPortSysTickHandler,
7
8
//  SVCall_Handler,              
9
//  DebugMon_Handler,            
10
//      0,
11
//  PendSV_Handler,              
12
//  SysTick_Handler,

Was benutz du für eine Startup-Variante?

von peter_w. (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

danke erstmal für die Antwort. Ich denke schon, dass der SysTickHandler 
richtig gesetzt ist.

Habe es bisher mit 2 Varianten versucht. Zuerst mit einem Startupfile, 
das ich über Google gefunden und angepasst habe und dann mit dem, was 
FreeRTOS in dem Demoprojekt für das RedSuit-Board verwendet (beide 
Varianten scheitern beim SVC Call). Aber ich arbeite jetzt mit den im 
Anhang befindlichen Startup- und Linkerfiles.

Mit freundlichen Grüßen
peter

von peter_w. (Gast)


Lesenswert?

Hey,

ich habe mir heute mal im HardFault Handler die CFSR und HFSR 
Registerwerte ausgeben lassen:

HFSR ist 0x4000 0000, also ein forced HardFault. Ist auch irgendwie 
klar, weil eigentlich sollte ja in den SVCHandler gesprungen werden.
Doch das Interesante ist, das der Inhalt von CFSR 0x0 ist. Also kann ich 
über diese Register auch den Fehler nicht eingrenzen.

Hat vielleicht jemand eine Idee woran das liegen kann, dass beim SVC 
Call in den HardFault Handler gesprungen wird?

MfG. peter

von holger (Gast)


Lesenswert?

.equ    Stack_Size, 0x00000100

256 Bytes Stack sind schon ein wenig grenzwertig für
eine 32 Bit Maschine;)

von peter_w. (Gast)


Lesenswert?

Hey,

ok, und wieviel wäre dann Deiner Meinung nach sinnvoll? Habe das 
Startupfile wie gesagt so gefunden und nur die Funktions- und 
Variablennamen angepasst.

Mit freundlichen Grüßen
Peter

von holger (Gast)


Lesenswert?

>ok, und wieviel wäre dann Deiner Meinung nach sinnvoll?

Unter 1kB würde ich da gar nicht erst anfangen.

> Habe das Startupfile wie gesagt so gefunden und nur die Funktions- und
>Variablennamen angepasst.

Scheinbar aber nicht konseqent:

    .weak   PendSV_Handler
    .type   PendSV_Handler, %function
PendSV_Handler:
    B       .
    .size   PendSV_Handler, . - PendSV_Handler

Keine Ahnung ob das was ausmacht, aber ich würde mal in
das Assembler Listing File vom Compiler schauen ob da auch
die entsprechenden Funktionen von FreeRTOS benutzt werden.

Ein komplettes Projekt mit deinem Minimalbeispiel könnte
auch helfen hier nicht mehr im Nebel zu stochern.

von peter_w. (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

ja kein Thema, im Anhang das gezippte Projekt.

Mit freundlichen Grüßen
peter

von Jürgen (jliegner)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier mal ein Projekt für den LPC1769 drangehängt mit einem 
simplen Demo. Ist aber makefile basierend. Die drei buildxx.bat sind zum 
Übersetzen unter LPCXpresso (CodeRed), codesourcery lite und yagarto. 
Ich probiere so immer mal was die (leicht) verschiedenen Compiler so 
daraus machen. Hier ist der Startup mit Dateien aus dem CMSIS sowie dem 
etwas geänderten Startup aus dem LPCXpresso. Es wird immer die newlib 
verwendet und auch cpp ist möglich.
Eventuell bringt es dir was. Die Pfade in der buildxx.bat sind 
anzupassen und im Tools-Verzeichnis sind ein paar binaries aus den 
yagarto-tools die bei codesoucery fehlen.
Hoffe das hilft. Die 2. Ram-Bank vom LPC1768 steht übrigens in deinem 
Link-Script auch nicht drin.

von holger (Gast)


Lesenswert?

Aus deinem Example1.lst

00000510 <SVCHandler>:
    .section ".text"

    .weak   SVCHandler
    .type   SVCHandler, %function
SVCHandler:
    B       .
     510:  e7fe        b.n  510 <SVCHandler>
00000514 <PendSV_Handler>:
    .size   DebugMon_Handler, . - DebugMon_Handler

    .weak   PendSV_Handler
    .type   PendSV_Handler, %function
PendSV_Handler:
    B       .
     514:  e7fe        b.n  514 <PendSV_Handler>

00000516 <SysTick_Handler>:
    .size   PendSV_Handler, . - PendSV_Handler

    .weak   SysTick_Handler
    .type   SysTick_Handler, %function
SysTick_Handler:
    B       .
     516:  e7fe        b.n  516 <SysTick_Handler>

Die FreeRTOS Handler werden nicht benutzt.
Deshalb kracht das.

Dort müssten diese Handler stehen

  vPortSVCHandler,                /* SVCall Handler */
  xPortPendSVHandler,             /* PendSV Handler */
  xPortSysTickHandler,            /* SysTick Handler */

von peter_w. (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

aha. Problem ist, wie im ersten Post erwähnt ich kenn mich mit 
Startupfiles nicht wirklich aus. Ich habe jetzt das Sartupfile 
dahingehend verändert, dass in den Handlern auf die FreeRTOS Handler 
verzweigt wird?
Im Anhang wie ich es gelöst habe. Aber offensichtlich habe ich es falsch 
gelöst, denn es wird immer noch ein HardFault ausgelöst.

Mit freundlichen Grüßen
peter

von holger (Gast)


Lesenswert?

.long   SVCHandler                  /* SVCall Handler               */
    .long   DebugMon_Handler            /* Debug Monitor Handler 
*/
    .long   0                           /* Reserved 
*/
    .long   PendSVHandler              /* PendSV Handler 
*/
    .long   SysTickHandler             /* SysTick Handler 
*/

Was sagt dir das? Ich seh nix von

  vPortSVCHandler
  xPortPendSVHandler
  xPortSysTickHandler

Ohne Worte!

von peter_w. (Gast)


Angehängte Dateien:

Lesenswert?

Hey,

Entschuldigung, bitte nicht tot machen.

Das war vorher auch anders. Ich dachte, die Definitionen im Startupfile 
mit den verzweigen dann sowieso auf die richtige Funktion. Aber das war 
nicht das Problem!

MfG peter

von peter_w. (Gast)


Lesenswert?

Hey,

habe ich jetzt immer noch was falsch in der letzten startup-Datei 
hochgeladen habe, oder war das einfach nicht der Fehler.

Ich denke nämlich, dass ich jetzt schon verstanden hab, was holger 
meinte, aber es löst das Problem nicht. Es wird immer noch beim svc call 
in den hard-fault handler gesprungenn. Interessanterweise wird wenn ich 
vor dem svc call ein b vPortSVCHandler mache, in den SVC Handler 
gesprungen. Natürlich passiert dann dort auch wieder ein HardFault.

MfG. peter

von thinkJD (Gast)


Lesenswert?

Ich habe versucht das Beispiel von Jürgen auf nem Mac mit der yagarto 
Toolchain zu kompilieren. Leider bekomme ich folgende Fehlermeldung:
1
/Users/thinkJD/arm_toolchain/yagarto-4.6.2/bin/arm-none-eabi-gcc  ./libs/freertos/heap_1.o ./libs/freertos/list.o ./libs/freertos/port.o ./libs/freertos/queue.o ./libs/freertos/tasks.o ./libs/freertos/timers.o ./system/core_cm3.o ./system/cr_startup_lpc176x.o ./system/system_LPC17xx.o ./src/main.o  -mcpu=cortex-m3 -mthumb -nostartfiles -T./system/lpc1769_flash.ld -Wl,-Map=freertos.map,--cref,--no-warn-mismatch,--gc-sections -L./system   -o freertos.elf
2
/Users/thinkJD/arm_toolchain/yagarto-4.6.2/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/v7m/libc.a(lib_a-abort.o): In function `abort':
3
/Users/mfischer/Projects/yagarto/newlib-build/arm-none-eabi/thumb/v7m/newlib/libc/stdlib/../../../../../../../newlib-1.19.0/newlib/libc/stdlib/abort.c:63: undefined reference to `_exit'
4
/Users/thinkJD/arm_toolchain/yagarto-4.6.2/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/v7m/libc.a(lib_a-signalr.o): In function `_kill_r':
5
/Users/mfischer/Projects/yagarto/newlib-build/arm-none-eabi/thumb/v7m/newlib/libc/reent/../../../../../../../newlib-1.19.0/newlib/libc/reent/signalr.c:61: undefined reference to `_kill'
6
/Users/thinkJD/arm_toolchain/yagarto-4.6.2/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/v7m/libc.a(lib_a-signalr.o): In function `_getpid_r':
7
/Users/mfischer/Projects/yagarto/newlib-build/arm-none-eabi/thumb/v7m/newlib/libc/reent/../../../../../../../newlib-1.19.0/newlib/libc/reent/signalr.c:96: undefined reference to `_getpid'
8
/Users/thinkJD/arm_toolchain/yagarto-4.6.2/bin/../lib/gcc/arm-none-eabi/4.6.2/../../../../arm-none-eabi/lib/thumb/v7m/libc.a(lib_a-sbrkr.o): In function `_sbrk_r':
9
/Users/mfischer/Projects/yagarto/newlib-build/arm-none-eabi/thumb/v7m/newlib/libc/reent/../../../../../../../newlib-1.19.0/newlib/libc/reent/sbrkr.c:60: undefined reference to `_sbrk'
10
collect2: ld returned 1 exit status
11
make: *** [freertos.elf] Error 1

Es scheint etwas mit meinem Makefile nicht zu stimmen.
Eventuell kann mir jemand auf die Sprünge helfen?

Grüße thinkJD

von Jürgen (jliegner)


Lesenswert?

Versuch mal folgendes im makefile:
1
-------------------
2
ASFLAGS = $(MCFLAGS) -g -gdwarf-2 -Wa,-amhls=$(<:.s=.lst) $(ADEFS)
3
CPFLAGS = $(MCFLAGS) $(OPT) -gdwarf-2 -mthumb -fno-strict-aliasing -fomit-frame-pointer -Wall -fverbose-asm -Wa,-ahlms=$(<:.c=.lst) $(DEFS)
4
CPFLAGS += -std=gnu99 -MD -MP -MF .dep/$(@F).d  -ffunction-sections 
5
LDFLAGS = $(MCFLAGS) -mthumb -nostartfiles -T$(LDSCRIPT) -Wl,-Map=$(FULL_PRJ).map,--cref,--no-warn-mismatch,--gc-sections $(LIBDIR)
6
-------------------

Wichtig ist der Eintrag: -ffunction-sections

Das bewirkt, dass der Compiler alle Funktionen in ein extra 
.text-segment packt und die nicht benötigten werden mit --gc-sections 
rausgeschmissen. Dein Code sollte dadurch auch kleiner werden.

Die Linkerfehler kommen aber aus der newlib. Sobald du irgendeine der 
Funktionen wie printf sprintf puts u.s.w. benutzt, sind die Fehler 
wieder da. Mann muss dann entweder diese Funktionen wie _sbreak _getpid 
programmieren (meistens sind's nur Dummys) oder auf alle Funktionen 
verzichten die diese Linkerfehler auslösen.
Am besten aus meiner Sicht ist es für die gesamte (xx)printf-Schiene 
eine der häufig zu findenden Mini-Implementierungen zu verwenden. Das 
spart eine Menge an Code der dazugelinkt wird.

von thinkJD (Gast)


Lesenswert?

Hey,
vielen Dank für die schnelle Antwort.
Ich habe die Änderung gemacht, habe aber immer noch die selben 
Linkerfehler.

Was ich nicht verstehe, warum läuft das bei Dir und bei mir nicht.
War de eine Änderung in yargato? Ich hab an den Sourcefiles nichts 
geändert.

Gruß JD

von thinkJD (Gast)


Lesenswert?

Ah, falscher Alarm!
Ein "make clean" und die Welt ist wieder in Ordnung :)
Vielen Dank für die schnelle Hilfe!

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.