Forum: Mikrocontroller und Digitale Elektronik Cortex M3 ISR-Problem


von Joachim .. (joachim_01)


Lesenswert?

Hallo Mädchen und Jungens,

hab hiern SAM3X8E mit zwei eingebauten CAN-Modulen der sich hartnäckig 
weigert per ISR auf ne Nachricht zu reagieren. Die ISR wird überhaupt 
nicht angesprungen. Ich habe das Beispiel aus der ASF für das SAM3X-EK 
Board von Atmel genommen. Mein Board, ein Arduino DUE hat genau den 
gleichen uC. Die Hardware bzgl. des CAN-Aufbaus ist ebenfalls ne 
1:1-Kopie aus dem Manual von Atmel. Mein Oszi bestätigt mir das 
Empfangen der Bits über den CAN-Bus am Port-Pin. Anschließend hab ich 
noch den Port auf Schaltfunktion (Taster + LED an anderem Portpin) 
getestet, das geht ebenfalls. Hardwaremäßig scheint das ganze wohl somit 
wasserdicht zu sein.

Trotzdem reagiert die ISR nicht.
Hab dann mal den Code nach logischen Fehlern abgesucht, mit dem Hilfe im 
ASF verglichen aber nix gefunden.

Das ganze dreht sich eigentlich um:

/* Enable CAN0 & CAN1 clock. */
pmc_enable_periph_clk(ID_CAN0);
pmc_enable_periph_clk(ID_CAN1);

/* Configure and enable interrupt of CAN1, as the tests will use 
receiver interrupt. */
NVIC_EnableIRQ(CAN1_IRQn);

später dann wird die Mailbox dazugeschaltet:

/* Enable CAN1 mailbox 0 interrupt. */
can_enable_interrupt(CAN1, CAN_IER_MB0);


Langsam weiß ich nicht mehr weiter. Im Nested Vectored Interrupt 
Controller gibt's noch ein 'Interrupt Set-pending Register' aber das hat 
laut Datenblatt keinen Einfluß auf den Empfang.


Den Code hab ich nicht komplett kopiert; eine Auswertung der 
CAN-Nachricht ist erstmal ned wichtig, einzig die ISR muß angesprungen 
werden. Es sind also eigentlich nur die Zeilen für das setzen der 
Interrupt-Enable-Bits wichtig.


1
 C-Code
2
#include <stdio.h>
3
#include <string.h>
4
#include "board.h"
5
#include "sysclk.h"
6
#include "exceptions.h"
7
#include "uart.h"
8
#include "pmc.h"
9
#include "gpio.h"
10
#include "can.h"
11
#include "stdio_serial.h"
12
#include "sn65hvd234.h"
13
#include "conf_board.h"
14
#include "conf_clock.h"
15
16
//prototypes
17
void showRegister(void);
18
19
20
#define STRING_EOL    "\r"
21
22
#define STRING_HEADER "-- CAN Example --\r\n" \
23
                      "-- "BOARD_NAME" --\r\n" \
24
                      "-- Compiled: "__DATE__" "__TIME__" --"STRING_EOL
25
26
#define CAN_MSG_TOGGLE_LED_0        0x11223344
27
#define CAN_MSG_TOGGLE_LED_1        0xAABBCCDD
28
#define CAN_MSG_DUMMY_DATA          0x55AAAA55
29
30
/** CAN frame max data length */
31
#define MAX_CAN_FRAME_DATA_LEN      8
32
33
/** CAN0 Transceiver */
34
sn65hvd234_ctrl_t can0_transceiver;
35
36
/** CAN1 Transceiver */
37
sn65hvd234_ctrl_t can1_transceiver;
38
39
/** CAN0 Transfer mailbox structure */
40
can_mb_conf_t can0_mailbox;
41
42
/** CAN1 Transfer mailbox structure */
43
can_mb_conf_t can1_mailbox;
44
45
/** Receive status */
46
volatile uint32_t g_ul_recv_status = 0;
47
] 
48
49
/**
50
 * \brief Default interrupt handler for CAN 1.
51
 */
52
53
/*- - - - - - - - - - - - - - - - - - - - - - */
54
55
void CAN1_Handler(void)  // stellt sich tot
56
{
57
  uint32_t ul_status;
58
  printf("\rDEBUG: \(1a\) in CAN1_Handler\r");
59
60
  ul_status = can_get_status(CAN1);
61
    printf("\rDEBUG: \(1a_a\) in CAN1_Handler\r");
62
  if (ul_status & GLOBAL_MAILBOX_MASK) {
63
    printf("\rDEBUG: \(1b\) in CAN1_Handler ul_status \& GLOBAL_MAILBOX_MASK\r");    
64
    for (uint8_t i = 0; i < CANMB_NUMBER; i++) {
65
      ul_status = can_mailbox_get_status(CAN1, i);
66
      if ((ul_status & CAN_MSR_MRDY) == CAN_MSR_MRDY) {
67
      printf("\rDEBUG: \(1c\) in CAN1_Handler ul_status \& CAN_MSR_MRDY\r");      
68
        can1_mailbox.ul_mb_idx = i;
69
        can1_mailbox.ul_status = ul_status;
70
        can_mailbox_read(CAN1, &can1_mailbox);
71
        g_ul_recv_status = 1;
72
        break;
73
      }
74
    }
75
  }
76
}
77
/*- - - - - - - - - - - - - - - - - - - - - - */
78
79
/**
80
 * \brief Decode CAN messages.
81
 *
82
 *  \param p_mailbox Pointer to CAN Mailbox structure.
83
 */
84
static void decode_can_msg(can_mb_conf_t *p_mailbox)
85
{
86
  int a;
87
  uint32_t ul_led_Ctrl = p_mailbox->ul_datal;
88
  if (p_mailbox->ul_datal == CAN_MSG_TOGGLE_LED_0) a=1;
89
  
90
91
  puts("CAN message:" STRING_EOL);
92
  if (ul_led_Ctrl == CAN_MSG_TOGGLE_LED_0) {
93
    puts("  Toggle LED 0" STRING_EOL);
94
    gpio_toggle_pin(LED0_GPIO);  //PB27 PWM13 Arduino::13
95
  } else if (ul_led_Ctrl == CAN_MSG_TOGGLE_LED_1) {
96
    puts("  Toggle LED 1" STRING_EOL);
97
    gpio_toggle_pin(LED1_GPIO);  //PC21 PWM9 Arduino::9
98
  }
99
}
100
101
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
102
/**
103
 * \brief Reset mailbox configure structure.
104
 *
105
 *  \param p_mailbox Pointer to mailbox configure structure.
106
 */
107
static void reset_mailbox_conf(can_mb_conf_t *p_mailbox)
108
{
109
  p_mailbox->ul_mb_idx = 0;
110
  p_mailbox->uc_obj_type = 0;
111
  p_mailbox->uc_id_ver = 0;
112
  p_mailbox->uc_length = 0;
113
  p_mailbox->uc_tx_prio = 0;
114
  p_mailbox->ul_status = 0;
115
  p_mailbox->ul_id_msk = 0;
116
  p_mailbox->ul_id = 0;
117
  p_mailbox->ul_fid = 0;
118
  p_mailbox->ul_datal = 0;
119
  p_mailbox->ul_datah = 0;
120
}
121
122
#define TEST1_CAN_COMM_MB_IDX    0
123
#define TEST1_CAN_TRANSFER_ID    0x07
124
#define TEST1_CAN0_TX_PRIO       15
125
126
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
127
/**
128
 *  \brief Test the transmission from CAN0 Mailbox 0 to CAN1 Mailbox 0.
129
 */
