Forum: Compiler & IDEs AVR: sscanf() liest keine float


von Matthias (Gast)


Lesenswert?

Hallo zusammen,

ich habe ein Problem mit dem Lesen eine float-Zahl aus einem String. Es 
wird immer der Wert 0 gelesen.
Ich nutze AVR Studio 6.2.1153, mit einem ATMEGA2560 und dem JTAGICE 
mkII. Als lib habe ich libm, libscanf_flt und libprintf_flt eingebunden.
Der Schalter "Use vprintf library" unter AVR/GNU Linker ist gesetzt.

Hier ist mein code:

#include <stdio.h>
#include <string.h>
int main(void)
{
  int i;
  float f;
  const char in[] = "100 1.123";
  sscanf( in, "%d %f", &i, &f);

...

f ist immer 0!

PS: Der Code funktioniert auf meinem PC einwanfrei (MS Visual Studio).

Ich vermute, das Problem liegt irgendwo in den Compilereinstellungen od. 
Bibliotheken, kann aber im Netz keinen Hinweis finden.

Kann mir jemand bitte einen Tipp geben, wie dieses Problem gelöst werden 
kann?

MFG

Matthias

von Oliver S. (oliverso)


Lesenswert?

Zeig doch mal den kompletten Compiler- und Linkeraufruf.

Oliver

von Udo S. (urschmitt)


Lesenswert?

sprintf und sscanf sind Riesenfunktionen. Oft ist es performanter (und 
spart im µC ggf. auch flash Speicher) statt dessen atoi und atof zu 
benutzen.
Hast du das mal versucht?

von Zurtog (Gast)


Lesenswert?

Suche hier im Forum, wie man die entsprechende Lib linkt, denn von Haus 
aus gibt es keine Unterstützung von float.

von Matthias (Gast)


Lesenswert?

Hallo zusammen,
Danke für die Antworten:

@Oliver: Hier mein Compiler/Linkeraufruf
1
------ Rebuild All started: Project: test, Configuration: Debug AVR ------
2
Build started.
3
Project "test.cproj" (Clean target(s)):
4
Target "Clean" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Compiler.targets" from project "C:\Users\m.geisler\Documents\Atmel Studio\6.2\test\test\test.cproj" (entry point):
5
  Task "RunCompilerTask"
6
    Shell Utils Path C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils
7
    C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils\make.exe clean 
8
    rm -rf  test.o   
9
    rm -rf  test.d   
10
    rm -rf "test.elf" "test.a" "test.hex" "test.lss" "test.eep" "test.map" "test.srec" "test.usersignatures"
11
  Done executing task "RunCompilerTask".
12
Done building target "Clean" in project "test.cproj".
13
Done building project "test.cproj".
14
15
Build succeeded.
16
------ Rebuild All started: Project: test, Configuration: Debug AVR ------
17
Build started.
18
Project "test.cproj" (default targets):
19
Target "PreBuildEvent" skipped, due to false condition; ('$(PreBuildEvent)'!='') was evaluated as (''!='').
20
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Compiler.targets" from project "C:\Users\m.geisler\Documents\Atmel Studio\6.2\test\test\test.cproj" (target "Build" depends on it):
21
  Task "RunCompilerTask"
22
    Shell Utils Path C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils
23
    C:\Program Files (x86)\Atmel\Atmel Studio 6.2\shellUtils\make.exe all 
24
    Building file: .././test.c
25
    Invoking: AVR/GNU C Compiler : 4.8.1
26
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-gcc.exe"  -x c -funsigned-char -funsigned-bitfields -DDEBUG  -O0 -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -mrelax -g2 -Wall -mmcu=atmega2560 -c -std=gnu99 -MD -MP -MF "test.d" -MT"test.d" -MT"test.o"   -o "test.o" ".././test.c" 
27
    Finished building: .././test.c
28
    Building target: test.elf
29
    Invoking: AVR/GNU Linker : 4.8.1
30
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-gcc.exe" -o test.elf  test.o   -Wl,-Map="test.map" -Wl,-u,vfprintf -Wl,--start-group -Wl,-lm -Wl,-lc -Wl,-lprintf_flt -Wl,-lscanf_flt  -Wl,--end-group -Wl,--gc-sections -mrelax -mmcu=atmega2560  
31
    Finished building target: test.elf
32
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O ihex -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures  "test.elf" "test.hex"
33
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objcopy.exe" -j .eeprom  --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0  --no-change-warnings -O ihex "test.elf" "test.eep" || exit 0
34
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objdump.exe" -h -S "test.elf" > "test.lss"
35
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-objcopy.exe" -O srec -R .eeprom -R .fuse -R .lock -R .signature -R .user_signatures "test.elf" "test.srec"
36
    "C:\Program Files (x86)\Atmel\Atmel Toolchain\AVR8 GCC\Native\3.4.1056\avr8-gnu-toolchain\bin\avr-size.exe" "test.elf"
37
       text     data      bss      dec      hex  filename
38
       3474       16        8     3498      daa  test.elf
39
  Done executing task "RunCompilerTask".
40
  Task "RunOutputFileVerifyTask"
41
        Program Memory Usage   :  3490 bytes   1,3 % Full
42
        Data Memory Usage     :  24 bytes   0,3 % Full
43
  Done executing task "RunOutputFileVerifyTask".
44
Done building target "CoreBuild" in project "test.cproj".
45
Target "PostBuildEvent" skipped, due to false condition; ('$(PostBuildEvent)' != '') was evaluated as ('' != '').
46
Target "Build" in file "C:\Program Files (x86)\Atmel\Atmel Studio 6.2\Vs\Avr.common.targets" from project "C:\Users\m.geisler\Documents\Atmel Studio\6.2\test\test\test.cproj" (entry point):
47
Done building target "Build" in project "test.cproj".
48
Done building project "test.cproj".
49
50
Build succeeded.
51
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========

@Udo: atoi funktioniert, atof ebenfalls nicht.

@Zurtog: ich habe die libs wie oben gelinkt! Ich weiß nicht, welche 
fehlt.

@ALLE: Mittlerweile habe ich eine eigene Funktion geschrieben (als 
Workaround, spielt auch), es würde mich trotzdem interessieren, woran es 
hängt!!

von Oliver S. (oliverso)


Lesenswert?

Laut avrlibc-Doku sollte das so aussehen:

> -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt

Oliver

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Oliver S. schrieb:
> Laut avrlibc-Doku sollte das so aussehen:
>
>> -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt
>
> Oliver

Zum Teil steht das oben da.

Was aber noch fehlt, ist das erzwingen einer Referenz auf vfscanf:
1
-Wl,-u,vfscanf

Was passiert, ist folgendes:

Der Linker beginnt seinen Job.  An der Stelle, an der die
Bibliothek libscanf_flt.a abgearbeitet wird (-lscanf_flt), stellt er
fest, dass er den Inhalt dieser Bibliothek nicht zum Auflösen einer
unbekannten Referenz benutzen kann, denn darin befindet sich lediglich
das Symbol “vfscanf”, und nach dem hatte bislang noch keiner gefragt.

Wenn er dann später die Standardbibliothek verarbeitet (libc.a), löst
er das bislang unbekannte Symbol “fscanf” (durch den Nutzercode
referenziert gewesen) aus dieser auf.  Dabei stellt er nun fest, dass
er jetzt ein “vfscanf” in der Folge benötigt.  Allerdings ist die
Verarbeitung der libscanf_flt.a jetzt bereits Geschichte, daher
entnimmt er den Code für “vfscanf” nun in der Standardform ebenfalls
der libc.a.

Indem man nun vor der Verarbeitung der libscanf_flt.a eine Referenz
auf “vfscanf” erzeugt (Linker-Option -u), dann wird nachfolgend der
Modul tatsächlich aus dieser Bibliothek entnommen.  Wenn dann später
“fscanf” (aus der Standardbibliothek) auf dieses Symbol zugreifen
will, ist es nun bereits vorhanden, mit der korrekten Version.

Aus heutiger Sicht würde ich die Bibliothek vfscanf_flt.a wohl anders
bauen, das ist eher ein historisches Versehen so.

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.