Forum: Compiler & IDEs AVR "ret" springt zu 0x00


von Hugo P. (portisch)


Lesenswert?

Hallo,

ich habe ein Problem mit der MCP2515 CAN lib vom kreatives-chaos.

Und zwar mache ich das CAN Init:
1
InitCANBus(BITRATE_10_KBPS, can_filter);
1
void InitCANBus(uint8_t bitrate, const prog_uint8_t *filter)
2
{
3
  
4
  // init can buffer
5
  memset(&can_buffer, 0x00, sizeof(CAN_BUFFER));
6
    
7
  can_init(bitrate);                      // Initialize MCP2515
8
  can_static_filter(filter);                  // Load filters and masks  
9
}

Nun habe ich mir das in Assembler angesehen (mit MKII per DebugWIRE):
1
  sei();                                // global interrupt enable  
2
0000008F  SEI     Global Interrupt Enable 
3
  InitCANBus(BITRATE_10_KBPS, can_filter);
4
00000090  LDI R22,0x00    Load immediate 
5
00000091  LDI R23,0x01    Load immediate 
6
00000092  LDI R24,0x00    Load immediate 
7
00000093  CALL 0x000004CC    Call subroutine


Die Funktion selbst:
1
--- H:\Data\AVR\AVR_7.0_09022016\AVR_CAN\Debug/../global/can_transfer.c --------
2
{
3
000004CC  PUSH R28    Push register on stack 
4
000004CD  PUSH R29    Push register on stack 
5
000004CE  MOVW R28,R22    Copy register pair 
6
  memset(&can_buffer, 0x00, sizeof(CAN_BUFFER));
7
000004CF  LDI R25,0xB5    Load immediate 
8
000004D0  LDI R30,0xCC    Load immediate 
9
000004D1  LDI R31,0x03    Load immediate 
10
000004D2  MOVW R26,R30    Copy register pair 
11
000004D3  ST X+,R1    Store indirect and postincrement 
12
000004D4  DEC R25    Decrement 
13
000004D5  BRNE PC-0x02    Branch if not equal 
14
  can_init(bitrate);                      // Initialize MCP2515
15
000004D6  CALL 0x000001BD    Call subroutine 
16
  can_static_filter(filter);                  // Load filters and masks  
17
000004D8  MOVW R24,R28    Copy register pair 
18
000004D9  CALL 0x00000334    Call subroutine 
19
}
20
000004DB  POP R29    Pop register from stack 
21
000004DC  POP R28    Pop register from stack 
22
000004DD  RET     Subroutine return

Nach 0x4DD wenn ich mit F10 ein Step Over mache springt der AVR auf 
0x00:
1
--- No source file -------------------------------------------------------------
2
00000000  JMP 0x0000003A    Jump

Somit gibt das eine Endlosschleife. Wie komme ich nun dem Problem auf 
die Spur? In welchen Register steht die Adresse wo der "RET" hinspringen 
soll?

Ich habe ein uart Init vor dem CAN Init und wenn ich da das CALL & RET 
durchsteppe komme ich schön wieder mit dem RET nach dem CALL raus.

Nur beim CAN Init gibt es ein Problem was ich nicht finde.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hugo P. schrieb:
> In welchen Register steht die Adresse wo der "RET" hinspringen soll?

In keinem. Das steht auf dem Stack.

>   memset(&can_buffer, 0x00, sizeof(CAN_BUFFER));

Wo ist diese Variable definiert? Vielleicht hast Du nicht mehr 
ausreichend Platz im RAM, so daß der Stack in diese Variable hineinläuft 
und durch Dein memset dann hübsch "genullt" wird.

von Hugo P. (portisch)


Lesenswert?

Ich habe jetzt noch folgendes entdeckt.
Es gab Probleme von AVR Studio 5 zu 7 mit der Program Memory.
1
prog_uint8_t can_filter[] = {
2
  // Group 0
3
  MCP2515_FILTER(0x000),        // Filter 0
4
  MCP2515_FILTER(0x000),        // Filter 1
5
    
6
  // Group 1
7
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 2
8
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 3
9
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 4
10
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 5
11
    
12
  MCP2515_FILTER(0x0FF),        // Mask 0 (for group 0)
13
  MCP2515_FILTER(0x7FF),        // Mask 1 (for group 1)
14
};

Das habe ich nun so umgearbeitet:
1
static const uint8_t can_filter[] PROGMEM = {
2
  // Group 0
3
  MCP2515_FILTER(0x000),        // Filter 0
4
  MCP2515_FILTER(0x000),        // Filter 1
5
    
6
  // Group 1
7
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 2
8
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 3
9
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 4
10
  MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 5
11
    
12
  MCP2515_FILTER(0x0FF),        // Mask 0 (for group 0)
13
  MCP2515_FILTER(0x7FF),        // Mask 1 (for group 1)
14
};

Nun ist der Pointer von can_filter im Program Memory und das Init des 
CAN Busses läuft nun durch.

Aber die Watchlist zeigt mir, dass die Werte nicht drinnen sind. Wie 
bekomme ich diese in die ProgMem?

Das sind noch die Macros:
1
  #define  MCP2515_FILTER(id) \
2
      (uint8_t)((uint32_t) id >> 3), \
3
      (uint8_t)((uint32_t) id << 5), \
4
      0, \
5
      0

von Hugo P. (portisch)


Lesenswert?

Jetzt kenne ich mich gar nicht mehr aus!