130
static void test_1(void)
131
{
132
  can_reset_all_mailbox(CAN0);
133
  can_reset_all_mailbox(CAN1);
134
135
  printf("In Test1: CAN0 Mailbox 0 transmitting to CAN1 Mailbox 0\r");
136
137
138
139
  /* Init CAN1 Mailbox 0 to Reception Mailbox. */
140
  reset_mailbox_conf(&can1_mailbox);
141
  can1_mailbox.ul_mb_idx = TEST1_CAN_COMM_MB_IDX;
142
  can1_mailbox.uc_obj_type = CAN_MB_RX_MODE;
143
  can1_mailbox.ul_id_msk = CAN_MAM_MIDvA_Msk | CAN_MAM_MIDvB_Msk;
144
  can1_mailbox.ul_id = CAN_MID_MIDvA(TEST1_CAN_TRANSFER_ID);
145
  can_mailbox_init(CAN1, &can1_mailbox);
146
147
  /* Init CAN0 Mailbox 0 to Transmit Mailbox. */
148
  reset_mailbox_conf(&can0_mailbox);
149
  can0_mailbox.ul_mb_idx = TEST1_CAN_COMM_MB_IDX;
150
  can0_mailbox.uc_obj_type = CAN_MB_TX_MODE;
151
  can0_mailbox.uc_tx_prio = TEST1_CAN0_TX_PRIO;
152
  can0_mailbox.uc_id_ver = 0;
153
  can0_mailbox.ul_id_msk = 0;
154
  can_mailbox_init(CAN0, &can0_mailbox);
155
156
  /* Write transmit information into mailbox. */
157
  can0_mailbox.ul_id = CAN_MID_MIDvA(TEST1_CAN_TRANSFER_ID);
158
  can0_mailbox.ul_datal = CAN_MSG_TOGGLE_LED_0;
159
  can0_mailbox.ul_datah = CAN_MSG_DUMMY_DATA;
160
  can0_mailbox.uc_length = MAX_CAN_FRAME_DATA_LEN;
161
  can_mailbox_write(CAN0, &can0_mailbox);
162
163
    printf("DEBUG: Transmit information written into mailbox\r");
164
  //showRegister();
165
    
166
  
167
  
168
  
169
  /* Enable CAN1 mailbox 0 interrupt. */
170
  can_enable_interrupt(CAN1, CAN_IER_MB0);
171
  
172
  /* Send out the information in the mailbox. */
173
    can_global_send_transfer_cmd(CAN0, CAN_TCR_MB0);
174
175
  printf("\rDEBUG: \(1\) g_ul_recv_status = %d\r",g_ul_recv_status);
176
  
177
  //Ab hier passiert nix mehr weil Abarbeitung in Empfänger-ISR:
178
   while (!g_ul_recv_status);  /////////////////////////////////////////////////////////////
179
180
  printf("DEBUG: \(2\) g_ul_recv_status = %d\r\r",g_ul_recv_status);
181
  printf("DEBUG: still in Test 1\r\r");
182
  if ((can1_mailbox.ul_datal == CAN_MSG_TOGGLE_LED_0) &&
183
    (can1_mailbox.uc_length == MAX_CAN_FRAME_DATA_LEN)) {
184
    puts("Test1 passed" STRING_EOL);
185
    decode_can_msg(&can1_mailbox);
186
  } else {
187
    puts("Test1 ERROR" STRING_EOL);
188
  }
189
}
190
191
192
193
/**
194
 *  Configure UART for debug message output.
195
 */
196
static void configure_console(void)
197
{
198
  const usart_serial_options_t uart_serial_options = {
199
    .baudrate = CONF_UART_BAUDRATE,
200
    .paritytype = CONF_UART_PARITY
201
  };
202
  
203
  /* Configure console UART. */
204
  sysclk_enable_peripheral_clock(CONSOLE_UART_ID);
205
  stdio_serial_init(CONF_UART, &uart_serial_options);
206
}
207
208
209
210
/**
211
 *  \brief can_example application entry point.
212
 *
213
 *  \return Unused (ANSI-C compatibility).
214
 */
