Guten Morgen,
je nach Zielplattform benötigt meine main()-Funktion eine
unterschiedliche Signatur. Bei einem Target kehrt sie zurueck, bei einem
anderen nie. Bislang habe ich das so gelöst:
1 | #if DOXYGEN
|
2 | /* Fuer Doxygen darf der Funktionsname nicht als Makro definiert sein */
|
3 |
|
4 | #elif defined( STM32F10x ) || defined( STM32F4XX )
|
5 | /* Zielplattform (Debug, Release, Modultests) */
|
6 | #define MAINFUN() main(void)
|
7 |
|
8 | #elif defined( MOCKUP_SDL )
|
9 | /* Mockup */
|
10 | #define MAINFUN() SDL_main(int argc, char *argv[])
|
11 |
|
12 | #elif PC_UNITTEST
|
13 | /* Fuer Modultests auf dem PC existiert eine andere main() in UnityTestRunner.c */
|
14 | #define MAINFUN() neverstart(void)
|
15 |
|
16 | #else
|
17 | #error "unknown platform"
|
18 |
|
19 | #endif
|
20 |
|
21 | /** Main-Funktion fuer Zielplattform und PC-Mockup
|
22 | *
|
23 | * Die Main-Funktion benoetigt je nach Ziemplattform eine unterschiedliche Signatur. Sie
|
24 | * kehrt bei manchen Plattformen zurueck, bei manchen nie. */
|
25 | int MAINFUN()
|
26 | {
|
27 | #if defined( STM32F4XX ) || defined( STM32F10x )
|
28 |
|
29 | /* Timer und Interrupt-Prioritaeten einstellen */
|
30 | /* SysTick-IRQ deaktivieren.
|
31 | /* NVIC/ISRs konfigurieren */
|
32 | /* Zyklenzaehler fuer Profiling aktivieren */
|
33 | hierStehtQuelltext();
|
34 |
|
35 | #elif MOCKUP_SDL
|
36 |
|
37 | (void) argc;
|
38 | (void) argv;
|
39 | mocksdl_timer_init();
|
40 |
|
41 | #elif PC_UNITTEST
|
42 |
|
43 | #else
|
44 | #error "Undefined Target"
|
45 |
|
46 | #endif
|
47 |
|
48 | /* Plattform-unabhaengige Initialsierungen */
|
49 | ...
|
50 |
|
51 | /* Hauptschleife */
|
52 | while( 1 )
|
53 | {
|
54 | /* Was eine Hauptschleife eben so macht */
|
55 | ...
|
56 |
|
57 | /* Auf dem PC wird die Hauptschleife auch beendet */
|
58 | #ifdef MOCKUP_SDL
|
59 | /* Emulation beenden */
|
60 | if( ui_getAction() )
|
61 | {
|
62 | break;
|
63 | }
|
64 | #endif
|
65 | }
|
66 |
|
67 |
|
68 | #ifdef MOCKUP_SDL
|
69 | mocksdl_timer_deinit();
|
70 | return 0;
|
71 | #endif
|
72 | }
|
Diese Lösung hat mir noch nie gefallen, ist aber so gewachsen. Die
praktischen Nachteile liegen vor allem darin, dass externe Werkzeuge,
die auf dem Quelltext arbeiten (Doxygen und der CDT Standalone Debugger)
die main()-Funktionen nicht erkennen können.
Jetzt will ich es richtig machen.
Aber wie macht man es sinnvoller?
1 | static inline __attribute__((always_inline)) void realMain(void);
|
2 |
|
3 |
|
4 | #if defined( STM32F10x ) || defined( STM32F4XX )
|
5 | /* Zielplattform (Debug, Release, Modultests) */
|
6 | __attribute__((noreturn)) main(void)
|
7 | {
|
8 | realMain();
|
9 | }
|
10 |
|
11 | #elif defined( MOCKUP_SDL )
|
12 | /* Mockup */
|
13 | int SDL_main(int argc, char *argv[])
|
14 | {
|
15 | (void) argc;
|
16 | (void) argv;
|
17 | mocksdl_timer_init();
|
18 | realMain();
|
19 | mocksdl_timer_deinit();
|
20 | return 0;
|
21 | }
|
22 |
|
23 | ... usw.
|
24 |
|
25 | #endif
|
Eine Deklaration "static inline __attribute__((always_inline))" ist ja
auch nicht unbedingt dazu geeignet, Debugging zu erleichern.
Wie geht es besser?