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.
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.
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 | }
|
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.
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.
Hättest du in dem Zusammenhang nach "name mangling" gesucht, du wärst fündig geworden. ;-)
>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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.