215
int main(void)
216
{
217
  uint32_t ul_sysclk;
218
  uint8_t uc_char;
219
220
  /* Initialize the SAM system. */
221
  sysclk_init();
222
  board_init();
223
224
#ifdef CONF_BOARD_CAN0
225
/* Configure the CAN0 TX and RX pins. */
226
gpio_configure_pin(PIN_CAN0_RX_IDX, PIN_CAN0_RX_FLAGS);
227
gpio_configure_pin(PIN_CAN0_TX_IDX, PIN_CAN0_TX_FLAGS);
228
/* Configure the transceiver0 RS & EN pins. */
229
gpio_configure_pin(PIN_CAN0_TR_RS_IDX, PIN_CAN0_TR_RS_FLAGS);
230
gpio_configure_pin(PIN_CAN0_TR_EN_IDX, PIN_CAN0_TR_EN_FLAGS);
231
#endif
232
233
#ifdef CONF_BOARD_CAN1
234
/* Configure the CAN1 TX and RX pin. */
235
gpio_configure_pin(PIN_CAN1_RX_IDX, PIN_CAN1_RX_FLAGS);
236
gpio_configure_pin(PIN_CAN1_TX_IDX, PIN_CAN1_TX_FLAGS);
237
/* Configure the transceiver1 RS & EN pins. */
238
gpio_configure_pin(PIN_CAN1_TR_RS_IDX, PIN_CAN1_TR_RS_FLAGS);
239
gpio_configure_pin(PIN_CAN1_TR_EN_IDX, PIN_CAN1_TR_EN_FLAGS);
240
#endif
241
242
243
244
245
246
  /* Configure UART for debug message output. */
247
  configure_console();
248
249
  /* Output example information. */
250
  puts(STRING_HEADER);
251
252
253
254
255
//Test PB15 CAN1 RX
256
257
while (0){
258
// - - - - - - - - - - - - - - - - - - - - -
259
//eine LED mit Taster einschalten, 01.03.2013
260
261
pmc_enable_periph_clk(PIN_PUSHBUTTON_1_ID);
262
pio_pull_up(PIN_PUSHBUTTON_1_PIO, PIN_PUSHBUTTON_1_MASK, PIO_PULLUP);  //pmc_enable_periph_clk nicht vergessen!
263
264
while (1) {
265
  
266
  if (!( pio_get(PIN_PUSHBUTTON_1_PIO, PIO_INPUT, PIN_PUSHBUTTON_1_MASK) ))
267
        gpio_set_pin_high(LED0_GPIO);
268
  else  gpio_set_pin_low(LED0_GPIO);
269
}
270
271
272
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
273
}
274
275
276
277
278
279
280
281
  /* Initialize CAN0 Transceiver. */
282
  sn65hvd234_set_rs(&can0_transceiver, PIN_CAN0_TR_RS_IDX);
283
  sn65hvd234_set_en(&can0_transceiver, PIN_CAN0_TR_EN_IDX);
284
  /* Enable CAN0 Transceiver. */
285
  sn65hvd234_disable_low_power(&can0_transceiver);
286
  sn65hvd234_enable(&can0_transceiver);
287
288
  /* Initialize CAN1 Transceiver. */
289
  sn65hvd234_set_rs(&can1_transceiver, PIN_CAN1_TR_RS_IDX);
290
  sn65hvd234_set_en(&can1_transceiver, PIN_CAN1_TR_EN_IDX);
291
  /* Enable CAN1 Transceiver. */
292
  sn65hvd234_disable_low_power(&can1_transceiver);
293
  sn65hvd234_enable(&can1_transceiver);
294
295
  /* Enable CAN0 & CAN1 clock. */
296
  pmc_enable_periph_clk(ID_CAN0);
297
  pmc_enable_periph_clk(ID_CAN1);
298
299
  ul_sysclk = sysclk_get_cpu_hz();
300
  if (can_init(CAN0, ul_sysclk, CAN_BPS_1000K) &&    //1000K
301
    can_init(CAN1, ul_sysclk, CAN_BPS_1000K)) {    //1000K
302
    puts("CAN initialization is completed." STRING_EOL);
303
304
    /* Disable all CAN0 & CAN1 interrupts. */
305
    can_disable_interrupt(CAN0, CAN_DISABLE_ALL_INTERRUPT_MASK);
306
    can_disable_interrupt(CAN1, CAN_DISABLE_ALL_INTERRUPT_MASK);
307
308
    /* Configure and enable interrupt of CAN1, as the tests will use receiver interrupt. */
309
    NVIC_EnableIRQ(CAN1_IRQn);
310
311
312
313
    /* Run tests. */
314
    //while (1) {
315
    //  puts("Press any key to start test" STRING_EOL);
316
    //  while (uart_read(CONSOLE_UART, &uc_char)) {  };
317
    //}    
318
319
    puts("Test1 beginnt" STRING_EOL);
320
    test_1(); 
321
    g_ul_recv_status = 0;
322
323
    puts("Test2 beginnt: Press any key to continue..." 
324
    //...
325
                //... weitere Tests
326
    
327
}

(Mod.: abschliessendes [ / c ] ergänzt)

von Dr. Sommer (Gast)


Lesenswert?

Führst du überhaupt jemals (indirekt?) "cpsie i" aus um die Behandlung 
von Interrupts einzuschalten? Wo ist überhaupt deine Hauptschleife? Mal 
im Debugger geschaut ob der Interrupt "Pending" wurde (im entsprechenden 
NVIC_ISPRn Register, siehe S.757 im ARMv7M Architecture Reference 
Manual) aber lediglich die ISR nicht ausgeführt wurde?
Außerdem überprüft ob sich das CAN-Modul auch auf den Bus synchronisiert 
(die CAN-Module vom STM32 zB müssen 11 sukzessive rezessive Bits sehen)? 
Oszilloskopbild vom Bus? Die Status-Register vom CAN mal im Debugger 
angeschaut ob was empfangen wurde bzw. per einfachem Polling im Code?

Joachim ... schrieb:
> /* Disable all CAN0 & CAN1 interrupts. */
>     can_disable_interrupt(CAN0, CAN_DISABLE_ALL_INTERRUPT_MASK);
>     can_disable_interrupt(CAN1, CAN_DISABLE_ALL_INTERRUPT_MASK);
hö???

PS: Dein Code ist chaotisch und schlecht eingerückt.

von Joachim .. (joachim_01)


Lesenswert?

Danke, ich werd's mir morgen mal genauer anschauen. Hab leider keinen 
Debugger, werd aber in die Register schauen.

Seltsamerweise funktioniert die C-Formatierung nicht, deswegen gibt's 
hier auch kein Einrücken. Hm.
An sich sieht's nur chaotisch aus, weil unwichtiger Code fehlt.



Das hier:
> /* Disable all CAN0 & CAN1 interrupts. */
>     can_disable_interrupt(CAN0, CAN_DISABLE_ALL_INTERRUPT_MASK);
>     can_disable_interrupt(CAN1, CAN_DISABLE_ALL_INTERRUPT_MASK);

das passt wohl schon (ist original Atmel Code), der CAN0 wird in test1() 
kurz darauf wieder in eingeschaltet.


Das hier ist die Warteschleife:
 while (!g_ul_recv_status);

g_ul_recv_status kommt aus der nicht funktionsfähigen ISR...

von Dr. Sommer (Gast)


Lesenswert?

Joachim ... schrieb:
> Danke, ich werd's mir morgen mal genauer anschauen. Hab leider
> keinen
> Debugger, werd aber in die Register schauen.
Leg dir mal einen zu, die sind enorm hilfreich... Die Tage an Arbeit 
die dir erspart bleiben sind die paar €uros wert.
>
> Seltsamerweise funktioniert die C-Formatierung nicht, deswegen gibt's
> hier auch kein Einrücken.
Du hast das [/c] am Ende vergessen. Alternativ kann man Code auch 
anhängen...

von Joachim .. (joachim_01)


Lesenswert?

>Führst du überhaupt jemals (indirekt?) "cpsie i" aus um die Behandlung
>von Interrupts einzuschalten?
Hm...
zumindest wird "cpsie" im assemblierten Code nicht gefunden...
Werd morgen mal weiter graben....

N8.

von Lothar (Gast)


Lesenswert?

Joachim ... schrieb:
> "cpsie"

In C üblicherweise:

__disable_interrupt();
NVIC_EnableIRQ(CAN1_IRQn);
__enable_interrupt();

von Dr. Sommer (Gast)


Lesenswert?

Lothar schrieb:
> In C üblicherweise:
Achja, er verwendet ja die CMSIS. Streng genommen ist das dann kein C 
mehr, denn der C-Standard verbietet Bezeichnern außerhalb der Standard 
Libraries mit __ zu beginnen... Aber niemand hat behauptet die CMSIS sei 
C-compliant oder gar "gut programmiert" :-)
> __disable_interrupt();
> NVIC_EnableIRQ(CAN1_IRQn);
> __enable_interrupt();
Die Interrupts sind ja von Anfang an deaktiviert, von daher ist das 
disable dort unnötig; falls es nötig wäre sollte es wenn schon ganz an 
den Anfang und nicht nach die sonstige Initialisierung.

von Joachim .. (joachim_01)


Lesenswert?

Sooo...
>Achja, er verwendet ja die CMSIS.
Gibt's denn in diesem Zusammenhang auch was anderes? Er hat noch nicht 
so viel Erfahrung mit ARM.

Nunja. Das hat ihm jetzt doch keine Ruhe gelassen. Mittlerweile ist es 
halb vier - und es funktioniert. Offensichtlich ist ihm durch das hin- 
und herkopieren und dem allgemeinen Rumfuscheln die ein oder andere 
Zeile kaputtgegangen. Mit nem neuen Projekt und ein paar Anpassungen 
geht's nun.

von Dr. Sommer (Gast)


Lesenswert?

Joachim ... schrieb:
> Sooo...
>>Achja, er verwendet ja die CMSIS.
> Gibt's denn in diesem Zusammenhang auch was anderes? Er hat noch nicht
> so viel Erfahrung mit ARM.
Weiß nicht, ich hab mir den Zugriffslayer selbst geschrieben weil ich 
die CMSIS hässlich fand... Aber okay sie funktioniert.

Spricht er von sich selbst in der dritten Person? :-D

> Nunja. Das hat ihm jetzt doch keine Ruhe gelassen. Mittlerweile ist es
> halb vier - und es funktioniert. Offensichtlich ist ihm durch das hin-
> und herkopieren und dem allgemeinen Rumfuscheln die ein oder andere
> Zeile kaputtgegangen. Mit nem neuen Projekt und ein paar Anpassungen
> geht's nun.
Oha... Mit "cpsie i"?

von Joachim (Gast)


Lesenswert?

Dr. Sommer schrieb:
>Achja, er verwendet ja die CMSIS.

Joachim schrieb:
>Spricht er von sich selbst in der dritten Person? :-D
Du hast mit der dritten schließlich angefangen ;-)



