From 7b1ae2029ad33a38e1e718a33e2879325b389332 Mon Sep 17 00:00:00 2001 From: Srimanta Panda Date: Thu, 13 Oct 2011 10:17:16 +0200 Subject: Added Windows Support RIFF will be supported for the Windows platform. It requires libusb-win32 library to build it. --- .gitignore | 16 +++ CDAL/AsyncCommunication.cpp | 2 +- CDAL/CDAL.cpp | 116 ++++++++++++++++- CDAL/CDAL.h | 12 +- CDAL/CDAL.mk | 5 +- CDAL/CDAL.vcproj | 286 +++++++++++++++++++++++++++++++++++++++++ CDAL/CommDevice.cpp | 2 + CDAL/CommDeviceManager.cpp | 1 + CDAL/CommDeviceManager.h | 4 + CDAL/CommException.cpp | 1 + CDAL/Debug.h | 10 +- CDAL/LibusbDevice.cpp | 1 + CDAL/LibusbDevice_win.cpp | 195 ++++++++++++++++++++++++++++ CDAL/LibusbDevice_win.h | 51 ++++++++ CDAL/stdafx.cpp | 13 ++ CDAL/stdafx.h | 30 +++++ README | 3 +- README-WINDOWS | 110 ++++++++++++++++ dependencies/readme.txt | 9 ++ doc/man/man1 | 2 +- os_wrappers/CriticalSection.h | 5 +- os_wrappers/Event.cpp | 9 +- os_wrappers/Utilities.h | 9 ++ packages/control | 4 +- riff/Config.cpp | 3 +- riff/DUT.cpp | 4 +- riff/DumpArea.cpp | 41 +++--- riff/EraseArea.cpp | 4 +- riff/InitializeDut.cpp | 24 ++-- riff/Logger.cpp | 11 +- riff/Logger.h | 6 +- riff/ProcessRawImage.cpp | 13 +- riff/Shutdown.cpp | 2 +- riff/main.cpp | 54 ++++---- riff/main.h | 6 + riff/riff.vcproj | 293 ++++++++++++++++++++++++++++++++++++++++++ 36 files changed, 1276 insertions(+), 81 deletions(-) create mode 100644 CDAL/CDAL.vcproj create mode 100644 CDAL/LibusbDevice_win.cpp create mode 100644 CDAL/LibusbDevice_win.h create mode 100644 CDAL/stdafx.cpp create mode 100644 CDAL/stdafx.h create mode 100644 README-WINDOWS create mode 100644 dependencies/readme.txt create mode 100644 riff/riff.vcproj diff --git a/.gitignore b/.gitignore index 71095c3..6a0ccc2 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,19 @@ core *.BACKUP.*.txt *.REMOTE.*.txt *.orig +*.sln +*.ncb +*.suo +*.user +*.obj +CDAL/Debug/ +CDAL/Release/ +riff/Debug/ +riff/Release/ +output/ +dependencies/CDAL.h +dependencies/CDAL.lib +dependencies/LCDriver.h +dependencies/LCDriver_CNH1606432.lib +dependencies/libusb.lib +dependencies/usb.h \ No newline at end of file diff --git a/CDAL/AsyncCommunication.cpp b/CDAL/AsyncCommunication.cpp index e767a61..3987de8 100644 --- a/CDAL/AsyncCommunication.cpp +++ b/CDAL/AsyncCommunication.cpp @@ -9,7 +9,7 @@ * License terms: 3-clause BSD license * */ - +#include "stdafx.h" #include "AsyncCommunication.h" #include "CommDevice.h" #include "Debug.h" diff --git a/CDAL/CDAL.cpp b/CDAL/CDAL.cpp index 99cadf7..6b4a457 100644 --- a/CDAL/CDAL.cpp +++ b/CDAL/CDAL.cpp @@ -10,6 +10,7 @@ * */ +#include "stdafx.h" #include "CDAL.h" #include "Debug.h" #include "CommDevice.h" @@ -17,21 +18,28 @@ #include "CommException.h" #include "Event.h" #include "Thread.h" -#include "LibusbDevice.h" -#include #include #include #include +#ifdef _WIN32 +#include "LibusbDevice_win.h" +#else +#include "LibusbDevice.h" +#endif using namespace std; +#ifndef _WIN32 +static libusb_context* context; +#endif + static int DUT_VENDOR_ID = 0x04cc; static int DUT_PRODUCT_ID = 0x8500; -static libusb_context* context; static Thread* workerThread; static void* LibusbWorker(void* arg); volatile bool shutdown = false; int error = 0; + static EventCallback_t OnDeviceCallback = NULL; void usb_init_driver(const char* vendorId, const char* productId) @@ -44,8 +52,13 @@ void usb_init_driver(const char* vendorId, const char* productId) DUT_PRODUCT_ID = strtol(productId, NULL, 16); } +#ifdef _WIN32 + usb_init(); + usb_set_debug(2); +#else libusb_init(&context); - libusb_set_debug(context, 3); + libusb_set_debug(context, 2); +#endif workerThread = new Thread(LibusbWorker, 0); } @@ -63,7 +76,10 @@ void usb_deinit_driver() CommDeviceManager::destroyAll(); +#ifndef _WIN32 libusb_exit(context); +#endif + } void usb_destroy_device(Device_t device, int error_code) @@ -134,11 +150,102 @@ void comm_progress(void *Communication_p, unsigned long long totalbytes, fflush(stdout); } +#ifdef _WIN32 +// As we are going to use libusb 0.1 version in Windows, +// this function needs to be re-writtten with the API +// related to the 0.1 version. The libusb 1.0 and 0.1 +// differs a lot according to their function calls and +// the way USB devices are recognized and handled. +static void* LibusbWorker(void* arg) +{ + struct usb_bus *busses; + struct usb_bus *bus; + + while (!shutdown) { + + usb_find_busses(); + usb_find_devices(); + busses = usb_get_busses(); + + if(busses == NULL ) { + Debug::info("No USB device connected."); + Sleep(10); + continue; + } + + for (bus = busses; bus; bus = bus->next) { + struct usb_device *dev = NULL; + + for (dev = bus->devices; dev; dev = dev->next) { + if ((dev->descriptor.idProduct == DUT_PRODUCT_ID) && (dev->descriptor.idVendor == DUT_VENDOR_ID) && (!shutdown)) { + + LibusbDevice *device; + + device = CommDeviceManager::getDevice(dev); + + if (0 == device) { + // new device found + try { + device = CommDeviceManager::createDevice (dev); + Debug::info("Libusb worker: Connected libusb device"); + OnDeviceCallback(COMM_DEVICE_SUCCESS, + LIBUSB_DEVICE_CONNECTED, device); + } catch (CommException e) { + Debug::error("Libusb worker: %s", e.what()); + OnDeviceCallback(e.getError(), + COMM_DEVICE_UNDEFINED_EVENT, 0); + } + } + } + } + } + + vector devices = CommDeviceManager::getAllDevices(); + + for (vector::iterator i = devices.begin(); i + != devices.end(); ++i) { + LibusbDevice* device = dynamic_cast(*i); + + if (0 == device) { + continue; + } + + bool connected = false; + struct usb_device *dev; + for (bus = busses; bus; bus = bus->next) { + for (dev = bus->devices; dev; dev = dev->next) { + if (dev == device->getPort()) { + connected = true; + break; + } + } + if(connected == true) + break; + } + + if (!connected) { + Debug::info("Libusb worker: Disconnected device with id %d", *i); + OnDeviceCallback(COMM_DEVICE_SUCCESS, + LIBUSB_DEVICE_DISCONNECTED, *i); + shutdown = true; + } + } + + Sleep(10); + } + + return 0; +} +#else +// In Linux, libusb 1.0 version is used. Therefore, +// the below LibusbWorker function is based on API +// for libusb 1.0 for handling USB devices. static void* LibusbWorker(void* arg __attribute__((unused))) { timespec delay; delay.tv_sec = 0; delay.tv_nsec = 10 * 1000000; // 10ms + libusb_device** deviceList; ssize_t deviceCount; libusb_device_descriptor descriptor; @@ -220,4 +327,5 @@ static void* LibusbWorker(void* arg __attribute__((unused))) return 0; } +#endif diff --git a/CDAL/CDAL.h b/CDAL/CDAL.h index d87b79b..33e6d18 100644 --- a/CDAL/CDAL.h +++ b/CDAL/CDAL.h @@ -14,12 +14,21 @@ * channel. */ #pragma once + +#if defined(_WIN32) +#ifdef CDAL_EXPORTS +#define CDAL_API __declspec(dllexport) +#else +#define CDAL_API __declspec(dllimport) +#endif +#elif defined(__linux__) #include #ifdef CDAL_EXPORTS #define CDAL_API __attribute__((visibility("default"))) #else #define CDAL_API #endif +#endif // type of the device typedef enum { @@ -38,7 +47,8 @@ typedef enum { COMM_DEVICE_UART_FAILED_TO_CONFIGURE_PORT = 5, COMM_DEVICE_LIBUSB_FAILED_TO_OPEN_PORT = 6, COMM_DEVICE_LIBUSB_FAILED_TO_CLAIM_INTERFACE = 7, - COMM_DEVICE_PEEK_BUFFER_SIZE_ERROR = 8 + COMM_DEVICE_PEEK_BUFFER_SIZE_ERROR = 8, + COMM_DEVICE_LIBUSB_FAILED_TO_SET_CONFIG = 9 } DeviceStatus_t; // device events codes diff --git a/CDAL/CDAL.mk b/CDAL/CDAL.mk index e324b7d..043015c 100644 --- a/CDAL/CDAL.mk +++ b/CDAL/CDAL.mk @@ -24,6 +24,7 @@ SOURCE_FILES= \ ./CommDeviceManager.cpp \ ./CommException.cpp \ ./LibusbDevice.cpp \ + ./stdafx.cpp \ ../os_wrappers/CriticalSection.cpp \ ../os_wrappers/Event.cpp \ ../os_wrappers/Thread.cpp \ @@ -34,8 +35,9 @@ HEADER_FILES= \ ./CommDevice.h \ ./CommDeviceManager.h \ ./CommException.h \ - ./LibusbDevice.h \ ./Debug.h \ + ./LibusbDevice.h \ + ./stdafx.h \ ../os_wrappers/CriticalSection.h \ ../os_wrappers/Event.h \ ../os_wrappers/Thread.h \ @@ -48,6 +50,7 @@ OBJS= \ ./CommDeviceManager.o \ ./CommException.o \ ./LibusbDevice.o \ + ./stdafx.o \ ../os_wrappers/CriticalSection.o \ ../os_wrappers/Event.o \ ../os_wrappers/Thread.o \ diff --git a/CDAL/CDAL.vcproj b/CDAL/CDAL.vcproj new file mode 100644 index 0000000..19485c4 --- /dev/null +++ b/CDAL/CDAL.vcproj @@ -0,0 +1,286 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/CDAL/CommDevice.cpp b/CDAL/CommDevice.cpp index d4c1f71..4f4b1c7 100644 --- a/CDAL/CommDevice.cpp +++ b/CDAL/CommDevice.cpp @@ -10,9 +10,11 @@ * */ +#include "stdafx.h" #include "CommDevice.h" #include "AsyncCommunication.h" +using namespace std; CommDevice::CommDevice(): isReadCanceled_(false) { async_ = new AsyncCommunication(this); diff --git a/CDAL/CommDeviceManager.cpp b/CDAL/CommDeviceManager.cpp index bd94651..0c9da52 100644 --- a/CDAL/CommDeviceManager.cpp +++ b/CDAL/CommDeviceManager.cpp @@ -10,6 +10,7 @@ * */ +#include "stdafx.h" #include "CommDeviceManager.h" #include "CommDevice.h" #include "CommException.h" diff --git a/CDAL/CommDeviceManager.h b/CDAL/CommDeviceManager.h index fef36de..b13a613 100644 --- a/CDAL/CommDeviceManager.h +++ b/CDAL/CommDeviceManager.h @@ -15,7 +15,11 @@ #include "CDAL.h" #include "CommDevice.h" #include +#ifdef _WIN32 +#include +#else #include +#endif class CommDeviceManager { diff --git a/CDAL/CommException.cpp b/CDAL/CommException.cpp index 4485cba..81f78f7 100644 --- a/CDAL/CommException.cpp +++ b/CDAL/CommException.cpp @@ -10,6 +10,7 @@ * */ +#include "stdafx.h" #include "CommException.h" #include #include diff --git a/CDAL/Debug.h b/CDAL/Debug.h index 69e5112..cb3a503 100644 --- a/CDAL/Debug.h +++ b/CDAL/Debug.h @@ -13,9 +13,9 @@ #pragma once //#define _DEBUG +#define DEBUG_ERROR #ifdef _DEBUG #define DEBUG_INFO -#define DEBUG_ERROR #define DEBUG_HEXDUMP #define DEBUG_HEXDUMP_SIZE 1024 #endif @@ -35,7 +35,11 @@ class Debug { public: +#ifdef _WIN32 + inline static void error(const char* format, ...) { +#else inline static void error(const char* format, ...) __attribute__((format(printf, 1, 0))) { +#endif #ifdef DEBUG_ERROR flockfile(stdout); printf("ERROR - "); @@ -49,7 +53,11 @@ public: #endif } +#ifdef _WIN32 + static inline void info(const char* format, ...) { +#else static inline void info(const char* format, ...) __attribute__((format(printf, 1, 0))) { +#endif #ifdef DEBUG_INFO flockfile(stdout); printf("INFO - "); diff --git a/CDAL/LibusbDevice.cpp b/CDAL/LibusbDevice.cpp index 337df46..6e2c670 100644 --- a/CDAL/LibusbDevice.cpp +++ b/CDAL/LibusbDevice.cpp @@ -10,6 +10,7 @@ * */ +#include "stdafx.h" #include "LibusbDevice.h" #include "Debug.h" #include "CommException.h" diff --git a/CDAL/LibusbDevice_win.cpp b/CDAL/LibusbDevice_win.cpp new file mode 100644 index 0000000..443adcc --- /dev/null +++ b/CDAL/LibusbDevice_win.cpp @@ -0,0 +1,195 @@ +/* + * LibusbDevice_win.cpp + * + * Copyright (C) ST-Ericsson SA 2011 + * Authors: Srimanta Panda , + * Ola Borgelin , + * Karin Hedlund , + * Markus Andersson for ST-Ericsson. + * License terms: 3-clause BSD license + * + */ + +#include "stdafx.h" +#include "LibusbDevice_win.h" +#include "Debug.h" +#include "CommException.h" +#include +#include + +using namespace std; + +#define MIN(A, B) ((A) < (B) ? (A) : (B)) + +LibusbDevice::LibusbDevice(struct usb_device* device): + device_(device), + inEndpoint_(-1), + outEndpoint_(-1) +{ + // get the handle for the device + handle_ = usb_open(device_); + if (handle_ == NULL) { + throw CommException("failed to open usb device", COMM_DEVICE_LIBUSB_FAILED_TO_OPEN_PORT); + } + + int configValue_ = device_->config->bConfigurationValue; + + if (usb_set_configuration(handle_, configValue_)) { + Debug::error("Setting configuration failed!" ); + throw CommException("Setting configuration failed!", COMM_DEVICE_LIBUSB_FAILED_TO_SET_CONFIG); + } else { + Debug::info("Configuration has been set successfully.."); + } + + if ((this->device_->config->bNumInterfaces > 0) && (this->device_->config->interface->num_altsetting > 0)) { + interfaceNumber_ = device_->config->interface->altsetting->bInterfaceNumber; + +#if defined(LIBUSB_HAS_GET_DRIVER_NP) +#if defined(LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP) + char name[256]; + if (usb_get_driver_np(handle_, interfaceNumber_, (char *) name, sizeof(name))) { + Debug::info("Fetching driver name failed: %s", usb_strerror()); + } else { + Debug::info("Driver name: %s", name); + if (usb_detach_kernel_driver_np(handle_, interfaceNumber_)) { + Debug::error("Detaching kernel driver failed: %s", usb_strerror()); + } + Debug::info(""Kernel driver has been detached successfully."); + } +#endif +#endif + + // Claim the interface for the device + if (usb_claim_interface(handle_, interfaceNumber_)) { + opened_ = false; + Debug::error("Claiming interface failed: %s", usb_strerror()); + throw CommException("Claiming interface failed", COMM_DEVICE_LIBUSB_FAILED_TO_CLAIM_INTERFACE); + } else { + Debug::info("Interface has been claimed successfuly.."); + opened_ = true; + } + + Debug::info("Looking for endpoints.."); + + //find default endpoints + for (int i = 0; i < device_->config->interface->altsetting->bNumEndpoints; i++) { + if ((inEndpoint_ != -1) && (outEndpoint_ != -1)) break; + if (device_->config->interface->altsetting->endpoint[i].bEndpointAddress & 0x80) { + if ((inEndpoint_ == -1) + && ((device_->config->interface->altsetting->endpoint[i].bmAttributes & 0x3f) == 0x2)) + { + inEndpoint_ = device_->config->interface->altsetting->endpoint[i].bEndpointAddress; + Debug::info("Bulk IN endpoint found and ready to use on address %02xh", inEndpoint_); + } + } else { + if ((outEndpoint_ == -1) + && ((device_->config->interface->altsetting->endpoint[i].bmAttributes & 0x3f) == 0x2)) + { + outEndpoint_ = device_->config->interface->altsetting->endpoint[i].bEndpointAddress; + Debug::info("Bulk OUT endpoint found and ready to use on address %02xh", outEndpoint_); + } + } + } + + if ((inEndpoint_ == -1) || (outEndpoint_ == -1)) { + Debug::error("Bulk endpoints cannot be found!"); + throw CommException("Not able to set endpoints for device", COMM_DEVICE_LIBUSB_FAILED_TO_OPEN_PORT); + } + } + readBufferLength_ = 0; + readBufferHead_ = readBuffer_; +} + +LibusbDevice::~LibusbDevice() +{ + usb_release_interface(handle_, interfaceNumber_); + usb_close(handle_); +} + +int LibusbDevice::read(void *buffer, size_t size) +{ + Debug::info("LibusbDevice read: called with size %d", size); + unsigned char* dest = static_cast(buffer); + + while (true) { + if (readBufferLength_) { + size_t toCopy = MIN(readBufferLength_, size); + memcpy(dest, readBufferHead_, toCopy); + dest += toCopy; + size -= toCopy; + readBufferLength_ -= toCopy; + + if (readBufferLength_ != 0) { + readBufferHead_ += toCopy; + } else { + readBufferHead_ = readBuffer_; + } + } + + if (size == 0) { + break; + } + + int transfered; + transfered = usb_bulk_read(handle_, inEndpoint_, readBuffer_, READ_BUFFER_SIZE, 100000); + + if (isReadCanceled_) { + Debug::info("LibusbDevice read: canceled..."); + Debug::hexdump("read canceled", dest, transfered); + isReadCanceled_ = false; + return COMM_DEVICE_CANCEL; + } + + if (transfered < 0) { + if( transfered == USB_TIMEOUT_ERROR) { + Debug::info("LibusbDevice read : Usb read timeout"); + continue; + } else { + Debug::info("LibusbDevice read: error %d occured", transfered); + return transfered; + } + } + + readBufferLength_ = transfered; + } + + Debug::info("LibusbDevice read: complete"); + return 0; +} + +int LibusbDevice::write(void *buffer, size_t size) +{ + Debug::info("LibusbDevice write: called with size %d", size); + char* src = static_cast(buffer); + + while (size) { + int transfered; + //Call with timeout to enable possible cancel + transfered = usb_bulk_write(handle_, outEndpoint_, src, size, 100000); + if (transfered < 0) { + if( transfered == USB_TIMEOUT_ERROR) { + Debug::info("LibusbDevice write : Usb write timeout"); + continue; + } else { + Debug::info("LibusbDevice write: error %d occured", transfered); + return transfered; + } + } + + size -= transfered; + src += transfered; + } + + Debug::info("LibusbDevice write: complete"); + return 0; +} + +int LibusbDevice::getVendorId() +{ + return device_->descriptor.idVendor; +} + +struct usb_device* LibusbDevice::getPort() +{ + return device_; +} diff --git a/CDAL/LibusbDevice_win.h b/CDAL/LibusbDevice_win.h new file mode 100644 index 0000000..8ee484e --- /dev/null +++ b/CDAL/LibusbDevice_win.h @@ -0,0 +1,51 @@ +/* + * LibusbDevice_win.h + * + * Copyright (C) ST-Ericsson SA 2011 + * Authors: Srimanta Panda , + * Ola Borgelin , + * Karin Hedlund , + * Markus Andersson for ST-Ericsson. + * License terms: 3-clause BSD license + * + */ + +#pragma once +#ifdef _WIN32 +#include +#else +#include +#endif +#include "CommDevice.h" + +// Timeout error code for usb transfer +#define USB_TIMEOUT_ERROR -116 + +class LibusbDevice : public CommDevice +{ +public: + LibusbDevice(struct usb_device* device); + ~LibusbDevice(); + + int read(void* buffer, size_t size); + int write(void* buffer, size_t size); + + int getVendorId(); + struct usb_device* getPort(); + + unsigned long getPhysicalAddress() { + return 0; + } +private: + struct usb_device* device_; + struct usb_dev_handle* handle_; + int interfaceNumber_; + int outEndpoint_; + int inEndpoint_; + bool opened_; + + static const int READ_BUFFER_SIZE = 4096; + char readBuffer_[READ_BUFFER_SIZE]; + char* readBufferHead_; + size_t readBufferLength_; +}; diff --git a/CDAL/stdafx.cpp b/CDAL/stdafx.cpp new file mode 100644 index 0000000..169b1ed --- /dev/null +++ b/CDAL/stdafx.cpp @@ -0,0 +1,13 @@ +/* + * stdafx.cpp + * + * Copyright (C) ST-Ericsson SA 2011 + * Authors: Srimanta Panda , + * Ola Borgelin , + * Karin Hedlund , + * Markus Andersson for ST-Ericsson. + * License terms: 3-clause BSD license + * + */ + +#include "stdafx.h" diff --git a/CDAL/stdafx.h b/CDAL/stdafx.h new file mode 100644 index 0000000..65d5da9 --- /dev/null +++ b/CDAL/stdafx.h @@ -0,0 +1,30 @@ +/* + * stdafx.h + * + * Copyright (C) ST-Ericsson SA 2011 + * Authors: Srimanta Panda , + * Ola Borgelin , + * Karin Hedlund , + * Markus Andersson for ST-Ericsson. + * License terms: 3-clause BSD license + * + */ + +#pragma once + + +#ifdef _WIN32 + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include +#include +#include + +#include +#include +#include +#include +#else +#include +#endif // _WIN32 diff --git a/README b/README index 0a8bece..265d3d0 100644 --- a/README +++ b/README @@ -1,4 +1,4 @@ -riff - Raw Image File Flasher version 0.4.2 +riff - Raw Image File Flasher version 0.5.0 ================================================================================= Description: @@ -104,6 +104,7 @@ Version history and changelog: 0.4.0 Dump functionality added. 0.4.1 Packaging and README updated. 0.4.2 Larger image file support. +0.5.0 Support for Windows. ================================================================================= Contact and support diff --git a/README-WINDOWS b/README-WINDOWS new file mode 100644 index 0000000..e8d3b1b --- /dev/null +++ b/README-WINDOWS @@ -0,0 +1,110 @@ +riff - Raw Image File Flasher version 0.5.0 + +================================================================================= +Description: +================================================================================= +A tool for flashing a device. + +================================================================================= +Hardware and software requirements: +================================================================================= +NOTE that building the tool requires the following libraries and header file to +be placed on 'dependencies' folder: + +libusb.lib (libusb-win32 library for Windows, rename the library to libusb.lib) +usb.h + +LCDriver_CNH1606432.lib (riff-laodercomm library on Igloo) +LCDriver.h + +NOTE: To use riff on internal development board riff-configpack-internal also +needs to be installed. To use internal config pack instead of default use +'snowball_internal' config pack. + +================================================================================= +Usage: +================================================================================= + +'riff' build requires 'CDAL' library (CDAL.lib), therefore build the CDAL +project before building the project for 'riff'. Use 'Release' build to get +less debug messages during runtime. + +The required lib and executable will be created in a 'output' folder. Copy +'LCDriver_CNH1606432.dll' to 'output' folder to run 'riff.exe' + +## Configuration file ## +A template config file is provided in the source tree as config/riff.config +It will be renamed and placed in /output/riff/config + +This file can be overridden with a user-specific config file placed in +/.riff, or by providing a full path to a config file at +runtime, as option on the command line (using the -c option). + +riff will look for configuration file to use in the following order: +1) Config file provided on command line (using the -c option) at runtime. +2) Config file in user's home directory (/.riff/config) +3) //riff/config + + +## Running ## + +Usage: riff [OPTION]...[FILE]... + + Available command line arguments are: + + -h, --help Display this help message. + -m, --mode ACTION Select the mode. + ACTION is `flash` or `erase` + -c, --config PATH Give path to configuration file. + -f, --flashimage IMAGEPATH Give path to flashimage. + -a, --address FLASHADDR Give a start address in hex. + -l, --length HEXLENGTH Length of the dump [Byte] in hex. + -d, --dumppath DUMPPATH File path on PC where to store dump. + -v, --verbose Shows more detailed information. + --version Shows version information. + +Examples: + +$ riff -f + +Default mode 'flash' will be used, and configuration originally from config/riff.config +but put in /riff will be used (if the user hasn't overridden +this file by its own in /.riff/config). +The flashimage at the provided path will be flashed onto the device starting at address 0. + +To start at any other address than 0, use + +$ riff -f -a
+ +WARNING: +NOTE THAT RIFF HAS NO WAY OF KNOWING WHETHER YOU ARE OVERWRITING IMPORTANT +SECTIONS ON YOUR DEVICE OR NOT WHEN FLASHING! THE TOOL DOES NOT WARN YOU OR +PREVENT YOU FROM PROVIDING ANY ADDRESS TO FLASH TO. +In other words: it's up to you to know what you're doing, the tool takes no +responsibility for it! + +Path to flashimage can also be specified in the config file and the -f flag +can then be omitted. + + +================================================================================= +Known issues: +================================================================================= +1) Linux can't find device. +Power down device and disconnect and reconnect USB cable. +Restart the flash tool and power up the device. + +================================================================================= +Version history and changelog: +================================================================================= +0.3.0 Initial version. +0.4.0 Dump functionality added. +0.4.1 Packaging and README updated. +0.4.2 Larger image file support. +0.5.0 Support for Windows. + +================================================================================= +Contact and support +================================================================================= +http://igloocommunity.org/support + diff --git a/dependencies/readme.txt b/dependencies/readme.txt new file mode 100644 index 0000000..7c98f34 --- /dev/null +++ b/dependencies/readme.txt @@ -0,0 +1,9 @@ +Before building the loader communication you need to copy dependency libraries +and header files here. + +Here is how the contents of ./dependencies how it should look like: + +libusb.lib +LCDriver_CNH1606432.lib +usb.h +LCDriver.h \ No newline at end of file diff --git a/doc/man/man1 b/doc/man/man1 index 6b3c14d..240d6f9 100644 --- a/doc/man/man1 +++ b/doc/man/man1 @@ -20,7 +20,7 @@ Prints a breif description of the command-line options. .B -m ACTION, --mode ACTION .br -Use ACTION to select flash or erase mode. +Use ACTION to select flash, erase or dump mode. .B -c PATH, --config PATH .br diff --git a/os_wrappers/CriticalSection.h b/os_wrappers/CriticalSection.h index f67f42a..7b64f90 100644 --- a/os_wrappers/CriticalSection.h +++ b/os_wrappers/CriticalSection.h @@ -17,7 +17,10 @@ #pragma once -#ifndef _WIN32 +#ifdef _WIN32 +#include +#include +#else #include #endif diff --git a/os_wrappers/Event.cpp b/os_wrappers/Event.cpp index 0390735..cbe5aa3 100644 --- a/os_wrappers/Event.cpp +++ b/os_wrappers/Event.cpp @@ -44,13 +44,16 @@ void Event::signal() #endif } -void Event::wait(unsigned long timeout __attribute__((unused))) -{ #ifdef _WIN32 +void Event::wait(unsigned long timeout) +{ WaitForSingleObject(semaphore_, timeout); +} #else +void Event::wait(unsigned long timeout __attribute__((unused))) +{ sem_wait(&semaphore_); -#endif } +#endif /* @} */ diff --git a/os_wrappers/Utilities.h b/os_wrappers/Utilities.h index ca7eac9..ff7463d 100644 --- a/os_wrappers/Utilities.h +++ b/os_wrappers/Utilities.h @@ -18,16 +18,25 @@ #pragma once #include #include +#ifdef _WIN32 +#include +#endif using namespace std; + class Utilities { public: + static void sleep(int ms) { +#ifndef _WIN32 timespec delay; delay.tv_sec = 0; delay.tv_nsec = ms * 1000000; nanosleep(&delay, 0); +#else + Sleep(ms); +#endif } template diff --git a/packages/control b/packages/control index 8e933d5..92eb075 100644 --- a/packages/control +++ b/packages/control @@ -1,8 +1,8 @@ Package: riff -Version: 0.4.2 +Version: 0.5.0 Priority: optional Architecture: all -Depends: libusb-1.0-0, riff-configpack (>= 0.4.2), riff-loadercomm (>= 0.4.2) +Depends: libusb-1.0-0, riff-configpack (>= 0.4.3), riff-loadercomm (>= 0.4.3) Installed-Size: Maintainer: packages@igloocommunity.org Section: devel diff --git a/riff/Config.cpp b/riff/Config.cpp index c35f333..127f2b7 100644 --- a/riff/Config.cpp +++ b/riff/Config.cpp @@ -15,6 +15,7 @@ * @{ */ + #include "Config.h" #include "Utilities.h" #include @@ -61,7 +62,7 @@ bool Config::load(const string& path) return true; } else { - logger_.log(Logger::ERROR, "Failed to open configuration file \"%s\"", path.c_str()); + logger_.log(Logger::ERR, "Failed to open configuration file \"%s\"", path.c_str()); return false; } } diff --git a/riff/DUT.cpp b/riff/DUT.cpp index 6019518..747727d 100644 --- a/riff/DUT.cpp +++ b/riff/DUT.cpp @@ -31,7 +31,7 @@ using namespace std; do { \ if (0 != error) \ { \ - logger_.log(Logger::ERROR,"COMMAND ERROR: %s %d", message, error); \ + logger_.log(Logger::ERR,"COMMAND ERROR: %s %d", message, error); \ usb_destroy_device(commDevice_, error); \ errorcode_ = error; \ return; \ @@ -59,7 +59,7 @@ DUT::~DUT() int error = DestroyContext(&lcdContext_); if (0 != error) { - logger_.log(Logger::ERROR, "LCD ERROR: Failed to destroy LCD context %d", error); + logger_.log(Logger::ERR, "LCD ERROR: Failed to destroy LCD context %d", error); } else { logger_.log(Logger::INFO, "LCD context destroyed successfully"); } diff --git a/riff/DumpArea.cpp b/riff/DumpArea.cpp index 2f7fcf6..29343e7 100644 --- a/riff/DumpArea.cpp +++ b/riff/DumpArea.cpp @@ -37,31 +37,30 @@ DumpArea::DumpArea(const char* path, uint64 start, uint64 length, const char* fi int DumpArea::run(DUT* dut) { - logger_.log(Logger::PROGRESS, "Dumping area..."); - logger_.log(Logger::PROGRESS, "Dump path is %s", pchFilePath); - int error = checkInput(); - if (error == -1) { - return error; - } - error = Flash_DumpArea(dut->getLCDContext(), pchPath, uiStart, uiLength, pchFilePath, uiRedundantArea, iUseBulk); - if (0 != error) - { - logger_.log(Logger::ERROR,"LCD ERROR: Dump area failed %d", error); - return error; - } - // Need a new line braek after the progress bar - logger_.logRaw("\n"); - logger_.log(Logger::INFO, "Dump area finished successfully"); - return error; + logger_.log(Logger::PROGRESS, "Dumping area..."); + logger_.log(Logger::PROGRESS, "Dump path is %s", pchFilePath); + int error = checkInput(); + if (error == -1) { + return error; + } + error = Flash_DumpArea(dut->getLCDContext(), pchPath, uiStart, uiLength, pchFilePath, uiRedundantArea, iUseBulk); + if (0 != error) { + logger_.log(Logger::ERR,"LCD ERROR: Dump area failed %d", error); + return error; + } + // Need a new line braek after the progress bar + logger_.logRaw("\n"); + logger_.log(Logger::INFO, "Dump area finished successfully"); + return error; } int DumpArea::checkInput() { - if (uiLength <= 0) { - logger_.log(Logger::ERROR, "Length of the dump not specified. Use -l or --length option"); - return -1; - } - return 0; + if (uiLength <= 0) { + logger_.log(Logger::ERR, "Length of the dump not specified. Use -l or --length option"); + return -1; + } + return 0; } const char * DumpArea::get_command_name() diff --git a/riff/EraseArea.cpp b/riff/EraseArea.cpp index 3de8ed0..0198c6b 100644 --- a/riff/EraseArea.cpp +++ b/riff/EraseArea.cpp @@ -29,12 +29,12 @@ EraseArea::EraseArea(const char* path, uint64 start, uint64 length): int EraseArea::run(DUT* dut) { - logger_.log(Logger::PROGRESS, "Erasing area..."); + logger_.log(Logger::PROGRESS, "Erasing area..."); int error = Flash_EraseArea(dut->getLCDContext(), pchPath, uiStart, uiLength); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Erase area failed %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Erase area failed %d", error); return error; } diff --git a/riff/InitializeDut.cpp b/riff/InitializeDut.cpp index e2feb18..9088c13 100644 --- a/riff/InitializeDut.cpp +++ b/riff/InitializeDut.cpp @@ -36,7 +36,7 @@ int InitializeDut::readIsswFile(char* buf) isswImage = fopen(isswPath_, "rb"); if (isswImage == NULL) { - logger_.log(Logger::ERROR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, isswPath_); + logger_.log(Logger::ERR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, isswPath_); return -1; } @@ -54,7 +54,7 @@ int InitializeDut::readSecondIsswFile(char* buf) xloaderImage = fopen(xloaderPath_, "rb"); if (xloaderImage == NULL) { - logger_.log(Logger::ERROR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, xloaderPath_); + logger_.log(Logger::ERR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, xloaderPath_); return -1; } @@ -70,7 +70,7 @@ int InitializeDut::readPwrMgtFile(char* buf) pwrmgmtImage = fopen(pwrmgmtPath_, "rb"); if (pwrmgmtImage == NULL) { - logger_.log(Logger::ERROR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, pwrmgmtPath_); + logger_.log(Logger::ERR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, pwrmgmtPath_); return -1; } @@ -86,7 +86,7 @@ int InitializeDut::readMeminitFile(char* buf) meminitImage = fopen(meminitPath_, "rb"); if (meminitImage == NULL) { - logger_.log(Logger::ERROR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, meminitPath_); + logger_.log(Logger::ERR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, meminitPath_); return -1; } @@ -102,7 +102,7 @@ int InitializeDut::readNormal(char* buf) normalImage = fopen(normalPath_, "rb"); if (normalImage == NULL) { - logger_.log(Logger::ERROR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, normalPath_); + logger_.log(Logger::ERR, "InitializeDut.cpp (%d) %s() error while opening file %s", __LINE__, __FUNCTION__, normalPath_); return -1; } @@ -378,7 +378,7 @@ int InitializeDut::run(DUT* dut) error = initializeHardware(commDevice); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Error while initializing device %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Error while initializing device %d", error); return error; } @@ -389,7 +389,7 @@ int InitializeDut::run(DUT* dut) error = CreateContext(&lcdContext, dut->getId()); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Error while creating LCD context %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Error while creating LCD context %d", error); return error; } @@ -397,7 +397,7 @@ int InitializeDut::run(DUT* dut) error = ConfigureCommunicationDevice(lcdContext, (void*)comm_read_nowait, (void*)comm_write_nowait, (void*)comm_cancel); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Error while configuring communication device %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Error while configuring communication device %d", error); return error; } @@ -405,7 +405,7 @@ int InitializeDut::run(DUT* dut) error = SwitchProtocolFamily(lcdContext, R15_PROTOCOL_FAMILY); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Error while setting protocol family %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Error while setting protocol family %d", error); return error; } @@ -413,7 +413,7 @@ int InitializeDut::run(DUT* dut) error = StartContext(lcdContext, deviceObjectStorage); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Error while starting LCD context %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Error while starting LCD context %d", error); return error; } @@ -422,7 +422,7 @@ int InitializeDut::run(DUT* dut) error = SetProgressCallback(lcdContext, (void*)comm_progress); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Error while setting Progress listener %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Error while setting Progress listener %d", error); return error; } @@ -431,7 +431,7 @@ int InitializeDut::run(DUT* dut) error = System_LoaderStartupStatus(dut->getLCDContext(), version, &versionSize, protocol, &protocolSize); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Failed to receive loader startup status %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Failed to receive loader startup status %d", error); return error; } diff --git a/riff/Logger.cpp b/riff/Logger.cpp index a54e447..186451a 100644 --- a/riff/Logger.cpp +++ b/riff/Logger.cpp @@ -15,6 +15,7 @@ * @{ */ + #include "Logger.h" #include #include @@ -23,6 +24,14 @@ #include using namespace std; +#ifdef _WIN32 +#define flockfile _lock_file +#define funlockfile _unlock_file +#define popen _popen +#define pclose _pclose +#define localtime_r(t, lt) localtime_s(lt, t) +#endif + bool Logger::verbose_; Logger::Logger(const string& name): @@ -42,7 +51,7 @@ void Logger::log(LogSeverity severity, const char* format, ...) const tm lt; localtime_r(&t, <); - if (verbose_ || severity == Logger::PROGRESS || severity == Logger::ERROR) { + if (verbose_ || severity == Logger::PROGRESS || severity == Logger::ERR) { flockfile(console_); fprintf(console_, "%02d:%02d:%02d ", lt.tm_hour, lt.tm_min, lt.tm_sec); diff --git a/riff/Logger.h b/riff/Logger.h index c995abc..8734fb2 100644 --- a/riff/Logger.h +++ b/riff/Logger.h @@ -30,7 +30,7 @@ public: enum LogSeverity { PROGRESS, - ERROR, + ERR, WARNING, INFO }; @@ -58,7 +58,11 @@ public: * @param[in] format - printf style format of the message. * @param[in] ... - variable argument list. */ +#ifdef _WIN32 + void log(LogSeverity severity, const char* format, ...) const; +#else void log(LogSeverity severity, const char* format, ...) const __attribute__((format(printf, 3, 0))); +#endif /** * @brief Print hex dump of the buffer. diff --git a/riff/ProcessRawImage.cpp b/riff/ProcessRawImage.cpp index 77f9715..e95c5af 100644 --- a/riff/ProcessRawImage.cpp +++ b/riff/ProcessRawImage.cpp @@ -46,7 +46,7 @@ int ProcessRawImage::run(DUT* dut) error = Flash_FlashRaw(dut->getLCDContext(), pchPath, uiStart, length, uiDevice, iUseBulk, iDeleteBuffers); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Process raw image failed %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Process raw image failed %d", error); return error; } @@ -55,7 +55,7 @@ int ProcessRawImage::run(DUT* dut) logger_.log(Logger::PROGRESS, "Flashing finished successfully"); } else { error = -1; - logger_.log(Logger::ERROR,"LCD ERROR: Flash image is empty or doesn't exist %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Flash image is empty or doesn't exist %d", error); return error; } @@ -64,12 +64,21 @@ int ProcessRawImage::run(DUT* dut) uint64 ProcessRawImage::filesize(const char* filename) { +#ifdef _WIN32 + struct _stat64 st; + + if (_stat64(filename, &st) == 0) + { + return st.st_size; + } +#else struct stat64 st; if (stat64(filename, &st) == 0) { return st.st_size; } +#endif return 0; } diff --git a/riff/Shutdown.cpp b/riff/Shutdown.cpp index 3dcd1a9..bfc2d33 100644 --- a/riff/Shutdown.cpp +++ b/riff/Shutdown.cpp @@ -31,7 +31,7 @@ int Shutdown::run(DUT* dut) int error = System_Shutdown(dut->getLCDContext()); if (0 != error) { - logger_.log(Logger::ERROR,"LCD ERROR: Device shutdown failed %d", error); + logger_.log(Logger::ERR,"LCD ERROR: Device shutdown failed %d", error); return error; } diff --git a/riff/main.cpp b/riff/main.cpp index 803ebe7..ab7426f 100644 --- a/riff/main.cpp +++ b/riff/main.cpp @@ -30,7 +30,7 @@ volatile bool isDone = false; const string info = \ "\n \ ----------------------- riff - Raw Image File Flasher -------------------------\n \ -Version: 0.4.2\n \ +Version: 0.5.0\n \ " "Flash a device. Try `riff --help' for more information. \n \ " @@ -83,7 +83,11 @@ int main(int argc, char* argv[]) logger_->log(Logger::PROGRESS, "Listening on USB for device connection..."); while (!isDone) { +#ifdef _WIN32 + Sleep(1000); +#else sleep(1); +#endif } usb_deinit_driver(); @@ -114,7 +118,7 @@ void UsbDeviceEventCallback(DeviceStatus_t status, DeviceEvent_t event, Device_t } break; - case LIBUSB_DEVICE_DISCONNECTED: { + case LIBUSB_DEVICE_DISCONNECTED: logger_->log(Logger::INFO, "Disconnect detected on USB@%u", comm_get_physical_address(device)); dut = DutManager::getDut(device); @@ -125,18 +129,17 @@ void UsbDeviceEventCallback(DeviceStatus_t status, DeviceEvent_t event, Device_t } isDone = true; - } - break; + break; default: - logger_->log(Logger::ERROR, "Unknown USB event %d", event); + logger_->log(Logger::ERR, "Unknown USB event %d", event); break; } } else if (COMM_DEVICE_LIBUSB_FAILED_TO_OPEN_PORT == status) { - logger_->log(Logger::ERROR, "Cannot open USB device. Are you root?", status); + logger_->log(Logger::ERR, "Cannot open USB device. Are you root?", status); isDone = true; exitstatus = 1; } else { - logger_->log(Logger::ERROR, "USB device error %d", status); + logger_->log(Logger::ERR, "USB device error %d", status); } } void handleCmdLineInput(int argc, char* argv[]) @@ -191,7 +194,11 @@ void handleCmdLineInput(int argc, char* argv[]) if (!configPathSet) { FILE* userConfig; +#ifdef _WIN32 + char* home = getenv("USERPROFILE"); +#else char* home = getenv("HOME"); +#endif char homeConfigPath[50]; strcpy(homeConfigPath, home); strcat(homeConfigPath, "/.riff/config"); @@ -203,25 +210,28 @@ void handleCmdLineInput(int argc, char* argv[]) strcpy(configFile, homeConfigPath); fclose(userConfig); } - else - { - // It will check the default config in /usr/share folder otherwise - userConfig = fopen(configFile, "r"); - if(userConfig == NULL) - { - cout << cmdHelpString << endl; - _exit(0); - } + else { + // It will check the default config in /usr/share folder otherwise + // or //riff/config + userConfig = fopen(configFile, "r"); + if(userConfig == NULL) { + cout << cmdHelpString << endl; + _exit(0); + } } } - if (*dumpPath == '\0') { - //Sets default dump path if not provided - char* home = getenv("HOME"); - strcpy(dumpPath, home); - strcat(dumpPath, "/flashdump.bin"); - } + if (*dumpPath == '\0') { + //Sets default dump path if not provided +#ifdef _WIN32 + char* home = "."; +#else + char* home = getenv("HOME"); +#endif + strcpy(dumpPath, home); + strcat(dumpPath, "/flashdump.bin"); + } SequenceFactory::setArguments(configFile, mode, flashimage, address, length, dumpPath); } diff --git a/riff/main.h b/riff/main.h index 916e523..64077d1 100644 --- a/riff/main.h +++ b/riff/main.h @@ -29,9 +29,15 @@ enum ConnectionType { }; +#ifdef _WIN32 +#endif Logger* logger_; Config* config_; +#ifdef _WIN32 +char configFile[PATH_LENGTH] = "./riff/config"; +#else char configFile[PATH_LENGTH] = RIFF_CONFIG_PREFIX "/share/riff/config"; +#endif char flashimage[PATH_LENGTH] = "\0"; char address[PATH_LENGTH] = "0"; char length[PATH_LENGTH] = "0"; diff --git a/riff/riff.vcproj b/riff/riff.vcproj new file mode 100644 index 0000000..9087e48 --- /dev/null +++ b/riff/riff.vcproj @@ -0,0 +1,293 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.2.3