Digilent Nexys3 (Spartan6), Microblaze und die Interrupts

#4499277
Lesenswert?

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
Moderator (Firma: Titel) Persönliche Seite #4499535
Lesenswert?

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...
#4499669
Lesenswert?

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 :-)
Moderator (Firma: Titel) Persönliche Seite #4499691
Lesenswert?

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.
#4499752
Lesenswert?

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
#4500611
Lesenswert?

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/
#4500646
Lesenswert?

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?
#4500726
Lesenswert?

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.
Gast #4501397
Lesenswert?

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
#4502025
Lesenswert?

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.
#4502062
Lesenswert?

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?!
#4508045
Lesenswert?

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.
#4511004
Lesenswert?

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
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren