From a17a750317f7ef52fcafbb5d70a8cc806d9e7f82 Mon Sep 17 00:00:00 2001 From: Stephan Veigl Date: Fri, 30 Nov 2012 13:31:54 +0100 Subject: [PATCH] mingw: make simavr compilable with MinGW - patch makefiles to work with MinGW - compile to run_avr.exe on windows, otherwise run_avr cannot be started from the normal windows command prompt - add sim_network.h to encapsulate the network functions of different platforms (use winsock2 for Windows network functions) - make network helper functions static - force open() to use binary mode (on Windows default is text mode) - do not change stderr on Windows - exclude simduino example on Windows - add MinGW README Signed-off-by: Stephan Veigl --- Makefile.common | 14 ++++++ README.mingw | 78 ++++++++++++++++++++++++++++++++++ examples/Makefile | 5 +++ examples/Makefile.opengl | 4 ++ examples/parts/uart_pty.c | 2 +- examples/parts/uart_udp.c | 5 --- examples/parts/uart_udp.h | 2 +- simavr/.gitignore | 1 + simavr/Makefile | 6 ++- simavr/sim/sim_elf.c | 14 ++++-- simavr/sim/sim_gdb.c | 17 +++++--- simavr/sim/sim_network.h | 89 +++++++++++++++++++++++++++++++++++++++ simavr/sim/sim_vcd_file.c | 3 +- tests/tests.c | 27 +++++++----- 14 files changed, 237 insertions(+), 30 deletions(-) create mode 100644 README.mingw create mode 100644 simavr/sim/sim_network.h diff --git a/Makefile.common b/Makefile.common index 813901f..205ef6b 100644 --- a/Makefile.common +++ b/Makefile.common @@ -58,8 +58,18 @@ else AVR_ROOT := /usr/lib/avr AVR_INC := ${AVR_ROOT} AVR := avr- +ifeq (${shell uname -o}, Msys) +AVR_ROOT := ${shell echo "${AVR32_HOME}" | tr '\\' '/'} +AVR_INC := ${AVR_ROOT}/avr +AVR := ${AVR_ROOT}/bin/avr- +IPATH += ${PREFIX}/include +CFLAGS += -I${PREFIX}/include +LDFLAGS += -L/lib -L/local/lib +CFLAGS += -DNO_COLOR +else CFLAGS += -fPIC endif +endif CPPFLAGS += --std=gnu99 -Wall CPPFLAGS += ${patsubst %,-I%,${subst :, ,${IPATH}}} @@ -79,6 +89,10 @@ LDFLAGS += -L${LIBDIR} -lsimavr LDFLAGS += -lelf +ifeq (${shell uname -o}, Msys) +LDFLAGS += -lws2_32 +endif + ifeq (${shell uname}, Linux) ifeq ($(RELEASE),1) # allow the shared library to be found in the build directory diff --git a/README.mingw b/README.mingw new file mode 100644 index 0000000..012c2f7 --- /dev/null +++ b/README.mingw @@ -0,0 +1,78 @@ +ENVIRONMENT +=========== + +Microsoft SDK +------------- +Make sure that you have installed the ws2_32.lib, which is part of the Microsoft SDK. + +MinGW +----- +http://www.mingw.org/ +goto Downloads +download and install mingw_get_inst-????? +Select + C Compiler + C++ Compiler + MSYS Basic System + +Set the MINGW_HOME environment variable. +Add %MINGW_HOME%\msys\1.0\bin;%MINGW_HOME%\bin; to your PATH +Open a command shell and make sure that gcc is working: gcc –v + +LibELF +------ +Build and install libelf with mingw, or download the pre-compiled patch and copy it into your mingw root folder. +https://gitorious.org/mingw-libs-for-simavr/mingw-libs-for-simavr/trees/master + +FreeGLUT +-------- +Build and install freeglut with mingw, or download the pre-compiled patch and copy it into your mingw root folder. +https://gitorious.org/mingw-libs-for-simavr/mingw-libs-for-simavr/trees/master + + +WinAVR +----------- +If you have not already, download and install WinAVR. +http://winavr.sourceforge.net/ +(This tutorial assumes you are using WinAVR-20100110.) +Make sure that AVR32_HOME is set correctly and pointing do your WinAVR installation directory. +%AVR32_HOME%\bin\gcc –v +In the output you see that the target is avr, while the target of the host gcc is mingw32. + + +INSTALL simavr +=============== + +get simavr Sources +------------------- +Download the patched simavr sources of the mingw branch from: + https://github.com/the-real-orca/simavr/tree/mingw + and extract the sources to your development directory +- or - clone the GIT repository + https://github.com/the-real-orca/simavr.git + and switch to the mingw branch + + +compile simavr +--------------- + +Open a command window and change to your simavr directory: + make all +- or - + make –r all (this is a bit faster) + +TEST +==== + +make –C tests run_tests + + +INSTALL +======= + +make install DESTDIR=C:\path-to-your-development-directory + +It will create the following sub-directories and put the according simavr files into them. + - bin + - lib + - include diff --git a/examples/Makefile b/examples/Makefile index 3fd6771..65cc893 100644 --- a/examples/Makefile +++ b/examples/Makefile @@ -1,6 +1,11 @@ boards_base=${wildcard board_*} +# Remove simduino until FileMapping is implemented to work around missing mmap in Win32 +ifeq (${shell uname -o}, Msys) +boards=${subst board_usb,,${subst board_simduino,,$(boards_base)}} +else boards=$(boards_base) +endif all: for bi in ${boards}; do $(MAKE) -C $$bi; done diff --git a/examples/Makefile.opengl b/examples/Makefile.opengl index 5d30b80..158be54 100644 --- a/examples/Makefile.opengl +++ b/examples/Makefile.opengl @@ -8,10 +8,14 @@ ifeq (${UNAME}, Linux) CPPFLAGS += ${shell pkg-config --cflags glu} LDFLAGS += ${shell pkg-config --libs glu} -lglut else +ifeq (${shell uname -o}, Msys) +LDFLAGS += -mwindows -lopengl32 -lfreeglut +else CPPFLAGS += ${shell pkg-config --cflags glu glut} -DFREEBSD=1 LDFLAGS += ${shell pkg-config --libs glu glut} endif endif +endif ifeq (${UNAME}, FreeBSD) CPPFLAGS += -DFREEBSD=1 -DNO_ALLOCA=1 diff --git a/examples/parts/uart_pty.c b/examples/parts/uart_pty.c index ff95942..cbdedbc 100644 --- a/examples/parts/uart_pty.c +++ b/examples/parts/uart_pty.c @@ -19,7 +19,7 @@ along with simavr. If not, see . */ -#include +#include "sim_network.h" #include #include #include diff --git a/examples/parts/uart_udp.c b/examples/parts/uart_udp.c index 4a99803..d3ad0db 100644 --- a/examples/parts/uart_udp.c +++ b/examples/parts/uart_udp.c @@ -19,11 +19,6 @@ along with simavr. If not, see . */ -#include -#include -#include -#include -#include #include #include #include diff --git a/examples/parts/uart_udp.h b/examples/parts/uart_udp.h index 10b06fe..ee99505 100644 --- a/examples/parts/uart_udp.h +++ b/examples/parts/uart_udp.h @@ -23,7 +23,7 @@ #ifndef __UART_UDP_H___ #define __UART_UDP_H___ -#include +#include "sim_network.h" #include "sim_irq.h" #include "fifo_declare.h" diff --git a/simavr/.gitignore b/simavr/.gitignore index aba978b..2d16800 100644 --- a/simavr/.gitignore +++ b/simavr/.gitignore @@ -1,2 +1,3 @@ sim_core_decl.h sim_core_config.h +/run_avr.exe diff --git a/simavr/Makefile b/simavr/Makefile index d805820..bfac68f 100644 --- a/simavr/Makefile +++ b/simavr/Makefile @@ -79,10 +79,14 @@ endif ${OBJ}/${target}.elf : ${OBJ}/${target}.o ${target} : ${OBJ}/${target}.elf +ifeq (${shell uname -o}, Msys) + ln -sf $< $@.exe +else ln -sf $< $@ +endif clean: clean-${OBJ} - rm -rf ${target} *.a *.so + rm -rf ${target} *.a *.so *.exe rm -f sim_core_*.h DESTDIR = /usr/local diff --git a/simavr/sim/sim_elf.c b/simavr/sim/sim_elf.c index fee7cb8..90afccf 100644 --- a/simavr/sim/sim_elf.c +++ b/simavr/sim/sim_elf.c @@ -36,6 +36,10 @@ #include "sim_vcd_file.h" #include "avr_eeprom.h" +#ifndef O_BINARY +#define O_BINARY 0 +#endif + void avr_load_firmware(avr_t * avr, elf_firmware_t * firmware) { if (firmware->frequency) @@ -175,7 +179,7 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware) Elf *elf = NULL; /* Our Elf pointer for libelf */ int fd; // File Descriptor - if ((fd = open(file, O_RDONLY)) == -1 || + if ((fd = open(file, O_RDONLY | O_BINARY)) == -1 || (read(fd, &elf_header, sizeof(elf_header))) < sizeof(elf_header)) { printf("could not read %s\n", file); perror(file); @@ -280,16 +284,18 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware) (data_text ? data_text->d_size : 0) + (data_data ? data_data->d_size : 0); firmware->flash = malloc(firmware->flashsize); + + // using unsigned int for output, since there is no AVR with 4GB if (data_text) { // hdump("code", data_text->d_buf, data_text->d_size); memcpy(firmware->flash + offset, data_text->d_buf, data_text->d_size); offset += data_text->d_size; - printf("Loaded %zu .text\n", data_text->d_size); + printf("Loaded %u .text\n", (unsigned int)data_text->d_size); } if (data_data) { // hdump("data", data_data->d_buf, data_data->d_size); memcpy(firmware->flash + offset, data_data->d_buf, data_data->d_size); - printf("Loaded %zu .data\n", data_data->d_size); + printf("Loaded %u .data\n", (unsigned int)data_data->d_size); offset += data_data->d_size; firmware->datasize = data_data->d_size; } @@ -297,7 +303,7 @@ int elf_read_firmware(const char * file, elf_firmware_t * firmware) // hdump("eeprom", data_ee->d_buf, data_ee->d_size); firmware->eeprom = malloc(data_ee->d_size); memcpy(firmware->eeprom, data_ee->d_buf, data_ee->d_size); - printf("Loaded %zu .eeprom\n", data_ee->d_size); + printf("Loaded %u .eeprom\n", (unsigned int)data_ee->d_size); firmware->eesize = data_ee->d_size; } // hdump("flash", avr->flash, offset); diff --git a/simavr/sim/sim_gdb.c b/simavr/sim/sim_gdb.c index faa016f..7ddfb60 100644 --- a/simavr/sim/sim_gdb.c +++ b/simavr/sim/sim_gdb.c @@ -19,17 +19,13 @@ along with simavr. If not, see . */ -#include -#include -#include -#include +#include "sim_network.h" #include #include #include #include #include #include -#include #include #include "sim_avr.h" #include "sim_core.h" // for SET_SREG_FROM, READ_SREG_INTO @@ -536,13 +532,18 @@ int avr_gdb_init(avr_t * avr) avr->gdb = NULL; + if ( network_init() ) { + AVR_LOG(avr, LOG_ERROR, "GDB: Can't initialize network"); + return -1; + } + if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) { AVR_LOG(avr, LOG_ERROR, "GDB: Can't create socket: %s", strerror(errno)); return -1; } - int i = 1; - setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i)); + int optval = 1; + setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); struct sockaddr_in address = { 0 }; address.sin_family = AF_INET; @@ -574,4 +575,6 @@ void avr_deinit_gdb(avr_t * avr) if (avr->gdb->s != -1) close(avr->gdb->s); free(avr->gdb); + + network_release(); } diff --git a/simavr/sim/sim_network.h b/simavr/sim/sim_network.h new file mode 100644 index 0000000..a43e1d8 --- /dev/null +++ b/simavr/sim/sim_network.h @@ -0,0 +1,89 @@ +/* + sim_network.h + + Copyright 2012 Stephan Veigl + + This file is part of simavr. + + simavr is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + simavr is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with simavr. If not, see . + */ + +#ifndef __SIM_NETWORK_H__ +#define __SIM_NETWORK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __MINGW32__ + +// Windows with MinGW + +#include +#include +#include + +#define send(sockfd, buf, len, flags) \ + (ssize_t)send( (sockfd), (const char *)(buf), (len), (flags)) +#define setsockopt(sockfd, level, optname, optval, optlen) \ + setsockopt( (sockfd), (level), (optname), (void *)(optval), (optlen)) +#define recv(sockfd, buf, len, flags) \ + (ssize_t)recv( (sockfd), (char *)(buf), (len), (flags)) +#define sleep(x) Sleep((x)*1000) + +static inline int network_init() +{ + // Windows requires WinSock to be init before use + WSADATA wsaData; + if ( WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) ) + return -1; + + return 0; +} + +static inline void network_release() +{ + // close WinSock + WSACleanup(); +} + +#else + +// native Linux + +#include +#include +#include +#include +#include +#include + +static inline int network_init() +{ + // nothing to do + return 0; +} + +static inline void network_release() +{ + // nothing to do +} + +#endif + +#ifdef __cplusplus +}; +#endif + +#endif /*__SIM_NETWORK_H__*/ diff --git a/simavr/sim/sim_vcd_file.c b/simavr/sim/sim_vcd_file.c index 8d87f87..c6ce06c 100644 --- a/simavr/sim/sim_vcd_file.c +++ b/simavr/sim/sim_vcd_file.c @@ -25,6 +25,7 @@ #include #include #include +#include #include "sim_vcd_file.h" #include "sim_avr.h" #include "sim_time.h" @@ -129,7 +130,7 @@ static void avr_vcd_flush_log(avr_vcd_t * vcd) if (base > oldbase || li == 0) { seen = 0; - fprintf(vcd->output, "#%llu\n", (long long unsigned int)base); + fprintf(vcd->output, "#%" PRIu64 "\n", base); oldbase = base; } seen |= (1 << l->signal->irq.irq); // mark this trace as seen for this timestamp diff --git a/tests/tests.c b/tests/tests.c index d502fde..3b94cab 100644 --- a/tests/tests.c +++ b/tests/tests.c @@ -14,17 +14,28 @@ avr_cycle_count_t tests_cycle_count = 0; int tests_disable_stdout = 1; static char *test_name = "(uninitialized test)"; -static FILE *orig_stderr = NULL; static int finished = 0; +#ifdef __MINGW32__ +#define restore_stderr() {} +#define map_stderr() {} +#else +static FILE *orig_stderr = NULL; +#define restore_stderr() { if (orig_stderr) stderr = orig_stderr; } +#define map_stderr() { if (tests_disable_stdout) { \ + orig_stderr = stderr; \ + fclose(stdout); \ + stderr = stdout; \ + } } +#endif + static void atexit_handler(void) { if (!finished) _fail(NULL, 0, "Test exit without indicating success."); } void tests_success(void) { - if (orig_stderr) - stderr = orig_stderr; + restore_stderr(); fprintf(stderr, "OK: %s\n", test_name); finished = 1; } @@ -96,11 +107,8 @@ static int my_avr_run(avr_t * avr) avr_t *tests_init_avr(const char *elfname) { tests_cycle_count = 0; - if (tests_disable_stdout) { - orig_stderr = stderr; - fclose(stdout); - stderr = stdout; - } + map_stderr(); + elf_firmware_t fw; if (elf_read_firmware(elfname, &fw)) fail("Failed to read ELF firmware \"%s\"", elfname); @@ -229,8 +237,7 @@ void tests_assert_cycles_between(unsigned long min, unsigned long max) { } void _fail(const char *filename, int linenum, const char *fmt, ...) { - if (orig_stderr) - stderr = orig_stderr; + restore_stderr(); if (filename) fprintf(stderr, "%s:%d: ", filename, linenum); -- 2.39.5