kopia lustrzana https://github.com/stlink-org/stlink
Stop the sulk with GPL2016 on Windows (#602)
* Fixes for VS2017. * Added a getopt implementation. * Added a unistd.h. * Corrected closing of sockets for Windows versions. * Fixed gdbserver CMakeLists.txt to play nice with VS2017. * Fixed include of getopt.h and unistd.h for WIN32. * Added a unistd.h. * Corrected closing of sockets for Windows versions. * Fixed gdbserver CMakeLists.txt to play nice with VS2017. * Override /MD to /MT for MSVC to match libusb's builds. * MSVC settings should be if (MSVC). * Don't busy-wait for long periods in usleep(). * Dynamic link to MSVC libusb binaries. * Added Visual Studio section to compiling.md. * Added -D_CRT_NONSTDC_NO_WARNINGS to MSVC flags. * Prevented some more warnings under MSVC.pull/605/head
rodzic
55c057296a
commit
79d91786f7
|
@ -1,4 +1,5 @@
|
|||
cmake_minimum_required(VERSION 2.8.7)
|
||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE cmake/c_flag_overrides.cmake)
|
||||
project(stlink C)
|
||||
set(PROJECT_DESCRIPTION "Open source version of the STMicroelectronics Stlink Tools")
|
||||
set(STLINK_UDEV_RULES_DIR "/etc/udev/rules.d" CACHE PATH "Udev rules directory")
|
||||
|
@ -71,6 +72,12 @@ include_directories(${LIBUSB_INCLUDE_DIR})
|
|||
include_directories(include)
|
||||
include_directories(${PROJECT_BINARY_DIR}/include)
|
||||
include_directories(src/mingw)
|
||||
if (MSVC)
|
||||
include_directories(src/win32)
|
||||
include_directories(src/getopt)
|
||||
# Use string.h rather than strings.h and disable annoying warnings
|
||||
add_definitions(-DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS /wd4710)
|
||||
endif ()
|
||||
|
||||
###
|
||||
# Shared library
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
if(MSVC)
|
||||
message(STATUS "MSVC C Flags override to /MT")
|
||||
set(CMAKE_C_FLAGS_DEBUG_INIT "/D_DEBUG /MTd /Zi /Ob0 /Od /RTC1")
|
||||
set(CMAKE_C_FLAGS_MINSIZEREL_INIT "/MT /O1 /Ob1 /D NDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELEASE_INIT "/MT /O2 /Ob2 /D NDEBUG")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO_INIT "/MT /Zi /O2 /Ob1 /D NDEBUG")
|
||||
endif()
|
|
@ -67,10 +67,10 @@ if (MSYS OR MINGW)
|
|||
elseif(CMAKE_VS_PLATFORM_NAME)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME}
|
||||
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/static)
|
||||
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS64/dll)
|
||||
else ()
|
||||
find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME}
|
||||
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/static)
|
||||
HINTS ${LIBUSB_WIN_OUTPUT_FOLDER}/MS32/dll)
|
||||
endif ()
|
||||
else()
|
||||
find_library(LIBUSB_LIBRARY NAMES ${LIBUSB_NAME}
|
||||
|
|
|
@ -139,3 +139,34 @@ Check and execute (in the script folder) `<source-dir>\scripts\mingw64-build.bat
|
|||
|
||||
NOTE: when installing different toolchains make sure you edit the path in the `mingw64-build.bat`
|
||||
the build script uses currently `C:\Program Files\mingw-w64\x86_64-5.3.0-win32-sjlj-rt_v4-rev0\mingw64\bin`
|
||||
|
||||
## Windows (Visual Studio)
|
||||
|
||||
### Prerequisites
|
||||
|
||||
* 7Zip
|
||||
* CMake (tested with version 3.9.0-rc2)
|
||||
* Visual Studio 2017 Community (other versions will likely work but are untested; the Community edition is free for open source
|
||||
development)
|
||||
|
||||
### Installation
|
||||
|
||||
1. Install 7Zip from <http://www.7-zip.org>
|
||||
2. Install CMake from <https://cmake.org/download>
|
||||
3. Git clone or download stlink sourcefiles zip
|
||||
|
||||
### Building
|
||||
|
||||
These instructions are for a 32bit version.
|
||||
|
||||
In a command prompt, change directory to the folder where the stlink files were cloned (or unzipped).
|
||||
Make sure the build folder exists (`mkdir build` if not).
|
||||
From the build folder, run cmake (`cd build; cmake ..`).
|
||||
|
||||
This will create a solution (stlink.sln) in the build folder. Open it in Visual Studio, select the Solution Configuration (Debug or
|
||||
Release) and build the solution normally (F7).
|
||||
|
||||
NOTES: This solution will link to the dll version of libusb-1.0. To debug or run the executable, the dll version of libusb-1.0 must
|
||||
be either on the path, or in the same folder as the executable. It can be copied from here:
|
||||
`build\3thparty\libusb-1.0.21\MS32\dll\libusb-1.0.dll`.
|
||||
|
||||
|
|
|
@ -8,7 +8,15 @@
|
|||
#ifndef STLINK_SG_H
|
||||
#define STLINK_SG_H
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200 4255 4668 4820)
|
||||
#include <libusb.h>
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#include <libusb.h>
|
||||
#endif
|
||||
|
||||
#include "stlink.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
|
@ -23,7 +23,7 @@ struct flash_opts
|
|||
size_t flash_size; /* --flash=n[k][m] */
|
||||
};
|
||||
|
||||
#define FLASH_OPTS_INITIALIZER {0, NULL, {}, NULL, 0, 0, 0, 0, 0, 0 }
|
||||
#define FLASH_OPTS_INITIALIZER {0, NULL, { 0 }, NULL, 0, 0, 0, 0, 0, 0 }
|
||||
|
||||
int flash_get_opts(struct flash_opts* o, int ac, char** av);
|
||||
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
#ifndef _WIN32
|
||||
#define O_BINARY 0 //! @todo get rid of this OH MY (@xor-gate)
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
/* todo: stm32l15xxx flash memory, pm0062 manual */
|
||||
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
add_executable(st-util gdb-remote.c
|
||||
gdb-remote.h
|
||||
gdb-server.c
|
||||
gdb-server.h
|
||||
semihosting.c
|
||||
semihosting.h)
|
||||
set(STUTIL_SOURCE
|
||||
gdb-remote.c
|
||||
gdb-remote.h
|
||||
gdb-server.c
|
||||
gdb-server.h
|
||||
semihosting.c
|
||||
semihosting.h)
|
||||
|
||||
if (MSVC)
|
||||
# We need a getopt from somewhere...
|
||||
set(STUTIL_SOURCE "${STUTIL_SOURCE};../getopt/getopt.c")
|
||||
endif()
|
||||
|
||||
add_executable(st-util ${STUTIL_SOURCE})
|
||||
|
||||
if (WIN32 OR APPLE)
|
||||
target_link_libraries(st-util ${STLINK_LIB_STATIC})
|
||||
else()
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#ifdef __MINGW32__
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#include <mingw.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
|
|
@ -10,7 +10,11 @@
|
|||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef __MINGW32__
|
||||
#if defined(_MSC_VER)
|
||||
#include <stdbool.h>
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
#include <mingw.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
|
@ -239,7 +243,7 @@ int main(int argc, char** argv) {
|
|||
sl->verbose=0;
|
||||
current_memory_map = make_memory_map(sl);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
WSADATA wsadata;
|
||||
if (WSAStartup(MAKEWORD(2,2),&wsadata) !=0 ) {
|
||||
goto winsock_error;
|
||||
|
@ -260,7 +264,7 @@ int main(int argc, char** argv) {
|
|||
stlink_run(sl);
|
||||
} while (state.persistent);
|
||||
|
||||
#ifdef __MINGW32__
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
winsock_error:
|
||||
WSACleanup();
|
||||
#endif
|
||||
|
@ -1061,7 +1065,11 @@ int serve(stlink_t *sl, st_state_t *st) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
close(sock);
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
win32_close_socket(sock);
|
||||
#else
|
||||
close(sock);
|
||||
#endif
|
||||
|
||||
stlink_force_debug(sl);
|
||||
if (st->reset) {
|
||||
|
@ -1084,8 +1092,8 @@ int serve(stlink_t *sl, st_state_t *st) {
|
|||
int status = gdb_recv_packet(client, &packet);
|
||||
if(status < 0) {
|
||||
ELOG("cannot recv: %d\n", status);
|
||||
#ifdef __MINGW32__
|
||||
win32_close_socket(sock);
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
win32_close_socket(client);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -1337,8 +1345,8 @@ int serve(stlink_t *sl, st_state_t *st) {
|
|||
status = gdb_check_for_interrupt(client);
|
||||
if(status < 0) {
|
||||
ELOG("cannot check for int: %d\n", status);
|
||||
#ifdef __MINGW32__
|
||||
win32_close_socket(sock);
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
win32_close_socket(client);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -1739,8 +1747,8 @@ int serve(stlink_t *sl, st_state_t *st) {
|
|||
ELOG("cannot send: %d\n", result);
|
||||
free(reply);
|
||||
free(packet);
|
||||
#ifdef __MINGW32__
|
||||
win32_close_socket(sock);
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
win32_close_socket(client);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -1751,8 +1759,8 @@ int serve(stlink_t *sl, st_state_t *st) {
|
|||
free(packet);
|
||||
}
|
||||
|
||||
#ifdef __MINGW32__
|
||||
win32_close_socket(sock);
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
win32_close_socket(client);
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
Copyright (c) 2012, Kim Gräsman
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Kim Gräsman nor the
|
||||
names of contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL KIM GRÄSMAN BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,21 @@
|
|||
getopt_port
|
||||
===========
|
||||
|
||||
[Kim Gräsman](http://grundlig.wordpress.com)
|
||||
[@kimgr](http://twitter.com/kimgr)
|
||||
|
||||
An original implementation of `getopt` and `getopt_long` with limited GNU extensions. Provided under the BSD license, to allow non-GPL projects to use `getopt`-style command-line parsing.
|
||||
|
||||
So far only built with Visual C++, but has no inherently non-portable constructs.
|
||||
|
||||
Intended to be embedded into your code tree -- `getopt.h` and `getopt.c` are self-contained and should work in any context.
|
||||
|
||||
Comes with a reasonable unit test suite.
|
||||
|
||||
See also:
|
||||
|
||||
* [Full Win32 getopt port](http://www.codeproject.com/Articles/157001/Full-getopt-Port-for-Unicode-and-Multibyte-Microso) -- LGPL licensed.
|
||||
* [XGetOpt](http://www.codeproject.com/Articles/1940/XGetopt-A-Unix-compatible-getopt-for-MFC-and-Win32) -- No `getopt_long` support.
|
||||
* [Free Getopt](https://sourceforge.net/projects/freegetopt/) -- No `getopt_long` support.
|
||||
|
||||
For license terms, see LICENSE.txt.
|
|
@ -0,0 +1,206 @@
|
|||
#include "getopt.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
const int no_argument = 0;
|
||||
const int required_argument = 1;
|
||||
const int optional_argument = 2;
|
||||
#endif
|
||||
|
||||
char* optarg;
|
||||
int optopt;
|
||||
/* The variable optind [...] shall be initialized to 1 by the system. */
|
||||
int optind = 1;
|
||||
int opterr;
|
||||
|
||||
static char* optcursor = NULL;
|
||||
|
||||
/* Implemented based on [1] and [2] for optional arguments.
|
||||
optopt is handled FreeBSD-style, per [3].
|
||||
Other GNU and FreeBSD extensions are purely accidental.
|
||||
|
||||
[1] http://pubs.opengroup.org/onlinepubs/000095399/functions/getopt.html
|
||||
[2] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
[3] http://www.freebsd.org/cgi/man.cgi?query=getopt&sektion=3&manpath=FreeBSD+9.0-RELEASE
|
||||
*/
|
||||
int getopt(int argc, char* const argv[], const char* optstring) {
|
||||
int optchar = -1;
|
||||
const char* optdecl = NULL;
|
||||
|
||||
optarg = NULL;
|
||||
opterr = 0;
|
||||
optopt = 0;
|
||||
|
||||
/* Unspecified, but we need it to avoid overrunning the argv bounds. */
|
||||
if (optind >= argc)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] is a null pointer, getopt()
|
||||
shall return -1 without changing optind. */
|
||||
if (argv[optind] == NULL)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called *argv[optind] is not the character '-',
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (*argv[optind] != '-')
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "-",
|
||||
getopt() shall return -1 without changing optind. */
|
||||
if (strcmp(argv[optind], "-") == 0)
|
||||
goto no_more_optchars;
|
||||
|
||||
/* If, when getopt() is called argv[optind] points to the string "--",
|
||||
getopt() shall return -1 after incrementing optind. */
|
||||
if (strcmp(argv[optind], "--") == 0) {
|
||||
++optind;
|
||||
goto no_more_optchars;
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *optcursor == '\0')
|
||||
optcursor = argv[optind] + 1;
|
||||
|
||||
optchar = *optcursor;
|
||||
|
||||
/* FreeBSD: The variable optopt saves the last known option character
|
||||
returned by getopt(). */
|
||||
optopt = optchar;
|
||||
|
||||
/* The getopt() function shall return the next option character (if one is
|
||||
found) from argv that matches a character in optstring, if there is
|
||||
one that matches. */
|
||||
optdecl = strchr(optstring, optchar);
|
||||
if (optdecl) {
|
||||
/* [I]f a character is followed by a colon, the option takes an
|
||||
argument. */
|
||||
if (optdecl[1] == ':') {
|
||||
optarg = ++optcursor;
|
||||
if (*optarg == '\0') {
|
||||
/* GNU extension: Two colons mean an option takes an
|
||||
optional arg; if there is text in the current argv-element
|
||||
(i.e., in the same word as the option name itself, for example,
|
||||
"-oarg"), then it is returned in optarg, otherwise optarg is set
|
||||
to zero. */
|
||||
if (optdecl[2] != ':') {
|
||||
/* If the option was the last character in the string pointed to by
|
||||
an element of argv, then optarg shall contain the next element
|
||||
of argv, and optind shall be incremented by 2. If the resulting
|
||||
value of optind is greater than argc, this indicates a missing
|
||||
option-argument, and getopt() shall return an error indication.
|
||||
|
||||
Otherwise, optarg shall point to the string following the
|
||||
option character in that element of argv, and optind shall be
|
||||
incremented by 1.
|
||||
*/
|
||||
if (++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
} else {
|
||||
/* If it detects a missing option-argument, it shall return the
|
||||
colon character ( ':' ) if the first character of optstring
|
||||
was a colon, or a question-mark character ( '?' ) otherwise.
|
||||
*/
|
||||
optarg = NULL;
|
||||
optchar = (optstring[0] == ':') ? ':' : '?';
|
||||
}
|
||||
} else {
|
||||
optarg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
optcursor = NULL;
|
||||
}
|
||||
} else {
|
||||
/* If getopt() encounters an option character that is not contained in
|
||||
optstring, it shall return the question-mark ( '?' ) character. */
|
||||
optchar = '?';
|
||||
}
|
||||
|
||||
if (optcursor == NULL || *++optcursor == '\0')
|
||||
++optind;
|
||||
|
||||
return optchar;
|
||||
|
||||
no_more_optchars:
|
||||
optcursor = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Implementation based on [1].
|
||||
|
||||
[1] http://www.kernel.org/doc/man-pages/online/pages/man3/getopt.3.html
|
||||
*/
|
||||
int getopt_long(int argc, char* const argv[], const char* optstring,
|
||||
const struct option* longopts, int* longindex) {
|
||||
const struct option* o = longopts;
|
||||
const struct option* match = NULL;
|
||||
int num_matches = 0;
|
||||
size_t argument_name_length = 0;
|
||||
const char* current_argument = NULL;
|
||||
int retval = -1;
|
||||
|
||||
optarg = NULL;
|
||||
optopt = 0;
|
||||
|
||||
if (optind >= argc)
|
||||
return -1;
|
||||
|
||||
if (strlen(argv[optind]) < 3 || strncmp(argv[optind], "--", 2) != 0)
|
||||
return getopt(argc, argv, optstring);
|
||||
|
||||
/* It's an option; starts with -- and is longer than two chars. */
|
||||
current_argument = argv[optind] + 2;
|
||||
argument_name_length = strcspn(current_argument, "=");
|
||||
for (; o->name; ++o) {
|
||||
if (strncmp(o->name, current_argument, argument_name_length) == 0) {
|
||||
match = o;
|
||||
++num_matches;
|
||||
}
|
||||
}
|
||||
|
||||
if (num_matches == 1) {
|
||||
/* If longindex is not NULL, it points to a variable which is set to the
|
||||
index of the long option relative to longopts. */
|
||||
if (longindex)
|
||||
*longindex = (match - longopts);
|
||||
|
||||
/* If flag is NULL, then getopt_long() shall return val.
|
||||
Otherwise, getopt_long() returns 0, and flag shall point to a variable
|
||||
which shall be set to val if the option is found, but left unchanged if
|
||||
the option is not found. */
|
||||
if (match->flag)
|
||||
*(match->flag) = match->val;
|
||||
|
||||
retval = match->flag ? 0 : match->val;
|
||||
|
||||
if (match->has_arg != no_argument) {
|
||||
optarg = strchr(argv[optind], '=');
|
||||
if (optarg != NULL)
|
||||
++optarg;
|
||||
|
||||
if (match->has_arg == required_argument) {
|
||||
/* Only scan the next argv for required arguments. Behavior is not
|
||||
specified, but has been observed with Ubuntu and Mac OSX. */
|
||||
if (optarg == NULL && ++optind < argc) {
|
||||
optarg = argv[optind];
|
||||
}
|
||||
|
||||
if (optarg == NULL)
|
||||
retval = ':';
|
||||
}
|
||||
} else if (strchr(argv[optind], '=')) {
|
||||
/* An argument was provided to a non-argument option.
|
||||
I haven't seen this specified explicitly, but both GNU and BSD-based
|
||||
implementations show this behavior.
|
||||
*/
|
||||
retval = '?';
|
||||
}
|
||||
} else {
|
||||
/* Unknown option or ambiguous match. */
|
||||
retval = '?';
|
||||
}
|
||||
|
||||
++optind;
|
||||
return retval;
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
#ifndef INCLUDED_GETOPT_PORT_H
|
||||
#define INCLUDED_GETOPT_PORT_H
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
// These may be used to initialize structures and it fails with MSVC
|
||||
#define no_argument 0
|
||||
#define required_argument 1
|
||||
#define optional_argument 2
|
||||
#else
|
||||
extern const int no_argument;
|
||||
extern const int required_argument;
|
||||
extern const int optional_argument;
|
||||
#endif
|
||||
|
||||
extern char* optarg;
|
||||
extern int optind, opterr, optopt;
|
||||
|
||||
struct option {
|
||||
const char* name;
|
||||
int has_arg;
|
||||
int* flag;
|
||||
int val;
|
||||
};
|
||||
|
||||
int getopt(int argc, char* const argv[], const char* optstring);
|
||||
|
||||
int getopt_long(int argc, char* const argv[],
|
||||
const char* optstring, const struct option* longopts, int* longindex);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // INCLUDED_GETOPT_PORT_H
|
|
@ -1,4 +1,4 @@
|
|||
#ifdef __MINGW32__
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
|
||||
#include "mingw.h"
|
||||
|
||||
|
@ -18,6 +18,9 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
|
|||
unsigned int i, rc;
|
||||
|
||||
/* Set up the file-descriptor sets in ifds, ofds and efds. */
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4548)
|
||||
#endif
|
||||
FD_ZERO(&ifds);
|
||||
FD_ZERO(&ofds);
|
||||
FD_ZERO(&efds);
|
||||
|
@ -33,6 +36,9 @@ int win32_poll(struct pollfd *fds, unsigned int nfds, int timo)
|
|||
}
|
||||
FD_SET(fds[i].fd, &efds);
|
||||
}
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default: 4548)
|
||||
#endif
|
||||
|
||||
/* Set up the timeval structure for the timeout parameter */
|
||||
if(timo < 0) {
|
||||
|
@ -143,7 +149,7 @@ 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;
|
||||
newfd = (SOCKET)-1;
|
||||
}
|
||||
return newfd;
|
||||
}
|
||||
|
@ -267,6 +273,24 @@ char *win32_strsep (char **stringp, const char *delim)
|
|||
|
||||
void usleep(DWORD waitTime)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
if (waitTime >= 1000)
|
||||
{
|
||||
// Don't do long busy-waits.
|
||||
// However much it seems like the QPC code would be more accurate,
|
||||
// you can and probably will lose your time slice at any point during the wait,
|
||||
// so we might as well voluntarily give up the CPU with a WaitForSingleObject.
|
||||
HANDLE timer;
|
||||
LARGE_INTEGER dueTime;
|
||||
dueTime.QuadPart = -10 * (LONGLONG)waitTime;
|
||||
|
||||
timer = CreateWaitableTimer(NULL, TRUE, NULL);
|
||||
SetWaitableTimer(timer, &dueTime, 0, NULL, NULL, 0);
|
||||
WaitForSingleObject(timer, INFINITE);
|
||||
CloseHandle(timer);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
LARGE_INTEGER perf_cnt, start, now;
|
||||
|
||||
QueryPerformanceFrequency(&perf_cnt);
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
#ifdef __MINGW32__
|
||||
|
||||
#include <io.h>
|
||||
#if defined(__MINGW32__) || defined(_MSC_VER)
|
||||
|
||||
#define _USE_W32_SOCKETS 1
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4255 4668 4820)
|
||||
#endif
|
||||
|
||||
#include <io.h>
|
||||
#include <WinSock2.h>
|
||||
#pragma comment(lib, "ws2_32.lib")
|
||||
#include <unistd.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
/* 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.
|
||||
*/
|
||||
#if !defined(_WIN32_WINNT) || (_WIN32_WINNT < 0x0600)
|
||||
|
||||
#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 */
|
||||
|
@ -22,6 +34,7 @@ struct pollfd {
|
|||
short events; /* requested events */
|
||||
short revents; /* returned events */
|
||||
};
|
||||
#endif
|
||||
#define poll(x, y, z) win32_poll(x, y, z)
|
||||
|
||||
/* These wrappers do nothing special except set the global errno variable if
|
||||
|
|
10
src/usb.c
10
src/usb.c
|
@ -2,9 +2,19 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#if !defined(_MSC_VER)
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#if defined(_MSC_VER)
|
||||
#include <mingw.h>
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4200 4255 4668 4820)
|
||||
#include <libusb.h>
|
||||
#pragma warning(pop)
|
||||
#else
|
||||
#include <libusb.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
#ifndef _UNISTD_H
|
||||
#define _UNISTD_H 1
|
||||
|
||||
/* This file intended to serve as a drop-in replacement for
|
||||
* unistd.h on Windows
|
||||
* Please add functionality as neeeded
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4820)
|
||||
#endif
|
||||
#include <io.h>
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
#include <getopt.h> /* getopt at: https://gist.github.com/ashelly/7776712 */
|
||||
#include <process.h> /* for getpid() and the exec..() family */
|
||||
#include <direct.h> /* for _getcwd() and _chdir() */
|
||||
|
||||
#define srandom srand
|
||||
#define random rand
|
||||
|
||||
/* Values for the second argument to access.
|
||||
These may be OR'd together. */
|
||||
#define R_OK 4 /* Test for read permission. */
|
||||
#define W_OK 2 /* Test for write permission. */
|
||||
//#define X_OK 1 /* execute permission - unsupported in windows*/
|
||||
#define F_OK 0 /* Test for existence. */
|
||||
|
||||
#define access _access
|
||||
#define dup2 _dup2
|
||||
#define execve _execve
|
||||
#define ftruncate _chsize
|
||||
#define unlink _unlink
|
||||
#define fileno _fileno
|
||||
#define getcwd _getcwd
|
||||
#define chdir _chdir
|
||||
#define isatty _isatty
|
||||
#define lseek _lseek
|
||||
/* read, write, and close are NOT being #defined here, because while there are file handle specific versions for Windows, they probably don't work for sockets. You need to look at your app and consider whether to call e.g. closesocket(). */
|
||||
|
||||
#define ssize_t int
|
||||
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
#define STDERR_FILENO 2
|
||||
/* should be in some equivalent to <sys/types.h> */
|
||||
typedef __int8 int8_t;
|
||||
typedef __int16 int16_t;
|
||||
typedef __int32 int32_t;
|
||||
typedef __int64 int64_t;
|
||||
typedef unsigned __int8 uint8_t;
|
||||
typedef unsigned __int16 uint16_t;
|
||||
typedef unsigned __int32 uint32_t;
|
||||
typedef unsigned __int64 uint64_t;
|
||||
|
||||
#endif /* unistd.h */
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
#include <stlink.h>
|
||||
#include <stlink/tools/flash.h>
|
||||
#if defined(_MSC_VER)
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
struct Test {
|
||||
const char * cmd_line;
|
||||
|
@ -26,7 +29,11 @@ static bool execute_test(const struct Test * test) {
|
|||
char* av[32];
|
||||
|
||||
// parse (tokenize) the test command line
|
||||
#if defined(_MSC_VER)
|
||||
char *cmd_line = alloca(strlen(test->cmd_line));
|
||||
#else
|
||||
char cmd_line[strlen(test->cmd_line)];
|
||||
#endif
|
||||
strcpy(cmd_line, test->cmd_line);
|
||||
|
||||
for(char * tok = strtok(cmd_line, " "); tok; tok = strtok(NULL, " ")) {
|
||||
|
@ -62,26 +69,26 @@ static bool execute_test(const struct Test * test) {
|
|||
static struct Test tests[] = {
|
||||
{ "", -1, FLASH_OPTS_INITIALIZER },
|
||||
{ "--debug --reset read /dev/sg0 test.bin 0x80000000 0x1000", 0,
|
||||
{ .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin",
|
||||
{ .cmd = FLASH_CMD_READ, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin",
|
||||
.addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } },
|
||||
{ "--debug --reset write /dev/sg0 test.bin 0x80000000", 0,
|
||||
{ .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = {}, .filename = "test.bin",
|
||||
{ .cmd = FLASH_CMD_WRITE, .devname = "/dev/sg0", .serial = { 0 }, .filename = "test.bin",
|
||||
.addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } },
|
||||
{ "--serial A1020304 /dev/sg0 erase", -1, FLASH_OPTS_INITIALIZER },
|
||||
{ "/dev/sg0 erase", 0,
|
||||
{ .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = {}, .filename = NULL,
|
||||
{ .cmd = FLASH_CMD_ERASE, .devname = "/dev/sg0", .serial = { 0 }, .filename = NULL,
|
||||
.addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } },
|
||||
{ "--debug --reset read test.bin 0x80000000 0x1000", 0,
|
||||
{ .cmd = FLASH_CMD_READ, .devname = NULL, .serial = {}, .filename = "test.bin",
|
||||
{ .cmd = FLASH_CMD_READ, .devname = NULL, .serial = { 0 }, .filename = "test.bin",
|
||||
.addr = 0x80000000, .size = 0x1000, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } },
|
||||
{ "--debug --reset write test.bin 0x80000000", 0,
|
||||
{ .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.bin",
|
||||
{ .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.bin",
|
||||
.addr = 0x80000000, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } },
|
||||
{ "erase", 0,
|
||||
{ .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = {}, .filename = NULL,
|
||||
{ .cmd = FLASH_CMD_ERASE, .devname = NULL, .serial = { 0 }, .filename = NULL,
|
||||
.addr = 0, .size = 0, .reset = 0, .log_level = STND_LOG_LEVEL, .format = FLASH_FORMAT_BINARY } },
|
||||
{ "--debug --reset --format=ihex write test.hex", 0,
|
||||
{ .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = {}, .filename = "test.hex",
|
||||
{ .cmd = FLASH_CMD_WRITE, .devname = NULL, .serial = { 0 }, .filename = "test.hex",
|
||||
.addr = 0, .size = 0, .reset = 1, .log_level = DEBUG_LOG_LEVEL, .format = FLASH_FORMAT_IHEX } },
|
||||
{ "--debug --reset --format=binary write test.hex", -1, FLASH_OPTS_INITIALIZER },
|
||||
{ "--debug --reset --format=ihex write test.hex 0x80000000", -1, FLASH_OPTS_INITIALIZER },
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
#include <string.h>
|
||||
#include <stlink.h>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#define __attribute__(x)
|
||||
#endif
|
||||
|
||||
static void __attribute__((unused)) mark_buf(stlink_t *sl) {
|
||||
memset(sl->q_buf, 0, sizeof(sl->q_buf));
|
||||
sl->q_buf[0] = 0xaa;
|
||||
|
|
Ładowanie…
Reference in New Issue