Skip to content

Instantly share code, notes, and snippets.

@Lauszus
Last active January 30, 2018 17:40
Show Gist options
  • Save Lauszus/207edfea5a492c2d3ce91e593bc9cbe7 to your computer and use it in GitHub Desktop.
Save Lauszus/207edfea5a492c2d3ce91e593bc9cbe7 to your computer and use it in GitHub Desktop.
Changes to blhost for Mac
#-----------------------------------------------
# Make command:
# make build=<build> all
# <build>: debug or release, release by default.
#-----------------------------------------------
#-----------------------------------------------
# setup variables
# ----------------------------------------------
BOOT_ROOT := $(abspath ../../..)
OUTPUT_ROOT := $(abspath ./)
APP_NAME = blhost
#-----------------------------------------------
# Debug or Release
# Release by default
#-----------------------------------------------
build ?= release
include $(BOOT_ROOT)/mk/common.mk
#-----------------------------------------------
# Include path. Add the include paths like this:
# INCLUDES += ./include/
#-----------------------------------------------
INCLUDES += $(BOOT_ROOT)/validation/blhost/src \
$(BOOT_ROOT)/src \
$(BOOT_ROOT)/src/include \
$(BOOT_ROOT)/src/blfwk \
$(BOOT_ROOT)/src/sbloader \
$(BOOT_ROOT)/src/bootloader \
$(BOOT_ROOT)/src/crc \
$(BOOT_ROOT)/src/packet \
$(BOOT_ROOT)/src/property \
$(BOOT_ROOT)/src/drivers/common \
$(BOOT_ROOT)/src/bm_usb
CXXFLAGS := -D BOOTLOADER_HOST -std=c++11
CFLAGS := -std=c99 -D BOOTLOADER_HOST -D _GNU_SOURCE
LD := g++
SOURCES := $(BOOT_ROOT)/validation/blhost/src/blhost.cpp \
$(BOOT_ROOT)/src/blfwk/src/Blob.cpp \
$(BOOT_ROOT)/src/blfwk/src/Bootloader.cpp \
$(BOOT_ROOT)/src/blfwk/src/BusPal.cpp \
$(BOOT_ROOT)/src/blfwk/src/BusPalPeripheral.cpp \
$(BOOT_ROOT)/src/blfwk/src/Command.cpp \
$(BOOT_ROOT)/src/blfwk/src/DataSource.cpp \
$(BOOT_ROOT)/src/blfwk/src/DataSourceImager.cpp \
$(BOOT_ROOT)/src/blfwk/src/DataTarget.cpp \
$(BOOT_ROOT)/src/blfwk/src/ELFSourceFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/ExcludesListMatcher.cpp \
$(BOOT_ROOT)/src/blfwk/src/format_string.cpp \
$(BOOT_ROOT)/src/blfwk/src/GHSSecInfo.cpp \
$(BOOT_ROOT)/src/blfwk/src/GlobMatcher.cpp \
$(BOOT_ROOT)/src/blfwk/src/jsoncpp.cpp \
$(BOOT_ROOT)/src/blfwk/src/Logging.cpp \
$(BOOT_ROOT)/src/blfwk/src/options.cpp \
$(BOOT_ROOT)/src/blfwk/src/SBSourceFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/SearchPath.cpp \
$(BOOT_ROOT)/src/blfwk/src/serial.c \
$(BOOT_ROOT)/src/blfwk/src/SerialPacketizer.cpp \
$(BOOT_ROOT)/src/blfwk/src/SourceFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/SRecordSourceFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/IntelHexSourceFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/StELFFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/StExecutableImage.cpp \
$(BOOT_ROOT)/src/blfwk/src/StSRecordFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/StIntelHexFile.cpp \
$(BOOT_ROOT)/src/blfwk/src/Updater.cpp \
$(BOOT_ROOT)/src/blfwk/src/UartPeripheral.cpp \
$(BOOT_ROOT)/src/blfwk/src/UsbHidPacketizer.cpp \
$(BOOT_ROOT)/src/blfwk/src/UsbHidPeripheral.cpp \
$(BOOT_ROOT)/src/blfwk/src/utils.cpp \
$(BOOT_ROOT)/src/blfwk/src/Value.cpp \
$(BOOT_ROOT)/src/crc/src/crc16.c \
$(BOOT_ROOT)/src/crc/src/crc32.c \
#$(BOOT_ROOT)/src/blfwk/src/Simulator.cpp
#$(BOOT_ROOT)/src/blfwk/src/SimulatorMemory.cpp
#$(BOOT_ROOT)/src/blfwk/src/SimPacketizer.cpp
#$(BOOT_ROOT)/src/blfwk/src/SimPeripheral.cpp
#$(BOOT_ROOT)/src/bootloader/src/command.cpp
#$(BOOT_ROOT)/src/sbloader/src/sbloader.c
#$(BOOT_ROOT)/src/property/src/property.c
#$(BOOT_ROOT)/src/memory/src/memory.c
#$(BOOT_ROOT)/src/bootloader/src/bootloader_context.cpp
INCLUDES := $(foreach includes, $(INCLUDES), -I $(includes))
ifeq "$(build)" "debug"
DEBUG_OR_RELEASE := Debug
CFLAGS += -g
CXXFLAGS += -g
LDFLAGS += -g
else
DEBUG_OR_RELEASE := Release
endif
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
CXXFLAGS += -D LINUX
CFLAGS += -D LINUX
SOURCES += $(BOOT_ROOT)/src/blfwk/src/hid-linux.c
LDFLAGS += -ludev
endif
ifeq ($(UNAME_S),Darwin)
CXXFLAGS += -D MACOSX
CFLAGS += -D MACOSX
SOURCES += $(BOOT_ROOT)/src/blfwk/src/hid-mac.c
LDFLAGS += -lhidapi -framework IOKit -framework CoreFoundation
endif
TARGET_OUTPUT_ROOT := $(OUTPUT_ROOT)/$(DEBUG_OR_RELEASE)
MAKE_TARGET := $(TARGET_OUTPUT_ROOT)/$(APP_NAME)
OBJS_ROOT = $(TARGET_OUTPUT_ROOT)/obj
# Strip sources.
SOURCES := $(strip $(SOURCES))
# Convert sources list to absolute paths and root-relative paths.
SOURCES_ABS := $(foreach s,$(SOURCES),$(abspath $(s)))
SOURCES_REL := $(subst $(BOOT_ROOT)/,,$(SOURCES_ABS))
# Get a list of unique directories containing the source files.
SOURCE_DIRS_ABS := $(sort $(foreach f,$(SOURCES_ABS),$(dir $(f))))
SOURCE_DIRS_REL := $(subst $(BOOT_ROOT)/,,$(SOURCE_DIRS_ABS))
OBJECTS_DIRS := $(addprefix $(OBJS_ROOT)/,$(SOURCE_DIRS_REL))
# Filter source files list into separate source types.
C_SOURCES = $(filter %.c,$(SOURCES_REL))
CXX_SOURCES = $(filter %.cpp,$(SOURCES_REL))
ASM_s_SOURCES = $(filter %.s,$(SOURCES_REL))
ASM_S_SOURCES = $(filter %.S,$(SOURCES_REL))
# Convert sources to objects.
OBJECTS_C := $(addprefix $(OBJS_ROOT)/,$(C_SOURCES:.c=.o))
OBJECTS_CXX := $(addprefix $(OBJS_ROOT)/,$(CXX_SOURCES:.cpp=.o))
OBJECTS_ASM := $(addprefix $(OBJS_ROOT)/,$(ASM_s_SOURCES:.s=.o))
OBJECTS_ASM_S := $(addprefix $(OBJS_ROOT)/,$(ASM_S_SOURCES:.S=.o))
# Complete list of all object files.
OBJECTS_ALL := $(sort $(OBJECTS_C) $(OBJECTS_CXX) $(OBJECTS_ASM) $(OBJECTS_ASM_S))
#-------------------------------------------------------------------------------
# Default target
#-------------------------------------------------------------------------------
# Note that prerequisite order is important here. The subdirectories must be built first, or you
# may end up with files in the current directory not getting added to libraries. This would happen
# if subdirs modified the library file after local files were compiled but before they were added
# to the library.
.PHONY: all
all: $(MAKE_TARGET)
## Recipe to create the output object file directories.
$(OBJECTS_DIRS) :
$(at)mkdir -p $@
# Object files depend on the directories where they will be created.
#
# The dirs are made order-only prerequisites (by being listed after the '|') so they won't cause
# the objects to be rebuilt, as the modification date on a directory changes whenver its contents
# change. This would cause the objects to always be rebuilt if the dirs were normal prerequisites.
$(OBJECTS_ALL): | $(OBJECTS_DIRS)
#-------------------------------------------------------------------------------
# Pattern rules for compilation
#-------------------------------------------------------------------------------
# We cd into the source directory before calling the appropriate compiler. This must be done
# on a single command line since make calls individual recipe lines in separate shells, so
# '&&' is used to chain the commands.
#
# Generate make dependencies while compiling using the -MMD option, which excludes system headers.
# If system headers are included, there are path problems on cygwin. The -MP option creates empty
# targets for each header file so that a rebuild will be forced if the file goes missing, but
# no error will occur.
# Compile C sources.
$(OBJS_ROOT)/%.o: $(BOOT_ROOT)/%.c
@$(call printmessage,c,Compiling, $(subst $(BOOT_ROOT)/,,$<))
$(at)$(CC) $(CFLAGS) $(SYSTEM_INC) $(INCLUDES) $(DEFINES) -MMD -MF $(basename $@).d -MP -o $@ -c $<
# Compile C++ sources.
$(OBJS_ROOT)/%.o: $(BOOT_ROOT)/%.cpp
@$(call printmessage,cxx,Compiling, $(subst $(BOOT_ROOT)/,,$<))
$(at)$(CXX) $(CXXFLAGS) $(SYSTEM_INC) $(INCLUDES) $(DEFINES) -MMD -MF $(basename $@).d -MP -o $@ -c $<
# For .S assembly files, first run through the C preprocessor then assemble.
$(OBJS_ROOT)/%.o: $(BOOT_ROOT)/%.S
@$(call printmessage,asm,Assembling, $(subst $(BOOT_ROOT)/,,$<))
$(at)$(CPP) -D__LANGUAGE_ASM__ $(INCLUDES) $(DEFINES) -o $(basename $@).s $< \
&& $(AS) $(ASFLAGS) $(INCLUDES) -MD $(OBJS_ROOT)/$*.d -o $@ $(basename $@).s
# Assembler sources.
$(OBJS_ROOT)/%.o: $(BOOT_ROOT)/%.s
@$(call printmessage,asm,Assembling, $(subst $(BOOT_ROOT)/,,$<))
$(at)$(AS) $(ASFLAGS) $(INCLUDES) -MD $(basename $@).d -o $@ $<
#------------------------------------------------------------------------
# Build the tagrget
#------------------------------------------------------------------------
# Wrap the link objects in start/end group so that ld re-checks each
# file for dependencies. Otherwise linking static libs can be a pain
# since order matters.
$(MAKE_TARGET): $(OBJECTS_ALL)
@$(call printmessage,link,Linking, $(APP_NAME))
$(at)$(LD) $(LDFLAGS) \
$(OBJECTS_ALL) \
-lc -lstdc++ -lm \
-o $@
@echo "Output binary:" ; echo " $(APP_NAME)"
#-------------------------------------------------------------------------------
# Clean
#-------------------------------------------------------------------------------
.PHONY: clean cleanall
cleanall: clean
clean:
$(at)rm -rf $(OBJECTS_ALL) $(OBJECTS_DIRS) $(MAKE_TARGET) $(APP_NAME)
# Include dependency files.
-include $(OBJECTS_ALL:.o=.d)
/*
* This file is part of the Bus Pirate project (http://code.google.com/p/the-bus-pirate/).
*
* Written and maintained by the Bus Pirate project and http://dangerousprototypes.com
*
* To the extent possible under law, the project has
* waived all copyright and related or neighboring rights to Bus Pirate. This
* work is published from United States.
*
* For details see: http://creativecommons.org/publicdomain/zero/1.0/.
*
* 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.
*/
/*
* OS independent serial interface
*
* Heavily based on Pirate-Loader:
* http://the-bus-pirate.googlecode.com/svn/trunk/bootloader-v4/pirate-loader/source/pirate-loader.c
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include "blfwk/serial.h"
#ifdef LINUX
#include <termios.h>
#endif
int serial_setup(int fd, speed_t speed)
{
#if defined(WIN32)
COMMTIMEOUTS timeouts;
DCB dcb = { 0 };
HANDLE hCom = (HANDLE)fd;
dcb.DCBlength = sizeof(dcb);
dcb.BaudRate = speed;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
if (!SetCommState(hCom, &dcb))
{
return -1;
}
// These timeouts mean:
// read: return immediately with whatever data is available, if any
// write: timeouts not used
// reference: http://www.robbayer.com/files/serial-win.pdf
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (!SetCommTimeouts(hCom, &timeouts))
{
return -1;
}
#elif defined(LINUX)
struct termios tty;
memset(&tty, 0x00, sizeof(tty));
cfmakeraw(&tty);
tty.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
tty.c_cflag |= (CS8 | CLOCAL | CREAD);
tty.c_oflag = 0;
tty.c_lflag = 0;
switch (speed)
{
case 9600:
speed = B9600;
break;
case 38400:
speed = B38400;
break;
case 115200:
speed = B115200;
break;
case 57600:
default:
speed = B57600;
break;
}
cfsetospeed(&tty, speed);
cfsetispeed(&tty, speed);
// Completely non-blocking read
// VMIN = 0 and VTIME = 0
// Completely non-blocking read
// reference: http://www.unixwiz.net/techtips/termios-vmin-vtime.html
tty.c_cc[VTIME] = 0;
tty.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSAFLUSH, &tty) < 0)
{
return -1;
}
#elif defined(MACOSX)
struct termios tty;
memset(&tty, 0x00, sizeof(tty));
if (tcgetattr(fd, &tty) < 0)
{
return -1;
}
tty.c_cflag |= (CLOCAL | CREAD); // Enable local mode and serial data receipt
if (tcsetattr(fd, TCSAFLUSH, &tty) < 0)
{
return -1;
}
return ioctl(fd, IOSSIOSPEED, &speed);
#endif // WIN32
return 0;
}
int serial_set_read_timeout(int fd, uint32_t timeoutMs)
{
#if defined(WIN32)
COMMTIMEOUTS timeouts;
HANDLE hCom = (HANDLE)fd;
// These timeouts mean:
// read: return if:
// 1. Inter-character timeout exceeds ReadIntervalTimeout
// 2. Total timeout exceeds (ReadIntervalTimeout*ReadTotalTimeoutMultiplier*number of characters) +
// ReadTotalTimeoutConstant
// In practice it seems that no matter how many characters you ask for, if no characters appear on the interface
// then
// only ReadTotalTimeoutConstant applies.
// write: timeouts not used
// reference: http://www.robbayer.com/files/serial-win.pdf
if (timeoutMs != 0)
{
timeouts.ReadIntervalTimeout = 1000;
timeouts.ReadTotalTimeoutMultiplier = 10;
timeouts.ReadTotalTimeoutConstant = timeoutMs;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
}
else
{
// Need a seperate case for timeoutMs == 0
// setting all these values to 0 results in no timeout
// so set them to a minimum value, this will return immediately
// if there is no data available
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 1;
timeouts.ReadTotalTimeoutConstant = 1;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
}
if (!SetCommTimeouts(hCom, &timeouts))
{
return -1;
}
#elif defined(LINUX)
struct termios tty;
memset(&tty, 0x00, sizeof(tty));
cfmakeraw(&tty);
tty.c_cflag &= ~(PARENB | CSTOPB | CSIZE);
tty.c_cflag |= (CS8 | CLOCAL | CREAD);
tty.c_oflag = 0;
tty.c_lflag = 0;
// Completely non-blocking read
// VMIN = 0 and VTIME > 0
// Pure timed read
// reference: http://www.unixwiz.net/techtips/termios-vmin-vtime.html
if (timeoutMs && (timeoutMs < 100))
{
// since the lowest resolution this handles is .1 seconds we will set it to that for any non zero
// timeout value less than 100ms
tty.c_cc[VTIME] = 1;
}
else
{
tty.c_cc[VTIME] = (timeoutMs / 100); // in 0.1 sec intervals
}
tty.c_cc[VMIN] = 0;
if (tcsetattr(fd, TCSAFLUSH, &tty) < 0)
{
return -1;
}
#elif defined(MAXOSX)
// Setting tty.c_cc seems to hang up the serial driver on El Capitan,
// so now using IOSSDATALAT ioctl with timeout set to 1 us.
uint32_t us = 1UL;
if (ioctl(fd, IOSSDATALAT, &us) < 0)
{
return -1;
}
#endif // WIN32
return 0;
}
int serial_write(int fd, char *buf, int size)
{
#ifdef WIN32
HANDLE hCom = (HANDLE)fd;
unsigned long bwritten = 0;
if (!WriteFile(hCom, buf, size, &bwritten, NULL))
{
return 0;
}
else
{
return bwritten;
}
#else
return write(fd, buf, size);
#endif
}
int serial_read(int fd, char *buf, int size)
{
#ifdef WIN32
HANDLE hCom = (HANDLE)fd;
unsigned long bread = 0;
if (!ReadFile(hCom, buf, size, &bread, NULL))
{
return 0;
}
else
{
return bread;
}
#else
int len = 0;
int ret = 0;
int timeout = 0;
while (len < size)
{
ret = read(fd, buf + len, size - len);
if (ret == -1)
{
return -1;
}
if (ret == 0)
{
timeout++;
if (timeout >= 10)
{
break;
}
continue;
}
len += ret;
}
return len;
#endif
}
int serial_open(char *port)
{
int fd;
#ifdef WIN32
static char full_path[32] = { 0 };
HANDLE hCom = NULL;
if (port[0] != '\\')
{
_snprintf(full_path, sizeof(full_path) - 1, "\\\\.\\%s", port);
port = full_path;
}
#pragma warning(suppress : 6053)
hCom = CreateFileA(port, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (!hCom || hCom == INVALID_HANDLE_VALUE)
{
fd = -1;
}
else
{
fd = (int)hCom;
}
#else
fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
fprintf(stderr, "Could not open serial port.");
return -1;
}
#endif
return fd;
}
int serial_close(int fd)
{
#ifdef WIN32
HANDLE hCom = (HANDLE)fd;
CloseHandle(hCom);
#else
close(fd);
#endif
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment