From: Dave Murphy Date: Sun, 29 Apr 2012 13:43:46 +0000 (+0100) Subject: build with mingw X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=7ed5be296326a770bb8c66eff7f549b8b35327e2;p=fw%2Fstlink build with mingw --- diff --git a/Makefile.am b/Makefile.am index 28e11d5..a315dd7 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,7 @@ bin_PROGRAMS = st-flash st-util noinst_LIBRARIES = libstlink.a st_flash_SOURCES = flash/main.c -st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c +st_util_SOURCES = gdbserver/gdb-remote.c gdbserver/gdb-remote.h gdbserver/gdb-server.c mingw/mingw.c mingw/mingw.h CFILES = \ src/stlink-common.c \ @@ -28,10 +28,10 @@ libstlink_a_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 libstlink_a_LIBADD = $(LIBOBJS) st_flash_LDADD = libstlink.a -st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src +st_flash_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw st_util_LDADD = libstlink.a -st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src +st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw EXTRA_DIST = autogen.sh diff --git a/configure.ac b/configure.ac index a19bba4..7b4d590 100644 --- a/configure.ac +++ b/configure.ac @@ -14,10 +14,10 @@ AC_PROG_INSTALL AC_CANONICAL_HOST AC_CANONICAL_BUILD AC_PROG_RANLIB -#AC_PROG_LIBTOOL AM_PROG_CC_C_O AC_CHECK_HEADERS(sys/mman.h) +AC_CHECK_HEADERS(sys/poll.h) AC_CHECK_FUNCS(mmap) AC_REPLACE_FUNCS(mmap pread) @@ -29,6 +29,11 @@ AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb) LIBS="$LIBS $USB_LIBS" CFLAGS="$CFLAGS $USB_CFLAGS" +case "${host}" in + *-mingw32*) + LIBS="$LIBS -lws2_32" + ;; +esac AC_CONFIG_FILES([Makefile]) AC_OUTPUT diff --git a/gdbserver/gdb-remote.c b/gdbserver/gdb-remote.c index f6bf02d..1b0488e 100644 --- a/gdbserver/gdb-remote.c +++ b/gdbserver/gdb-remote.c @@ -11,7 +11,11 @@ #include #include #include +#ifdef __MINGW32__ +#include "mingw.h" +#else #include +#endif static const char hex[] = "0123456789abcdef"; @@ -24,7 +28,7 @@ int gdb_send_packet(int fd, char* data) { packet[0] = '$'; uint8_t cksum = 0; - for(int i = 0; i < strlen(data); i++) { + for(unsigned int i = 0; i < strlen(data); i++) { packet[i + 1] = data[i]; cksum += data[i]; } diff --git a/gdbserver/gdb-server.c b/gdbserver/gdb-server.c index 94784fc..b0b43d8 100644 --- a/gdbserver/gdb-server.c +++ b/gdbserver/gdb-server.c @@ -12,10 +12,14 @@ #include #include #include +#ifdef __MINGW32__ +#include "mingw.h" +#else #include #include #include #include +#endif #include @@ -203,15 +207,15 @@ static const char* const memory_map_template = "" "" - " " // code = sram, bootrom or flash; flash is bigger - " " // sram 8k - " " - " 0x%x" + " " // code = sram, bootrom or flash; flash is bigger + " " // sram 8k + " " + " 0x%zx" " " " " // peripheral regs " " // cortex regs - " " // bootrom - " " // option byte area + " " // bootrom + " " // option byte area ""; char* make_memory_map(stlink_t *sl) { @@ -291,7 +295,7 @@ static int add_data_watchpoint(stlink_t *sl, enum watchfun wf, stm32_addr_t addr mask++; } - if((mask != -1) && (mask < 16)) { + if((mask != (uint32_t)-1) && (mask < 16)) { for(i = 0; i < DATA_WATCH_NUM; i++) { // is this an empty slot ? if(data_watches[i].fun == WATCHDISABLED) { @@ -461,7 +465,7 @@ static int flash_add_block(stm32_addr_t addr, unsigned length, stlink_t *sl) { } static int flash_populate(stm32_addr_t addr, uint8_t* data, unsigned length) { - int fit_blocks = 0, fit_length = 0; + unsigned int fit_blocks = 0, fit_length = 0; for(struct flash_block* fb = flash_root; fb; fb = fb->next) { /* Block: ------X------Y-------- @@ -553,7 +557,8 @@ int serve(stlink_t *sl, int port) { unsigned int val = 1; setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); - struct sockaddr_in serv_addr = {0}; + struct sockaddr_in serv_addr; + bzero(&serv_addr,sizeof(struct sockaddr_in)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); serv_addr.sin_port = htons(port); @@ -576,7 +581,7 @@ int serve(stlink_t *sl, int port) { printf("Listening at *:%d...\n", port); int client = accept(sock, NULL, NULL); - signal (SIGINT, SIG_DFL); + //signal (SIGINT, SIG_DFL); if(client < 0) { perror("accept"); return 1; @@ -633,17 +638,17 @@ int serve(stlink_t *sl, int port) { if(!strcmp(queryName, "Supported")) { reply = strdup("PacketSize=3fff;qXfer:memory-map:read+"); } else if(!strcmp(queryName, "Xfer")) { - char *type, *op, *s_addr, *s_length; + char *type, *op, *__s_addr, *s_length; char *tok = params; char *annex __attribute__((unused)); type = strsep(&tok, ":"); op = strsep(&tok, ":"); annex = strsep(&tok, ":"); - s_addr = strsep(&tok, ","); + __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = strtoul(s_addr, NULL, 16), + unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); #ifdef DEBUG @@ -729,13 +734,13 @@ int serve(stlink_t *sl, int port) { cmdName++; // vCommand -> Command if(!strcmp(cmdName, "FlashErase")) { - char *s_addr, *s_length; + char *__s_addr, *s_length; char *tok = params; - s_addr = strsep(&tok, ","); + __s_addr = strsep(&tok, ","); s_length = tok; - unsigned addr = strtoul(s_addr, NULL, 16), + unsigned addr = strtoul(__s_addr, NULL, 16), length = strtoul(s_length, NULL, 16); #ifdef DEBUG @@ -749,13 +754,13 @@ int serve(stlink_t *sl, int port) { reply = strdup("OK"); } } else if(!strcmp(cmdName, "FlashWrite")) { - char *s_addr, *data; + char *__s_addr, *data; char *tok = params; - s_addr = strsep(&tok, ":"); + __s_addr = strsep(&tok, ":"); data = tok; - unsigned addr = strtoul(s_addr, NULL, 16); + unsigned addr = strtoul(__s_addr, NULL, 16); unsigned data_length = status - (data - packet); // Length of decoded data cannot be more than @@ -763,7 +768,7 @@ int serve(stlink_t *sl, int port) { // Additional byte is reserved for alignment fix. uint8_t *decoded = calloc(data_length + 1, 1); unsigned dec_index = 0; - for(int i = 0; i < data_length; i++) { + for(unsigned int i = 0; i < data_length; i++) { if(data[i] == 0x7d) { i++; decoded[dec_index++] = data[i] ^ 0x20; @@ -919,7 +924,7 @@ int serve(stlink_t *sl, int port) { count : count + 4 - (count % 4)); reply = calloc(count * 2 + 1, 1); - for(int i = 0; i < count; i++) { + for(unsigned int i = 0; i < count; i++) { reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4]; reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf]; } @@ -935,7 +940,7 @@ int serve(stlink_t *sl, int port) { stm32_addr_t start = strtoul(s_start, NULL, 16); unsigned count = strtoul(s_count, NULL, 16); - for(int i = 0; i < count; i ++) { + for(unsigned int i = 0; i < count; i ++) { char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 }; uint8_t byte = strtoul(hex, NULL, 16); sl->q_buf[i] = byte; diff --git a/mingw/mingw.c b/mingw/mingw.c new file mode 100644 index 0000000..c394a16 --- /dev/null +++ b/mingw/mingw.c @@ -0,0 +1,263 @@ +#ifdef __MINGW32__ + +#include "mingw.h" + +#include +#include +#include + +int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) +{ + struct timeval timeout, *toptr; + fd_set ifds, ofds, efds, *ip, *op; + int i, rc; + + /* Set up the file-descriptor sets in ifds, ofds and efds. */ + FD_ZERO(&ifds); + FD_ZERO(&ofds); + FD_ZERO(&efds); + for (i = 0, op = ip = 0; i < nfds; ++i) { + fds[i].revents = 0; + if(fds[i].events & (POLLIN|POLLPRI)) { + ip = &ifds; + FD_SET(fds[i].fd, ip); + } + if(fds[i].events & POLLOUT) { + op = &ofds; + FD_SET(fds[i].fd, op); + } + FD_SET(fds[i].fd, &efds); + } + + /* Set up the timeval structure for the timeout parameter */ + if(timo < 0) { + toptr = 0; + } else { + toptr = &timeout; + timeout.tv_sec = timo / 1000; + timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; + } + +#ifdef DEBUG_POLL + printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", + (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); +#endif + rc = select(0, ip, op, &efds, toptr); +#ifdef DEBUG_POLL + printf("Exiting select rc=%d\n", rc); +#endif + + if(rc <= 0) + return rc; + + if(rc > 0) { + for (i = 0; i < nfds; ++i) { + int fd = fds[i].fd; + if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) + fds[i].revents |= POLLIN; + if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) + fds[i].revents |= POLLOUT; + if(FD_ISSET(fd, &efds)) + /* Some error was detected ... should be some way to know. */ + fds[i].revents |= POLLHUP; +#ifdef DEBUG_POLL + printf("%d %d %d revent = %x\n", + FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), + fds[i].revents + ); +#endif + } + } + return rc; +} +static void +set_connect_errno(int winsock_err) +{ + switch(winsock_err) { + case WSAEINVAL: + case WSAEALREADY: + case WSAEWOULDBLOCK: + errno = EINPROGRESS; + break; + default: + errno = winsock_err; + break; + } +} + +static void +set_socket_errno(int winsock_err) +{ + switch(winsock_err) { + case WSAEWOULDBLOCK: + errno = EAGAIN; + break; + default: + errno = winsock_err; + break; + } +} +/* + * A wrapper around the socket() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +SOCKET +win32_socket(int domain, int type, int protocol) +{ + SOCKET fd = socket(domain, type, protocol); + if(fd == INVALID_SOCKET) { + set_socket_errno(WSAGetLastError()); + } + return fd; +} +/* + * A wrapper around the connect() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +int +win32_connect(SOCKET fd, struct sockaddr *addr, socklen_t addr_len) +{ + int rc = connect(fd, addr, addr_len); + assert(rc == 0 || rc == SOCKET_ERROR); + if(rc == SOCKET_ERROR) { + set_connect_errno(WSAGetLastError()); + } + return rc; +} + +/* + * A wrapper around the accept() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +SOCKET +win32_accept(SOCKET fd, struct sockaddr *addr, socklen_t *addr_len) +{ + SOCKET newfd = accept(fd, addr, addr_len); + if(newfd == INVALID_SOCKET) { + set_socket_errno(WSAGetLastError()); + newfd = -1; + } + return newfd; +} + +/* + * A wrapper around the shutdown() function. The purpose of this wrapper + * is to ensure that the global errno symbol is set if an error occurs, + * even if we are using winsock. + */ +int +win32_shutdown(SOCKET fd, int mode) +{ + int rc = shutdown(fd, mode); + assert(rc == 0 || rc == SOCKET_ERROR); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} +int win32_close_socket(SOCKET fd) { + int rc; + + rc = closesocket(fd); + return 0; +} + + +int win32_write_socket(SOCKET fd, void *buf, int n) +{ + int rc = send(fd, buf, n, 0); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + +int win32_read_socket(SOCKET fd, void *buf, int n) +{ + int rc = recv(fd, buf, n, 0); + if(rc == SOCKET_ERROR) { + set_socket_errno(WSAGetLastError()); + } + return rc; +} + + +char * win32_strtok_r(char *s, const char *delim, char **lasts) +{ + register char *spanp; + register int c, sc; + char *tok; + + + if (s == NULL && (s = *lasts) == NULL) + return (NULL); + + /* + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). + */ +cont: + c = *s++; + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { + if (c == sc) + goto cont; + } + + if (c == 0) { /* no non-delimiter characters */ + *lasts = NULL; + return (NULL); + } + tok = s - 1; + + /* + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). + * Note that delim must have one NUL; we stop if we see that, too. + */ + for (;;) { + c = *s++; + spanp = (char *)delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *lasts = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +char *win32_strsep (char **stringp, const char *delim) +{ + register char *s; + register const char *spanp; + register int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + +#endif + + diff --git a/mingw/mingw.h b/mingw/mingw.h new file mode 100644 index 0000000..93b3702 --- /dev/null +++ b/mingw/mingw.h @@ -0,0 +1,61 @@ +#ifdef __MINGW32__ + +#include + +#include + +#define ENOTCONN WSAENOTCONN +#define EWOULDBLOCK WSAEWOULDBLOCK +#define ENOBUFS WSAENOBUFS +#define ECONNRESET WSAECONNRESET +#define ESHUTDOWN WSAESHUTDOWN +#define EAFNOSUPPORT WSAEAFNOSUPPORT +#define EPROTONOSUPPORT WSAEPROTONOSUPPORT +#define EINPROGRESS WSAEINPROGRESS +#define EISCONN WSAEISCONN + +/* winsock doesn't feature poll(), so there is a version implemented + * in terms of select() in mingw.c. The following definitions + * are copied from linux man pages. A poll() macro is defined to + * call the version in mingw.c. + */ +#define POLLIN 0x0001 /* There is data to read */ +#define POLLPRI 0x0002 /* There is urgent data to read */ +#define POLLOUT 0x0004 /* Writing now will not block */ +#define POLLERR 0x0008 /* Error condition */ +#define POLLHUP 0x0010 /* Hung up */ +#define POLLNVAL 0x0020 /* Invalid request: fd not open */ +struct pollfd { + SOCKET fd; /* file descriptor */ + short events; /* requested events */ + short revents; /* returned events */ +}; +#define poll(x, y, z) win32_poll(x, y, z) + +/* These wrappers do nothing special except set the global errno variable if + * an error occurs (winsock doesn't do this by default). They set errno + * to unix-like values (i.e. WSAEWOULDBLOCK is mapped to EAGAIN), so code + * outside of this file "shouldn't" have to worry about winsock specific error + * handling. + */ +#define socket(x, y, z) win32_socket(x, y, z) +#define connect(x, y, z) win32_connect(x, y, z) +#define accept(x, y, z) win32_accept(x, y, z) +#define shutdown(x, y) win32_shutdown(x, y) + +/* Winsock uses int instead of the usual socklen_t */ +typedef int socklen_t; + +int win32_poll(struct pollfd *, unsigned int, int); +SOCKET win32_socket(int, int, int); +int win32_connect(SOCKET, struct sockaddr*, socklen_t); +SOCKET win32_accept(SOCKET, struct sockaddr*, socklen_t *); +int win32_shutdown(SOCKET, int); + +#define strtok_r(x, y, z) win32_strtok_r(x, y, z) +#define strsep(x,y) win32_strsep(x,y) + +char *win32_strtok_r(char *s, const char *delim, char **lasts); +char *win32_strsep(char **stringp, const char *delim); + +#endif