>Oha... Mit "cpsie i"?

Hm. Hab eben nochmals im Assembler-Listing geschaut. Weder der Befehl 
"cpsid" noch "cpsie" wird mit Strg + F gefunden. Stattddessen wird zB. 
das hier erzeugt:
1
C-Code
2
3
/* Enable CAN1 mailbox 0 interrupt. */
4
can_enable_interrupt(CAN1, CAN_IER_MB0);
5
   816de:  4628        mov  r0, r5
6
   816e0:  4649        mov  r1, r9
7
   816e2:  f240 33d1   movw  r3, #977  ; 0x3d1
8
   816e6:  f2c0 0308   movt  r3, #8
9
   816ea:  4798        blx  r3
Scheinbar führen auch hier verschiedene Wege nach Rom.

von (prx) A. K. (prx)


Lesenswert?

Joachim schrieb:
> Scheinbar führen auch hier verschiedene Wege nach Rom.

Die in diesem Code aufgerufene Funktion wird wohl den Interrupt vom CAN1 
einschalten (NVIC), wird aber wahrscheinlich nicht den Interrupt des 
Cores einschalten (CPSIE).

von (prx) A. K. (prx)


Lesenswert?

Joachim ... schrieb:
> zumindest wird "cpsie" im assemblierten Code nicht gefunden...

