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.
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.
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
|
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?
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.
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!
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));
|
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.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|