kopia lustrzana https://github.com/stlink-org/stlink
Merge pull request #77 from WinterMute/mingw
Changes to allow compiling for windows using mingw toolchainspull/79/merge
commit
d2c78b96e0
|
|
@ -1,18 +1,29 @@
|
|||
nbproject
|
||||
.project
|
||||
COPYING
|
||||
INSTALL
|
||||
Makefile.in
|
||||
aclocal.m4
|
||||
autom4te.cache
|
||||
config.guess
|
||||
config.sub
|
||||
configure
|
||||
depcomp
|
||||
install-sh
|
||||
ltmain.sh
|
||||
missing
|
||||
*.bz2
|
||||
*.lo
|
||||
*.o
|
||||
*.elf
|
||||
doc/tutorial/*.log
|
||||
doc/tutorial/*.aux
|
||||
libstlink.a
|
||||
test_usb
|
||||
test_sg
|
||||
gdbserver/st-util
|
||||
flash/flash
|
||||
*.log
|
||||
example/*/*.bin
|
||||
example/*/*.elf
|
||||
example/*/*/*.bin
|
||||
example/*/*/*/*.bin
|
||||
example/*/*/*.a
|
||||
example/*/*/*/*.a
|
||||
.libs
|
||||
libtool
|
||||
*.la
|
||||
config.log
|
||||
config.status
|
||||
compile
|
||||
st-flash
|
||||
st-util
|
||||
*.deps*
|
||||
*.dirstamp
|
||||
*.a
|
||||
Makefile
|
||||
*.exe
|
||||
example/blink/*.elf
|
||||
|
|
|
|||
58
Makefile
58
Makefile
|
|
@ -1,58 +0,0 @@
|
|||
# make ... for both stlink v1 and stlink v2 support
|
||||
##
|
||||
VPATH=src
|
||||
|
||||
SOURCES_LIB=stlink-common.c stlink-usb.c stlink-sg.c uglylogging.c
|
||||
OBJS_LIB=$(SOURCES_LIB:.c=.o)
|
||||
TEST_PROGRAMS=test_usb test_sg
|
||||
LDFLAGS=-L. -lstlink
|
||||
|
||||
# libusb location
|
||||
LDFLAGS+=`pkg-config --libs libusb-1.0`
|
||||
CFLAGS+=`pkg-config --cflags libusb-1.0`
|
||||
|
||||
CFLAGS+=-g
|
||||
CFLAGS+=-DDEBUG=1
|
||||
CFLAGS+=-std=gnu99
|
||||
CFLAGS+=-Wall -Wextra
|
||||
|
||||
|
||||
LIBRARY=libstlink.a
|
||||
|
||||
all: $(LIBRARY) flash gdbserver $(TEST_PROGRAMS)
|
||||
|
||||
$(LIBRARY): $(OBJS_LIB)
|
||||
@echo "objs are $(OBJS_LIB)"
|
||||
$(AR) -cr $@ $^
|
||||
@echo "done making library"
|
||||
|
||||
|
||||
test_sg: test_sg.o $(LIBRARY)
|
||||
@echo "building test_sg"
|
||||
$(CC) test_sg.o $(LDFLAGS) -o $@
|
||||
|
||||
test_usb: test_usb.o $(LIBRARY)
|
||||
@echo "building test_usb"
|
||||
$(CC) test_usb.o $(LDFLAGS) -o $@
|
||||
@echo "done linking"
|
||||
|
||||
%.o: %.c
|
||||
@echo "building $^ into $@"
|
||||
$(CC) $(CFLAGS) -c $^ -o $@
|
||||
@echo "done compiling"
|
||||
|
||||
clean:
|
||||
rm -rf $(OBJS_LIB)
|
||||
rm -rf $(LIBRARY)
|
||||
rm -rf test_usb*
|
||||
rm -rf test_sg*
|
||||
$(MAKE) -C flash clean
|
||||
$(MAKE) -C gdbserver clean
|
||||
|
||||
flash:
|
||||
$(MAKE) -C flash
|
||||
|
||||
gdbserver:
|
||||
$(MAKE) -C gdbserver CONFIG_USE_LIBSG="$(CONFIG_USE_LIBSG)"
|
||||
|
||||
.PHONY: clean all flash gdbserver
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
# Makefile.am -- Process this file with automake to produce Makefile.in
|
||||
|
||||
AUTOMAKE_OPTIONS = subdir-objects
|
||||
|
||||
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 mingw/mingw.c mingw/mingw.h
|
||||
|
||||
CFILES = \
|
||||
src/stlink-common.c \
|
||||
src/stlink-usb.c \
|
||||
src/stlink-sg.c \
|
||||
src/uglylogging.c
|
||||
|
||||
HFILES = \
|
||||
src/stlink-common.h \
|
||||
src/stlink-usb.h \
|
||||
src/stlink-sg.h \
|
||||
src/uglylogging.h \
|
||||
src/mmap.h
|
||||
|
||||
libstlink_a_SOURCES = $(CFILES) $(HFILES)
|
||||
|
||||
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 -I$(top_srcdir)/mingw
|
||||
|
||||
st_util_LDADD = libstlink.a
|
||||
st_util_CPPFLAGS = -std=gnu99 -Wall -Wextra -O2 -I$(top_srcdir)/src -I$(top_srcdir)/mingw
|
||||
|
||||
EXTRA_DIST = autogen.sh
|
||||
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
#!/bin/sh
|
||||
autoreconf --install --force --verbose
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
# -*- Autoconf -*-
|
||||
# Process this file with autoconf to produce a configure script.
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
AC_INIT([stlink],[0.5.2],[davem@devkitpro.org])
|
||||
AC_CONFIG_SRCDIR([src/stlink-common.c])
|
||||
AC_CONFIG_LIBOBJ_DIR([src])
|
||||
AM_INIT_AUTOMAKE([1.10])
|
||||
|
||||
|
||||
# Checks for programs.
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
AC_CANONICAL_HOST
|
||||
AC_CANONICAL_BUILD
|
||||
AC_PROG_RANLIB
|
||||
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)
|
||||
|
||||
# Checks for libraries.
|
||||
PKG_CHECK_MODULES(USB, libusb-1.0 >= 1.0.0,,
|
||||
AC_MSG_ERROR([*** Required libusb-1.0 >= 1.0.0 not installed ***]))
|
||||
AC_CHECK_LIB([usbpath],[usb_path2devnum],,,-lusb)
|
||||
|
||||
LIBS="$LIBS $USB_LIBS"
|
||||
CFLAGS="$CFLAGS $USB_CFLAGS"
|
||||
|
||||
case "${host}" in
|
||||
*-mingw32*)
|
||||
LIBS="$LIBS -lws2_32"
|
||||
CPPFLAGS="-D__USE_MINGW_ANSI_STDIO=1 $CPPFLAGS"
|
||||
;;
|
||||
esac
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
/* missing type */
|
||||
|
||||
typedef unsigned int uint32_t;
|
||||
|
||||
void main(void);
|
||||
|
||||
/* hardware configuration */
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,16 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdint.h>
|
||||
#ifdef __MINGW32__
|
||||
#include "mingw.h"
|
||||
#else
|
||||
#include <sys/poll.h>
|
||||
#endif
|
||||
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
|
||||
int gdb_send_packet(int fd, char* data) {
|
||||
unsigned length = strlen(data) + 5;
|
||||
int length = strlen(data) + 5;
|
||||
char* packet = malloc(length); /* '$' data (hex) '#' cksum (hex) */
|
||||
|
||||
memset(packet, 0, length);
|
||||
|
|
@ -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];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,10 +12,14 @@
|
|||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef __MINGW32__
|
||||
#include "mingw.h"
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
#include <stlink-common.h>
|
||||
|
||||
|
|
@ -166,8 +170,20 @@ int main(int argc, char** argv) {
|
|||
|
||||
current_memory_map = make_memory_map(sl);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
WSADATA wsadata;
|
||||
if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) {
|
||||
goto winsock_error;
|
||||
}
|
||||
#endif
|
||||
|
||||
while(serve(sl, state.listen_port) == 0);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
winsock_error:
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
||||
/* Switch back to mass storage mode before closing. */
|
||||
stlink_run(sl);
|
||||
stlink_exit_debug_mode(sl);
|
||||
|
|
@ -204,15 +220,15 @@ static const char* const memory_map_template =
|
|||
"<!DOCTYPE memory-map PUBLIC \"+//IDN gnu.org//DTD GDB Memory Map V1.0//EN\""
|
||||
" \"http://sourceware.org/gdb/gdb-memory-map.dtd\">"
|
||||
"<memory-map>"
|
||||
" <memory type=\"rom\" start=\"0x00000000\" length=\"0x%x\"/>" // code = sram, bootrom or flash; flash is bigger
|
||||
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x%x\"/>" // sram 8k
|
||||
" <memory type=\"flash\" start=\"0x08000000\" length=\"0x%x\">"
|
||||
" <property name=\"blocksize\">0x%x</property>"
|
||||
" <memory type=\"rom\" start=\"0x00000000\" length=\"0x%zx\"/>" // code = sram, bootrom or flash; flash is bigger
|
||||
" <memory type=\"ram\" start=\"0x20000000\" length=\"0x%zx\"/>" // sram 8k
|
||||
" <memory type=\"flash\" start=\"0x08000000\" length=\"0x%zx\">"
|
||||
" <property name=\"blocksize\">0x%zx</property>"
|
||||
" </memory>"
|
||||
" <memory type=\"ram\" start=\"0x40000000\" length=\"0x1fffffff\"/>" // peripheral regs
|
||||
" <memory type=\"ram\" start=\"0xe0000000\" length=\"0x1fffffff\"/>" // cortex regs
|
||||
" <memory type=\"rom\" start=\"0x%08x\" length=\"0x%x\"/>" // bootrom
|
||||
" <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8\"/>" // option byte area
|
||||
" <memory type=\"rom\" start=\"0x%08x\" length=\"0x%zx\"/>" // bootrom
|
||||
" <memory type=\"rom\" start=\"0x1ffff800\" length=\"0x8x\"/>" // option byte area
|
||||
"</memory-map>";
|
||||
|
||||
char* make_memory_map(stlink_t *sl) {
|
||||
|
|
@ -292,7 +308,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) {
|
||||
|
|
@ -462,7 +478,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--------
|
||||
|
|
@ -552,9 +568,10 @@ int serve(stlink_t *sl, int port) {
|
|||
}
|
||||
|
||||
unsigned int val = 1;
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
|
||||
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
|
||||
|
||||
struct sockaddr_in serv_addr = {0};
|
||||
struct sockaddr_in serv_addr;
|
||||
memset(&serv_addr,0,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);
|
||||
|
|
@ -577,7 +594,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;
|
||||
|
|
@ -634,17 +651,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
|
||||
|
|
@ -730,13 +747,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
|
||||
|
|
@ -750,13 +767,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
|
||||
|
|
@ -764,7 +781,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;
|
||||
|
|
@ -920,7 +937,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];
|
||||
}
|
||||
|
|
@ -936,7 +953,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;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,268 @@
|
|||
#ifdef __MINGW32__
|
||||
|
||||
#include "mingw.h"
|
||||
|
||||
#undef socket
|
||||
#undef connect
|
||||
#undef accept
|
||||
#undef shutdown
|
||||
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
|
||||
int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
|
||||
{
|
||||
struct timeval timeout, *toptr;
|
||||
fd_set ifds, ofds, efds, *ip, *op;
|
||||
unsigned 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 rc;
|
||||
}
|
||||
|
||||
|
||||
ssize_t 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;
|
||||
}
|
||||
|
||||
ssize_t 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
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
#ifdef __MINGW32__
|
||||
|
||||
#include <io.h>
|
||||
|
||||
#define _USE_W32_SOCKETS 1
|
||||
#include <windows.h>
|
||||
|
||||
#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)
|
||||
#define read(x, y, z) win32_read_socket(x, y, z)
|
||||
#define write(x, y, z) win32_write_socket(x, y, z)
|
||||
|
||||
/* 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);
|
||||
|
||||
ssize_t win32_read_socket(SOCKET fd, void *buf, int n);
|
||||
ssize_t win32_write_socket(SOCKET fd, void *buf, int n);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* mmap.c -- version of mmap for gold. */
|
||||
|
||||
/* Copyright 2009 Free Software Foundation, Inc.
|
||||
Written by Vladimir Simonov <sv@sw.ru>.
|
||||
|
||||
This file is part of gold.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
//#include "config.h"
|
||||
//#include "ansidecl.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_STDLIB_H
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#include "mmap.h"
|
||||
|
||||
extern ssize_t pread (int, void *, size_t, off_t);
|
||||
|
||||
void *
|
||||
mmap (void *__addr, size_t __len, int __prot,
|
||||
int __flags, int __fd, long long __offset)
|
||||
{
|
||||
void *ret;
|
||||
ssize_t count;
|
||||
|
||||
if (__addr || (__fd != -1 && (__prot & PROT_WRITE))
|
||||
|| (__flags & MAP_SHARED))
|
||||
return MAP_FAILED;
|
||||
|
||||
ret = malloc (__len);
|
||||
if (!ret)
|
||||
return MAP_FAILED;
|
||||
|
||||
if (__fd == -1)
|
||||
return ret;
|
||||
|
||||
count = pread (__fd, ret, __len, __offset);
|
||||
if ((size_t) count != __len)
|
||||
{
|
||||
free (ret);
|
||||
return MAP_FAILED;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
munmap (void *__addr, size_t __len)
|
||||
{
|
||||
free (__addr);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/* mmap.h -- mmap family functions prototypes for gold. */
|
||||
|
||||
/* Copyright 2009 Free Software Foundation, Inc.
|
||||
Written by Vladimir Simonov <sv@sw.ru>
|
||||
|
||||
This file is part of gold.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
#ifndef GOLD_MMAP_H
|
||||
#define GOLD_MMAP_H
|
||||
|
||||
#ifdef HAVE_SYS_MMAN_H
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
/* Some BSD systems still use MAP_ANON instead of MAP_ANONYMOUS. */
|
||||
|
||||
#ifndef MAP_ANONYMOUS
|
||||
# define MAP_ANONYMOUS MAP_ANON
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define PROT_READ 0x1
|
||||
#define PROT_WRITE 0x2
|
||||
|
||||
#define MAP_SHARED 0x01
|
||||
#define MAP_PRIVATE 0x02
|
||||
|
||||
#define MAP_ANONYMOUS 0x20
|
||||
|
||||
#define MAP_FAILED ((void *) -1)
|
||||
#endif /* HAVE_SYS_MMAN_H */
|
||||
|
||||
#ifndef HAVE_MMAP
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
extern void *mmap (void *__addr, size_t __len, int __prot,
|
||||
int __flags, int __fd, long long __offset);
|
||||
extern int munmap (void *__addr, size_t __len);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* HAVE_MMAP */
|
||||
|
||||
#endif /* GOLD_MMAP_H */
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* pread.c -- version of pread for gold. */
|
||||
|
||||
/* Copyright 2006, 2007, 2009 Free Software Foundation, Inc.
|
||||
Written by Ian Lance Taylor <iant@google.com>.
|
||||
|
||||
This file is part of gold.
|
||||
|
||||
This program 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.
|
||||
|
||||
This program 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 this program; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
|
||||
MA 02110-1301, USA. */
|
||||
|
||||
/* This file implements pread for systems which don't have it. This
|
||||
file is only compiled if pread is not present on the system. This
|
||||
is not an exact version of pread, as it does not preserve the
|
||||
current file offset. */
|
||||
|
||||
//#include "config.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern ssize_t pread (int, void *, size_t, off_t);
|
||||
|
||||
ssize_t
|
||||
pread (int fd, void *buf, size_t count, off_t offset)
|
||||
{
|
||||
if (lseek(fd, offset, SEEK_SET) != offset)
|
||||
return -1;
|
||||
return read(fd, buf, count);
|
||||
}
|
||||
|
|
@ -9,8 +9,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
#include "mmap.h"
|
||||
|
||||
#include "stlink-common.h"
|
||||
#include "uglylogging.h"
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@
|
|||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include "mmap.h"
|
||||
|
||||
#include "stlink-common.h"
|
||||
#include "stlink-sg.h"
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <libusb.h>
|
||||
|
||||
|
|
@ -16,6 +16,18 @@
|
|||
#define WLOG(format, args...) ugly_log(UWARN, LOG_TAG, format, ## args)
|
||||
#define fatal(format, args...) ugly_log(UFATAL, LOG_TAG, format, ## args)
|
||||
|
||||
#ifndef timersub
|
||||
/* This is a copy from GNU C Library (GNU LGPL 2.1), sys/time.h. */
|
||||
# define timersub(a, b, result) \
|
||||
do { \
|
||||
(result)->tv_sec = (a)->tv_sec - (b)->tv_sec; \
|
||||
(result)->tv_usec = (a)->tv_usec - (b)->tv_usec; \
|
||||
if ((result)->tv_usec < 0) { \
|
||||
--(result)->tv_sec; \
|
||||
(result)->tv_usec += 1000000; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
enum SCSI_Generic_Direction {SG_DXFER_TO_DEV=0, SG_DXFER_FROM_DEV=0x80};
|
||||
|
||||
|
|
@ -45,7 +57,7 @@ struct trans_ctx {
|
|||
volatile unsigned long flags;
|
||||
};
|
||||
|
||||
static void on_trans_done(struct libusb_transfer * trans) {
|
||||
static void LIBUSB_CALL on_trans_done(struct libusb_transfer * trans) {
|
||||
struct trans_ctx * const ctx = trans->user_data;
|
||||
|
||||
if (trans->status != LIBUSB_TRANSFER_COMPLETED)
|
||||
|
|
|
|||
Ładowanie…
Reference in New Issue