Forum: Mikrocontroller und Digitale Elektronik Xpresso und Rowley - user definierte ISR werden nicht gelinked?


von Johannes V. (johannes_v)


Lesenswert?

Guten Tag,

vorab, Ich habe den ganzen Tag gegoogeld und selbst rumprobiert, aber 
nichts zweckmäßiges gefunden. Weder bei Rowley direkt noch sonst wo im 
Netz.

Aber erstmal zu meinem Problem.

Ich habe mit einem LCP 1769 Xpresso angefangen, alles schon und gut 
funktioniert in der Red-Suite.
Aber da ich in C++ programmieren will und noch 2 weitere Controller hier 
liegen habe kann ich nun einen j-link edu mein eigen nennen.

Im Moment nutze ich die Rowley Crossworks Trial version, aber ich kann 
keine Intterrupts nutzen. Das Problem ist, die Vector Tabelle wird von 
Rowleys startup file (assembler) richtig angelegt.
Allerdings wenn ein Intterupt eintritt springt der Controller nicht zu 
meinen gleichnamigen Handlern (in C geschrieben und auch im speicher 
vorhanden laut .map) sondern die Intterrupts der Tabelle springen sich 
nur selbst an, also eine Dauerschleife.

Warum werden nicht die richtigen Sprungadressen anstelle der Labels der 
startup.s eingetragen?

Lösungen die ich fand war eine startup.c zu erstellen und das 
Linkerscript dementsprechen anzupassen, aber ich fand nie etwas explizit 
in einem Rowley context weshalb ich davon ausgehe, dass es doch 
irgendwie funktionieren muss.
Momentan ist meine Vermutung, dass der Linker keinen Zusammenhang 
zwischen den Labels und den Funktionen sieht, trotz gleichem Namen. In 
den startup.c files werden diese immer "forward" deklariert bevor die 
Tabelle angelegt wird. Aber wie soll ich das in Assembler umsetzen? Muss 
ich überhaupt?

Bin für jeden Tip dankbar und hoffe das waren genug Informationen um das 
Problem zu identifizieren. Das ganze läuft über Rowley cpu support 
package und die darin enthaltene CMSIS natürlich

Danke.

von Johannes V. (johannes_v)


Lesenswert?

Weiss den wirklich niemand warum bei mir in der Vector table die 
Standard_ISR_Handler (__weak) nicht durch pointer auf meine funktionen 
ersetzt werden?

Es kann doch nciht sein das ich der erste bin der in der Crossworks 
Umgebung Interrupts nutzen will.

Rowleys sagt nur die Intterrupt Routienen müssen in assembler 
geschrieben werden, aber reden im nächsten Satz auch weiter über 
Vorgehensweisen die sich nur auf ARM7 beziehen.

Das ist ja gerade einer der Vorteile des Cortex, das ich mich nicht mit 
asm rumschlagen muss.

von Johannes V. (johannes_v)


Lesenswert?

1
/* Startup.s  */
2
3
.global reset_handler
4
5
  .syntax unified
6
7
  .section .vectors, "ax"
8
  .code 16
9
  .align 0
10
  .global _vectors
11
12
.macro DEFAULT_ISR_HANDLER name=
13
  .thumb_func
14
  .weak \name
15
\name:
16
1: b 1b /* endless loop */
17
.endm
18
19
_vectors:
20
  .word __stack_end__
21
#ifdef STARTUP_FROM_RESET
22
  .word reset_handler
23
#else
24
  .word reset_wait
25
#endif /* STARTUP_FROM_RESET */
26
  .word NMI_Handler
27
  .word HardFault_Handler
28
  .word MemManage_Handler
29
  .word BusFault_Handler
30
  .word UsageFault_Handler
31
  .word 0 // Reserved
32
  .word 0 // Reserved
33
  .word 0 // Reserved
34
  .word 0 // Reserved
35
  .word SVC_Handler
36
  .word DebugMon_Handler
37
  .word 0 // Reserved
38
  .word PendSV_Handler
39
  .word SysTick_Handler
40
  .word WDT_IRQHandler