Von allein landet das evtl. auch nicht darin. Oft ist es so, dass man im 
Rahmen der eigenen Initialisierung irgendwann den Prozessor-Interrupt 
explizit freigibt. Geschieht das nicht, dann gibts auch keinen 
Interrupt.

von Joachim (Gast)


Lesenswert?

Einen hübschen NVIC hab ich noch, der hier schaltet das Modul für den 
Empfang ein. Ist aber auch ohne "cpsie" erzeugt.
1
C-Code
2
3
    /* Configure and enable interrupt of CAN1, as the tests will use receiver interrupt. */
4
    NVIC_EnableIRQ(CAN1_IRQn);
5
6
ergibt:
7
8
  \param [in]      IRQn  External interrupt number. Value cannot be negative.
9
 */
10
__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn)
11
{
12
  NVIC->ISER[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* enable interrupt */
13
   815ec:  f44f 4361   mov.w  r3, #57600  ; 0xe100
14
   815f0:  f2ce 0300   movt  r3, #57344  ; 0xe000
15
   815f4:  f44f 5280   mov.w  r2, #4096  ; 0x1000
16
   815f8:  605a        str  r2, [r3, #4]

Der Code besteht scheinbar zu 99% aus load, move und store. Vielleicht 
ist das ne Schwäche vom Compiler...

von Dr. Sommer (Gast)


Lesenswert?

Joachim schrieb:
> Du hast mit der dritten schließlich angefangen ;-)
Naja die Antwort war ja an Lothar gerichtet ;-)

Joachim schrieb:
> Scheinbar führen auch hier verschiedene Wege nach Rom.
Das kann eigentlich nicht. Vielleicht sind die Interrupts doch 
standardmäßig eingeschaltet. NVIC_EnableIRQ schaltet nur einen 
bestimmten Interrupt ein, und um die allgemeine Behandlung von 
Interrupts überhaupt einzuschalten braucht man zusätzlich ein 
__enable_interrupt(); was ich auf jeden Fall einbauen würde.

Joachim schrieb:
> Der Code besteht scheinbar zu 99% aus load, move und store. Vielleicht
> ist das ne Schwäche vom Compiler...
Naja bei der Initialisierung der Hardware-Module macht man ja auch 
nichts anderes als vordefinierte Werte in die entsprechenden Register zu 
schreiben, daher sieht der Code nunmal so aus. Wenn du mit -Os 
kompilierst wird dieser Code kürzer (aber langsamer) und besteht nur 
noch aus "ldr" und "str".

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.