mikrocontroller.net

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


Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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 ?
  case LONG_CLICK: //
                MenuAction(ptrMenu);
                USART_putstring("MenuAction \n\r");
break;


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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Kaj G. (Firma: RUB) (bloody)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Sollbruch (Gast)
Datum:

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

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: holger (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: C. A. Rotwang (Gast)
Datum:

Bewertung
-3 lesenswert
nicht 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.

Autor: Carl Drexler (jcw2)
Datum:

Bewertung
1 lesenswert
nicht 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.

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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=Speicherv...

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
int freeRam () {
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}

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

: Bearbeitet durch User
Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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
void MenuAction(struct MenuEntry *Menu ){
    uint8_t activItem   = 0;

    do{
        if (Menu[activItem].flags.ACTIVEITEM) {
            Menu[activItem].function(Menu[activItem].subMenu);
            drawMenu(ptrMenu);
//            uart_puts_p("hier kommt blödsinn raus ");
            return;
        }
        activItem++;
    }while (!Menu[activItem - 1 ].flags.MENUEND);
}
....
....
....
  switch (getClickType())
        {
            case NO_CLICK: // do nothing
                break;
                
            case LONG_CLICK: //
                MenuAction(ptrMenu);
....

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
Autor: Nop (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Olaf (Gast)
Datum:

Bewertung
1 lesenswert
nicht 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

Autor: D. Chung (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auf welche ide sollte ich dann zurückgreifen?

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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 ?

Autor: Kaj (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
D. C. schrieb:
> Gibts hier ne
> alternative ?
Simulator

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Weg führt wieder nach Atmel studio ?

Autor: C. A. Rotwang (Gast)
Datum:

Bewertung
-2 lesenswert
nicht 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

Autor: D. Chung (joker89)
Datum:

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

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht 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 :-)

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versteh gerade nur noch Bahnhof....

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht 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 :-) ...

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#include <stdio.h>
#include <stdlib.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <avr/pgmspace.h>

#include "define.h"
#include "RX5808.h"
#include "max7456.h"
#include "uart.h"

//******************************************************************************
//*                             declar
//******************************************************************************

RX5808 rx;
Max7456 osd;
uint8_t currentChannel = 0;
char buffer[5];                                 //Output of the itoa function

//forward declaration
uint8_t getClickType();

//******************************************************************************
//*                          AVR IO Funktion
//******************************************************************************
int freeRam () {
    extern int __heap_start, *__brkval;
    int v;
    return (int) &v - (__brkval == 0 ? (int) &__heap_start : (int) __brkval);
}
uint16_t read_adc(uint8_t channel){
    ADMUX &= 0xF0;                   //Clear the older channel that was read
    ADMUX |= channel;                //Defines the new ADC channel to be read
    ADCSRA |= (1<<ADSC);             //Starts a new conversion
    while(ADCSRA & (1<<ADSC));       //Wait until the conversion is done
    return ADCW;                     //Returns the ADC value of the chosen channel
}

void printFreeMEM(){
    uart_puts_P("free: ");
    itoa(freeRam(), buffer, 10);      //Convert the read value to an ascii string
//    itoa(static_cast<uint8_t>(get_mem_unused()), buffer, 10);      //Convert the read value to an ascii string
    uart_puts(buffer);
    uart_puts_P("\n");
}

//******************************************************************************
//*                              init
//******************************************************************************

void init(){
//---------------------------------
// initialize LED pin as output
//---------------------------------
    DDRB |= (1<<LED_PIN);
    _delay_ms(20);
    
//---------------------------------
// initialize button pin as input
//---------------------------------
    DDRD &= ~(1 << BUTTON_PIN);
    PORTD |= (1<<LED_PIN);  //set internall pullup
    
//---------------------------------
// initialize analog input
//---------------------------------
    ADCSRA |= ((1<<ADPS2)|(1<<ADPS1)|(1<<ADPS0));       //16Mhz/128 = 125Khz the ADC reference clock
    ADMUX |= (1<<REFS0);                                //Voltage reference from Avcc (5v)
    ADCSRA |= (1<<ADEN);                                //Turn on ADC
    ADCSRA |= (1<<ADSC);                                //Do an initial conversion because this one is the slowest and to ensure that everything is up and running
    
//---------------------------------
// initialize timer 0
//---------------------------------
    //(8000000/8)/256 Hz = 390.000 Hz -> 2,56 ms
    //TCCR0 = (1<<CS01); // Prescaler 8
    //TIMSK |= (1<<TOIE0); // Overflow Interrupt
    sei(); // interrupt allow

//---------------------------------
// initialize uart
//---------------------------------
    uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
    sei();
//---------------------------------
// OSD initialize Settings
//---------------------------------
    osd.setDisplayOffsets(45,25);   //x , y
    osd.setBlinkParams( _8fields , _3BT_BT );
    osd.activateExternalVideo();

}
//******************************************************************************
//                             RX5808
//******************************************************************************

//******************************************************************************
//* Positions in the frequency table for the 40 channels
//* Direct access via array operations does not work since data is stored in
//* flash, not in RAM. Use getPosition to retrieve data

const uint8_t positions[] PROGMEM = {
    19, 18, 32, 17, 33, 16,  7, 34,  8, 24,  6,  9, 25,  5, 35, 10, 26,  4, 11, 27,
    3, 36, 12, 28,  2, 13, 29, 37,  1, 14, 30,  0, 15, 31, 38, 20, 21, 39, 22, 23
};

uint16_t getPosition( uint8_t channel ) {
    return pgm_read_byte_near(positions + channel);
}

//******************************************************************************
//* Frequencies for the 40 channels
//* Direct access via array operations does not work since data is stored in
//* flash, not in RAM. Use getFrequency to retrieve data

const uint16_t channelFrequencies[] PROGMEM = {
    5865, 5845, 5825, 5805, 5785, 5765, 5745, 5725, // Band A - Boscam A
    5733, 5752, 5771, 5790, 5809, 5828, 5847, 5866, // Band B - Boscam B
    5705, 5685, 5665, 5645, 5885, 5905, 5925, 5945, // Band E - DJI
    5740, 5760, 5780, 5800, 5820, 5840, 5860, 5880, // Band F - FatShark \ Immersion
    5658, 5695, 5732, 5769, 5806, 5843, 5880, 5917  // Band C - Raceband
};

uint16_t getFrequency( uint8_t channel ) {
    return pgm_read_word_near(channelFrequencies + getPosition(channel));
}

//******************************************************************************
//* function: nextChannel
//******************************************************************************
uint8_t nextChannel(uint8_t channel)
{
    if (channel > (CHANNEL_MAX - 1))
        return CHANNEL_MIN;
    else
        return channel + 1;
    
}//******************************************************************************
//* function: updateScannerScreen
//*         : position = 0 to 99
//*         : value = 0 to 53
//*         : must be fast since there are frequent updates
//******************************************************************************
void updateScannerScreen(uint8_t position, uint8_t value ) {

    osd.print( read_adc(RSSI_PIN), 5, 5, 4, 0);
    
}

//******************************************************************************
//* function: drawAutoScanScreen
//******************************************************************************
void drawScanScreen( uint16_t Mhz, uint8_t channel , uint16_t rssi ) {
    
    osd.print("Auto Scanner", 7, 3);
    osd.print("Channel", 2, 6);
    osd.print(" MHz", 12, 6);
    osd.print("RSSI ", 20, 6);
    osd.print( channel, 2, 8, 2, 0);
    osd.print( Mhz, 12, 8, 4, 0);
    osd.print( rssi, 20, 8, 4, 0);

}
//******************************************************************************
//* function: drawScannerScreen
//******************************************************************************

void drawScannerScreen( void ) {
    
    osd.printMax7456Chars( bar, 25, 2, 12);
    osd.print("5.65       5.8       5.95", 2, 13);
    updateScannerScreen(0, 0);
}

//******************************************************************************
//* function: autoScan
//******************************************************************************
uint16_t autoScan( uint16_t frequency ) {
    
    uint8_t i;
    uint16_t scanRssi = 0;
    uint16_t bestRssi = 0;
    uint16_t scanFrequency;
    uint16_t bestFrequency;
    
    drawScanScreen(0,0,0);
    
    // Skip 10 MHz forward to avoid detecting the current channel
    scanFrequency = frequency + 10;
    if (!(scanFrequency % 2))
        scanFrequency++;        // RTC6715 can only generate odd frequencies
    
    // Coarse tuning
    bestFrequency = scanFrequency;
    for (i = 0; i < 60 && (scanRssi < RSSI_TRESHOLD); i++) {
        if ( scanFrequency <= (FREQUENCY_MAX - 5))
            scanFrequency += 5;
        else
            scanFrequency = FREQUENCY_MIN;
        rx.setFrequency(scanFrequency);
    _delay_ms( RSSI_STABILITY_DELAY_MS );
        scanRssi = read_adc(RSSI_PIN);
        if (bestRssi < scanRssi) {
            bestRssi = scanRssi;
            bestFrequency = scanFrequency;
        }
#ifdef debugSerialScanner
        char buffer[5];                                 //Output of the itoa function
        USART_putstring("F: ");
        itoa(bestFrequency, buffer, 10);      //Convert the read value to an ascii string
        USART_putstring(buffer);
        USART_putstring("RSSI: ");
        itoa(bestRssi, buffer, 10);                     //Convert the read value to an ascii string
        USART_putstring(buffer);                        //Send the converted value to the terminal
        USART_putstring("\r\n");

#endif
    }
    // Fine tuning
    scanFrequency = bestFrequency - 20;
    bestRssi = 0;
    for (i = 0; i < 20; i++, scanFrequency += 2) {
        rx.setFrequency(scanFrequency);
        _delay_ms( RSSI_STABILITY_DELAY_MS );
        scanRssi = read_adc(RSSI_PIN);
        if (bestRssi < scanRssi) {
            bestRssi = scanRssi;
            bestFrequency = scanFrequency;
        }
#ifdef debugSerialScanner
        USART_putstring("F: ");
        itoa(bestFrequency, buffer, 10);      //Convert the read value to an ascii string
        USART_putstring(buffer);
        USART_putstring("RSSI: ");
        itoa(bestRssi, buffer, 10);                     //Convert the read value to an ascii string
        USART_putstring(buffer);                        //Send the converted value to the terminal
        USART_putstring("\r\n");
#endif
    }

    drawScanScreen(bestFrequency,0, bestRssi);
    
    while (!getClickType()){
#ifdef debugSerialScanner
        USART_putstring("wait");
#endif
    }
    // Return the best frequency
    rx.setFrequency(bestFrequency);
    return (bestFrequency);

}

//******************************************************************************
//* function: graphicScanner
//*         : scans the 5.8 GHz band in 3 MHz increments and draws a graphical
//*         : representation. when the button is pressed the currently
//*         : scanned frequency is returned.
//******************************************************************************
uint16_t graphicScanner( uint16_t frequency ) {
    uint8_t i;
    uint16_t scanRssi;
    uint16_t bestRssi = 0;
    uint16_t scanFrequency = frequency;
    uint16_t bestFrequency = frequency;
    uint8_t rssiDisplayValue;
    
    // Draw screen frame etc
    drawScannerScreen();
    
    while ( getClickType() == NO_CLICK) {
        scanFrequency += 3;
        if (scanFrequency > FREQUENCY_MAX)
            scanFrequency = FREQUENCY_MIN;
        rx.setFrequency(scanFrequency);
        _delay_ms( RSSI_STABILITY_DELAY_MS );
        scanRssi = read_adc(1);
        rssiDisplayValue = (scanRssi - 140) / 10;    // Roughly 2 - 46
        updateScannerScreen(100 - ((FREQUENCY_MAX - scanFrequency) / 3), rssiDisplayValue );

#ifdef debugSerialScanner
        USART_putstring(": ");
        itoa(bestFrequency, buffer, 10);      //Convert the read value to an ascii string
        USART_putstring(buffer);
        USART_putstring("RSSI: ");
        itoa(bestRssi, buffer, 10);                     //Convert the read value to an ascii string
        USART_putstring(buffer);                        //Send the converted value to the terminal
        USART_putstring("\r\n");
#endif
    }
    // Fine tuning
    scanFrequency = scanFrequency - 20;
    for (i = 0; i < 20; i++, scanFrequency += 2) {
        rx.setFrequency(scanFrequency);
        _delay_ms( RSSI_STABILITY_DELAY_MS );
        scanRssi = read_adc(RSSI_PIN);
        if (bestRssi < scanRssi) {
            bestRssi = scanRssi;
            bestFrequency = scanFrequency;
        }
    }
    while (!getClickType())
    // Return the best frequency
    rx.setFrequency(bestFrequency);
    return (bestFrequency);
}
//******************************************************************************
//* function: bestChannelMatch
//*         : finds the best matching standard channel for a given frequency
//******************************************************************************
uint8_t bestChannelMatch( uint16_t frequency )
{
    int16_t comp;
    int16_t bestComp = 300;
    uint8_t bestChannel = CHANNEL_MIN;
    uint8_t i;
    
    for (i = CHANNEL_MIN; i <= CHANNEL_MAX; i++) {
        comp = abs( (int16_t)getFrequency(i) - (int16_t)frequency );
        if (comp < bestComp)
        {
            bestComp = comp;
            bestChannel = i;
        }
    }
    return bestChannel;
}

//******************************************************************************
//                              Menu
//******************************************************************************

//******************************************************************************
//* function: get_click_type
//*         : Polls the specified pin and returns the type of click that was
//*         : performed NO_CLICK, SINGLE_CLICK, DOUBLE_CLICK, LONG_CLICK
//*         : or LONG_LONG_CLICK
//******************************************************************************

uint8_t getClickType() {
    uint16_t timer = 0;
    uint8_t click_type = NO_CLICK;
    
    // check if the key has been pressed
    if (!BUTTON_PRESSED) return NO_CLICK ;
    
    while (BUTTON_PRESSED) {
        timer++;
        _delay_ms(1);
    }
    if (timer < 600)
        click_type = SINGLE_CLICK;

    if (timer >= 600)
        click_type = LONG_CLICK;
    
    // Check if there is a second click
    if ((click_type == SINGLE_CLICK) ) {
        
    }
    
    while ((!BUTTON_PRESSED) && (timer++ < 120)) {
        _delay_ms(1);
    }
    if (timer >= 200) {
        return click_type;
    }
    if (BUTTON_PRESSED ) {
        click_type = DOUBLE_CLICK;
        while (BUTTON_PRESSED) ;
    }
    return (click_type);
}

//******************************************************************************
//Flags
struct Flags {
     bool MENUEND;
     bool ACTIVEITEM;
     bool REFRESHINTERVAL;
};

struct MenuEntry ;   // dummy

typedef void (*MenuFnct) (struct MenuEntry*);
extern struct MenuEntry MainMenu[];

struct MenuEntry
{
    char*               text;
    MenuFnct            function;
    Flags               flags;
//    struct MenuEntry    *subMenu;
//    uint8_t             storage;
};

void MenuRefresh(struct MenuEntry *Menu );
MenuEntry *ptrMenu = NULL;
MenuEntry *ptrOldMenu = NULL;

void drawMenu(struct MenuEntry *Menu){
    ptrMenu = Menu;
    MenuRefresh(ptrMenu);
}

void exit(struct MenuEntry *Menu){
    osd.clearScreen();
}

void AutoSearch (struct MenuEntry *Menu)
{
    osd.clearScreen();
    currentChannel = bestChannelMatch(autoScan(getFrequency(currentChannel)));
    ptrMenu = MainMenu;
}

void BandScanner (struct MenuEntry *Menu)
{
    osd.clearScreen();
    currentChannel =  bestChannelMatch(graphicScanner(getFrequency(currentChannel)));
    ptrMenu = MainMenu;

}

void ManualMode (struct MenuEntry *Menu)
{
    uart_puts_p("ManualMode");
    while (!(getClickType() == LONG_CLICK)) {
        
        currentChannel = nextChannel( currentChannel );
        rx.setFrequency(getFrequency(currentChannel));
    }
}
/*
struct MenuEntry Settings[] =
{
    { "Batterie BEEPS",  NULL , { 0 , 0 , 0 } , NULL , 0 },
    { "Calibrate RSSI",  NULL , { 0 , 0 , 0 } , NULL , 0 },
    { "Video Input", NULL , { 0 , 0 , 0 } , NULL , 0 },
    { "Back", drawMenu , { 1 , 0 , 0} , MainMenu , 0 },
};
*/
struct MenuEntry MainMenu[] =
{
    { "Auto Scanner",  AutoSearch, { 0 , 1 , 0 } /*, NULL , 0*/},
    { "Band Scanner",  BandScanner, { 0 , 0 , 0 } /*, NULL , 0 */},
    { "Manual Mode", ManualMode, { 0 , 0 , 0 } /*, NULL , 0 */},
    { "Settings", drawMenu , { 0 , 0 , 0 } /*, NULL , 0 */},
    { "Exit", exit , { 1 , 0 , 0} /*, NULL , 0 */},

};

void MenuRefresh(struct MenuEntry *Menu )
{   //*----------------frame---------------
    osd.activateOSD();
    osd.clearScreen();
    osd.print("CYCLOPS OSD Menu", 5, 3);
    //*------------------------------------
    
    // find activ menu item
    uint8_t activItem   = 0;
    while (true) {
        if (Menu[activItem].flags.MENUEND) {
            osd.printMax7456Char(0xfC, 5, 7 + 0, true, true);
            Menu[0].flags.ACTIVEITEM = true;
            break;
        }
        activItem++;
    }
    
    // draw until the end of pointer list
    uint8_t         i = 0;
    do {
        osd.print(Menu[i].text, 7, 7+i);
        i++;
    } while (!Menu[i-1].flags.MENUEND);
    _delay_ms(20);
}

void MenuAction(struct MenuEntry *Menu ){
    uint8_t activItem   = 0;

    do{
        if (Menu[activItem].flags.ACTIVEITEM) {
//            Menu[activItem].function(Menu[activItem].subMenu);
            drawMenu(ptrMenu);
            uart_puts_p("hier kommt blödsinn raus ");
            return;
        }
        activItem++;
    }while (!Menu[activItem - 1 ].flags.MENUEND);
}

void MenuNext(struct MenuEntry *Menu ){
    uint8_t activItem   = 0;

    while (true) {
        if (Menu[activItem].flags.MENUEND && Menu[activItem].flags.ACTIVEITEM) {
            osd.printMax7456Char(0x00, 5, 7 + activItem);
            Menu[activItem].flags.ACTIVEITEM = false;
            MenuRefresh(Menu);
            return;
        }
        if (Menu[activItem].flags.ACTIVEITEM) {
            Menu[activItem].flags.ACTIVEITEM = false;
            Menu[activItem + 1].flags.ACTIVEITEM = true;
            osd.printMax7456Char(0x00, 5, 7 + activItem);
            osd.printMax7456Char(0xfC, 5, 8 + activItem, true ,true );
            return;
        }
        activItem++;
    }
}
void MenuIntervalAction(struct MenuEntry *Menu){
    
    // refresh Manager
    uint8_t activItem   = 0;
    do {
        // single refresh
        if (Menu[activItem].flags.ACTIVEITEM) {
            if (Menu[activItem].flags.REFRESHINTERVAL) {
                Menu[activItem].function(NULL);
            }
        }
    } while (!Menu[activItem - 1 ].flags.MENUEND);
}
//******************************************************************************
//*                             Main loop
//******************************************************************************

int main(void) {
    // init
    init();
    // init menu -> jump to MainMenu
    ptrMenu = MainMenu;
    MenuRefresh(ptrMenu);
    // ready
    uart_puts("Cyclops init \n\r");
    
    for(;;)
    {
//        MenuIntervalAction(ptrMenu);
        
        switch (getClickType())
        {
            case NO_CLICK: // do nothing
                break;
                
            case LONG_CLICK: //
                MenuAction(ptrMenu);
                break;
            case SINGLE_CLICK: //
                MenuNext(ptrMenu);
                break;
                
            case DOUBLE_CLICK:  //
                break;
        }

        
        
    }
    
    return 0; // never reached
}


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

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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....

Autor: D. Chung (joker89)
Datum:
Angehängte Dateien:

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

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht 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 ...

Autor: Dieter F. (jim_quakenbush)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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 
...

Autor: C. A. Rotwang (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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
Autor: Jim Meba (turboj)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: C. A. Rotwang (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: D. Chung (joker89)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht 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ß

Autor: D. Chung (joker89)
Datum:

Bewertung
0 lesenswert
nicht 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
gdb-config: 
  @$(REMOVE) $(GDBINIT_FILE)
  @echo define reset >> $(GDBINIT_FILE)
  @echo SIGNAL SIGHUP >> $(GDBINIT_FILE)
  @echo end >> $(GDBINIT_FILE)
  @echo file $(OBJDIR)/$(TARGET).elf >> $(GDBINIT_FILE)
  @echo target remote $(DEBUG_HOST):$(DEBUG_PORT)  >> $(GDBINIT_FILE)
ifeq ($(DEBUG_BACKEND),simulavr)
  @echo load  >> $(GDBINIT_FILE)
endif  
  @echo break main >> $(GDBINIT_FILE)

debug: gdb-config $(OBJDIR)/$(TARGET).elf
ifeq ($(DEBUG_BACKEND), avarice)
  @echo Starting AVaRICE - Press enter when "waiting to connect" message displays.
  @avarice --jtag $(JTAG_DEV) --erase --program --file \
  /$(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT)
  @ /c pause
else
  @simulavr --gdbserver --device $(MCU) --clock-freq \
  $(DEBUG_MFREQ) --port $(DEBUG_PORT)
endif
  @ /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 ?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.