41
  .word TIMER0_IRQHandler
42
  .word TIMER1_IRQHandler
43
  .word TIMER2_IRQHandler
44
  .word TIMER3_IRQHandler
45
  .word UART0_IRQHandler
46
  .word UART1_IRQHandler
47
  .word UART2_IRQHandler
48
  .word UART3_IRQHandler
49
  .word PWM1_IRQHandler
50
  .word I2C0_IRQHandler
51
  .word I2C1_IRQHandler
52
  .word I2C2_IRQHandler
53
  .word SPI_IRQHandler
54
  .word SSP0_IRQHandler
55
  .word SSP1_IRQHandler
56
  .word PLL0_IRQHandler
57
  .word RTC_IRQHandler
58
  .word EINT0_IRQHandler
59
  .word EINT1_IRQHandler
60
  .word EINT2_IRQHandler
61
  .word EINT3_IRQHandler
62
  .word ADC_IRQHandler
63
  .word BOD_IRQHandler
64
  .word USB_IRQHandler
65
  .word CAN_IRQHandler
66
  .word GPDMA_IRQHandler
67
  .word I2S_IRQHandler
68
  .word ENET_IRQHandler
69
  .word RIT_IRQHandler
70
  .word MCPWM_IRQHandler
71
  .word QEI_IRQHandler
72
  .word PLL1_IRQHandler
73
  .word USBACT_IRQHandler
74
  .word CANACT_IRQHandler
75
76
  .section .init, "ax"
77
  .thumb_func
78
79
reset_handler:
80
#ifndef NO_SYSTEM_INIT
81
  ldr sp, =__RAM_segment_end__
82
  ldr r0, =SystemInit
83
  blx r0
84
#endif
85
86
  /* Configure vector table offset register */
87
  ldr r0, =0xE000ED08
88
  ldr r1, =_vectors
89
  str r1, [r0]
90
91
  b _start
