Hallo zusammen, als Teil meiner Masterarbeit möchte ich einen diskreten Zustandsregler für ein inverses Pendel implementieren. Das Ganze soll jedoch nicht auf einem µController erfolgen, sondern auf einer FPGA-Platform auf der ich einen Microblaze IPCore aufsetze. Wie aus dem Titel ersichtlich handelt es sich um ein Nexys3 Board der Firma Digilent, auf welchem ein Xilinx Spartan6 FPGA verbaut ist. Ich arbeite somit mit der ISE Design Suite 14.7 mit Webpack Lizenz. Bisher habe ich schon mehrfach erfolgreich das Microblaze MCS mit Hilfe des IPCoreGenerators eingebuden und auch einfache Testprogramme ("HelloWorld" per UART) mit dem SDK erzeugt. Leider findet man über die Programmierung des Microblaze nur sehr wenige Informationen. Bisher waren meine beste Informationsquelle diverse Problem-Threads aus dem Xilinx-Forum. Natürlich habe ich auch schon etliche PDFs an Dokumentation über Microblaze durchsucht, leider ohne großen Erfolg. Ich habe das "HelloWorld"-Programm so modifiziert, dass immer bei einem Tastendruck eine UART-Ausgabe erhalte. Dies läuft im Moment jedoch nur über Polling. Als nächsten Schritt wollte ich mich mit Interrupts des Microblaze beschäftigen, jedoch komme ich hierbei kein Stück weiter. Zwar habe ich schon verschiedene Tutorials zum Microblaze gefunden, allerdings wird hierbei in der Regel das EDK mit Xilinx Platform Studio benutzt, wofür meine Webpack-Lizenz nicht auszureichen scheint, und hören die Tutorials meistens nach dem Laden des "HelloWorld"-Programms auf. Ich bin für jeden Tipp dankbar! Gruß, Matthias
Matthias W. schrieb: > Das Ganze soll jedoch nicht auf einem µController erfolgen, sondern auf > einer FPGA-Platform auf der ich einen Microblaze IPCore aufsetze. Und was (ausser dem signifikant höheren Preis) genau ist nun der relevante Unterschied zwischen einem fertigen Softcore-uC im FPGA und einem fertigen uC z.B. mit ARM Core? Richtig: eigentlich keiner. Wenn du den Start und die Regelung direkt in VHDL machen würdest, das wäre was...
:
Bearbeitet durch Moderator
Lothar M. schrieb: > Matthias W. schrieb: >> Das Ganze soll jedoch nicht auf einem µController erfolgen, sondern auf >> einer FPGA-Platform auf der ich einen Microblaze IPCore aufsetze. > Und was (ausser dem signifikant höheren Preis) genau ist nun der > relevante Unterschied zwischen einem fertigen Softcore-uC im FPGA und > einem fertigen uC z.B. mit ARM Core? Richtig: eigentlich keiner. > > Wenn du den Start und die Regelung direkt in VHDL machen würdest, das > wäre was... Na ja, ausgesucht habe ich mir das nur bedingt... ;-) Es geht vorallem darum, sich in den Microblaze einzuarbeiten und die Information für zukünftige Projekte verfügbar zu machen. Als SoC könnte man das Ganze ja noch um weitere Komponenten wie z.B. eine Kommutierungslogik für BLDC Motoren erweiteren, die dann auch tatsächlich von dem Geschwindigkeitsplus des FPGA profitieren. Im Moment wäre es mir auch lieber, die Regelung auf einem Cortex-M4 umzusetzen. Hierfür finde ich wesentlich mehr Informationen. Die Zustandsregelung in VHDL umzusetzen wäre tatsächlich mal eine Aufgabe, jedoch bezweifel ich mit meinen beschränkten Kenntnissen, dass das so ohne weiteres machbar ist. Ich lasse mich jedoch gerne eines besseren belehren :-)
Matthias W. schrieb: > Es geht vorallem darum, sich in den Microblaze einzuarbeiten und die > Information für zukünftige Projekte verfügbar zu machen. Der scheint zwischenzeitlich tatsächlich frei verfügbar zu sein. Ob es allerdings ohne EDK "Spass" macht, damit zu arbeiten, sei dahingestellt.
Lothar M. schrieb: > Matthias W. schrieb: >> Es geht vorallem darum, sich in den Microblaze einzuarbeiten und die >> Information für zukünftige Projekte verfügbar zu machen. > Der scheint zwischenzeitlich tatsächlich frei verfügbar zu sein. Ob es > allerdings ohne EDK "Spass" macht, damit zu arbeiten, sei dahingestellt. Also bisher kann ich sagen, dass sich der Spaß definitiv in Grenzen hält. Würde ich wenigstens einfache Beispiel-Projekte finden können, in denen mal ein externes Interrupt oder ein Timer verwendet wird, wäre mir ja schon ein ganzes Stück geholfen. Leider wirkt es so, als wäre ich der erste, der diesen umständlichen Weg beschreitet. :-D
Mittlerweile habe ich ein Beispiel gefunden, bei dem ein Timer-Interrupt verwendet wird. Ich habe also ein neues Projekt angelegt und den Code übernommen, um die Initialisierung nachvollziehen zu können. Leider bekomme ich jetzt beim Kompilieren des SDK-Projektes eine Fehlermeldung, dass ich die Größe meines BlockRAMs um knapp 3kB überschritten hätte. Ich kann mir das eigentlich kaum vorstellen, da ich den Microblaze mit 64kB Programmspeicher erstellt habe und das Programm wirklich kurz ist. Es handelt sich eigentlich um ein "HelloWorld" mit einem Timer-Interrupt. Hier meine Quelle: http://www.ibelimb.com/2014/03/30/generating-a-microblaze-soft-processor-with-ise-webpack-14-dot-7/
mikroblaze gcc-kompilerschalter -s (Optimierung auf size) aktivieren
Matthias W. schrieb: > Leider > bekomme ich jetzt beim Kompilieren des SDK-Projektes eine Fehlermeldung, > dass ich die Größe meines BlockRAMs um knapp 3kB überschritten hätte. > Ich kann mir das eigentlich kaum vorstellen, da ich den Microblaze mit > 64kB Programmspeicher erstellt habe und das Programm wirklich kurz ist. Die BRAMs werden in kiloBIT angegeben. Nicht kiloBYTE. FPGAs haben zwar rattenschnellen Speicher, aber i.d.R. recht wenig. Edit: Evtl. hab ichs auch falsch gelesen - hast Du das schon erfolgreich mit 64KByte synthetisiert?
:
Bearbeitet durch User
Mac G. schrieb: > Die BRAMs werden in kiloBIT angegeben. Nicht kiloBYTE. > FPGAs haben zwar rattenschnellen Speicher, aber i.d.R. recht wenig. > > Edit: > Evtl. hab ichs auch falsch gelesen - hast Du das schon erfolgreich mit > 64KByte synthetisiert? Also die Synthese funktionierte bisher einwandfrei. Ich habe mich zunächst gewundert, dass ich mittlerweile die kostenlose Microblaze-Variante mit 64kB erstellen kann. Bis vor kurzem war hier eine Grenze bei 16kB. Nach einem Update des IPCores wurde die Grenze aber offenbar nach oben verschoben.
Bit Wurschtler schrieb: > mikroblaze gcc-kompilerschalter -s (Optimierung auf size) aktivieren Mit Optimierung auf size sind es leider noch 2984 byte.
Das passt doch locker in 64kByte rein und auch in 64kBit (= 8kByte).
Gustl B. schrieb: > Das passt doch locker in 64kByte rein und auch in 64kBit (= 8kByte). Ich meinte damit 2984 byte zu groß! (66984 byte) ;-)
Da läuft irgendwas beim Linken oder mit den Bibliotheken schief. Ein UART + Hello World sollte in unter 1 kByte passen. Du kannst ja mal mit nm nachschauen, wo die Bytes verballert werden:
1 | $ zpu-elf-nm --print-size --size-sort main.elf |
2 | 00003f37 00000001 T __malloc_lock |
3 | 00003f38 00000001 T __malloc_unlock |
4 | 00005bfc 00000001 D char_count |
5 | 000074b0 00000001 B command_number |
6 | ... |
Duke
Duke Scarring schrieb: > Da läuft irgendwas beim Linken oder mit den Bibliotheken schief. > Ein UART + Hello World sollte in unter 1 kByte passen. > > Du kannst ja mal mit nm nachschauen, wo die Bytes verballert werden: >
1 | > $ zpu-elf-nm --print-size --size-sort main.elf |
2 | > 00003f37 00000001 T __malloc_lock |
3 | > 00003f38 00000001 T __malloc_unlock |
4 | > 00005bfc 00000001 D char_count |
5 | > 000074b0 00000001 B command_number |
6 | > ... |
7 | > |
> > Duke Ok, ich glaube an dieser Stelle werden meine Kompetenzen überschritten... :-D Soll heißen, ich habe keine Ahnung wie ich das bewerkstellige.
Hm, auf Grund deines Hinweises bezüglich des Linkers, habe ich mir gerade mal genauer das Linker Script angeschaut. Irgendwie sieht das alles recht komisch aus. (Available Memory Regions: ilmb_cntlr_dlmb_cntlr Base Adress: 0x00000050 Size: 0x00001FB0) Wenn ich mir mit Hilfe des Xilinx Tools "Generate a linker script" ein neues erzeugen möchte, ist beim Hardware Memory Map auch nur die Rede von 8 kB Speicher?!
Wie es aussieht, habe ich beim Erstellen des Hardware Projects im SDK das falsche BMM-File ausgewählt. Ich kann mittlerweile die besagten Code kompilieren und ausführen. Auch externe Interrupts habe ich mit Hilfe eines Buttons triggern können. Jetzt versuche ich derzeit zwei externe Interrupts über zwei verschiedene Buttons zu triggern. Leider scheitere ich hierbei. Ich initialisiere beide Buttons über XIOModule, da ich dies in der xiomodule.h gelesen habe. Nach dem Aufruf von XIOModule_Intialize, _Start, _Connect und _Enable für beide XIOModule funktioniert jedoch immer nur eins. Offenbar überschreibe ich den anderen immer wieder.
Offenbar funktioniert es so nicht. Vermutlich verstehe ich die Funktion des XIOModules nicht. In der xiomodule.h habe ich gelesen, dass ich für jedes IO-Device eine XIOModule-Variable anlegen muss. Leider scheine ich die Initialisierung meines ersten Interrupts durch das zweite zu überschreiben. Leider ist mir nicht ganz klar wieso... Hier mein Code:
1 | #include <stdio.h> |
2 | #include <xparameters.h> |
3 | #include <xiomodule.h> |
4 | #include "init.h" |
5 | |
6 | |
7 | void btnrISR(void); |
8 | void btnlISR(void); |
9 | |
10 | char btnrFlg=0,btnlFlg=0; |
11 | XIOModule btnr,btnl; |
12 | |
13 | int main() |
14 | {
|
15 | init(); |
16 | |
17 | microblaze_register_handler(XIOModule_DeviceInterruptHandler,XPAR_IOMODULE_0_DEVICE_ID); |
18 | |
19 | XIOModule_Initialize(&btnr,XPAR_IOMODULE_0_DEVICE_ID); |
20 | XIOModule_Start(&btnr); |
21 | XIOModule_Connect(&btnr,XIN_IOMODULE_GPI_1_INTERRUPT_INTR,btnrISR,NULL); |
22 | XIOModule_Enable(&btnr,XIN_IOMODULE_GPI_1_INTERRUPT_INTR); |
23 | |
24 | XIOModule_Initialize(&btnl,XPAR_IOMODULE_0_DEVICE_ID); |
25 | XIOModule_Start(&btnl); |
26 | XIOModule_Connect(&btnl,XIN_IOMODULE_GPI_1_INTERRUPT_INTR,btnlISR,NULL); |
27 | XIOModule_Enable(&btnl,XIN_IOMODULE_GPI_1_INTERRUPT_INTR); |
28 | |
29 | microblaze_enable_interrupts(); |
30 | |
31 | xil_printf("start\n\r"); |
32 | |
33 | while(1){ |
34 | if(btnrFlg==1){ |
35 | btnrFlg=0; |
36 | xil_printf("Button Right\n\r"); |
37 | }
|
38 | if(btnlFlg==1){ |
39 | btnlFlg=0; |
40 | xil_printf("Button Left\n\r"); |
41 | }
|
42 | }
|
43 | |
44 | return 0; |
45 | }
|
46 | |
47 | void btnrISR(void){ |
48 | btnrFlg=1; |
49 | }
|
50 | void btnlISR(void){ |
51 | btnlFlg=1; |
52 | }
|
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.