- 12V Akku mit 280 Ah bauen         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: kriege Pointer auf String im Flash nicht übergeben...

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2006
    Ort
    Stuttgart
    Alter
    47
    Beiträge
    8

    kriege Pointer auf String im Flash nicht übergeben...

    Anzeige

    E-Bike
    Hi!

    Ich bin grad dabei meine LCD-lib etwas aufzumöbeln und kriege einen Pointer auf einen String im Flash im zusammenspiel mit einer variablen Argumentenliste nicht übergeben.

    Das Funktioniert einwandfrei:
    Code:
    void lcd_test_p(uint8_t x, uint8_t y, PGM_P test) {
    	char temp[LCD_WIDTH];
    	sprintf_P(temp,test);
    	lcd_gotoxy(x,y);
    	lcd_write(temp);
    }
    das allerdings garnicht (crashed mein Programm):
    Code:
    void lcd_printf_xy_p(uint8_t x, uint8_t y, PGM_P fmt, ...) {
    	char temp[LCD_WIDTH];
    	va_list argp;
    	va_start(argp, fmt);
    	vsprintf_P(temp, fmt, argp);
    	va_end(argp);
    	lcd_gotoxy(x, y);
    	lcd_write(temp);
    }
    hab probiert die argumente zu vertauschen (erst das PGM_P fmt, dann x und y, dann die variable Argumentenliste) aber das hat garnix gebracht.

    aufgerufen hab ich die funktionen so:
    Code:
    lcd_test_p(0,0,PSTR("Test")); /* funktioniert */
    lcd_printf_xy_p(0,0,PSTR("Test"));  /* funktioniert nicht */
    lcd_printf_xy_p(0,0,PSTR("test %i"),1); /* funktioniert nicht */
    wie kriegt man das gelöst?

    grüße,
    Basti

  2. #2
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Kann man so schlecht sagen. Schau mal in den erzeugten Assembler, dann gibt's vielleicht ein Aha-Erlebnis. Wahrscheinlich fehlt eine Indirektonirgendwo oder ein Cast stimmt nicht
    Disclaimer: none. Sue me.

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    21.10.2005
    Ort
    Erde
    Alter
    57
    Beiträge
    1.195
    Schau Dir mal die Makros für PGM_P va_start() und va_arg an. Ich vermute mal, da geht irgend etwas bei der Makrop-Expansion schief.

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Soweit ich sehen kann ist ok, was da raus kommt. Die Offsets stimmen (LCD_WIDTH=16).

    Kann es sein, daß das Problem ganz woanders ist, daß dir RAM oder Flash ausgeht? Oder Arrays nicht groß genug sind?

    *.i:
    Code:
    void lcd_printf_xy_p(uint8_t x, uint8_t y, const prog_char * fmt, ...) {
       char temp[16];
       va_list argp;
       __builtin_va_start(argp,fmt);
       vsprintf_P(temp, fmt, argp);
       __builtin_va_end(argp);
       lcd_gotoxy(x, y);
       lcd_write(temp);
    }
    
    void foo(int val)
    {
     lcd_printf_xy_p(1, 2, ({static char __c[] __attribute__((__progmem__)) = ("Hallo %d"); __c;}), val);
    }
    *.s:
    Code:
    .global	lcd_printf_xy_p
    	.type	lcd_printf_xy_p, @function
    lcd_printf_xy_p:
    /* prologue: frame size=16 */
    	push r16
    	push r17
    	push r28
    	push r29
    	in r28,__SP_L__
    	in r29,__SP_H__
    	sbiw r28,16
    	in __tmp_reg__,__SREG__
    	cli
    	out __SP_H__,r29
    	out __SREG__,__tmp_reg__
    	out __SP_L__,r28
    /* prologue end (size=12) */
    	ldd r16,Y+23	 ;  x, x	 ;  3	*movqi/4	[length = 1]
    	ldd r17,Y+24	 ;  y, y	 ;  4	*movqi/4	[length = 1]
    	ldd r24,Y+25	 ;  fmt, fmt	 ;  5	*movhi/2	[length = 2]
    	ldd r25,Y+26	 ;  fmt, fmt
    	movw r20,r28	 ;  argp,	 ;  37	*movhi/1	[length = 1]
    	subi r20,lo8(-(27))	 ;  argp,	 ;  16	*addhi3/4	[length = 2]
    	sbci r21,hi8(-(27))	 ;  argp,
    	movw r22,r24	 ;  fmt, fmt	 ;  17	*movhi/1	[length = 1]
    	movw r24,r28	 ; ,	 ;  38	*movhi/1	[length = 1]
    	adiw r24,1	 ; ,	 ;  18	*addhi3/2	[length = 1]
    	rcall vsprintf_P	 ; 	 ;  19	call_value_insn/3	[length = 1]
    	mov r24,r17	 ;  y, y	 ;  22	zero_extendqihi2/2	[length = 2]
    	clr r25	 ;  y
    	movw r22,r24	 ;  y, y	 ;  24	*movhi/1	[length = 1]
    	mov r24,r16	 ;  x, x	 ;  25	zero_extendqihi2/2	[length = 2]
    	clr r25	 ;  x
    	rcall lcd_gotoxy	 ; 	 ;  26	call_value_insn/3	[length = 1]
    	movw r24,r28	 ; ,	 ;  39	*movhi/1	[length = 1]
    	adiw r24,1	 ; ,	 ;  28	*addhi3/2	[length = 1]
    	rcall lcd_write	 ; 	 ;  29	call_value_insn/3	[length = 1]
    /* epilogue: frame size=16 */
    	adiw r28,16
    	in __tmp_reg__,__SREG__
    	cli
    	out __SP_H__,r29
    	out __SREG__,__tmp_reg__
    	out __SP_L__,r28
    	pop r29
    	pop r28
    	pop r17
    	pop r16
    	ret
    /* epilogue end (size=11) */
    /* function lcd_printf_xy_p size 43 (20) */
    	.size	lcd_printf_xy_p, .-lcd_printf_xy_p
    	.section	.progmem.data
    	.type	__c.0, @object
    	.size	__c.0, 9
    __c.0:
    	.string	"Hallo %d"
    	.text
    .global	foo
    	.type	foo, @function
    foo:
    /* prologue: frame size=0 */
    /* prologue end (size=0) */
    	push r25	 ;  val	 ;  12	*pushhi/1	[length = 2]
    	push r24	 ;  val
    	ldi r24,lo8(__c.0)	 ;  tmp42,	 ;  13	*movhi/4	[length = 2]
    	ldi r25,hi8(__c.0)	 ;  tmp42,
    	push r25	 ;  tmp42	 ;  14	*pushhi/1	[length = 2]
    	push r24	 ;  tmp42
    	ldi r24,lo8(2)	 ;  tmp43,	 ;  15	*movqi/2	[length = 1]
    	push r24	 ;  tmp43	 ;  16	*pushqi/1	[length = 1]
    	ldi r24,lo8(1)	 ;  tmp44,	 ;  17	*movqi/2	[length = 1]
    	push r24	 ;  tmp44	 ;  18	*pushqi/1	[length = 1]
    	rcall lcd_printf_xy_p	 ; 	 ;  19	call_insn/3	[length = 1]
    	in r24,__SP_L__	 ; 	 ;  28	*movhi/7	[length = 2]
    	in r25,__SP_H__	 ; 
    	adiw r24,6	 ; ,	 ;  21	*addhi3/2	[length = 1]
    	in __tmp_reg__,__SREG__	 ;  29	*movhi/6	[length = 5]
    	cli
    	out __SP_H__,r25	 ; 
    	out __SREG__,__tmp_reg__
    	out __SP_L__,r24	 ; 
    /* epilogue: frame size=0 */
    	ret
    Disclaimer: none. Sue me.

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2006
    Ort
    Stuttgart
    Alter
    47
    Beiträge
    8
    Danke für die Antworten erstmal!
    ...leider übersteigen sie mein derzeitigen Horizont etwas...

    Hab noch nie was mit AVR-Assembler gemacht und kannte C bis vor kurzem auch nur von anderen Plattformen...

    Kann es sein, daß das Problem ganz woanders ist, daß dir RAM oder Flash ausgeht? Oder Arrays nicht groß genug sind?
    Ich glaube nicht, hab das Programm eben darauf reduziert das LCD zu initialisieren und einmal die lcd_prinft_xy_p() aufzurufen, der Compiler meldet dabei 59% Flash belegt und 55% Ram belegt.

    Dann eine Frage, Du hast hier ein *.i gepastet, scheint wohl das C-File zu sein nachdem der Preprozessor die Makros expandiert hat. Beim compilieren entsteht bei mir aber kein *.i File, wie kommt man da ran?

    Hab grad mal das Quellcode-Stück mit den expandierten Makros von Dir verwendet, macht kein unterschied. D.h. dann dass es nicht an der Expansion der Makros liegt, oder?

    Das *.s scheint wohl der erzeugte Assembler zu sein, etwas ähnliches befindet sich bei mir in main.lss. Sieht ziemlich gleich aus wie das was Du gepastet hast, nur ohne Kommentare. Leider versteh ich fast nur Bahnhof wenn ich da reinschau...

    Heisst das nun: wenn ich diesen Fehler finden und beheben will komm ich nicht drum rum mich in AVR-Assembler einzuarbeiten?

    Gruß,
    Basti

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    avr-gcc erzeugt das precompile (*.i) und den Assembler (*.s) nur temporär und löscht diese Dateien wieder. Mit der Option -save-temps bleiben die Dateien erhalten.

    An den Makros schein's nicht zu liegen.
    Und der Assembler schaut auch ganz ok aus. Einfacher durchzusteigen ist vielleicht mit einem Debugger (auf asm-Ebene) durchzusteppen und zu schauen, ob die Adressen stimmen.

    Die Speicher-Verbrauche kommen mir recht hoch vor, nur für LCD Ausgabe. Andererseits sind die *printf* als Speicherfresser bekannt...

    Zur Compile-Zeit (bzw Link-Zeit) kann nur der statische Speicherplatzbedarf bestimmt werden. Da kommt noch hinzu, was der Compiler nicht sehen kann, also Platz für die Frames von Funktionen, Funktionsaufrufe und dynamischer Speicher via malloc, etc

    Assembler zu können ist nicht notwendig, aber manche Fehler lassen sich fix finden, wenn man nen Blick ins asm wirft und es einem wie Schuppen von den Augen fällt...
    Disclaimer: none. Sue me.

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2006
    Ort
    Stuttgart
    Alter
    47
    Beiträge
    8
    irgendwie krieg ich das mit den save-temps nicht hin. Hab folgende Zeile in mein Makefile geschrieben:
    CFLAGS += -save-temps
    hab die Zeile nach CFLAGS += -O$(OPT) eingefügt...
    aber ich kann keine .i und .s dateien finden... was mach ich falsch?

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Die Dateien müssten im gleichen Verzeichnis auftauchen wie deine Objekte (*.o). Mit -save-temps bleiebn die Dateien erhalten wie von GCC erzeugt. Man kann auch Optionen mit -Wa,-adhlns=<Dateiname> an den Assembler (avr-as) weiterleiten, so daß er ein Listing schreibt. Zusammen mit -g hat man dann ein Mix aus asm und C-Quelle, wenn man das mag. Bei -save-temps kann man aber noch optionen angeben und sieht besser, aus welchen internen Operationen (INSNS) GCC den Assembler baut.

    Ich vermute mal, du hast das Makefile nicht selber geschrieben und es sieht nicht gerade gut durchdringbar aus... Eigentlich sollte es gehen. Ich verwende allerdings 2 Compileläufe, einen mit -c bis zum Object und einen mit -dp -S -save-temps -fverbose-asm für *.s und *.i.

    Das *.lss oder *.lst ist kein Assembler-Listing, sondern ein Disassemble aus dem Object (*.o oder *.elf) und ebthält kaum noch Symbolinfos. Zusammen mit -g kann man aber auch mit C-Quelle mischen.

    Kannst du irgendwie eingrenzen, was bei deinem Beispiel nicht funktioniert?
    Disclaimer: none. Sue me.

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Das Beispiel von oben hab ich mal durchdebuggt. Es geht so, wie man sich das vorstellt. Die Funktionen werden richtig aufgerufen, Stack richtig aufgebaut/abgebaut und Argumente korrekt übergeben.
    Der String steht danach dort, wo er soll, und das Programm kehrt friedlich zurück nach main.

    Das lcd_gotoxy und lcd_write hab ich rausgeworfen (hab ich net).

    Also ist der Fehler dort, oder der Wurm ist wirklich beim Speicherverbrauch oder im Rest deines Programms.

    Das kleine Progrämmchen (nur main, foo, lcd_printf_xy_p und die Lib-Funcs) brauchen mit -O2 schon über 0x700 (Dez ca. 1800) Bytes an Flash!!!
    vsprintf scheint ca 60 Bytes an SRAM zu brauchen.

    Check mal durch, ob das wirklich alles reinpasst bei dir.
    Disclaimer: none. Sue me.

  10. #10
    Neuer Benutzer Öfters hier
    Registriert seit
    01.03.2006
    Ort
    Stuttgart
    Alter
    47
    Beiträge
    8
    Vielen Dank für deine Mühe SprinterSB,
    der Fehler war wie Du sagtest woanders im Programm, es lag einfach an meiner Dummheit... Der Compiler hatts mir immer gesagt, aber ich hab unter lauter "enumartion not handled in switch" warnings übersehen dass ich die lcd_printf_xy_p selbst nicht richtig deklariert hab. Habs erst dann bemerkt als ich nochmal nen leeres Projekt benutzt hab um die lcd lib zu testen...
    "thy shall not ignore compiler warnings..." nochmal passiert mir das nicht... *schäm*

    Das mit dem Speicherbedarf is echt bissle heftig, is mir auch erst so richtig aufgefallen als Du mich mal drauf hingewiesen hast... Hab mal diese compiler-switches probiert um mit der abgespeckten Printf Version bissle Flash zu sparen, aber das lohnt ja kaum und ich brauch die Formatierung mit vorangestellter Null... Ich überleg mal ob ich um diese printf geschichte rumkomm, aber das ist halt so schön komfortabel...

    Danke nochma,
    Basti

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

12V Akku bauen