Du hast aus versehen den Source Code statt dem Compilerout hingeschrieben.
Hi,
habe jetzt einen RP6 und habe gleich mal ein kleines Testprogramm geschrieben, das aber nicht läuft.
Hier mein Source-Code:
Und hier der Compiler-Output:Code:#include "RP6RobotBaseLib.h" int main(void) { initRobotBase(); powerON(); char receiveBuffer[5]; receiveBytes(5); waitUntilReceptionComplete(); copyReceivedBytesToBuffer(&receiveBuffer[0]); if(receiveBuffer == "Hello") { writeString_P("Hi!\n"); } }
Code:> "C:\RP6Examples\RP6BASE_EXAMPLES\Test\\make_all.bat" C:\RP6Examples\RP6BASE_EXAMPLES\Test>set LANG=C C:\RP6Examples\RP6BASE_EXAMPLES\Test>make all -------- begin -------- avr-gcc (GCC) 4.1.2 (WinAVR 20070525) Copyright (C) 2006 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. Compiling: Test.c avr-gcc -c -mmcu=atmega32 -I. -gdwarf-2 -DDEBUG_MEASURE_DUTY_CYCLE -O -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=Test.lst -I../../RP6lib -I../../RP6lib/RP6base -I../../RP6lib/RP6common -std=gnu99 -MD -MP -MF .dep/Test.o.d Test.c -o Test.o Linking: Test.elf avr-gcc -mmcu=atmega32 -I. -gdwarf-2 -DDEBUG_MEASURE_DUTY_CYCLE -O -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=Test.o -I../../RP6lib -I../../RP6lib/RP6base -I../../RP6lib/RP6common -std=gnu99 -MD -MP -MF .dep/Test.elf.d Test.o --output Test.elf -Wl,-Map=Test.map,--cref -lm Test.o: In function `main': C:\RP6Examples\RP6BASE_EXAMPLES\Test/Test.c:5: undefined reference to `initRobotBase' C:\RP6Examples\RP6BASE_EXAMPLES\Test/Test.c:8: undefined reference to `receiveBytes' C:\RP6Examples\RP6BASE_EXAMPLES\Test/Test.c:9: undefined reference to `waitUntilReceptionComplete' C:\RP6Examples\RP6BASE_EXAMPLES\Test/Test.c:10: undefined reference to `copyReceivedBytesToBuffer' C:\RP6Examples\RP6BASE_EXAMPLES\Test/Test.c:13: undefined reference to `writeNStringP' make: *** [Test.elf] Error 1 > Process Exit Code: 2 > Time Taken: 00:03Ist editiert, danke für den Hinweis.Zitat von Luki.B.
Du hast aus versehen den Source Code statt dem Compilerout hingeschrieben.
Ist in diesem Fall aber auch egal
Das oben kann schon deswegen nicht so wie gedacht funktionieren, weil da überhaupt keine Endlosschleife im Code drin ist (s. Anleitung und Beispiele ).
Weiterhin kannst Du keine Zeichenkette mit einer einfachen Bedingung wie "if(receiveBuffer == "Hello") " vergleichen.
Das geht nur mit einzelnen Zeichen direkt.
Eine Zeichenkette ist ein ARRAY mit Bytes (also quasi ein ganzer Haufen von Variablen) - Du kannst kein Array mit einem Array über "==" vergleichen - jedes Element muss einzeln mit dem entsprechenden anderen Element verglichen werden.
Musst schon Funktionen wie strcmp verwenden (oder selbst duch das Array laufen... ).
So in etwa:
if(strcmp(receiveBuffer,"Hello")==0)
// mach was...
Hoffe das hilft Dir weiter, frag ruhig wenn noch was unklar ist.
MfG,
SlyD
Der Source-Code sieht jetzt so aus:
Der Compiler-Output ist immernoch derselbe.Code:#include "RP6RobotBaseLib.h" int main(void) { initRobotBase(); powerON(); char receiveBuffer[5]; while(true) { receiveBytes(5); waitUntilReceptionComplete(); copyReceivedBytesToBuffer(&receiveBuffer[0]); if(strcmp(receiveBuffer,"Hello")==0) { writeString_P("Hi!\n"); } } }
btw: Wofür genau ist eigentlich die Endlosschleife gut? Ohne müsste das Programm doch normalerweisse auch laufen(Würde zwar nach einem Durchlauf abbrechen, aber laufen müsste es doch, oder?)
Ja eigentlich sollte es auch ohne laufen - aber der Programmzähler des Mikrocontrollers könnte dann einfach über den Reset des Programmspeichers laufen... wenn da noch überreste von alten Programmen vorhanden sind, kann sonstwas passieren.
Die Fehlermeldungen vom Compiler deuten darauf hin das in Deinem Makefile was nicht richtig ist oder Du die Ordnerstruktur nicht so aufgebaut hast wie bei den Beispielprogrammen (die Relativposition der RP6Lib muss stimmen, sonst findet die der Compiler nicht (oder man passt das entsprechend im Makefile an) - zwei Verzeichnisebenen höher... )
Hier mal ein Beispiel:
http://www.arexx.com/rp6/downloads/R...t_template.zip
(die Lib die hier dabei ist eine ALTE 2007er Version... die nicht mehr verwenden - muss ich mal updaten das Beispiel.)
MfG,
SlyD
Also die Verzeichnisstruktur sieht bei mir so aus:
Das Makefile sieht so aus:Code:C:\RP6Examples\ -RP6BASE_EXAMPLES -Test -Test.c -makefile -make_all.bat -make_clean.bat -RP6CONTROL_EXAMPLES -RP6Lib
Code:TARGET = Test RP6_LIB_PATH=../../RP6lib RP6_LIB_PATH_OTHERS= $(RP6_LIB_PATH)/RP6base $(RP6_LIB_PATH)/RP6common SRC = $(TARGET).c MCU = atmega32 FORMAT = ihex ASRC= DEBUG =dwarf-2 EXTRAINCDIRS = $(RP6_LIB_PATH) $(RP6_LIB_PATH_OTHERS) CSTANDARD = -std=gnu99 CDEFS = -DDEBUG_MEASURE_DUTY_CYCLE CINCS = CFLAGS = -g$(DEBUG) CFLAGS += $(CDEFS) $(CINCS) CFLAGS += -O$(OPT) CFLAGS += -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums CFLAGS += -Wall -Wstrict-prototypes CFLAGS += -Wa,-adhlns=$(<:.c=.lst) CFLAGS += $(patsubst %,-I%,$(EXTRAINCDIRS)) CFLAGS += $(CSTANDARD) PRINTF_LIB_MIN = -Wl,-u,vfprintf -lprintf_min PRINTF_LIB_FLOAT = -Wl,-u,vfprintf -lprintf_flt PRINTF_LIB = SCANF_LIB_MIN = -Wl,-u,vfscanf -lscanf_min SCANF_LIB_FLOAT = -Wl,-u,vfscanf -lscanf_flt SCANF_LIB = MATH_LIB = -lm EXTMEMOPTS = LDFLAGS = -Wl,-Map=$(TARGET).map,--cref LDFLAGS += $(EXTMEMOPTS) LDFLAGS += $(PRINTF_LIB) $(SCANF_LIB) $(MATH_LIB) AVRDUDE_PROGRAMMER = stk500 AVRDUDE_PORT = com1 # Programmer connected to serial device AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex AVRDUDE_FLAGS = -p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) AVRDUDE_FLAGS += $(AVRDUDE_NO_VERIFY) AVRDUDE_FLAGS += $(AVRDUDE_VERBOSE) AVRDUDE_FLAGS += $(AVRDUDE_ERASE_COUNTER) DEBUG_MFREQ = $(F_CPU) DEBUG_UI = insight DEBUG_BACKEND = avarice GDBINIT_FILE = __avr_gdbinit JTAG_DEV = /dev/com1 DEBUG_PORT = 4242 DEBUG_HOST = localhost SHELL = sh CC = avr-gcc OBJCOPY = avr-objcopy OBJDUMP = avr-objdump SIZE = avr-size NM = avr-nm AVRDUDE = avrdude REMOVE = rm -f REMOVEDIR = rmdir COPY = cp WINSHELL = cmd MSG_ERRORS_NONE = Errors: none MSG_BEGIN = -------- begin -------- MSG_END = -------- end -------- MSG_SIZE_BEFORE = Size before: MSG_SIZE_AFTER = Size after: MSG_COFF = Converting to AVR COFF: MSG_EXTENDED_COFF = Converting to AVR Extended COFF: MSG_FLASH = Creating load file for Flash: MSG_EEPROM = Creating load file for EEPROM: MSG_EXTENDED_LISTING = Creating Extended Listing: MSG_SYMBOL_TABLE = Creating Symbol Table: MSG_LINKING = Linking: MSG_COMPILING = Compiling: MSG_ASSEMBLING = Assembling: MSG_CLEANING = Cleaning project: OBJ = $(SRC:.c=.o) $(ASRC:.S=.o) LST = $(SRC:.c=.lst) $(ASRC:.S=.lst) GENDEPFLAGS = -MD -MP -MF .dep/$(@F).d ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS) $(GENDEPFLAGS) ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS) all: begin gccversion sizebefore build sizeafter end build: elf hex eep lss sym elf: $(TARGET).elf hex: $(TARGET).hex eep: $(TARGET).eep lss: $(TARGET).lss sym: $(TARGET).sym begin: @echo @echo $(MSG_BEGIN) end: @echo $(MSG_END) @echo HEXSIZE = $(SIZE) --target=$(FORMAT) $(TARGET).hex ELFSIZE = $(SIZE) --format=avr --mcu=$(MCU) $(TARGET).elf sizebefore: @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_BEFORE); $(ELFSIZE); \ 2>/dev/null; echo; fi sizeafter: @if test -f $(TARGET).elf; then echo; echo $(MSG_SIZE_AFTER); $(ELFSIZE); \ 2>/dev/null; echo; fi gccversion : @$(CC) --version program: $(TARGET).hex $(TARGET).eep $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH) $(AVRDUDE_WRITE_EEPROM) gdb-config: @$(REMOVE) $(GDBINIT_FILE) @echo define reset >> $(GDBINIT_FILE) @echo SIGNAL SIGHUP >> $(GDBINIT_FILE) @echo end >> $(GDBINIT_FILE) @echo file $(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 $(TARGET).elf ifeq ($(DEBUG_BACKEND), avarice) @echo Starting AVaRICE - Press enter when "waiting to connect" message displays. @$(WINSHELL) /c start avarice --jtag $(JTAG_DEV) --erase --program --file \ $(TARGET).elf $(DEBUG_HOST):$(DEBUG_PORT) @$(WINSHELL) /c pause else @$(WINSHELL) /c start simulavr --gdbserver --device $(MCU) --clock-freq \ $(DEBUG_MFREQ) --port $(DEBUG_PORT) endif @$(WINSHELL) /c start avr-$(DEBUG_UI) --command=$(GDBINIT_FILE) COFFCONVERT=$(OBJCOPY) --debugging \ --change-section-address .data-0x800000 \ --change-section-address .bss-0x800000 \ --change-section-address .noinit-0x800000 \ --change-section-address .eeprom-0x810000 coff: $(TARGET).elf @echo @echo $(MSG_COFF) $(TARGET).cof $(COFFCONVERT) -O coff-avr $< $(TARGET).cof extcoff: $(TARGET).elf @echo @echo $(MSG_EXTENDED_COFF) $(TARGET).cof $(COFFCONVERT) -O coff-ext-avr $< $(TARGET).cof %.hex: %.elf @echo @echo $(MSG_FLASH) $@ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@ %.eep: %.elf @echo @echo $(MSG_EEPROM) $@ -$(OBJCOPY) -j .eeprom --set-section-flags .eeprom=alloc,load \ --change-section-lma .eeprom=0 --no-change-warnings -O $(FORMAT) $< $@ || exit 0 %.lss: %.elf @echo @echo $(MSG_EXTENDED_LISTING) $@ $(OBJDUMP) -h -S $< > $@ %.sym: %.elf @echo @echo $(MSG_SYMBOL_TABLE) $@ $(NM) -n $< > $@ .SECONDARY : $(TARGET).elf .PRECIOUS : $(OBJ) %.elf: $(OBJ) @echo @echo $(MSG_LINKING) $@ $(CC) $(ALL_CFLAGS) $^ --output $@ $(LDFLAGS) %.o : %.c @echo @echo $(MSG_COMPILING) $< $(CC) -c $(ALL_CFLAGS) $< -o $@ %.s : %.c $(CC) -S $(ALL_CFLAGS) $< -o $@ %.o : %.S @echo @echo $(MSG_ASSEMBLING) $< $(CC) -c $(ALL_ASFLAGS) $< -o $@ %.i : %.c $(CC) -E -mmcu=$(MCU) -I. $(CFLAGS) $< -o $@ clean: begin clean_list end clean_list : @echo @echo $(MSG_CLEANING) include $(shell mkdir .dep 2>/dev/null) $(wildcard .dep/*) .PHONY : all begin finish end sizebefore sizeafter gccversion \ build elf hex eep lss sym coff extcoff \ clean clean_list program debug gdb-config
Automatisch generiert?
Nunja. In dem obigen Makefile hast Du bei src die C Dateien der RP6Lib nicht eingetragen. Den Rest hab ich mir nicht mehr angeschaut.
Nimm am besten das aus dem oben verlinkten Zip Archiv und ändere da einfach den Namen von deinem Programm. Der Rest passt dann schon sofort.
MfG,
SlyD
Hat funktioniert, Danke!Zitat von SlyD
Habe noch ein kleines Problem.
Wenn ich folgendes Programm kompiliere, auf den Roboter lade und starte:
wird erstmal "Programm gestartet!" ausgegeben.Code:#include "RP6RobotBaseLib.h" int main(void) { initRobotBase(); powerON(); char receiveBuffer[5]; while(true) { writeString_P("Programm gestartet!\n"); receiveBytes(5); waitUntilReceptionComplete(); copyReceivedBytesToBuffer(&receiveBuffer[0]); if(strcmp(receiveBuffer,"Hello")==0) { writeString_P("Hi!\n"); } } }
Wenn ich allerdings "Hello" eingebe, gibt der Roboter nichts aus, er sollte aber "Hi!" ausgeben.
Hallo 9999,
die beste Art, eigene Programme für den RP6 zu schreiben ist, erst mal die Demos zu ändern mit eigenen Ideen.
In der Demo "Example_02_UART_02" wird z.B. gezeigt, wie man eine Benutzereingabe machen kann und Text als Antwort ausgibt.
Gruß Dirk
Lesezeichen