Forum: Mikrocontroller und Digitale Elektronik Parallele Schnittstelle an AVR?


von Jabberwock (Gast)


Angehängte Dateien:

Lesenswert?

Hallo, ich habe ein Problem und weiß nicht genau wie ich es lösen 
könnte. Da ich die ganze µC Sache eigentlich nur Hobbymäßig macht fehlt 
mir auch einfach das Wissen dazu.

Also, Ich habe ein Wigglerkabel das an dem Parallelport einer Windows 
Maschine hängt. Dazu eine Software in C die über den Port und das Kabel 
per JTAG Lese und Schreibaktionen auf einem SMP8634 Prozessor ausführt.

Nun möchte ich den Rechner durch einen AVR ersetzen. Die Software habe 
ich bereits auf einem Butterfly einigermaßen zum Laufen bekommen. Aber 
was mir fehlt ist der Output.

Kann ich die parallele Schnittstelle irgendwie in dem AVR darstellen?
Das Wigglerkabel soll also an den AVR und der soll dann die 
entsprechenden Befehle senden.

In dem WinProgramm habe ich folgendes gefunden.
1
if(wiggler) data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 << WTRST_N);
2
   else        data = (1 << TDO) | (0 << TCK) | (tms << TMS) | (tdi << TDI);

TDI, TDO, TMS, TCK sind ja die Pins des JTAGs
Könnte ich einfach Pins im AVR dafür definieren?

Ich wäre euch echt sehr dankbar wenn ihr mir ein bisschen helfen 
könntet.
Ich habe das Projekt angehängt, fall jemand einen Blick drauf werfen 
möchte...

mfg
Jabberwock

von Falk B. (falk)


Lesenswert?

@ Jabberwock (Gast)

>TDI, TDO, TMS, TCK sind ja die Pins des JTAGs
>Könnte ich einfach Pins im AVR dafür definieren?

Sicher, such dir die schönsten aus ;-)

MfG
Falk

von Jabberwock (Gast)


Lesenswert?

Hallo, danke für die sehr schnelle Antwort.

Also könnte ich einfach

statt

data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 << 
WTRST_N)

PORTB |= ( 1 << WTD0 ) | (0 << WTCK ) | (tms << WTMS ) | (tdi << WTDI) | 
(1 << WTRST_N);

schreiben?

Wie ist das mit der Datenrichtung, das muss ja auch empfangen könne? 
Weil ja auch Sachen gelesen werden.

von Falk B. (falk)


Lesenswert?

@  Jabberwock (Gast)

>Wie ist das mit der Datenrichtung, das muss ja auch empfangen könne?
>Weil ja auch Sachen gelesen werden.

Irgenwie glaube iuch nicht dass

"Die Software habe ich bereits auf einem Butterfly einigermaßen zum 
Laufen bekommen."

Das sind elementare Grundlagen. Ohe die wird das GAR NICHTS.

AVR-GCC-Tutorial

MFG
Falk

von Tilo (Gast)


Lesenswert?

Natürlich musst du die Ein/Ausgänge entsprechend konfigurieren. Wie das 
geht steht im Handbuch deines uC. Am PC wird der Parallelport für solche
Basteleien gerne verwendet, da man ihn recht einfach ansteuern kann
und die Schnittstelle TTL Pegel hat. Mit einem Parallelen Bus hat das 
nicht
mehr viel zu tun.

von Jabberwock (Gast)


Lesenswert?

Sie lässt sich kompilieren und ich habe sie auf dem Butterfly.
Die Ausgaben des Porgrammes  habe ich geändert und gebe die jetzt über 
rs232 auf den Terminal aus. Das läuft soweit schon. Nur bleibt er hängen 
weil er noch nichts lesen oder schreiben kann und dann  auf Daten 
wartet.  Außerdem bekomme ich noch ein paar Warnungen aber es scheint zu 
gehen.
Das Programm habe ich ja auch nicht geschrieben sondern nur angepasst 
für den AVR.