92
93
DEFAULT_ISR_HANDLER NMI_Handler
94
DEFAULT_ISR_HANDLER HardFault_Handler
95
DEFAULT_ISR_HANDLER MemManage_Handler
96
DEFAULT_ISR_HANDLER BusFault_Handler
97
DEFAULT_ISR_HANDLER UsageFault_Handler
98
DEFAULT_ISR_HANDLER SVC_Handler
99
DEFAULT_ISR_HANDLER DebugMon_Handler
100
DEFAULT_ISR_HANDLER PendSV_Handler
101
DEFAULT_ISR_HANDLER SysTick_Handler
102
DEFAULT_ISR_HANDLER WDT_IRQHandler
103
DEFAULT_ISR_HANDLER TIMER0_IRQHandler
104
DEFAULT_ISR_HANDLER TIMER1_IRQHandler
105
DEFAULT_ISR_HANDLER TIMER2_IRQHandler
106
DEFAULT_ISR_HANDLER TIMER3_IRQHandler
107
DEFAULT_ISR_HANDLER UART0_IRQHandler
108
DEFAULT_ISR_HANDLER UART1_IRQHandler
109
DEFAULT_ISR_HANDLER UART2_IRQHandler
110
DEFAULT_ISR_HANDLER UART3_IRQHandler
111
DEFAULT_ISR_HANDLER PWM1_IRQHandler
112
DEFAULT_ISR_HANDLER I2C0_IRQHandler
113
DEFAULT_ISR_HANDLER I2C1_IRQHandler
114
DEFAULT_ISR_HANDLER I2C2_IRQHandler
115
DEFAULT_ISR_HANDLER SPI_IRQHandler
116
DEFAULT_ISR_HANDLER SSP0_IRQHandler
117
DEFAULT_ISR_HANDLER SSP1_IRQHandler
118
DEFAULT_ISR_HANDLER PLL0_IRQHandler
119
DEFAULT_ISR_HANDLER RTC_IRQHandler
120
DEFAULT_ISR_HANDLER EINT0_IRQHandler
121
DEFAULT_ISR_HANDLER EINT1_IRQHandler
122
DEFAULT_ISR_HANDLER EINT2_IRQHandler
123
DEFAULT_ISR_HANDLER EINT3_IRQHandler
124
DEFAULT_ISR_HANDLER ADC_IRQHandler
125
DEFAULT_ISR_HANDLER BOD_IRQHandler
126
DEFAULT_ISR_HANDLER USB_IRQHandler
127
DEFAULT_ISR_HANDLER CAN_IRQHandler
128
DEFAULT_ISR_HANDLER GPDMA_IRQHandler
129
DEFAULT_ISR_HANDLER I2S_IRQHandler
130
DEFAULT_ISR_HANDLER ENET_IRQHandler
131
DEFAULT_ISR_HANDLER RIT_IRQHandler
132
DEFAULT_ISR_HANDLER MCPWM_IRQHandler
133
DEFAULT_ISR_HANDLER QEI_IRQHandler
134
DEFAULT_ISR_HANDLER PLL1_IRQHandler
135
DEFAULT_ISR_HANDLER USBACT_IRQHandler
136
DEFAULT_ISR_HANDLER CANACT_IRQHandler
137
138
#ifndef STARTUP_FROM_RESET
139
DEFAULT_ISR_HANDLER reset_wait
140
#endif /* STARTUP_FROM_RESET */
141
142
143
144
145
/* ExtInt.h  */
146
147
#pragma once
148
149
class ExtInt{
150
public:
151
  static int init();
152
};
153
154
extern void EINT0_IRQHandler(void);
155
extern void EINT1_IRQHandler(void);
156
extern void EINT2_IRQHandler(void);
157
// EINT3 is also the GPIO IRQ Handler
158
extern void EINT3_IRQHandler(void);
159
160
161
162
/* ExtInt.cpp */
163
164
#include "LPC17xx_Settings.h"    //besteht nur aus defines mit einstellungen für die pheripherie register und PERIxactive und #include ".../LPC17xx.h"
165
#include "LPC17xx_ExtInt.h"
166
167
/* EINT0 Includes */
168
169
170
/* EINT1 Includes */
171
172
173
/* EINT2 Includes */
174
//#include "BMP085.h"
175
176
/* EINT3 Includes */
177
178
#ifdef EINT0active
179
void EINT0_IRQHandler(void)
180
{
181
  LPC_SC->EXTINT |= (1 << 0);    // clear interrupt flag
182
183
}
184
#endif
185
#ifdef EINT1active
186
void EINT1_IRQHandler(void)
187
{
188
  LPC_SC->EXTINT |= (1 << 1);    // clear interrupt flag
189
190
}
191
#endif
192
#ifdef EINT2active
193
void EINT2_IRQHandler(void)
194
{
195
  LPC_SC->EXTINT |= (1 << 2);    // clear interrupt flag
196
  //BMP085::irq();          // end of conversion, update BMP085status
197
}
198
#endif
199
#ifdef EINT3active
200
void EINT3_IRQHandler(void)
201
{
202
  LPC_SC->EXTINT |= (1 << 3);    // clear interrupt flag
203
204
}
205
#endif
206
207
int ExtInt::init()
208
{
209
#ifdef EINT0active
210
  LPC_PINCON->PINSEL4 |= (1 << 20);  // select pin mode P2.10 "ExtIntO"
211
#if (EINT0mode == 1)          // level sensitive
212
  LPC_SC->EXTMODE ^= (1 << 0);    // ExtInt0 is level sensitive
213
#else
214
  LPC_SC->EXTMODE |= (1 << 0);    // ExtInt0 is edge sensitive
215
#endif
216
#if (EINT0logic == 1)          // high / rising sensitive
217
  LPC_SC->EXTPOLAR |= (1 << 0);    // set polarity to rising / high sensitivity
218
#else
219
  LPC_SC->EXTPOLAR ^= (1 << 0);    // set polarity to falling / low sensitivity
220
#endif
221
  NVIC_EnableIRQ(EINT0_IRQn);      // enable interrupt
222
#endif  // EINT0active
223
224
225
#ifdef EINT1active
226
  LPC_PINCON->PINSEL4 |= (1 << 22);  // select pin mode P2.11 "ExtInt1"
227
#if (EINT1mode == 1)
228
  LPC_SC->EXTMODE ^= (1 << 1);    // ExtInt1 is level sensitive
229
#else
230
  LPC_SC->EXTMODE |= (1 << 1);    // ExtInt1 is edge sensitive
231
#endif
232
#if (EINT1logic == 1)
233
  LPC_SC->EXTPOLAR |= (1 << 1);    // set polarity to rising / high sensitivity
234
#else
235
  LPC_SC->EXTPOLAR ^= (1 << 1);    // set polarity to falling / low sensitivity
236
#endif
237
  NVIC_EnableIRQ(EINT1_IRQn);      // enable interrupt
238
#endif  // EINT1active
239
240
241
#ifdef EINT2active
242
  LPC_PINCON->PINSEL4 |= (1 << 24);  // select pin mode P2.12 "ExtInt2"
243
#if (EINT2mode == 1)
244
  LPC_SC->EXTMODE ^= (1 << 2);    // ExtInt2 is level sensitive
245
#else
246
  LPC_SC->EXTMODE |= (1 << 2);    // ExtInt2 is edge sensitive
247
#endif
248
#if (EINT2logic == 1)
249
  LPC_SC->EXTPOLAR |= (1 << 2);    // set polarity to rising / high sensitivity
250
#else
251
  LPC_SC->EXTPOLAR ^= (1 << 2);    // set polarity to falling / low sensitivity
252
#endif
253
  NVIC_EnableIRQ(EINT2_IRQn);      // enable interrupt
254
#endif  // EINT2active
255
256
257
#ifdef EINT3active
258
  LPC_PINCON->PINSEL4 |= (1 << 26);  // select pin mode P2.13 "ExtInt3"
259
#if (EINT3mode == 1)
260
  LPC_SC->EXTMODE ^= (1 << 3);    // ExtInt3 is level sensitive
261
#else
262
  LPC_SC->EXTMODE |= (1 << 3);    // ExtInt3 is edge sensitive
263
#endif
264
#if (EINT3logic == 1)
265
  LPC_SC->EXTPOLAR |= (1 << 3);    // set polarity to rising / high sensitivity
266
#else
267
  LPC_SC->EXTPOLAR ^= (1 << 3);    // set polarity to falling / low sensitivity
268
#endif
269
  NVIC_EnableIRQ(EINT3_IRQn);      // enable interrupt
270
#endif  // EINT3active
271
  return(1);
272
}

