Forum: Compiler & IDEs AVR GCC Debug Möglichkeiten , nicht nachvollziehbarer Fehler


von D. C. (joker89)


Lesenswert?

Hallo,
ich arbeite an einem Program für einen Atmega, in dem Program gibt es 
Funktionspointer und nach einem Aufruf und deren Abarbeitung springt 
mein Programzeiger herraus wieder in ein Switch case und danach hängt 
sich der AVR auf . Welche Möglichkeiten habe ich denn jetzt ?
1
  case LONG_CLICK: //
2
                MenuAction(ptrMenu);
3
                USART_putstring("MenuAction \n\r");
4
break;

"USART_putstring("MenuAction \n\r");" wird noch aufgerufen aber danach 
ist Schluss

von holger (Gast)


Lesenswert?

>Welche Möglichkeiten habe ich denn jetzt ?

Einen Controller mit mehr RAM nehmen oder
USART_putstring() so umbauen das es Strings aus dem Flash nimmt.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Stack/Heap kaputt?
Kann passieren, wenn da ein Pointer Amok läuft oder der Stack/Heap über- 
bzw. unterläuft.

D. C. schrieb:
> danach hängt sich der AVR auf
Das stellst du wie genau fest?

Hast du dein Programm mal durch einen Simulator laufen lassen?

von Sollbruch (Gast)


Lesenswert?

Eine Möglichkeit (auch wenn es schwer fällt): Atmel Studio 7 
installieren und den Simulator zum Debuggen verwenden.

von D. C. (joker89)


Lesenswert?

Ich nutze Xcode als editor mit einem einfachen Makefile, dh wird das 
schwierig.

Ob der SRam überläuft glaube ich kaum weil das Program überschaubar ist 
bzw kaum was gespeichert wird

von holger (Gast)


Lesenswert?

>Ob der SRam überläuft glaube ich kaum weil das Program überschaubar ist
>bzw kaum was gespeichert wird

Manchmal hilft Glauben nicht, Wissen ist besser.
Da niemand weiss wie dein Code aussieht ist die Ratestunde
für mich dann mal beendet.

von C. A. Rotwang (Gast)


Lesenswert?

D. C. schrieb:

> mein Programzeiger herraus wieder in ein Switch case und danach hängt
> sich der AVR auf . Welche Möglichkeiten habe ich denn jetzt ?



Schreib einen WDT-ISR der einen Reg-Dump über eine Schnittstelle 
rauspustet.

Schliess die Fehlerquelle Compiler aus, indem du das ganze in Assembler 
schreibst.

von Carl D. (jcw2)


Lesenswert?

C. A. Rotwang schrieb:
> D. C. schrieb:
>
>> mein Programzeiger herraus wieder in ein Switch case und danach hängt
>> sich der AVR auf . Welche Möglichkeiten habe ich denn jetzt ?
>
>
>
> Schreib einen WDT-ISR der einen Reg-Dump über eine Schnittstelle
> rauspustet.
>
> Schliess die Fehlerquelle Compiler aus, indem du das ganze in Assembler
> schreibst.

Wenn er das in Assembler schreiben kann, dann kann er auch den 
Compiler-Output auf Korrektheit prüfen.
Andernfalls würde er dann ein "Compiler-Backend" benutzen, das sich auf 
seiner Jungfernfahrt befindet.

von D. C. (joker89)


Lesenswert?

Carl D. schrieb:

> Wenn er das in Assembler schreiben kann, dann kann er auch den
> Compiler-Output auf Korrektheit prüfen.
> Andernfalls würde er dann ein "Compiler-Backend" benutzen, das sich auf
> seiner Jungfernfahrt befindet.

Ja wenn ich das könnte ich hab hier eine Array of struct s in dem sich 
funktionspointer befinden. In Assembler übersteigt das bei weitem meine 
Fähigkeiten

Ich habe gerade versucht mir den freien Speicher auszugeben nach diesem 
Beispiel -> 
http://rn-wissen.de/wiki/index.php?title=Speicherverbrauch_bestimmen_mit_avr-gcc#Dynamischer_RAM-Verbrauch

Ich gebe das Serial an den PC zurück bekomme aber nur immer eine 0 
zurück.
Muss ich jetzt die init hier noch aufrufen , im .h steht sie ja schon 
mal nicht.

"// !!! Never call this function, it is part of .init-Code" Würde ja 
nein heißen aber geht eben nicht ...


edit :

Das hier funktioniert
1
int freeRam () {
2
    extern int __heap_start, *__brkval;
3
    int v;
4
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
5
}

1356 wird mir zurück gegeben.
Da dich Dynamisch keinen Speicher verwalte sollt das immer identisch 
sein
Gruß

: Bearbeitet durch User
von D. C. (joker89)


Lesenswert?

