Hallo, habe das Problem, dass er während er in eine uart_funktion geht auf eine andere Position vorher im Code zurückspringt. Ich habe das auch schon in den µC gebrannt, leider hängt er da auch iwo. Denke, dass ich daher einen Bug im Avr Studio 5 ausschließen kann. Ohne Optimierung läuft das soweit durch und funktioniert auch aufm µC. Aber das kann ja nicht die Lösung sein. Weiß jemand warum das passiert? Ich wollte gerne den Bootlader ausprobieren : http://www.mikrocontroller.net/articles/AVR_Bootloader_in_C_-_eine_einfache_Anleitung wenn er dort ankommt, springt er irgendwo hin.... uart_puts("Hallo hier ist der echte Bootloader\n\r"); /* * Bootlader_644.c * * Created: 02.08.2011 11:36:54 * Author: iwi */ #define F_CPU 16000000UL #include <string.h> #include <avr/io.h> #include <avr/interrupt.h> #include <avr/boot.h> #include <util/delay.h> #include "uart.h" #define BOOT_UART_BAUD_RATE 9600 /* Baudrate */ #define XON 17 /* XON Zeichen */ #define XOFF 19 /* XOFF Zeichen */ #define START_SIGN ':' /* Hex-Datei Zeilenstartzeichen */ /* Zustände des Bootloader-Programms */ #define BOOT_STATE_EXIT 0 #define BOOT_STATE_PARSER 1 /* Zustände des Hex-File-Parsers */ #define PARSER_STATE_START 0 #define PARSER_STATE_SIZE 1 #define PARSER_STATE_ADDRESS 2 #define PARSER_STATE_TYPE 3 #define PARSER_STATE_DATA 4 #define PARSER_STATE_CHECKSUM 5 #define PARSER_STATE_ERROR 6 void program_page (uint32_t page, uint8_t *buf) { uint16_t i; uint8_t sreg; /* Disable interrupts */ sreg = SREG; cli(); eeprom_busy_wait (); boot_page_erase (page); boot_spm_busy_wait (); /* Wait until the memory is erased. */ for (i=0; i<SPM_PAGESIZE; i+=2) { /* Set up little-endian word. */ uint16_t w = *buf++; w += (*buf++) << 8; boot_page_fill (page + i, w); } boot_page_write (page); /* Store buffer in flash page. */ boot_spm_busy_wait(); /* Wait until the memory is written.*/ /* Reenable RWW-section again. We need this if we want to jump back */ /* to the application after bootloading. */ boot_rww_enable (); /* Re-enable interrupts (if they were ever enabled). */ SREG = sreg; } static uint16_t hex2num (const uint8_t * ascii, uint8_t num) { uint8_t i; uint16_t val = 0; for (i=0; i<num; i++) { uint8_t c = ascii[i]; /* Hex-Ziffer auf ihren Wert abbilden */ if (c >= '0' && c <= '9') c -= '0'; else if (c >= 'A' && c <= 'F') c -= 'A' - 10; else if (c >= 'a' && c <= 'f') c -= 'a' - 10; val = 16 * val + c; } return val; } int main() { /* Empfangenes Zeichen + Statuscode */ uint16_t c = 0, /* Intel-HEX Zieladresse */ hex_addr = 0, /* Zu schreibende Flash-Page */ flash_page = 0, /* Intel-HEX Checksumme zum Überprüfen der Daten */ hex_check = 0, /* Positions zum Schreiben in der Datenpuffer */ flash_cnt = 0; /* temporäre Variable */ uint8_t temp, /* Flag zum steuern des Programmiermodus */ boot_state = BOOT_STATE_EXIT, /* Empfangszustandssteuerung */ parser_state = PARSER_STATE_START, /* Flag zum ermitteln einer neuen Flash-Page */ flash_page_flag = 1, /* Datenpuffer für die Hexdaten*/ flash_data[SPM_PAGESIZE], /* Position zum Schreiben in den HEX-Puffer */ hex_cnt = 0, /* Puffer für die Umwandlung der ASCII in Binärdaten */ hex_buffer[5], /* Intel-HEX Datenlänge */ hex_size = 0, /* Zähler für die empfangenen HEX-Daten einer Zeile */ hex_data_cnt = 0, /* Intel-HEX Recordtype */ hex_type = 0, /* empfangene HEX-Checksumme */ hex_checksum=0; /* Funktionspointer auf 0x0000 */ void (*start)( void ) = 0x0000; /* Füllen der Puffer mit definierten Werten */ memset(hex_buffer, 0x00, sizeof(hex_buffer)); memset(flash_data, 0xFF, sizeof(flash_data)); /* Interrupt Vektoren verbiegen */ temp = MCUCR; MCUCR = temp | (1<<IVCE); MCUCR = temp | (1<<IVSEL); /* Einstellen der Baudrate und aktivieren der Interrupts */ uart_init( UART_BAUD_SELECT(BOOT_UART_BAUD_RATE,F_CPU) ); sei(); uart_puts("Hallo hier ist der echte Bootloader\n\r"); _delay_ms(2000); do { c = uart_getc(); if( !(c & UART_NO_DATA) ) { /* Programmzustand: Parser */ if(boot_state == BOOT_STATE_PARSER) { switch(parser_state) { /* Warte auf Zeilen-Startzeichen */ case PARSER_STATE_START: if((uint8_t)c == START_SIGN) { uart_putc(XOFF); parser_state = PARSER_STATE_SIZE; hex_cnt = 0; hex_check = 0; uart_putc(XON); } break; /* Parse Datengröße */ case PARSER_STATE_SIZE: hex_buffer[hex_cnt++] = (uint8_t)c; if(hex_cnt == 2) { uart_putc(XOFF); parser_state = PARSER_STATE_ADDRESS; hex_cnt = 0; hex_size = (uint8_t)hex2num(hex_buffer, 2); hex_check += hex_size; uart_putc(XON); } break; /* Parse Zieladresse */ case PARSER_STATE_ADDRESS: hex_buffer[hex_cnt++] = (uint8_t)c; if(hex_cnt == 4) { uart_putc(XOFF); parser_state = PARSER_STATE_TYPE; hex_cnt = 0; hex_addr = hex2num(hex_buffer, 4); hex_check += (uint8_t) hex_addr; hex_check += (uint8_t) (hex_addr >> 8); if(flash_page_flag) { flash_page = hex_addr - hex_addr % SPM_PAGESIZE; flash_page_flag = 0; } uart_putc(XON); } break; /* Parse Zeilentyp */ case PARSER_STATE_TYPE: hex_buffer[hex_cnt++] = (uint8_t)c; if(hex_cnt == 2) { uart_putc(XOFF); hex_cnt = 0; hex_data_cnt = 0; hex_type = (uint8_t)hex2num(hex_buffer, 2); hex_check += hex_type; switch(hex_type) { case 0: parser_state = PARSER_STATE_DATA; break; case 1: parser_state = PARSER_STATE_CHECKSUM; break; default: parser_state = PARSER_STATE_DATA; break; } uart_putc(XON); } break; /* Parse Flash-Daten */ case PARSER_STATE_DATA: hex_buffer[hex_cnt++] = (uint8_t)c; if(hex_cnt == 2) { uart_putc(XOFF); uart_putc('.'); hex_cnt = 0; flash_data[flash_cnt] = (uint8_t)hex2num(hex_buffer, 2); hex_check += flash_data[flash_cnt]; flash_cnt++; hex_data_cnt++; if(hex_data_cnt == hex_size) { parser_state = PARSER_STATE_CHECKSUM; hex_data_cnt=0; hex_cnt = 0; } /* Puffer voll -> schreibe Page */ if(flash_cnt == SPM_PAGESIZE) { uart_puts("P\n\r"); _delay_ms(100); program_page((uint16_t)flash_page, flash_data); memset(flash_data, 0xFF, sizeof(flash_data)); flash_cnt = 0; flash_page_flag = 1; } uart_putc(XON); } break; /* Parse Checksumme */ case PARSER_STATE_CHECKSUM: hex_buffer[hex_cnt++] = (uint8_t)c; if(hex_cnt == 2) { uart_putc(XOFF); hex_checksum = (uint8_t)hex2num(hex_buffer, 2); hex_check += hex_checksum; hex_check &= 0x00FF; /* Dateiende -> schreibe Restdaten */ if(hex_type == 1) { uart_puts("P\n\r"); _delay_ms(100); program_page((uint16_t)flash_page, flash_data); boot_state = BOOT_STATE_EXIT; } /* Überprüfe Checksumme -> muss '0' sein */ if(hex_check == 0) parser_state = PARSER_STATE_START; else parser_state = PARSER_STATE_ERROR; uart_putc(XON); } break; /* Parserfehler (falsche Checksumme) */ case PARSER_STATE_ERROR: uart_putc('#'); break; default: break; } } /* Programmzustand: UART Kommunikation */ else if(boot_state != BOOT_STATE_PARSER) { switch((uint8_t)c) { case 'p': boot_state = BOOT_STATE_PARSER; uart_puts("Programmiere den Flash!\n\r"); uart_puts("Kopiere die Hex-Datei und füge sie" " hier ein (rechte Maustaste)\n\r"); break; case 'q': boot_state = BOOT_STATE_EXIT; uart_puts("Verlasse den Bootloader!\n\r"); break; default: uart_puts("Du hast folgendes Zeichen gesendet: "); uart_putc((unsigned char)c); uart_puts("\n\r"); break; } } } } while(boot_state!=BOOT_STATE_EXIT); uart_puts("Reset AVR!\n\r"); _delay_ms(500); /* Interrupt Vektoren wieder gerade biegen */ temp = MCUCR; MCUCR = temp | (1<<IVCE); MCUCR = temp & ~(1<<IVSEL); /* Reset */ start(); return 0; }
>> habe das Problem, dass er während er in eine uart_funktion geht auf eine >> andere Position vorher im Code zurückspringt. >Könnte ein buffer overflow sein. @A.K. Nein, das ist normal. Ich hatte diesen Effekt auch schon mal und habe die Stelle so umprogrammiert dass es geht. Alternativ müssen die Quellcode-Dateien mit Problemen mit -O0 kompiliert werden. Siehe Hier: Beitrag "GCC kompiliert falsch?"
Andre Iwers schrieb: > habe das Problem, dass er während er in eine uart_funktion geht auf > eine andere Position vorher im Code zurückspringt. > wenn er dort ankommt, springt er irgendwo hin.... Liegt das Problem nun beim Hin- oder beim Rücksprung? Will sagen: Kommt von dem UART-Kram was, oder geht er gleich stiften? Rücksprungfehler deuten aus Stack- oder Buffer-Overflow hin. Gehts schon vorher in die Binsen, beispielsweise direkt nach dem "sei", dann könnte ein Interrupt-Handler mitmischen. Code dieser Grössenordnung bitte als Anhang. Den verwendeten Controller könntest du auch auch verraten.
Markus Müller schrieb: > Ich hatte diesen Effekt auch schon mal und habe > die Stelle so umprogrammiert dass es geht. > Alternativ müssen die Quellcode-Dateien mit Problemen mit -O0 kompiliert > werden. > > Siehe Hier: Beitrag "GCC kompiliert falsch?" Dieser Thread endete ziemlich fruchtlos im Sande, d.h. es der dort beschriebene Effekt ist weiterhin ungeklärt. Zudem bezog er sich auf ARM. Daraus zu schliessen, dass es sich hier um das gleiche Problem handelt erscheint mir ziemlich gewagt. Vermutete Compilerfehler glaube ich üblicherweise erst wenn ich den im erzeugten Code sehen kann.
Ja okay den habe ich nun dummerweise vergessen. Ich nutze den Mega644A @ 16MHz BOOTSZ @ 4096W_7000 BOOTRST enabled
Welchen Parameter sollte ich setzen um das GCC Listing (C-Code/Assembler) sehen zu können?
sry bin noch nicht so lange dabei, was meinst du damit? Was meinst du mit erzeugeten Code sehen? Das .LSS file?
Markus Müller schrieb: > Welchen Parameter sollte ich setzen um das GCC Listing > (C-Code/Assembler) sehen zu können? Beispielsweise kannst du mit -S den Assemberquellcode erzeugen, an Stelle des Objektfiles. Du kannst auch mit objdump das ELF/... File disassemblieren.
Andre Iwers schrieb: > Was meinst du mit erzeugeten Code sehen? Das .LSS file? Ja. Wobei ich damit aber Markus und sein Problem gemeint hatte.
Wer sucht, der Findet...
1 | -Wa,-ahlms=$(addprefix $(OBJDIR), $(<:.c=.lst)) |
als Parameter dem GCC mit übergeben, dann macht der die Datei. Ich muss erst noch testen, dass ich das Problem von damals wieder "reinprogrammiere".
Aber mach damit im alten Thread weiter, hier gehört das nicht rein.
Stimmt, das -S geht auch. Ich hatte -s eingegeben, dann ging es nicht.
(Die lst-Datei hat über 100000 Zeilen)
> alter Thread...
Ja, mach ich.
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.