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
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?
Suche hier im Forum, wie man die entsprechende Lib linkt, denn von Haus aus gibt es keine Unterstützung von float.
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!!
Laut avrlibc-Doku sollte das so aussehen:
> -Wl,-u,vfprintf -lprintf_flt -Wl,-u,vfscanf -lscanf_flt
Oliver
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.