From e23fe653b039386ba27664ab218fd4d72cd7fd20 Mon Sep 17 00:00:00 2001 From: Justin Mitchell Date: Tue, 1 Oct 2013 10:26:13 +0100 Subject: [PATCH] Build options for WIN32 (using mingw) --- cli/Makefile | 19 +++++++-- cli/boot.c | 28 +++++++++++++- cli/log.c | 77 +++++++++++++++++++++++++++++++++++++ cli/protocol.c | 4 +- cli/serial-win.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 237 insertions(+), 6 deletions(-) create mode 100644 cli/serial-win.c diff --git a/cli/Makefile b/cli/Makefile index 3615658..6566a12 100644 --- a/cli/Makefile +++ b/cli/Makefile @@ -1,7 +1,20 @@ -CFLAGS= -g -fstack-protector-all -Wall -pedantic -std=gnu99 -fPIC -D_GNU_SOURCE +CFLAGS= -g -fstack-protector-all -Wall -pedantic -std=gnu99 -D_GNU_SOURCE LDFLAGS= $(CFLAGS) -SRC=serial.c log.c boot.c protocol.c devices.c memory.c +SRC=log.c boot.c protocol.c devices.c memory.c + +WINDOWS=0 + +ifeq ($(WINDOWS),1) +PREFIX=i686-w64-mingw32- +SRC += serial-win.c +CFLAGS += -static -mwindows -DDEFPORT="COM4:" +else +CFLAGS += -fPIC -DDEFPORT="/dev/ttyUSB0" +SRC += serial.c +endif + +CC=$(PREFIX)gcc OBJS=$(SRC:%.c=%.o) @@ -13,5 +26,5 @@ boot: $(OBJS) $(CC) $(CFLAGS) -c -o $@ $< clean: - rm -f $(OBJS) boot + rm -f $(OBJS) $(TARGET) diff --git a/cli/boot.c b/cli/boot.c index 7a3e26e..087b47a 100644 --- a/cli/boot.c +++ b/cli/boot.c @@ -12,7 +12,24 @@ #include "memory.h" #define BAUD_RATE 19200 + +#define STRINGIFY(n) #n + +#ifdef DEFPORT +#define PORT_NAME STRINGIFY(DEFPORT) +#else #define PORT_NAME "/dev/ttyUSB0" +#endif + +#ifdef _WIN32 +static void keypress(void) +{ + printf("Press ENTER to exit\n"); + getchar(); +} +#else +static void keypress(void) {} +#endif void usage(const char * name) @@ -170,6 +187,7 @@ int main(int argc, char **argv) if (!idonly && optind >= argc) { loge("Error: missing hexfile"); + keypress(); return 1; } @@ -179,6 +197,7 @@ int main(int argc, char **argv) FILE * fd = NULL; if ((fd = fopen(argv[optind], "r"))==NULL) { loge("Error opening %s: %s", argv[optind], strerror(errno)); + keypress(); return 1; } ram = load_ihex(fd); @@ -190,11 +209,15 @@ int main(int argc, char **argv) logd("open serial port %s at %d baud", port, baud); port_t * pt = serial_open(port, baud); - if (pt == NULL) return 1; + if (pt == NULL) { + keypress(); + return 1; + } uint16_t maxmem; uint16_t devid; if (loader_connect(pt, &maxmem, &devid)) { + keypress(); return 1; } @@ -208,6 +231,7 @@ int main(int argc, char **argv) logi(" Max Mem: %d", dev->memsize ); } + keypress(); return 0; } if (dev) logd("Device Name: %s", dev->name); @@ -215,6 +239,7 @@ int main(int argc, char **argv) /* check that the selected program will fit on this device */ if (makesafe_mem(&ram, maxmem)) { serial_close(pt); + keypress(); return 1; } logd("After re-organisation"); @@ -231,6 +256,7 @@ int main(int argc, char **argv) /* finished */ serial_close(pt); logd("done."); + keypress(); return 0; } diff --git a/cli/log.c b/cli/log.c index ff27062..e32cd67 100644 --- a/cli/log.c +++ b/cli/log.c @@ -7,8 +7,53 @@ int debug = 0; +#ifdef _WIN32 +#include +#include +#include + +static const WORD MAX_CONSOLE_LINES = 500; + void logit(int type, const char * format, ...) { + static int hConHandle = 0; + + if (hConHandle == 0) { + CONSOLE_SCREEN_BUFFER_INFO coninfo; + AllocConsole(); + //AttachConsole(ATTACH_PARENT_PROCESS); + GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); + coninfo.dwSize.Y = MAX_CONSOLE_LINES; + SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); + + int hConHandle; + long lStdHandle; + FILE *fp; + + // redirect unbuffered STDOUT to the console + lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "w" ); + *stdout = *fp; + setvbuf( stdout, NULL, _IONBF, 0 ); + + // redirect unbuffered STDIN to the console + lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "r" ); + *stdin = *fp; + + setvbuf( stdin, NULL, _IONBF, 0 ); + + // redirect unbuffered STDERR to the console + lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); + hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); + fp = _fdopen( hConHandle, "w" ); + *stderr = *fp; + + setvbuf( stderr, NULL, _IONBF, 0 ); + } + va_list va; va_start(va, format); @@ -34,3 +79,35 @@ void logit(int type, const char * format, ...) va_end(va); } + +#else + +void logit(int type, const char * format, ...) +{ + va_list va; + va_start(va, format); + + struct timeval now; + gettimeofday(&now, NULL); + + struct tm * now_tm = localtime(&(now.tv_sec)); + + if (type == LOG_INFO) { + vfprintf(stdout, format, va); + fprintf(stdout, "\n"); + } else + if (type == LOG_DEBUG) { + if (debug > 0) { + fprintf(stderr, "%02d:%02d:%02d.%03d ", now_tm->tm_hour, now_tm->tm_min, now_tm->tm_sec, (int)(now.tv_usec / 1000)); + vfprintf(stderr, format, va); + fprintf(stderr, "\n"); + } + } else { + vfprintf(stderr, format, va); + fprintf(stderr, "\n"); + } + + va_end(va); +} + +#endif diff --git a/cli/protocol.c b/cli/protocol.c index 5d6e028..c9db1e0 100644 --- a/cli/protocol.c +++ b/cli/protocol.c @@ -64,7 +64,7 @@ int loader_readmem(port_t * pt, uint16_t addr, uint8_t * memory, int words) int ret = serial_write(pt, buff, 4); if (ret <= 0) return 1; - bzero(buff, len); + memset(buff, 0, len); /* read the response */ if (serial_read(pt, buff, 1)<=0) return 1; @@ -219,7 +219,7 @@ int loader_connect(port_t * pt, uint16_t *maxmem, uint16_t *devid) } else { logd("Connect: Want 'BL' got '%c%c' ret=%d", buff[1], buff[2], ret); } - bzero(buff,3); + memset(buff,0,3); } if (ret <= 0) { diff --git a/cli/serial-win.c b/cli/serial-win.c new file mode 100644 index 0000000..9dd5cbe --- /dev/null +++ b/cli/serial-win.c @@ -0,0 +1,115 @@ +#include +#include +#include + +#include +#include + +#include "log.h" +#include "serial.h" + +struct serial_port { + HANDLE handle; +}; + +port_t * serial_open(const char *name, int speed) +{ + port_t *pt = NULL; + HANDLE port = CreateFileA(name, GENERIC_READ | GENERIC_WRITE, + 0, NULL, OPEN_EXISTING, 0, NULL); + + if (port == INVALID_HANDLE_VALUE) return NULL; + + DCB settings; + memset(&settings, 0, sizeof(settings)); + settings.DCBlength = sizeof(settings); + + char seta[120]; + snprintf(seta, sizeof(seta), "baud=%d data=8 parity=N stop=1 dtr=off rts=off", speed); + if (!BuildCommDCBA(seta, &settings)) { + loge("Invalid serial port settings"); + CloseHandle(port); + return NULL; + } + + if (!SetCommState(port, &settings)) { + loge("Unable to configure serial port"); + CloseHandle(port); + return NULL; + } + + COMMTIMEOUTS tout; + tout.ReadIntervalTimeout = MAXDWORD; + tout.ReadTotalTimeoutMultiplier = MAXDWORD; + tout.ReadTotalTimeoutConstant = 30000; + tout.WriteTotalTimeoutMultiplier = 0; + tout.WriteTotalTimeoutConstant = 0; + + if (!SetCommTimeouts(port, &tout)) { + loge("Unable to set serial timeouts"); + CloseHandle(port); + return NULL; + } + + pt = malloc(sizeof(port_t)); + pt->handle = port; + + return pt; + +} + +void serial_close(port_t * pt) +{ + if (pt == NULL) return; + if (pt->handle == INVALID_HANDLE_VALUE) return; + + CloseHandle(pt->handle); + pt->handle = INVALID_HANDLE_VALUE; + + return; +} + +int serial_read(port_t * pt, unsigned char * buff, size_t len) +{ + if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1; + int count = 0; + unsigned char * p = buff; + int done = 0; + + /* read will block if no chars, will return whats there otherwise, + * and will timeout after 30 seconds */ + while (done < len) { + if (!ReadFile(pt->handle, p, len-done, (LPDWORD)&count, NULL)) + return -1; + p += count; + done += count; + } + + return count; +} + +int serial_write(port_t * pt, unsigned char * buff, size_t len) +{ + if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1; + + int n; + + if (WriteFile(pt->handle, buff, len, (LPDWORD)&n, NULL)) + return n; + + return 0; +} + +int serial_break(port_t * pt, int set) +{ + if (pt == NULL || pt->handle == INVALID_HANDLE_VALUE) return -1; + + if (set) { + SetCommBreak(pt->handle); + } else { + ClearCommBreak(pt->handle); + } + + return 0; +} + -- 1.8.3.1