von Johannes V. (johannes_v)


Lesenswert?

Ich habe das Problem gefunden.

Anscheinend gefällt es dem Programm nicht wenn ich meine Interrupts in 
einer .cpp definiere.

Wenn ich sie in einer .c definiere ercheinen sie in der .map auch genau 
wie die Labels, ohne () am Ende des Funktion Namens.

Mal sehen wie ich das jetzt schön verpacke, auf C++ werde ich aber 
definitv nicht verzichten. Vielleicht schaffe ich das ganze ja sogar mit 
einem Macro direkt auf meine C++ IRQs zu lenken.

von Johannes V. (johannes_v)


Lesenswert?

1
extern "C" {
2
extern void EINT0_IRQHandler(void);
3
extern void EINT1_IRQHandler(void);
4
extern void EINT2_IRQHandler(void);
5
// EINT3 is also the GPIO IRQ Handler
6
extern void EINT3_IRQHandler(void);
7
}

Wieder was gelernt.. Hoffentlich nützt dieser Thread mal jemand der das 
gleiche Problem hat, google hat leider nichts vernünftiges ausgespuckt.

von (prx) A. K. (prx)


Lesenswert?

Hättest du in dem Zusammenhang nach "name mangling" gesucht, du wärst 
fündig geworden. ;-)

von Herbert (Gast)


Lesenswert?

>Hättest du in dem Zusammenhang nach "name mangling" gesucht, du wärst
>fündig geworden. ;-)

Hätte, wenn und aber
alles nur Gelaber ;-)

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.