Ein klein wenig konnte ich nun doch noch die Stelle eingrenzen, an der
sich der Code aufhängt, wenn ich die Optimierung auf -O0 stelle.
Im nun zusammengewürfelten Projekt aus FreeRTOS+USB ist somit auch das
Symbol "FREERTOS_USED" definiert. Unter anderem wird es bei der IRQ
verwendet:
file: usbb_device.c
1 | /**
|
2 | * \brief Function called by USBB interrupt to manage USB device interrupts
|
3 | *
|
4 | * USB Device interrupt events are split in three parts:
|
5 | * - USB line events (SOF, reset, suspend, resume, wakeup)
|
6 | * - control endpoint events (setup reception, end of data transfer, underflow, overflow, stall)
|
7 | * - bulk/interrupt/isochronous endpoints events (end of data transfer)
|
8 | *
|
9 | * Note:
|
10 | * Here, the global interrupt mask is not clear when an USB interrupt is enabled
|
11 | * because this one can not be occurred during the USB ISR (=during INTX is masked).
|
12 | * See Technical reference $3.8.3 Masking interrupt requests in peripheral modules.
|
13 | */
|
14 | #ifdef UHD_ENABLE
|
15 | void udd_interrupt(void); // To avoid GCC warning
|
16 | void udd_interrupt(void)
|
17 | #else
|
18 | # ifdef FREERTOS_USED
|
19 | # include "FreeRTOS.h"
|
20 | # include "task.h"
|
21 | ISR_FREERTOS(udd_interrupt, AVR32_USBB_IRQ_GROUP, UDD_USB_INT_LEVEL) // <-- geht nicht!!!
|
22 | # else
|
23 | ISR(udd_interrupt, AVR32_USBB_IRQ_GROUP, UDD_USB_INT_LEVEL) // <-- geht !!!
|
24 | # endif
|
25 | #endif
|
26 | {
|
27 | if (Is_udd_sof()) {
|
28 | udd_ack_sof();
|
29 | if (Is_udd_full_speed_mode()) {
|
30 | udc_sof_notify();
|
31 | }
|
32 | ...
|
Wenn ich nun die somit verwendete Zeile
1 | ISR_FREERTOS(udd_interrupt, AVR32_USBB_IRQ_GROUP, UDD_USB_INT_LEVEL)
|
durch die "normale" ISR() austausche läuft wieder alles wie geschmiert.
Die Definition für ISR_FREERTOS() liegt in der Datei portmacro.h
Diese sieht allerdings hochgradig kompliziert aus :)
1 | #define ISR_FREERTOS(func, int_grp, int_lvl) \
|
2 | __attribute__((__noinline__)) static portBASE_TYPE func##_not_naked(void); \
|
3 | __attribute__((__naked__)) static void func(void) \
|
4 | { \
|
5 | portENTER_SWITCHING_ISR(); \
|
6 | func##_not_naked(); \
|
7 | /* portEXIT_SWITCHING_ISR() expects an input parameter in R12. */ \
|
8 | /* This parameter is the return value of func##_not_naked() */ \
|
9 | portEXIT_SWITCHING_ISR(); \
|
10 | } \
|
11 | __attribute__((__noinline__)) static portBASE_TYPE func##_not_naked(void)
|
Das in der ISR_FREERTOS() nun zur eigentlichen ISR noch ein Teil davor
und danach ausgeführt wird, habe ich soweit verstanden. Jedoch kann ich
das ja nicht einfach so weg lassen, sonst läuft es später an anderer
Stelle schief.