Ich zerlege das Program gerade um herauszufinden ab wann es nicht mehr 
weiter geht. Ich habe eine Funktion die aufgerufen wird wenn ich eine 
Aktion im Menu abfeuern will
1
void MenuAction(struct MenuEntry *Menu ){
2
    uint8_t activItem   = 0;
3
4
    do{
5
        if (Menu[activItem].flags.ACTIVEITEM) {
6
            Menu[activItem].function(Menu[activItem].subMenu);
7
            drawMenu(ptrMenu);
8
//            uart_puts_p("hier kommt blödsinn raus ");
9
            return;
10
        }
11
        activItem++;
12
    }while (!Menu[activItem - 1 ].flags.MENUEND);
13
}
14
....
15
....
16
....
17
  switch (getClickType())
18
        {
19
            case NO_CLICK: // do nothing
20
                break;
21
                
22
            case LONG_CLICK: //
23
                MenuAction(ptrMenu);
24
....

ist " uart_puts_p("hier kommt blödsinn raus ");" nicht ausgeklammert 
kommt an der Console "¹[05]À‚àŠ•ñ÷" an

Nicht optimiert kommt das hier raus -> "
«¼œ[01]­[01]¼[01]Í[01][0E]”3'Ü[01]Ë[01]‰‡š‡«‡¼‡ 
à0à@è_ãm~˜…[0E]”—'ˆ#[1C]ôà‡²À 
à?ïOçWäi…z…‹…œ…[0E]”á([18][16][0C]ð{À 
à0àJçTäiz‹œ[0E]”›'Ü[01]Ë[01]Ž‡Ÿ‡¨‹¹‹ 
à0àJïTän……ˆ‰™‰[0E]”å(Ü[01]Ë[01]Š‹›‹¬‹½‹ 
à0à@è_ãj‰{‰Œ‰‰[0E]”—'ˆ#,ôààŸ‹Ž‹?À à?ïOçWäj‰{‰Œ‰‰[0E]”á([18][16]Lõ 
à0à@âQän……ˆ‰™‰[0E]”å(Ü[01]Ë[01]¼[01]Í[01][0E]”[03](Ü[01]Ë[01]Ÿ‹Ž‹[0F]Àˆ 
ìà™ˆˆ™[01]—ñ÷™ˆŽ‰Ÿ‰[01]—Ÿ‹Ž‹Ž‰Ÿ‰  "

Gruß

: Bearbeitet durch User
von Nop (Gast)


Lesenswert?

Der Code ist ein klassisches Beispiel für den legendären Spruch von 
Kerninghan:

"Debuggen ist doppelt so hart wie überhaupt das Programm zu schreiben. 
Wenn Du also so clever programmierst, wie Du kannst, wie willst Du das 
jemals debuggen?"

Will sagen, das sieht nach einem Fehler mit den Pointern in den Arrays 
usw. aus, eventuell auch Stack Overflow.

Abhilfe: KISS.

von Olaf (Gast)


Lesenswert?

> Ich zerlege das Program gerade um herauszufinden ab wann es nicht mehr
> weiter geht.

Ach du scheisse. Genau JETZT ist der Zeitpunkt in deinem Leben gekommen 
wo du lernen willst was ein Debugger ist. Und dann geht du einmal im 
Singlestep dadurch und behaelst deinen Stack im Auge.
Sehr wahrscheinlich wird Holger recht haben, aber es ist fuer dich 
besser wenn du es selber rausfindest.

Olaf

von D. Chung (Gast)


Lesenswert?

Auf welche ide sollte ich dann zurückgreifen?

von D. C. (joker89)


Lesenswert?

ich gehe dann wieder einen Schritt für mich zurück ich hatte mir extra 
ein Template für Xcode gebastelt damit ich Atmel Studio nicht mehr 
benutzten muss. Ich brauche aber wohl dann auch einen Debugger für die 
8bit AVR s , der von Atmel kostet ja doch ein wenig. Gibts hier ne 
alternative ?

von Kaj (Gast)


Lesenswert?

D. C. schrieb:
> Gibts hier ne
> alternative ?
Simulator

von D. C. (joker89)


Lesenswert?

Der Weg führt wieder nach Atmel studio ?

von C. A. Rotwang (Gast)


Lesenswert?

Carl D. schrieb:

> Wenn er das in Assembler schreiben kann, dann kann er auch den
> Compiler-Output auf Korrektheit prüfen.

Dann generier mal ein Dissasembler listing, und poste das als Anhang, 
vielleicht findet sich ja in der Mitleserschaft genügend 
Assemblerverstand.

für atmega solle:
 avr-objdump -m avr4 -D                  rebuilt.hex > rebuilt.dis.S
ein dissassemblerlisting aus dem hexfile erzeugen.

Oder du stoppst den gcc nach der assemblererzeugung bspw:
 avr-gcc -mmcu=atmega8 -Os  -S  -o rebuilt.S  ..\src\rebuilt.c

von D. C. (joker89)


Lesenswert?

Es kommt dann nur die Meldung "avr-objdump: can't use supplied machine 
-avr4"

von Dieter F. (Gast)


Lesenswert?

D. C. schrieb:
> Der Weg führt wieder nach Atmel studio ?

Nein - feel free! Der Schei... Compiler muss sich gefälligst nach Dir 
und dem uns unbekannten Code richten! Mach ihm das deutlich (!) klar und 
alles wird gut :-)

von D. C. (joker89)


Lesenswert?

Ich versteh gerade nur noch Bahnhof....

von Dieter F. (Gast)


Lesenswert?

D. C. schrieb:
> Ich versteh gerade nur noch Bahnhof....

Willkommen im Club!

Wer soll Dir denn helfen, wenn Du Deinen Code nicht (vollständig) 
veröffentlichst?

Und wie viele ATMegas gibt es wohl?

Die meisten hier haben ihre Glaskugel in Reparatur oder zur Reinigung 
gegeben :-) ...

von D. C. (joker89)


Lesenswert?

1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <avr/io.h>
4
#include <avr/interrupt.h>
5
#include <util/delay.h>
6
#include <avr/pgmspace.h>
7
8
#include "define.h"
9
#include "RX5808.h"
10
#include "max7456.h"
11
#include "uart.h"
12
13
//******************************************************************************
14
//*                             declar
15
//******************************************************************************
16
17
RX5808 rx;
18
Max7456 osd;
19
uint8_t currentChannel = 0;
20
char buffer[5];                                 //Output of the itoa function
21
22
//forward declaration
23
uint8_t getClickType();
24
25
//******************************************************************************
26
//*                          AVR IO Funktion
27
//******************************************************************************
28
int freeRam () {
29
    extern int __heap_start, *__brkval;
30
    int v;
31
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
32
}
33
uint16_t read_adc(uint8_t channel){
34
    ADMUX &= 0xF0;                   //Clear the older channel that was read
35
    ADMUX |= channel;                //Defines the new ADC channel to be read
36
    ADCSRA |= (1<<ADSC);             //Starts a new conversion
37
    while(ADCSRA & (1<<ADSC));       //Wait until the conversion is done
38
    return ADCW;                     //Returns the ADC value of the chosen channel
39
}
40
41
void printFreeMEM(){
42
    uart_puts_P("free: ");
43
    itoa(freeRam(), buffer, 10);      //Convert the read value to an ascii string
44
//    itoa(static_cast<uint8_t>(get_mem_unused()), buffer, 10);      //Convert the read value to an ascii string
45
    uart_puts(buffer);
46
    uart_puts_P("\n");
47
}
48
49
//******************************************************************************
50
//*                              init
51
//******************************************************************************
52
53
void init(){
54
//---------------------------------
55
// initialize LED pin as output
56
//---------------------------------
57
    DDRB |= (1<<LED_PIN);
58
    _delay_ms(20);
59
    
60
//---------------------------------
61
// initialize button pin as input
62
//---------------------------------
63
    DDRD &= ~(1 << BUTTON_PIN);
64
    PORTD |= (1<<LED_PIN);  //set internall pullup
65
    
66
//---------------------------------
67
// initialize analog input
68
//---------------------------------
69
    ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));       //16Mhz/128 = 125Khz the ADC reference clock
70
    ADMUX |= (1<<REFS0);                                //Voltage reference from Avcc (5v)
71
    ADCSRA |= (1<<ADEN);                                //Turn on ADC
72
    ADCSRA |= (1<<ADSC);                                //Do an initial conversion because this one is the slowest and to ensure that everything is up and running
73
    
74
//---------------------------------
75
// initialize timer 0
76
//---------------------------------
77
    //(8000000/8)/256 Hz = 390.000 Hz -> 2,56 ms
78
    //TCCR0 = (1<<CS01); // Prescaler 8
79
    //TIMSK |= (1<<TOIE0); // Overflow Interrupt
80
    sei(); // interrupt allow
81
82
//---------------------------------
83
// initialize uart
84
//---------------------------------
85
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
86
    sei();
87
//---------------------------------
88
// OSD initialize Settings
89
//---------------------------------
90
    osd.setDisplayOffsets(45,25);   //x , y
91
    osd.setBlinkParams( _8fields , _3BT_BT );
92
    osd.activateExternalVideo();
93
94
}
95
//******************************************************************************
96
//                             RX5808
97
//******************************************************************************
98
99
//******************************************************************************
100
//* Positions in the frequency table for the 40 channels
101
//* Direct access via array operations does not work since data is stored in
102
//* flash, not in RAM. Use getPosition to retrieve data
103
104
const uint8_t positions[] PROGMEM = {
105
    19, 18, 32, 17, 33, 16,  7, 34,  8, 24,  6,  9, 25,  5, 35, 10, 26,  4, 11, 27,
106
    3, 36, 12, 28,  2, 13, 29, 37,  1, 14, 30,  0, 15, 31, 38, 20, 21, 39, 22, 23
107
};
108
109
uint16_t getPosition( uint8_t channel ) {
110
    return pgm_read_byte_near(positions + channel);
111
}
112
113
//******************************************************************************
114
//* Frequencies for the 40 channels
115
//* Direct access via array operations does not work since data is stored in
116
//* flash, not in RAM. Use getFrequency to retrieve data
117
118
const uint16_t channelFrequencies[] PROGMEM = {
119
    5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725, // Band A - Boscam A
120
    5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866, // Band B - Boscam B
121
    5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945, // Band E - DJI
122
    5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880, // Band F - FatShark \ Immersion
123
    5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917  // Band C - Raceband
124
};
125
126
uint16_t getFrequency( uint8_t channel ) {
127
    return pgm_read_word_near(channelFrequencies + getPosition(channel));
128
}
129
130
//******************************************************************************
131
//* function: nextChannel
132
//******************************************************************************
133
uint8_t nextChannel(uint8_t channel)
134
{
135
    if (channel > (CHANNEL_MAX - 1))
136
        return CHANNEL_MIN;
137
    else
138
        return channel + 1;
139
    
140
}//******************************************************************************
141
//* function: updateScannerScreen
142
//*         : position = 0 to 99
143
//*         : value = 0 to 53
144
//*         : must be fast since there are frequent updates
145
//******************************************************************************
146
void updateScannerScreen(uint8_t position, uint8_t value ) {
147
148
    osd.print( read_adc(RSSI_PIN), 5, 5, 4, 0);
149
    
150
}
151
152
//******************************************************************************
153
//* function: drawAutoScanScreen
154
//******************************************************************************
155
void drawScanScreen( uint16_t Mhz, uint8_t channel , uint16_t rssi ) {
156
    
157
    osd.print("Auto Scanner", 7, 3);
158
    osd.print("Channel", 2, 6);
159
    osd.print(" MHz", 12, 6);
160
    osd.print("RSSI ", 20, 6);
161
    osd.print( channel, 2, 8, 2, 0);
162
    osd.print( Mhz, 12, 8, 4, 0);
163
    osd.print( rssi, 20, 8, 4, 0);
164
165
}
166
//******************************************************************************
167
//* function: drawScannerScreen
168
//******************************************************************************
169
170
void drawScannerScreen( void ) {
171
    
172
    osd.printMax7456Chars( bar, 25, 2, 12);
173
    osd.print("5.65       5.8       5.95", 2, 13);
174
    updateScannerScreen(0, 0);
175
}
176
177
//******************************************************************************
178
//* function: autoScan
179
//******************************************************************************
180
uint16_t autoScan( uint16_t frequency ) {
181
    
182
    uint8_t i;
183
    uint16_t scanRssi = 0;
184
    uint16_t bestRssi = 0;
185
    uint16_t scanFrequency;
186
    uint16_t bestFrequency;
187
    
188
    drawScanScreen(0,0,0);
189
    
190
    // Skip 10 MHz forward to avoid detecting the current channel
191
    scanFrequency = frequency + 10;
192
    if (!(scanFrequency % 2))
193
        scanFrequency++;        // RTC6715 can only generate odd frequencies
194
    
195
    // Coarse tuning
196
    bestFrequency = scanFrequency;
197
    for (i = 0; i < 60 && (scanRssi < RSSI_TRESHOLD); i++) {
198
        if ( scanFrequency <= (FREQUENCY_MAX - 5))
199
            scanFrequency += 5;
200
        else
201
            scanFrequency = FREQUENCY_MIN;
202
        rx.setFrequency(scanFrequency);
203
    _delay_ms( RSSI_STABILITY_DELAY_MS );
204
        scanRssi = read_adc(RSSI_PIN);
205
        if (bestRssi < scanRssi) {
206
            bestRssi = scanRssi;
207
            bestFrequency = scanFrequency;
208
        }
209
#ifdef debugSerialScanner
210
        char buffer[5];                                 //Output of the itoa function
211
        USART_putstring("F: ");
212
        itoa(bestFrequency, buffer, 10);      //Convert the read value to an ascii string
213
        USART_putstring(buffer);
214
        USART_putstring("RSSI: ");
215
        itoa(bestRssi, buffer, 10);                     //Convert the read value to an ascii string
216
        USART_putstring(buffer);                        //Send the converted value to the terminal
217
        USART_putstring("\r\n");
218
219
#endif
220
    }
221
    // Fine tuning
222
    scanFrequency = bestFrequency - 20;
223
    bestRssi = 0;
224
    for (i = 0; i < 20; i++, scanFrequency += 2) {
225
        rx.setFrequency(scanFrequency);
226
        _delay_ms( RSSI_STABILITY_DELAY_MS );
227
        scanRssi = read_adc(RSSI_PIN);
228
        if (bestRssi < scanRssi) {
229
            bestRssi = scanRssi;
230
            bestFrequency = scanFrequency;
231
        }
232
#ifdef debugSerialScanner
233
        USART_putstring("F: ");
234
        itoa(bestFrequency, buffer, 10);      //Convert the read value to an ascii string
235
        USART_putstring(buffer);
236
        USART_putstring("RSSI: ");
237
        itoa(bestRssi, buffer, 10);                     //Convert the read value to an ascii string
238
        USART_putstring(buffer);                        //Send the converted value to the terminal
239
        USART_putstring("\r\n");
240
#endif
241
    }
242
243
    drawScanScreen(bestFrequency,0, bestRssi);
244
    
245
    while (!getClickType()){
246
#ifdef debugSerialScanner
247
        USART_putstring("wait");
248
#endif
249
    }
250
    // Return the best frequency
251
    rx.setFrequency(bestFrequency);
252
    return (bestFrequency);
253
254
}
255
256
//******************************************************************************
257
//* function: graphicScanner
258
//*         : scans the 5.8 GHz band in 3 MHz increments and draws a graphical
259
//*         : representation. when the button is pressed the currently
260
//*         : scanned frequency is returned.
261
//******************************************************************************
262
uint16_t graphicScanner( uint16_t frequency ) {
263
    uint8_t i;
264
    uint16_t scanRssi;
265
    uint16_t bestRssi = 0;
266
    uint16_t scanFrequency = frequency;
267
    uint16_t bestFrequency = frequency;
268
    uint8_t rssiDisplayValue;
269
    
270
    // Draw screen frame etc
271
    drawScannerScreen();
272
    
273
    while ( getClickType() == NO_CLICK) {
274
        scanFrequency += 3;
275
        if (scanFrequency > FREQUENCY_MAX)
276
            scanFrequency = FREQUENCY_MIN;
277
        rx.setFrequency(scanFrequency);
278
        _delay_ms( RSSI_STABILITY_DELAY_MS );
279
        scanRssi = read_adc(1);
280
        rssiDisplayValue = (scanRssi - 140) / 10;    // Roughly 2 - 46
281
        updateScannerScreen(100 - ((FREQUENCY_MAX - scanFrequency) / 3), rssiDisplayValue );
282
283
#ifdef debugSerialScanner
284
        USART_putstring(": ");
285
        itoa(bestFrequency, buffer, 10);      //Convert the read value to an ascii string
286
        USART_putstring(buffer);
287
        USART_putstring("RSSI: ");
288
        itoa(bestRssi, buffer, 10);                     //Convert the read value to an ascii string
289
        USART_putstring(buffer);                        //Send the converted value to the terminal
290
        USART_putstring("\r\n");
291
#endif
292
    }
293
    // Fine tuning
294
    scanFrequency = scanFrequency - 20;
295
    for (i = 0; i < 20; i++, scanFrequency += 2) {
296
        rx.setFrequency(scanFrequency);
297
        _delay_ms( RSSI_STABILITY_DELAY_MS );
298
        scanRssi = read_adc(RSSI_PIN);
299
        if (bestRssi < scanRssi) {
300
            bestRssi = scanRssi;
301
            bestFrequency = scanFrequency;
302
        }
303
    }
304
    while (!getClickType())
305
    // Return the best frequency
306
    rx.setFrequency(bestFrequency);
307
    return (bestFrequency);
308
}
309
//******************************************************************************
310
//* function: bestChannelMatch
311
//*         : finds the best matching standard channel for a given frequency
312
//******************************************************************************
313
uint8_t bestChannelMatch( uint16_t frequency )
314
{
315
    int16_t comp;
316
    int16_t bestComp = 300;
317
    uint8_t bestChannel = CHANNEL_MIN;
318
    uint8_t i;
319
    
320
    for (i = CHANNEL_MIN; i <= CHANNEL_MAX; i++) {
321
        comp = abs( (int16_t)getFrequency(i) - (int16_t)frequency );
322
        if (comp < bestComp)
323
        {
324
            bestComp = comp;
325
            bestChannel = i;
326
        }
327
    }
328
    return bestChannel;
329
}
330
331
//******************************************************************************
332
//                              Menu
333
//******************************************************************************
334
335
//******************************************************************************
336
//* function: get_click_type
337
//*         : Polls the specified pin and returns the type of click that was
338
//*         : performed NO_CLICK, SINGLE_CLICK, DOUBLE_CLICK, LONG_CLICK
339
//*         : or LONG_LONG_CLICK
340
//******************************************************************************
341
342
uint8_t getClickType() {
343
    uint16_t timer = 0;
344
    uint8_t click_type = NO_CLICK;
345
    
346
    // check if the key has been pressed
347
    if (!BUTTON_PRESSED) return NO_CLICK ;
348
    
349
    while (BUTTON_PRESSED) {
350
        timer++;
351
        _delay_ms(1);
352
    }
353
    if (timer < 600)
354
        click_type = SINGLE_CLICK;
355
356
    if (timer >= 600)
357
        click_type = LONG_CLICK;
358
    
359
    // Check if there is a second click
360
    if ((click_type == SINGLE_CLICK) ) {
361
        
362
    }
363
    
364
    while ((!BUTTON_PRESSED) && (timer++ < 120)) {
365
        _delay_ms(1);
366
    }
367
    if (timer >= 200) {
368
        return click_type;
369
    }
370
    if (BUTTON_PRESSED ) {
371
        click_type = DOUBLE_CLICK;
372
        while (BUTTON_PRESSED) ;
373
    }
374
    return (click_type);
375
}
376
377
//******************************************************************************
378
//Flags
379
struct Flags {
380
     bool MENUEND;
381
     bool ACTIVEITEM;
382
     bool REFRESHINTERVAL;
383
};
384
385
struct MenuEntry ;   // dummy
386
387
typedef void (*MenuFnct) (struct MenuEntry*);
388
extern struct MenuEntry MainMenu[];
389
390
struct MenuEntry
391
{
392
    char*               text;
393
    MenuFnct            function;
394
    Flags               flags;
395
//    struct MenuEntry    *subMenu;
396
//    uint8_t             storage;
397
};
398
399
void MenuRefresh(struct MenuEntry *Menu );
400
MenuEntry *ptrMenu = NULL;
401
MenuEntry *ptrOldMenu = NULL;
402
403
void drawMenu(struct MenuEntry *Menu){
404
    ptrMenu = Menu;
405
    MenuRefresh(ptrMenu);
406
}
407
408
void exit(struct MenuEntry *Menu){
409
    osd.clearScreen();
410
}
411
412
void AutoSearch (struct MenuEntry *Menu)
413
{
414
    osd.clearScreen();
415
    currentChannel = bestChannelMatch(autoScan(getFrequency(currentChannel)));
416
    ptrMenu = MainMenu;
417
}
418
419
void BandScanner (struct MenuEntry *Menu)
420
{
421
    osd.clearScreen();
422
    currentChannel =  bestChannelMatch(graphicScanner(getFrequency(currentChannel)));
423
    ptrMenu = MainMenu;
424
425
}
426
427
void ManualMode (struct MenuEntry *Menu)
428
{
429
    uart_puts_p("ManualMode");
430
    while (!(getClickType() == LONG_CLICK)) {
431
        
432
        currentChannel = nextChannel( currentChannel );
433
        rx.setFrequency(getFrequency(currentChannel));
434
    }
435
}
436
/*
437
struct MenuEntry Settings[] =
438
{
439
    { "Batterie BEEPS",  NULL , { 0 , 0 , 0 } , NULL , 0 },
440
    { "Calibrate RSSI",  NULL , { 0 , 0 , 0 } , NULL , 0 },
441
    { "Video Input", NULL , { 0 , 0 , 0 } , NULL , 0 },
442
    { "Back", drawMenu , { 1 , 0 , 0} , MainMenu , 0 },
443
};
444
*/
445
struct MenuEntry MainMenu[] =
446
{
447
    { "Auto Scanner",  AutoSearch, { 0 , 1 , 0 } /*, NULL , 0*/},
448
    { "Band Scanner",  BandScanner, { 0 , 0 , 0 } /*, NULL , 0 */},
449
    { "Manual Mode", ManualMode, { 0 , 0 , 0 } /*, NULL , 0 */},
450
    { "Settings", drawMenu , { 0 , 0 , 0 } /*, NULL , 0 */},
451
    { "Exit", exit , { 1 , 0 , 0} /*, NULL , 0 */},
452
453
};
454
455
void MenuRefresh(struct MenuEntry *Menu )
456
{   //*----------------frame---------------
457
    osd.activateOSD();
458
    osd.clearScreen();
459
    osd.print("CYCLOPS OSD Menu", 5, 3);
460
    //*------------------------------------
461
    
462
    // find activ menu item
463
    uint8_t activItem   = 0;
464
    while (true) {
465
        if (Menu[activItem].flags.MENUEND) {
466
            osd.printMax7456Char(0xfC, 5, 7 + 0, true, true);
467
            Menu[0].flags.ACTIVEITEM = true;
468
            break;
469
        }
470
        activItem++;
471
    }
472
    
473
    // draw until the end of pointer list
474
    uint8_t         i = 0;
475
    do {
476
        osd.print(Menu[i].text, 7, 7+i);
477
        i++;
478
    } while (!Menu[i-1].flags.MENUEND);
479
    _delay_ms(20);
480
}
481
482
void MenuAction(struct MenuEntry *Menu ){
483
    uint8_t activItem   = 0;
484
485
    do{
486
        if (Menu[activItem].flags.ACTIVEITEM) {
487
//            Menu[activItem].function(Menu[activItem].subMenu);
488
            drawMenu(ptrMenu);
489
            uart_puts_p("hier kommt blödsinn raus ");
490
            return;
491
        }
492
        activItem++;
493
    }while (!Menu[activItem - 1 ].flags.MENUEND);
494
}
495
496
void MenuNext(struct MenuEntry *Menu ){
497
    uint8_t activItem   = 0;
498
499
    while (true) {
500
        if (Menu[activItem].flags.MENUEND && Menu[activItem].flags.ACTIVEITEM) {
501
            osd.printMax7456Char(0x00, 5, 7 + activItem);
502
            Menu[activItem].flags.ACTIVEITEM = false;
503
            MenuRefresh(Menu);
504
            return;
505
        }
506
        if (Menu[activItem].flags.ACTIVEITEM) {
507
            Menu[activItem].flags.ACTIVEITEM = false;
508
            Menu[activItem + 1].flags.ACTIVEITEM = true;
509
            osd.printMax7456Char(0x00, 5, 7 + activItem);
510
            osd.printMax7456Char(0xfC, 5, 8 + activItem, true ,true );
511
            return;
512
        }
513
        activItem++;
514
    }
515
}
516
void MenuIntervalAction(struct MenuEntry *Menu){
517
    
518
    // refresh Manager
519
    uint8_t activItem   = 0;
520
    do {
521
        // single refresh
522
        if (Menu[activItem].flags.ACTIVEITEM) {
523
            if (Menu[activItem].flags.REFRESHINTERVAL) {
524
                Menu[activItem].function(NULL);
525
            }
526
        }
527
    } while (!Menu[activItem - 1 ].flags.MENUEND);
528
}
529
//******************************************************************************
530
//*                             Main loop
531
//******************************************************************************
532
533
int main(void) {
534
    // init
535
    init();
536
    // init menu -> jump to MainMenu
537
    ptrMenu = MainMenu;
538
    MenuRefresh(ptrMenu);
539
    // ready
540
    uart_puts("Cyclops init \n\r");
541
    
542
    for(;;)
543
    {
544
//        MenuIntervalAction(ptrMenu);
545
        
546
        switch (getClickType())
547
        {
548
            case NO_CLICK: // do nothing
549
                break;
550
                
551
            case LONG_CLICK: //
552
                MenuAction(ptrMenu);
553
                break;
554
            case SINGLE_CLICK: //
555
                MenuNext(ptrMenu);
556
                break;
557
                
558
            case DOUBLE_CLICK:  //
559
                break;
560
        }
561
562
        
563
        
564
    }
565
    
566
    return 0; // never reached
567
}

Hier mal die main.cpp.
Und schon mal vielen dank!
Gruß

von Dieter F. (Gast)


Lesenswert?

D. C. schrieb:

> #include "RX5808.h"
> #include "max7456.h"


Scharf - und das Gesumse bleibt im Hintergrund?

Wenn Dein Programm so komplex ist (wie es scheint) solltest Du zur 
Fehlersuche (auch für uns) reduzieren. Nicht auf Code-Fragmente - 
sondern auf nicht funktionierende Mini-Programme, um die Ursache zu 
finden.

Wobei hier die Hardware (Schaltplan etc.) sicher auch interessant ist. 
RX5808 ist ja schon mal eine Hausnummer und MAX7456 ist auch kein 
Leichtgewicht. Ist aber erstmal egal.

Mache ein Mini-Programm, bei dem der Fehler auch auftritt (aber das muss 
ich Dir wahrscheinlich nicht schreiben) und taste Dich an die 
Fehlersituation heran.

von D. C. (joker89)


Lesenswert?

Hallo,
also der RX5808 wird via Software SPI angesteuert, und der Max7456 via 
Hardware SPI.

Das Menü lässt sich auch bedienen auch das Submenü tut erst mal das was 
es sollte. Nur wenn eine größere Routine(uint16_t graphicScanner(zb. 
"uint16_t frequency") via Funktionspointer aufgerufen wird wars das.

Ich hab gerade wieder Atmel Studio 7 installiert ich hatte ja auf meinem 
Macbook mit einem Template für Xcode gearbeitet weil Xcode für mich der 
beste Texteditor ist. Leider kam ich nie über avr gcc 4.8.1 hinaus da 
ich das aktuelle nicht bauen konnte und leider niemand ein fertiges 
hochgeladen hat.

Ich denke es ist wohl der erste Weg wieder mit Atmel Studio und dem 
aktuellen Avr gcc zuarbeiten, mein Makefile ist für xcode nämlich auch 
selbst gebaut und recht viel Erfahrung und Ahnung hab ich damit nicht 
aber es scheinte so als würds funktionieren....

von D. C. (joker89)


Angehängte Dateien:

Lesenswert?

Natürlich ist es viel verlangt aber ich hab das komplette Projekt mal 
gezipt...

von Dieter F. (Gast)


Lesenswert?

Wie sieht es denn mit ISR's (auch aus den nicht sichtbaren Teilen) aus? 
Können diese sich gegenseitig stören? Hört sich fast so an ...

von Dieter F. (Gast)


Lesenswert?

D. C. schrieb:
> Natürlich ist es viel verlangt aber ich hab das komplette Projekt mal
> gezipt...

Bringt nicht viel, wenn andere Deine Hardware-Ausstattung nicht haben 
...  aber danke dafür ...

Du wirst wohl nicht drum herum herumkommen, Komplexität herauszunehmen 
und zu beobachten. Das kann Dir auch niemand abnehmen, der nicht gleich 
ausgestattet ist.

Wenn Du die Komplexität reduziert hast kann  Dir ggf auch von hier aus 
geholfen werden. Hört sich blöd an - ist aber so.

von D. C. (joker89)


Lesenswert?

ISR's werden nur in der Uart lib benutzt das ist eine .c lib von Peter 
Fleury
ich hab daraus nur eine cpp gemacht da ich mich nicht ums linken von .c 
files kümmern wollte und der c++ compiler auch mit c klar kommen sollte.

von D. C. (joker89)


Lesenswert?

Also kann ich mir das mit Atmel Studio 7 jetzt auch sparen, oder doch 
eine gute idee? Ich scheitere sowieso gerade am einbinden des TinyUSBisp 
...

von C. A. Rotwang (Gast)


Lesenswert?

D. C. schrieb:
> Es kommt dann nur die Meldung "avr-objdump: can't use supplied machine
> -avr4"

die -m Option ist typabhängig, mit -m avr4 erwischt man viele kleine 
atmegas aber offensichtlich nicht deinen. Welchen atmega verwendest Du? 
Eine Tabelle welche -M Option du für welchen typ verwendest findet sich 
dort: http://www.nongnu.org/avr-libc/user-manual/using_tools.html

von D. C. (joker89)


Lesenswert?

ich nutze den Atmega 328p bzw mit dem muss ich arbeiten weil das Projekt 
auf einer Fertigaufgebauten platine laufen soll. Ich hab den ISP Header 
gefunden und ja die Möglichkeiten OEM waren einfach nur begrenzt :D

von D. C. (joker89)


Lesenswert?

Ich habe mich entschieden, ein wenig aufzurüsten . Der Atmel ICE ist 
bestellt und absofort wird wieder mit Atmel Studio gearbeitet.

Ich hatte aber gedacht dass wenn aus dem .hex wieder ein assembler code 
erstelle es nicht umbedingt dem original entsprechen muss?

Damit ich jetzt nicht blödes rede welche Endungen hätte denn dieses 
File.
Mein Makefile erzeugt sowieso immer auch die .lst .lss bzw gibt sie aus

: Bearbeitet durch User
von Jim M. (turboj)


Lesenswert?

D. C. schrieb:
> Ich hatte aber gedacht dass wenn aus dem .hex wieder ein assembler code
> erstelle es nicht umbedingt dem original entsprechen muss?

Falsch gedacht. Das ist genau der Code den der Prozessor sieht - der 
Disassembler macht nur die binären Zahlen (etwas ;-) besser lesbar.

Hilfreich wenn man mal ein volatile vergessen hat und dadurch der 
Optimizer eine Endlosschleife einbaut - den Befehl (Sprung auf sich 
selbst) erkennt auch das wenig geübte Auge recht schnell.

Völlig identisch zum Ausgangscode ist das Disassembly nicht (außer der 
Disassembler hat Zugriff auf die Debugging Symbole im .elf), da im Hex 
die ganzen Namen für Variablen oder Sprungmarken fehlen.

Aber dazu muss man sich natürlich auch mal mit dem Befahlssatz des µCs 
befasst haben.

von C. A. Rotwang (Gast)


Lesenswert?

D. C. schrieb:

> Ich hatte aber gedacht dass wenn aus dem .hex wieder ein assembler code
> erstelle es nicht umbedingt dem original entsprechen muss?

Doch, zum Test assembliere  und hex-convertiere mal das disassemblierte 
file. Wenn dir kein Fehler unterlaufen ist das passen die beiden 
hex-files 1:1

> Damit ich jetzt nicht blödes rede welche Endungen hätte denn dieses
> File.

Hm *.S war mal gängig für Assembler-source ansonsten halt das was man 
bei -o angibt.

> Mein Makefile erzeugt sowieso immer auch die .lst .lss bzw gibt sie aus

und was steht drin?

Statt aus dem Hexcode kannst du natürlich auch dem C-Compiler sagen er 
soll assembler rausschreiben (command line option -S) . Dieser 
Assembler-Code gefällt mir persönlich nicht so sehr da er noch info für 
den Linker enthält und der Kram aus den Standardlibs fehlt.

von D. C. (joker89)


Angehängte Dateien:

Lesenswert?

Hallo,
ich versuch mich gerade zu dem Thema einzulesen, es geht leider sehr 
spärlich voran. Die Infos die mir google dazu liefert sind schon sehr 
begrenzt... Ich hab jetzt mal den Build folder im Anhang, vllt 
interessiert sich der ein oder andere dafür.
Gruß

von D. C. (joker89)


Lesenswert?

Mein neuer debugger ist noch nicht da, also hab ich mein Makefile 
angepasst und mich zum Thema GDB und avarice/simulavr eingelesen, Ich 
hab in Xcode ein target hinzugefügt "debug" für
1
gdb-config: 
2
  @$(REMOVE) $(GDBINIT_FILE)
3
  @echo define reset >> $(GDBINIT_FILE)
4
  @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
5
  @echo end >> $(GDBINIT_FILE)
6
  @echo file $(OBJDIR)/$(TARGET).elf >> $(GDBINIT_FILE)
7
  @echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
8
ifeq ($(DEBUG_BACKEND),simulavr)
9
  @echo load  >> $(GDBINIT_FILE)
10
endif  
11
  @echo break main >> $(GDBINIT_FILE)
12
13
debug: gdb-config $(OBJDIR)/$(TARGET).elf
14
ifeq ($(DEBUG_BACKEND), avarice)
15
  @echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
16
  @avarice --jtag $(JTAG_DEV) --erase --program --file \
17
  /$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
18
  @ /c pause
19
else
20
  @simulavr --gdbserver --device $(MCU) --clock-freq \
21
  $(DEBUG_MFREQ) --port $(DEBUG_PORT)
22
endif
23
  @ /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE)

aktuell wartet die Console jetzt auf den client der Client ist doch 
soweit ich das jetzt verstanden hab simulavr oder ? Bei avarice wäre es 
mir vermeintlich klar da ich ihn noch nicht angeschlossen hab aber wieso 
bei simulavr auch ?

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.