Ich habe zum Testen einemal das Array so definiert:
1
static const uint8_t can_filter[] PROGMEM = {
2
  0,0,0,0,    //MCP2515_FILTER(0x000),        // Filter 0
3
  0,0,0,0,    //MCP2515_FILTER(0x000),        // Filter 1
4
  
5
  // Group 1
6
  32,0,0,0,    //MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 2
7
  32,0,0,0,    //MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 3
8
  32,0,0,0,    //MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 4
9
  32,0,0,0,    //MCP2515_FILTER(CAN_WHO_IS_ONLINE),  // Filter 5
10
  
11
  31,224,0,0,    //MCP2515_FILTER(0x0FF),        // Mask 0 (for group 0)
12
  255,224,0,0    //MCP2515_FILTER(0x7FF)        // Mask 1 (for group 1)  
13
};

Im Watchfenster wird mir aber das angezeigt:
1
-    can_filter  0x0068  prog_uint8_t[32]{prog}@0x0068
2
    [0]  0  prog_uint8_t{prog}@0x0068
3
    [1]  0  prog_uint8_t{prog}@0x0069
4
    [2]  0  prog_uint8_t{prog}@0x006a
5
    [3]  0  prog_uint8_t{prog}@0x006b
6
    [4]  0  prog_uint8_t{prog}@0x006c
7
    [5]  0  prog_uint8_t{prog}@0x006d
8
    [6]  0  prog_uint8_t{prog}@0x006e
9
    [7]  0  prog_uint8_t{prog}@0x006f
10
    [8]  0  prog_uint8_t{prog}@0x0070
11
    [9]  0  prog_uint8_t{prog}@0x0071
12
    [10]  0  prog_uint8_t{prog}@0x0072
13
    [11]  0  prog_uint8_t{prog}@0x0073
14
    [12]  0  prog_uint8_t{prog}@0x0074
15
    [13]  0  prog_uint8_t{prog}@0x0075
16
    [14]  0  prog_uint8_t{prog}@0x0076
17
    [15]  0  prog_uint8_t{prog}@0x0077
18
    [16]  0  prog_uint8_t{prog}@0x0078
19
    [17]  0  prog_uint8_t{prog}@0x0079
20
    [18]  0  prog_uint8_t{prog}@0x007a
21
    [19]  0  prog_uint8_t{prog}@0x007b
22
    [20]  0  prog_uint8_t{prog}@0x007c
23
    [21]  0  prog_uint8_t{prog}@0x007d
24
    [22]  0  prog_uint8_t{prog}@0x007e
25
    [23]  0  prog_uint8_t{prog}@0x007f
26
    [24]  0  prog_uint8_t{prog}@0x0080
27
    [25]  0  prog_uint8_t{prog}@0x0081
28
    [26]  0  prog_uint8_t{prog}@0x0082
29
    [27]  0  prog_uint8_t{prog}@0x0083
30
    [28]  0  prog_uint8_t{prog}@0x0084
31
    [29]  0  prog_uint8_t{prog}@0x0085
32
    [30]  0  prog_uint8_t{prog}@0x0086
33
    [31]  0  prog_uint8_t{prog}@0x0087

Warum ist das immer noch alles auf 0?

Edit:
Es scheint ein AVR Studio Bug zu sein!
Wenn ich mir die Memory dazu ansehe stimmen die Daten:
1
prog 0x0068  00 00 00 00 00 00 00  ..”s.......
2
prog 0x006E  00 00 20 00 00 00 20 00 00 00 20  .. ... ... 
3
prog 0x0079  00 00 00 20 00 00 00 1f e0 00 00  ... ....à..
4
prog 0x0084  ff e0 00 00

Jedoch löst das nicht das Problem wie ich das mit den Macros definieren 
kann! Hat jemand eine Idee?

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Hugo P. schrieb:
> Jedoch löst das nicht das Problem wie ich das mit den Macros definieren
> kann!

Wieso? Da funktioniert halt das Watch-Fenster auch nicht, aber im 
Speicher wird's schon gelandet sein, wie bei Deinem macrolosen Beispiel 
auch.

von Hugo P. (portisch)


Lesenswert?

Rufus Τ. F. schrieb:
> Hugo P. schrieb:
>> Jedoch löst das nicht das Problem wie ich das mit den Macros definieren
>> kann!
>
> Wieso? Da funktioniert halt das Watch-Fenster auch nicht, aber im
> Speicher wird's schon gelandet sein, wie bei Deinem macrolosen Beispiel
> auch.

Ja, beim durchlesen bin gerade selber darauf gekommen. Werde es morgen 
mal überprüfen!

von Jim M. (turboj)


Lesenswert?

Hugo P. schrieb:
> memset(&can_buffer, 0x00, sizeof(CAN_BUFFER));

Das ist fast sicher falsch (Pointer auf Pointer statt Pointer auf 
Array). Entweder
1
memset(can_buffer, 0x00, sizeof(CAN_BUFFER));

oder
1
memset(&can_buffer[0], 0x00, sizeof(CAN_BUFFER));

von B. S. (bestucki)


Lesenswert?

Jim M. schrieb:
> Hugo P. schrieb:
>> memset(&can_buffer, 0x00, sizeof(CAN_BUFFER));
>
> Das ist fast sicher falsch (Pointer auf Pointer statt Pointer auf
> Array). Entweder

Merkwürdig, warum man einen Buffer nullen muss. Da man in jedem Fall 
wissen muss, wo im Buffer das erste und letzte Element ist, reicht es, 
diese beiden Variablen entsprechen zu setzen. Der Inhalt des ungenutzten 
Buffers wird einfach ignoriert.

: Bearbeitet durch User
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.