Mir ist das nur mit der Ausgabe nicht ganz klar.
Wenn ich die Pins z.B als Ausgang definiere, wie kann er dann was 
empfanen? Oder sind manche von den JTAG pins zum senden und andere zum 
empfangen?

mfg
Jabberwock

von Falk B. (falk)


Lesenswert?

@ Jabberwock (Gast)

>Wenn ich die Pins z.B als Ausgang definiere, wie kann er dann was
>empfanen?

Kann er nicht.

> Oder sind manche von den JTAG pins zum senden und andere zum
>empfangen?

Auf JTAG hast du von deinem Anwenderprogramm keinen Zugriff. Du musst 
sogar das JTAG ver AVR Fuses bzw. Software abschalten, wenn du die 
Pins in deinem Programm nutzen willst.

MFG
Falk

von Jabberwock (Gast)


Angehängte Dateien:

Lesenswert?

Das verstehe ich jetzt nicht, das Programm das am PC läuft macht das 
doch auch. Es geht über den Parallelport auf die JTAG Schnittstelle 
einer IPTV Box und das funktioniert bestens. Das gleiche soll der Atmel 
auch machen.

Gut, JTAG kann ich abschalten. Brauch ich ja im Grunde nicht da das ja 
alles die Software übernimmt.

Ich habe mal ein .txt angehängt mit einem Auszug aus dem Quellcode. Mir 
wird nicht ganz klar wie die Daten übertragen werden.
Vieleicht verstehe ich da ja auch was total falsch.
Wäre super wenn du vieleicht einen Blick drauf werfen könntest.

mfg
Jabberwock

von Jabberwock (Gast)


Lesenswert?

Guten Morgen, auch auf die Gefahr hin dass ich nerve...

Bei Wikipedia steht: 
http://de.wikipedia.org/wiki/Joint_Test_Action_Group

Test Data Input (TDI) (positive Flanke)
Test Data Output (TDO) (negative Flanke)
Test Clock (TCK) (positive Flanke)
Test Mode Select Input (TMS)
Test Reset (TRST) (optional)

Also lege ich für die Pins TDI, TCD, TMS, TRST die Datenrichtung Ausgang 
fest und TDO als Eingang.
Oder ist das jetzt totaler quatsch?

Muss ich vielleicht dazusagen das es sich um EJTAG handelt?

mfg
Jabberwock

von Günter R. (galileo14)


Lesenswert?

Falk Brunner wrote:
>
> Auf JTAG hast du von deinem Anwenderprogramm keinen Zugriff. Du musst
> sogar das JTAG ver AVR Fuses bzw. Software abschalten, wenn du die
> Pins in deinem Programm nutzen willst.
>
> MFG
> Falk

Soweit ich den Jabberwock verstehe, will er doch nicht JTAG auf dem AVR 
verwenden, sondern den AVR quasi als PC-Ersatz einsetzen und damit einen 
ganz anderen Prozessor (SMP8634) über dessen JTAG-Schnittstelle 
ansteuern. Oder nicht, Jaberwock? Dazu braucht er sich nicht um die 
JTAG-Fuses am AVR zu kümmern.


Jabberwock wrote:

>Also lege ich für die Pins TDI, TCK, TMS, TRST die Datenrichtung Ausgang
>fest und TDO als Eingang.
>Oder ist das jetzt totaler quatsch?

Ich meine, das ist genau richtig.

Günter

von Stefan B. (stefan) Benutzerseite


Lesenswert?

@ Jabberwock

Das siehst du richtig.

Mit der Parallelschnittstelle am PC hat das nur soweit was zu tun, als 
dass das die physikalische Schnittstelle ist. Ein paar Pins dieser 
Schnittstelle werden zum Bitklappern benutzt.

Deine Idee ist interessant, stattdessen einfach ein paar Pins eines AVRs 
zu nehmen. Ich habe immer noch im Hinterkopf, mein ungenutztes 
Arthernet-Board für solche Zwecke zu missbrauchen ;-)

Ich würde solche Stellen komplett in Ruhe lassen:

data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 <<
WTRST_N)

und mir stattdessen ein paar Lowlevel-Funktionen basteln, die sich dem 
Programm gegenüber wie ein PC-System präsentieren.

Auf die Art brauchst du keine verstreuten Änderungen im Quellcode, 
sondern nur zentral 3-4 Funktionen, von denen die meisten einfache 
Dummies sind.

Ob es schlauer ist, die WINDOWS_VERSION zu erweitern oder die nicht 
WINDOWS_VERSION, muss man prüfen. Wenn man die WINDOWS_VERSION nimmt, 
könnte es so aussehen:

// Ausgabe eines Wertes
// WINDOWS_VERSION
//      _outp(0x378, data);

void _outp(uint16_t lptport, uint8_t data)
{
  // hier data an die AVR Pins ausgeben...
}

// Eingabe eines Wertes
// WINDOWS_VERSION
//      data = (unsigned char)_inp(0x379);

uint8_t _inp(uint16_t lptport)
{
  uint8_t data;

  // hier data von den AVR Pins einlesen...
  return data;
}

// Dummies
#define CreateFile(A, B, C, D, E, F, G) (A)
#define CloseHandle(h)
,,,

Was man sich dann noch ansehen muss ist das Timing und der 
Speicherbedarf. Die PC systeme könnten da für AVR Verhältnisse riesige 
Puffer benutzen.

Ehrlich gesagt sehe ich beim Speicher eine viel grössere Hürde als bei 
dem Klappern mit den Pins. Wenn ich das sehe:

int main(int argc, char** argv)
{
    char choice[128];
    ...

    if (argc > 1)
    {
       j = 1;
       while (j < argc)
       {
          strcpy(choice,argv[j]);

          if (strcasecmp(choice,"/wiggler")==0)
          {
              printf("\nusing Wiggler interface\n");
              wiggler = 1;
    ...

kräuseln sich aus AVR Sicht mit kostbarem paar KB kleinem RAM die 
Fussnägel, wenn 128 Bytes mal eben so verbraten werden. Sicher gibt es 
noch mehr ähnliche Stellen.

Aber du schreibst, das ist bis auf die Pingeschichte schon lauffähig 
portiert?

von Jabberwock (Gast)


Lesenswert?

Ja genau so habe ich das gemeint.

Ich verstehe nur diese Funktion nicht. Die wird von allen Lese 
/Scheibfunktionen aufgerufen. Ich denke das da die Bits an den Port 
gegeben werden. Weil _outp(0x378, data); müsste das glaube ich machen.
1
 static unsigned char clockin(uint8_t tms, uint8_t tdi)
2
{
3
   unsigned char data;
4
5
   tms = tms ? 1 : 0;
6
   tdi = tdi ? 1 : 0;
7
     
8
   if(wiggler) data = (1 << WTDO) | (0 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 << WTRST_N);
9
   else        data = (1 << TDO) | (0 << TCK) | (tms << TMS) | (tdi << TDI);
10
   #ifdef WINDOWS_VERSION   // ---- Compiler Specific Code ----  
11
      _outp(0x378, data);  
12
   #else  
13
      //ioctl(pfd, PPWDATA, &data);  Was ist das???
14
   #endif
15
16
   if(wiggler) data = (1 << WTDO) | (1 << WTCK) | (tms << WTMS) | (tdi << WTDI) | (1 << WTRST_N);
17
   else        data = (1 << TDO) | (1 << TCK) | (tms << TMS) | (tdi << TDI);
18
   #ifdef WINDOWS_VERSION   // ---- Compiler Specific Code ----  
19
      _outp(0x378, data);  
20
   #else  
21
      //ioctl(pfd, PPWDATA, &data);  Was ist das???
22
   #endif
23
24
   #ifdef WINDOWS_VERSION   // ---- Compiler Specific Code ----  
25
      data = (unsigned char)_inp(0x379);  
26
   #else  
27
    //  ioctl(pfd, PPRSTATUS, &data);  
28
   #endif
29
30
   data ^= 0x80;
31
   data >>= (wiggler ? WTDO : TDO);
32
   data &= 1;
33
34
   return data;
35
}

Was passiert denn da mit Data? und was bedeutet data >>=(wiggler ? WTDO 
: TDO)

Wenn das die Ausgabefunktion ist, an welcher stelle bringe ich dann 
meine Pins unter damit das nicht mehr über den Parallelport sonder über 
die Pins des Atemls raus geht?

1
void test_reset(void)
2
{
3
    clockin(1, 0);  // Run through a handful of clock cycles with TMS high to make sure
4
    clockin(1, 0);  // we are in the TEST-LOGIC-RESET state.
5
    clockin(1, 0);
6
    clockin(1, 0);
7
    clockin(1, 0);
8
    clockin(0, 0);  // enter runtest-idle
9
}
10
11
12
void set_instr(uint32_t instr)
13
{
14
    uint8_t i;
15
    static uint32_t curinstr = 0xFFFFFFFF;
16
17
    if (instr == curinstr)
18
       return;
19
20
    clockin(1, 0);  // enter select-dr-scan
21
    clockin(1, 0);  // enter select-ir-scan
22
    clockin(0, 0);  // enter capture-ir
23
    clockin(0, 0);  // enter shift-ir (dummy)
24
    for (i=0; i < instruction_length; i++)
25
    {
26
        clockin(i==(instruction_length - 1), (instr>>i)&1);
27
    }
28
    clockin(1, 0);  // enter update-ir
29
    clockin(0, 0);  // enter runtest-idle
30
31
    curinstr = instr;
32
}
33
34
35
static unsigned int ReadWriteData(uint32_t in_data)
36
{
37
    uint8_t i;
38
    uint32_t out_data = 0;
39
    unsigned char out_bit;
40
41
    clockin(1, 0);  // enter select-dr-scan
42
    clockin(0, 0);  // enter capture-dr
43
    clockin(0, 0);  // enter shift-dr
44
    for(i = 0 ; i < 32 ; i++)
45
    {
46
       out_bit  = clockin((i == 31), ((in_data >> i) & 1));
47
       out_data = out_data | (out_bit << i);
48
    }
49
    clockin(1,0);   // enter update-dr
50
    clockin(0,0);   // enter runtest-idle
51
    return out_data;
52
}

von Jabberwock (Gast)


Lesenswert?

Oh, du hast meine Frage ja schon beantwortet...

Danke für die schnelle Antwort, so hatte ich mir das auch gedacht nur 
war ich mir nicht sicher ob es überhaut gehen würde.

Du hast das jetzt aus dem .txt genommen, oder? das ist der originale PC 
Code. Ganz oben in dem ersten Post ist der angepasste Code in dem .zip 
(AVRStudio Projekt) Da ist einiges rausgeflogen.

mfg
Jabberwock

von Karl H. (kbuchegg)


Lesenswert?

Jabberwock wrote:
> Ja genau so habe ich das gemeint.
>
> Ich verstehe nur diese Funktion nicht. Die wird von allen Lese
> /Scheibfunktionen aufgerufen. Ich denke das da die Bits an den Port
> gegeben werden. Weil _outp(0x378, data); müsste das glaube ich machen.

Auf einem Windows System, ja.
Auf einem Unix System macht das ioctl (Damit hat sich deine
im Code eingebaute Frage: Was ist das??? erledigt)


>
> Was passiert denn da mit Data? und was bedeutet data >>=(wiggler ? WTDO
> : TDO)


Das ist eine ganz normale Kombination aus einem Schiebeoperator >>=
und einer ?: Operation

Die Operation ?: macht im Grunde folgendes

  a =  Vergleich ? Ja_Ausdruck : Nein_Ausdruck

und ist fast äquivalent zu

  if( Vergleich )
    a = Ja_Ausdruck
  else
    a = Nein_Ausdruck

Der einzige Unterschied ist, dass ?: ein Ausdruck ist, der
ein Ergebnis liefert. Trifft die Bedingung zu, dann ist das
Ergebnis des kompletten Ausdrucks der Ja_Ausdruck, trifft er
nicht zu, dann eben den Nein_Ausdruck

wiggler ? WTDO : TDO

liefert als Ergennis also entweder WTDO oder TDO, je nachdem
welchen Wert (nicht 0 oder 0) die Variable wiggler hat.

Und der Rest:
1
   a >>= b;
ist identisch zu
1
   a = a >> b;

a wird um b Stellen nach rechts geschoben.
1
  data >>=(wiggler ? WTDO > : TDO);

Hier wird also data um entweder WTDO oder TDO Stellen nach rechts
verschoben, abhängig davon, ob wiggler 0 oder nicht 0 ist.

Die 'Langform' dafür lautet
1
  if( wiggler )
2
    data = data >> WTDO;
3
  else
4
    data = data >> TDO;

von Karl H. (kbuchegg)


Lesenswert?

> Wenn das die Ausgabefunktion ist, an welcher stelle bringe ich dann
> meine Pins unter damit das nicht mehr über den Parallelport sonder über
> die Pins des Atemls raus geht?

Genau in dieser Funktion machst du die Ausgabe.

Anstelle von
  _outp(0x378, data);
kommt
  PORTB = data;

Ob dann allerdings die Pinbelegungen um Port zu denen des
parallel Ports passen, musst du hardwaremässig sicherstellen.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> und was bedeutet
>   data >>= (wiggler ? WTDO : TDO)

Das ist der Fragezeichenoperator, das ist eine Kurzschreibweise des 
if -Operators:
1
if (wiggler)
2
  data >>= WTDO;
3
else
4
  data >>= TDO;

von R. M. (rmax)


Lesenswert?

Karl heinz Buchegger wrote:
> Ob dann allerdings die Pinbelegungen um Port zu denen des
> parallel Ports passen, musst du hardwaremässig sicherstellen.

... geht auch in Software, indem die Makros für die JTAG-Pins für den 
AVR anders definiert werden als für den Parallelport, also z.B. sowas:
1
#define WTD0 PINB0
2
#define WTCK PINB1
3
// etc.
Das hat den Vorteil, daß man bei der Zuordnung der JTAG-Signale zu den 
Portpins freie Hand hat.

von Jabberwock (Gast)


Lesenswert?

ja genau... so langsarm verstehe ich es, vielen Dank.

Also definiere ich Pins und bei else schicke ich data auf den Port.

ca. so...
1
#ifdef WINDOWS_VERSION   // ---- Compiler Specific Code ----  
2
      _outp(0x378, data);  
3
   #else  
4
     
5
   //      PB0 = WTDO   PB1 = WTCK      PB2 = WTMS      PB3 = WTDI    PB4 = WTRST_N
6
   PORTB |= ( 1 << PB0 ) | (0 << PB1 ) | (tms << PB2 ) | (tdi << PB3 ) | (1 << PB4 ); 
7
   #endif

von Karl H. (kbuchegg)


Lesenswert?

Jabberwock wrote:
> ja genau... so langsarm verstehe ich es, vielen Dank.
>
> Also definiere ich Pins und bei else schicke ich data auf den Port.
>
> ca. so...
>
>
1
> #ifdef WINDOWS_VERSION   // ---- Compiler Specific Code ----
2
>       _outp(0x378, data);
3
>    #else
4
> 
5
>    //      PB0 = WTDO   PB1 = WTCK      PB2 = WTMS      PB3 = WTDI
6
> PB4 = WTRST_N
7
>    PORTB |= ( 1 << PB0 ) | (0 << PB1 ) | (tms << PB2 ) | (tdi << PB3 ) |
8
> (1 << PB4 );
9
>    #endif
10
> 
11
>

Äh, nein.
Mittels | (also: Oder) kannst du nur Bits auf 1 setzen
aber nicht einzelne Bits auf 0.
Bau dir zuerst, so wie im Originalcode, das komplette Byte
in einer Variablen zusammen und gib es dann in einem Rutsch

    PORTB = data;

aus.

von Jabberwock (Gast)


Lesenswert?

Ja ist mir auch schon aufgefallen... da war ich zu übereifrig.

habe es jetzt so.

[c]
#define WTD0   PINB0
#define WTCK   PINB1
#define WTMS   PINB2
#define WTDI   PINB3
#define WTRST_N PINB4

DDRB = 0xff;
DDRB &= ~(1<<PB0);



#ifdef WINDOWS_VERSION   // ---- Compiler Specific Code ----
      _outp(0x378, data);
   #else

   //original
   //ioctl(pfd, PPWDATA, &data);

   // Ausgabe auf die Pins
   PORTB =(PPWDATA, &data);
   #endif

[c/]
Muss ich noch irgendwas beachten was der Parallelport sonst übernimmt 
was mir hier dann noch fehlen würde?

von Jabberwock (Gast)


Lesenswert?

Hm... jetzt habe ich ein neues Problem...

Weiß jemand was das PPISDATA und PPIGSTATUS macht?
1
 #else  
2
     //original
3
     //ioctl(pfd, PPWDATA, &data);  
4
   
5
     // Ausgabe auf die Pins
6
    PORTB =(PPWDATA, &data);

im Headerfile wird es wie unten  definiert. Da fehlen mir dann wohl die 
includes.
Brauche ich die? Die sind ja für die Liunxvariante. Die Frage ist was 
bewirkt das in der Ausgabe?
1
#ifdef __FreeBSD__
2
      #include <dev/ppbus/ppi.h>
3
      #include <dev/ppbus/ppbconf.h>
4
      #define PPWDATA PPISDATA
5
      #define PPRSTATUS PPIGSTATUS
6
   #else
7
      #include <linux/ppdev.h>
8
   #endif

von Karl H. (kbuchegg)


Lesenswert?

Jabberwock wrote:

>      // Ausgabe auf die Pins
>     PORTB =(PPWDATA, &data);

Ich frag mich sowieso schon die ganze Zeit, was das sein soll.

Was ist an einem

    PORTB = data;

so schwierig?

von Jabberwock (Gast)


Lesenswert?

Ich weiß halt nicht was das bewirkt. Die Frage ist ja was der komische 
CPU auf der anderen Seite haben will. Aber ich denke das ist nur config 
für den Parallelport, oder?

Ich kann es leider nicht testen das ich die CPU dafür nicht hier habe. 
Außerdem bekomme ich noch 7-mal die Warnung die immer auf die gleiche 
Variable zeigt.

left shift count >= width of type

Was bedeutet das?

von Karl H. (kbuchegg)


Lesenswert?

Jabberwock wrote:
> Ich weiß halt nicht was das bewirkt.

Meine ehrliche Meinung:
Mach ein paar Vorübungen, ala: Wie schalte ich eine am Port
angeschlossene Led ein und wieder aus.

Das sind absoluet Grundlagen!

Einfach an den Port zuweisen und schon erscheint das Bitmuster
an der Hardware. Mehr ist da nicht.

http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#I.2FO-Register

>
> left shift count >= width of type
>
> Was bedeutet das?

Bei welcher Zeile?

von Jabberwock (Gast)


Lesenswert?

Es scheint die Varialble  ctrl_reg
zu sein.
1
void ExecuteDebugModule(uint32_t *pmodule)
2
{
3
   uint32_t ctrl_reg;
4
   uint32_t address;
5
   uint32_t data   = 0;
6
   uint32_t offset = 0;
7
   uint32_t finished = 0;
8
   uint32_t DEBUGMSG = 0;
9
      
10
   if (DEBUGMSG) uart_puts("DEBUGMODULE: Start module.\n");
11
   
12
   // Feed the chip an array of 32 bit values into the processor via the EJTAG port as instructions.
13
   while (1)
14
   {
15
      // Read the control register.  Make sure an access is requested, then do it.
16
      while(1) 
17
      {
18
         set_instr(INSTR_CONTROL);
19
         ctrl_reg = ReadWriteData(PRACC | PROBEN | SETDEV); //erste Warnung
20
         if (ctrl_reg & PRACC)  //zweite
21
            break;
22
         if (DEBUGMSG) uart_puts("DEBUGMODULE: No memory access in progress!\n");
23
      }
24
      
25
      set_instr(INSTR_ADDRESS);
26
      address = ReadData();
27
      
28
      // Check for read or write
29
      if (ctrl_reg & PRNW) // Bit set for a WRITE  //dritte Warunung
30
      {
31
         // Read the data out
32
         set_instr(INSTR_DATA);
33
         data = ReadData();
34
      
35
         // Clear the access pending bit (let the processor eat!)
36
         set_instr(INSTR_CONTROL);
37
         ctrl_reg = ReadWriteData(PROBEN | SETDEV);
38
      
39
         // Processor is writing to us
40
         if (DEBUGMSG) uart_puts("DEBUGMODULE: Write 0x%08X to address 0x%08X\n", data, address);
41
         // Handle Debug Write
42
         // If processor is writing to one of our psuedo virtual registers then save off data
43
         if (address == MIPS_VIRTUAL_ADDRESS_ACCESS)  address_register = data;
44
         if (address == MIPS_VIRTUAL_DATA_ACCESS)     data_register    = data;
45
      }
46
      
47
      else
48
      
49
      {
50
         // Check to see if its reading at the debug vector.  The first pass through
51
         // the module is always read at the vector, so the first one we allow.  When
52
         // the second read from the vector occurs we are done and just exit.
53
         if (address == MIPS_DEBUG_VECTOR_ADDRESS)
54
         {
55
            if (finished++) // Allows ONE pass
56
            {
57
               if (DEBUGMSG) uart_puts("DEBUGMODULE: Finished module.\n");
58
               return;
59
            }
60
         }
61
      
62
         // Processor is reading from us
63
         if (address >= MIPS_DEBUG_VECTOR_ADDRESS)
64
         {
65
            // Reading an instruction from our module so fetch the instruction from the module
66
            offset = (address - MIPS_DEBUG_VECTOR_ADDRESS) / 4;
67
            data = *(uint16_t *)(pmodule + offset);
68
            if (DEBUGMSG) uart_puts("DEBUGMODULE: Instruction read at 0x%08X  offset -> %04d  data -> 0x%08X\n", address, offset, data); //fflush(stdout);
69
         }
70
         else
71
         {
72
            // Reading from our virtual register area
73
            if (DEBUGMSG) uart_puts("DEBUGMODULE: Read address 0x%08X  data = 0x%08X\n", address, data);
74
            // Handle Debug Read
75
            // If processor is reading from one of our psuedo virtual registers then give it data
76
            if (address == MIPS_VIRTUAL_ADDRESS_ACCESS)  data = address_register;
77
            if (address == MIPS_VIRTUAL_DATA_ACCESS)     data = data_register;
78
         }
79
      
80
         // Send the data out
81
         set_instr(INSTR_DATA);
82
         data = ReadWriteData(data);
83
      
84
         // Clear the access pending bit (let the processor eat!)
85
         set_instr(INSTR_CONTROL);
86
         ctrl_reg = ReadWriteData(PROBEN | SETDEV);
87
      
88
      }
89
   }
90
}


Die anderen Warunungen sind in anderen Funktionen aber die gleiche 
Variable.


../x300tpatchv2.c:360: warning: left shift count >= width of type
../x300tpatchv2.c:361: warning: left shift count >= width of type
../x300tpatchv2.c:370: warning: left shift count >= width of type
../x300tpatchv2.c:842: warning: left shift count >= width of type
../x300tpatchv2.c:842: warning: left shift count >= width of type
../x300tpatchv2.c:854: warning: left shift count >= width of type
../x300tpatchv2.c:855: warning: left shift count >= width of type
../x300tpatchv2.c:291: warning: 'ejtag_read_h' defined but not used
avr-gcc.exe -mmcu=atmega169  x300tpatchv2.o     -o Modchip.elf
avr-objcopy -O ihex -R .eeprom  Modchip.elf Modchip.hex
avr-objcopy -j .eeprom --set-section-flags=.eeprom="alloc,load" 
--change-section-lma .eeprom=0 --no-change-warnings -O ihex Modchip.elf 
Modchip.eep || exit 0
c:\WinAVR-20070525\bin\avr-objcopy.exe: there are no sections to be 
copied!

AVR Memory Usage
----------------
Device: atmega169

Program:    4068 bytes (24.8% Full)
(.text + .data + .bootloader)

Data:       1055 bytes (103.0% Full)
(.data + .bss + .noinit)


Build succeeded with 11 Warnings...

von Michael Wilhelm (Gast)


Lesenswert?

>Data:       1055 bytes (103.0% Full)
>(.data + .bss + .noinit)


>Build succeeded with 11 Warnings...

nicht mal eine Fehlermeldung. Nicht schlecht.

MW

von Karl H. (kbuchegg)


Lesenswert?

Michael Wilhelm wrote:
>>Data:       1055 bytes (103.0% Full)
>>(.data + .bss + .noinit)
>
>
>>Build succeeded with 11 Warnings...
>
> nicht mal eine Fehlermeldung. Nicht schlecht.
>

:-)
Nur sind die Warnungen keineswegs harmlos.

@Jabberwock

> ../x300tpatchv2.c:360: warning: left shift count >= width of type

Und du glaubst jetzt wirklich ich zähle in deinem unvollständigen
Code die Zeilen aus bis ich bei 360 bin?

Aber was solls.
Was sagt den die Fehlermeldung

left shift count >= width of type

Da ist von einem left shift count die Rede. Wörtlich übersetzt:
Die Anzahl (der count) um die nach links geschoben (left shift)
wird.
Aha irgendwas stört den Compiler bei dem Versuch einen << anzuwenden.
Was kann das blos sein?

>=

dieser count ist also größer gleich.
Ja was den nun? Größer als was?

width of type

Die Breite (width) des Datentyps (type)

Zusammengefasst und in ein etwas besseres Deutsch verpackt:
Es wird versucht einen Datentyp so oft nach links zu verschieben,
daß alle Bits links herausfallen und nichts übrig bleibt.

Beispiel:
Wenn ich einen uint8_t 9-mal nach links verschiebe, dann ist von
den originalen Bits kein einziges mehr im uint8_t enthalten.
Man könnte auch sagen:

  uint8_t i;
  i << 9;

ist eine komplizierte Schreibweise für

   0

War doch nicht so schwer, oder? Nichts was sich nicht mit ein
bischen Nachdenken erklären lässt.

von Jabberwock (Gast)


Lesenswert?

>Und du glaubst jetzt wirklich ich zähle in deinem unvollständigen
>Code die Zeilen aus bis ich bei 360 bin?

Natürlich nicht, deshalb sind da Kommentare in dem Code der die Stellen 
der Warnungen anzeigt...

Der Vollständige Code ist dem ersten Post angehängt...
Wobei da noch ein paar mehr Warnungen drin sind die ich aber 
größtenteils weg bekommen habe.

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.