├── .gitignore ├── blhost Release Notes.pdf ├── docs └── blhost User's Guide.pdf ├── src ├── blfwk │ ├── format_string.h │ ├── int_size.h │ ├── BlfwkErrors.h │ ├── bootloader_config.h │ ├── doc │ │ ├── blfwk.md │ │ └── blfwk.dox │ ├── host_types.h │ ├── src │ │ ├── Value.cpp │ │ ├── DataTarget.cpp │ │ ├── format_string.cpp │ │ ├── ExcludesListMatcher.cpp │ │ ├── SBSourceFile.cpp │ │ ├── Blob.cpp │ │ ├── GHSSecInfo.cpp │ │ ├── SearchPath.cpp │ │ ├── I2cPeripheral.cpp │ │ ├── spi.c │ │ ├── i2c.c │ │ ├── GlobMatcher.cpp │ │ ├── DataSourceImager.cpp │ │ ├── SpiPeripheral.cpp │ │ ├── UsbHidPeripheral.cpp │ │ ├── UartPeripheral.cpp │ │ ├── Logging.cpp │ │ └── SourceFile.cpp │ ├── DataSourceImager.h │ ├── SearchPath.h │ ├── utils.h │ ├── OptionContext.h │ ├── serial.h │ ├── StringMatcher.h │ ├── GlobMatcher.h │ ├── Blob.h │ ├── BusPalPeripheral.h │ ├── ExcludesListMatcher.h │ ├── stdafx.h │ ├── i2c.h │ ├── spi.h │ ├── GHSSecInfo.h │ ├── IntelHexSourceFile.h │ ├── Progress.h │ ├── SRecordSourceFile.h │ ├── UsbHidPeripheral.h │ ├── UartPeripheral.h │ ├── UsbHidPacketizer.h │ ├── I2cPeripheral.h │ ├── Packetizer.h │ ├── Bootloader.h │ ├── StSRecordFile.h │ ├── SpiPeripheral.h │ ├── DataTarget.h │ ├── Peripheral.h │ ├── EndianUtilities.h │ ├── SerialPacketizer.h │ ├── Value.h │ ├── SBSourceFile.h │ └── StIntelHexFile.h ├── crc │ ├── src │ │ ├── crc16.c │ │ └── crc32.c │ ├── crc16.h │ └── crc32.h ├── include │ └── bootloader_hid_report_ids.h └── bootloader │ └── bl_peripheral.h ├── license-public.txt ├── .vscode └── settings.json ├── meson.build ├── SW-Content-Register.txt └── mk └── common.mk /.gitignore: -------------------------------------------------------------------------------- 1 | Release 2 | -------------------------------------------------------------------------------- /blhost Release Notes.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/blhost/main/blhost Release Notes.pdf -------------------------------------------------------------------------------- /docs/blhost User's Guide.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NVIDIA/blhost/main/docs/blhost User's Guide.pdf -------------------------------------------------------------------------------- /src/blfwk/format_string.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_format_string_h_) 8 | #define _format_string_h_ 9 | 10 | #include 11 | #include 12 | 13 | /*! 14 | * \brief Returns a formatted STL string using printf format strings. 15 | */ 16 | std::string format_string(const char *fmt, ...); 17 | 18 | #endif // _format_string_h_ 19 | -------------------------------------------------------------------------------- /license-public.txt: -------------------------------------------------------------------------------- 1 | This program is distributed in the hope that it will be useful, 2 | but WITHOUT ANY WARRANTY; without even the implied warranty of 3 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 4 | 5 | NOTE: not all files are public domain. 6 | 7 | Code, code modifications, and hardware created by Dangerous Prototypes are released into the public domain under the Creative Commons '0' license, as noted in the file header. 8 | 9 | This source may also include files from other authors which have other licenses, for example GPL, or other open but restrictive licenses. 10 | -------------------------------------------------------------------------------- /src/blfwk/int_size.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_int_size_h_) 8 | #define _int_size_h_ 9 | 10 | namespace blfwk 11 | { 12 | //! Supported sizes of integers. 13 | typedef enum 14 | { 15 | kWordSize, //!< 32-bit word. 16 | kHalfWordSize, //!< 16-bit half word. 17 | kByteSize //!< 8-bit byte. 18 | } int_size_t; 19 | 20 | enum 21 | { 22 | MinEraseAlignment = 1024, 23 | }; 24 | 25 | }; // namespace blfwk 26 | 27 | #endif // _int_size_h_ 28 | -------------------------------------------------------------------------------- /src/blfwk/BlfwkErrors.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: BlfwkErrors.h 3 | * 4 | * Copyright (c) 2015 Freescale Semiconductor, Inc. 5 | * All rights reserved. 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | #if !defined(_BlfwkErrors_h_) 10 | #define _BlfwkErrors_h_ 11 | 12 | #include 13 | #include 14 | 15 | //! @addtogroup host_error 16 | //! @{ 17 | 18 | namespace blfwk 19 | { 20 | /*! 21 | * \brief A semantic error discovered while processing the command file AST. 22 | */ 23 | class semantic_error : public std::runtime_error 24 | { 25 | public: 26 | explicit semantic_error(const std::string &msg) 27 | : std::runtime_error(msg) 28 | { 29 | } 30 | }; 31 | 32 | }; // namespace blfwk 33 | 34 | //! @} 35 | 36 | #endif // _BlfwkErrors_h_ 37 | -------------------------------------------------------------------------------- /src/blfwk/bootloader_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014, Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #ifndef __BOOTLOADER_CONFIG_H__ 8 | #define __BOOTLOADER_CONFIG_H__ 9 | 10 | //////////////////////////////////////////////////////////////////////////////// 11 | // Definitions 12 | //////////////////////////////////////////////////////////////////////////////// 13 | 14 | // 15 | // Bootloader configuration options 16 | // 17 | 18 | #define BL_HAS_QSPI_MODULE (0) 19 | 20 | #define BL_FEATURE_ENCRYPTION (0) 21 | 22 | #endif // __BOOTLOADER_CONFIG_H__ 23 | //////////////////////////////////////////////////////////////////////////////// 24 | // EOF 25 | //////////////////////////////////////////////////////////////////////////////// 26 | -------------------------------------------------------------------------------- /src/blfwk/doc/blfwk.md: -------------------------------------------------------------------------------- 1 | Host Bootloader Framework {#blfwk} 2 | ===== 3 | 4 | Introduction 5 | ----- 6 | The Bootloader Framework is a library of C++ classes implementing communication from a host PC to bootloader firmware running on a target device. Due to the nature of the underlying bootloader command and data protocol, the Bootloader Frameworks supports all target devices without requiring any device-specific knowledge. 7 | 8 | Applications 9 | ----- 10 | The Bootloader Framework library is used by the Blhost command line tool and by the KinetisFlashTool GUI firmware download tool. It can be built as a library or included as source in a PC or embedded application. The current release includes tool chains to build the library for Windows OS and Mac OS X. 11 | 12 | Peripherals 13 | ----- 14 | Support for the following PC peripherals is included: 15 | 16 | - UART (COM port) 17 | - USB-HID (using custom reports) 18 | - Bus Pal example (UART to I2C/SPI using special hardware) 19 | -------------------------------------------------------------------------------- /src/blfwk/host_types.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _host_types_h_ 9 | #define _host_types_h_ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | //! @brief An array of strings. 19 | typedef std::vector string_vector_t; 20 | 21 | //! @brief An array of bytes. 22 | typedef std::vector uchar_vector_t; 23 | 24 | //! @brief An array of uint32_t's. 25 | typedef std::vector uint32_vector_t; 26 | 27 | //! @brief A stream of bytes. 28 | typedef std::deque uchar_deque_t; 29 | 30 | #endif // _host_types_h_ 31 | 32 | //////////////////////////////////////////////////////////////////////////////// 33 | // EOF 34 | //////////////////////////////////////////////////////////////////////////////// 35 | -------------------------------------------------------------------------------- /src/blfwk/src/Value.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #include "blfwk/Value.h" 10 | 11 | using namespace blfwk; 12 | 13 | //! Returns a varying size depending on the word size attribute. 14 | //! 15 | size_t SizedIntegerValue::getSize() const 16 | { 17 | switch (m_size) 18 | { 19 | case kWordSize: 20 | return sizeof(uint32_t); 21 | case kHalfWordSize: 22 | return sizeof(uint16_t); 23 | case kByteSize: 24 | return sizeof(uint8_t); 25 | } 26 | return kWordSize; 27 | } 28 | 29 | //! The resulting mask can be used to truncate the integer value to be 30 | //! certain it doesn't extend beyond the associated word size. 31 | uint32_t SizedIntegerValue::getWordSizeMask() const 32 | { 33 | switch (m_size) 34 | { 35 | case kWordSize: 36 | return 0xffffffff; 37 | case kHalfWordSize: 38 | return 0x0000ffff; 39 | case kByteSize: 40 | return 0x000000ff; 41 | } 42 | return 0; 43 | } 44 | -------------------------------------------------------------------------------- /src/blfwk/DataSourceImager.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: DataSourceImager.h 3 | * 4 | * Copyright (c) 2015 Freescale Semiconductor, Inc. 5 | * All rights reserved. 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | #if !defined(_DataSourceImager_h_) 10 | #define _DataSourceImager_h_ 11 | 12 | #include "Blob.h" 13 | #include "DataSource.h" 14 | 15 | namespace blfwk 16 | { 17 | /*! 18 | * \brief Converts a DataSource into a single binary buffer. 19 | */ 20 | class DataSourceImager : public Blob 21 | { 22 | public: 23 | //! \brief Constructor. 24 | DataSourceImager(); 25 | 26 | //! \name Setup 27 | //@{ 28 | void setBaseAddress(uint32_t address); 29 | void setFillPattern(uint8_t pattern); 30 | //@} 31 | 32 | void reset(); 33 | 34 | //! \name Accessors 35 | //@{ 36 | uint32_t getBaseAddress() { return m_baseAddress; } 37 | //@} 38 | 39 | //! \name Operations 40 | //@{ 41 | //! \brief Adds all of the segments of which \a dataSource is composed. 42 | void addDataSource(DataSource *source); 43 | 44 | //! \brief Adds the data from one data segment. 45 | void addDataSegment(DataSource::Segment *segment); 46 | //@} 47 | 48 | protected: 49 | uint8_t m_fill; 50 | uint32_t m_baseAddress; 51 | bool m_isBaseAddressSet; 52 | }; 53 | }; 54 | 55 | #endif // _DataSourceImager_h_ 56 | -------------------------------------------------------------------------------- /src/blfwk/doc/blfwk.dox: -------------------------------------------------------------------------------- 1 | /*! 2 | 3 | @defgroup blfwk Host Bootloader Framework 4 | @brief Host Bootloader components. 5 | 6 | @defgroup bus_pal Bus Pal Transport 7 | @ingroup blfwk 8 | @brief Bus Pal transport support. 9 | 10 | @defgroup host_peripherals Peripherals 11 | @ingroup blfwk 12 | @brief Peripheral support. 13 | 14 | @defgroup bus_pal_peripheral Bus Pal Peripheral 15 | @ingroup host_peripherals 16 | @brief Bus Pal Peripheral. 17 | 18 | @defgroup uart_peripheral UART Peripheral 19 | @ingroup host_peripherals 20 | @brief UART Peripheral. 21 | 22 | @defgroup host_usb_hid_peripheral USB-HID Peripheral 23 | @ingroup host_peripherals 24 | @brief USB-HID Peripheral. 25 | 26 | @defgroup host_commands Commands 27 | @ingroup blfwk 28 | @brief Command support. 29 | 30 | @defgroup host_packetizers Packetizers 31 | @ingroup blfwk 32 | @brief Packet creation. 33 | 34 | @defgroup serial_packetizer Serial Packetizer 35 | @ingroup host_packetizers 36 | @brief Serial Packet creation. 37 | 38 | @defgroup usb_hid_packetizer USB-HID Packetizer 39 | @ingroup host_packetizers 40 | @brief USB-HID Packet creation. 41 | 42 | @defgroup logging Logging 43 | @ingroup blfwk 44 | @brief Logging support. 45 | 46 | @defgroup smart_pointer Smart Pointer 47 | @ingroup blfwk 48 | @brief Smart pointer. 49 | 50 | @defgroup host_error Error 51 | @ingroup blfwk 52 | @brief Errors. 53 | 54 | @defgroup host_updater Updater 55 | @ingroup blfwk 56 | @brief Updater application support. 57 | 58 | */ 59 | -------------------------------------------------------------------------------- /src/crc/src/crc16.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #include "crc/crc16.h" 8 | #include 9 | 10 | //////////////////////////////////////////////////////////////////////////////// 11 | // Code 12 | //////////////////////////////////////////////////////////////////////////////// 13 | void crc16_init(crc16_data_t *crc16Config) 14 | { 15 | assert(crc16Config); 16 | 17 | // initialize running crc and byte count 18 | crc16Config->currentCrc = 0; 19 | } 20 | 21 | void crc16_update(crc16_data_t *crc16Config, const uint8_t *src, uint32_t lengthInBytes) 22 | { 23 | assert(crc16Config); 24 | assert(src); 25 | 26 | uint32_t crc = crc16Config->currentCrc; 27 | 28 | uint32_t j; 29 | for (j = 0; j < lengthInBytes; ++j) 30 | { 31 | uint32_t i; 32 | uint32_t byte = src[j]; 33 | crc ^= byte << 8; 34 | for (i = 0; i < 8; ++i) 35 | { 36 | uint32_t temp = crc << 1; 37 | if (crc & 0x8000) 38 | { 39 | temp ^= 0x1021; 40 | } 41 | crc = temp; 42 | } 43 | } 44 | 45 | crc16Config->currentCrc = crc; 46 | } 47 | 48 | void crc16_finalize(crc16_data_t *crc16Config, uint16_t *hash) 49 | { 50 | assert(crc16Config); 51 | assert(hash); 52 | 53 | *hash = crc16Config->currentCrc; 54 | } 55 | //////////////////////////////////////////////////////////////////////////////// 56 | // EOF 57 | //////////////////////////////////////////////////////////////////////////////// 58 | -------------------------------------------------------------------------------- /src/blfwk/SearchPath.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_searchpath_h_) 8 | #define _searchpath_h_ 9 | 10 | #include 11 | #include 12 | 13 | /*! 14 | * \brief Handles searching a list of paths for a file. 15 | */ 16 | class PathSearcher 17 | { 18 | public: 19 | //! 20 | enum _target_type 21 | { 22 | kFindFile, 23 | kFindDirectory 24 | }; 25 | 26 | //! 27 | typedef enum _target_type target_type_t; 28 | 29 | protected: 30 | //! Global search object singleton. 31 | static PathSearcher *s_searcher; 32 | 33 | public: 34 | //! \brief Access global path searching object. 35 | static PathSearcher &getGlobalSearcher(); 36 | 37 | public: 38 | //! \brief Constructor. 39 | PathSearcher() {} 40 | //! \brief Add a new search path to the end of the list. 41 | void addSearchPath(std::string &path); 42 | 43 | //! \brief Attempts to locate a file by using the search paths. 44 | bool search(const std::string &base, target_type_t targetType, bool searchCwd, std::string &result); 45 | 46 | protected: 47 | typedef std::list string_list_t; //!< Linked list of strings. 48 | string_list_t m_paths; //!< Ordered list of paths to search. 49 | 50 | //! \brief Returns whether \a path is absolute. 51 | bool isAbsolute(const std::string &path); 52 | 53 | //! \brief Combines two paths into a single one. 54 | std::string joinPaths(const std::string &first, const std::string &second); 55 | }; 56 | 57 | #endif // _searchpath_h_ 58 | -------------------------------------------------------------------------------- /src/blfwk/utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _utils_h_ 9 | #define _utils_h_ 10 | 11 | #include 12 | #include 13 | 14 | namespace utils 15 | { 16 | //! @brief Split a string into tokens by delimiter. 17 | std::vector string_split(const std::string &s, char delim); 18 | 19 | //! @brief Remove all except hex digits from a string. 20 | std::string string_hex(const std::string &s); 21 | 22 | //! @brief Check if a string is signed a number. If so, return number. 23 | bool stringtoi(const std::string &s, int32_t &number); 24 | 25 | //! @brief Check if a string is an unsigned number. If so, return number. 26 | bool stringtoui(const std::string &s, uint32_t &number, int base = 0); 27 | 28 | //! @brief Format bytes into GB, MB, KB, or bytes. 29 | std::string scale_bytes(uint64_t sizeInBytes); 30 | 31 | } // namespace utils 32 | 33 | namespace nv_utils { 34 | bool capture_vendor_product_id(const std::string& str, std::string& vidstr, std::string& pidstr); 35 | 36 | bool capture_bus_device_interface(const std::string& str, std::string& bus, std::string& device, std::string& interface); 37 | 38 | bool file_exists(std::string str); 39 | 40 | //! @brief Check if a string is an unsigned number. If so, return number. 41 | template 42 | bool str_to_uint(const std::string& s, Tuint& number, int base = 0); 43 | 44 | std::string uint_to_hex(uint64_t num, uint8_t fill_digits = 0); 45 | 46 | } 47 | 48 | #endif // _utils_h_ 49 | 50 | //////////////////////////////////////////////////////////////////////////////// 51 | // EOF 52 | //////////////////////////////////////////////////////////////////////////////// 53 | -------------------------------------------------------------------------------- /src/blfwk/OptionContext.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_OptionContext_h_) 8 | #define _OptionContext_h_ 9 | 10 | #include 11 | #include "Value.h" 12 | 13 | namespace blfwk 14 | { 15 | /*! 16 | * \brief Pure abstract interface class to a table of options. 17 | */ 18 | class OptionContext 19 | { 20 | public: 21 | //! @brief Force a virtual destructor. 22 | virtual ~OptionContext() {} 23 | //! \brief Detemine whether the named option is present in the table. 24 | //! \param name The name of the option to query. 25 | //! \retval true The option is present and has a value. 26 | //! \retval false No option with that name is in the table. 27 | virtual bool hasOption(const std::string &name) const = 0; 28 | 29 | //! \brief Returns the option's value. 30 | //! \param name The name of the option. 31 | //! \return The value for the option named \a name. 32 | //! \retval NULL No option is in the table with that name. 33 | virtual const Value *getOption(const std::string &name) const = 0; 34 | 35 | //! \brief Adds or changes an option's value. 36 | //! 37 | //! If the option was not already present in the table, it is added. 38 | //! Otherwise the old value is replaced. 39 | //! 40 | //! \param name The option's name. 41 | //! \param value New value for the option. 42 | virtual void setOption(const std::string &name, Value *value) = 0; 43 | 44 | //! \brief Removes an option from the table. 45 | //! \param name The name of the option to remove. 46 | virtual void deleteOption(const std::string &name) = 0; 47 | }; 48 | 49 | }; // namespace blfwk 50 | 51 | #endif // _OptionContext_h_ 52 | -------------------------------------------------------------------------------- /src/blfwk/serial.h: -------------------------------------------------------------------------------- 1 | /* 2 | * This file is part of the Bus Pirate project (http://code.google.com/p/the-bus-pirate/). 3 | * 4 | * Written and maintained by the Bus Pirate project and http://dangerousprototypes.com 5 | * 6 | * To the extent possible under law, the project has 7 | * waived all copyright and related or neighboring rights to Bus Pirate. This 8 | * work is published from United States. 9 | * 10 | * For details see: http://creativecommons.org/publicdomain/zero/1.0/. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 15 | */ 16 | /* 17 | * OS independent serial interface 18 | * 19 | * Heavily based on Pirate-Loader: 20 | * http://the-bus-pirate.googlecode.com/svn/trunk/bootloader-v4/pirate-loader/source/pirate-loader.c 21 | * 22 | */ 23 | #ifndef MYSERIAL_H_ 24 | #define MYSERIAL_H_ 25 | 26 | #ifdef MACOSX 27 | #include 28 | #include 29 | 30 | #define B1500000 1500000 31 | #define B1000000 1000000 32 | #define B921600 921600 33 | #endif 34 | 35 | #include 36 | 37 | #ifdef WIN32 38 | #include 39 | #include 40 | 41 | #define B115200 115200 42 | #define B921600 921600 43 | 44 | typedef long speed_t; 45 | #else 46 | 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | #endif 54 | 55 | #if __cplusplus 56 | extern "C" { 57 | #endif 58 | 59 | int serial_setup(int fd, speed_t speed); 60 | int serial_set_read_timeout(int fd, uint32_t timeoutMs); 61 | int serial_write(int fd, char *buf, int size); 62 | int serial_read(int fd, char *buf, int size); 63 | int serial_open(char *port); 64 | int serial_close(int fd); 65 | 66 | #if __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | -------------------------------------------------------------------------------- /src/blfwk/StringMatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_StringMatcher_h_) 8 | #define _StringMatcher_h_ 9 | 10 | #include 11 | 12 | namespace blfwk 13 | { 14 | /*! 15 | * \brief Abstract interface class used to select strings by name. 16 | */ 17 | class StringMatcher 18 | { 19 | public: 20 | //! \brief Performs a single string match test against testValue. 21 | //! 22 | //! \retval true The \a testValue argument matches. 23 | //! \retval false No match was made against the argument. 24 | virtual bool match(const std::string &testValue) = 0; 25 | }; 26 | 27 | /*! 28 | * \brief String matcher subclass that matches all test strings. 29 | */ 30 | class WildcardMatcher : public StringMatcher 31 | { 32 | public: 33 | //! \brief Always returns true, indicating a positive match. 34 | virtual bool match(const std::string &testValue) { return true; } 35 | }; 36 | 37 | /*! 38 | * \brief Simple string matcher that compares against a fixed value. 39 | */ 40 | class FixedMatcher : public StringMatcher 41 | { 42 | public: 43 | //! \brief Constructor. Sets the string to compare against to be \a fixedValue. 44 | FixedMatcher(const std::string &fixedValue) 45 | : m_value(fixedValue) 46 | { 47 | } 48 | 49 | //! \brief Returns whether \a testValue is the same as the value passed to the constructor. 50 | //! 51 | //! \retval true The \a testValue argument matches the fixed compare value. 52 | //! \retval false The argument is not the same as the compare value. 53 | virtual bool match(const std::string &testValue) { return testValue == m_value; } 54 | protected: 55 | const std::string &m_value; //!< The section name to look for. 56 | }; 57 | 58 | }; // namespace blfwk 59 | 60 | #endif // _StringMatcher_h_ 61 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "chrono": "cpp", 4 | "filesystem": "cpp", 5 | "hidapi.h": "c", 6 | "new": "cpp", 7 | "*.tcc": "cpp", 8 | "numeric": "cpp", 9 | "format": "cpp", 10 | "fstream": "cpp", 11 | "iostream": "cpp", 12 | "istream": "cpp", 13 | "ostream": "cpp", 14 | "system_error": "cpp", 15 | "regex": "cpp", 16 | "typeinfo": "cpp", 17 | "variant": "cpp", 18 | "array": "cpp", 19 | "atomic": "cpp", 20 | "bit": "cpp", 21 | "bitset": "cpp", 22 | "cctype": "cpp", 23 | "charconv": "cpp", 24 | "clocale": "cpp", 25 | "cmath": "cpp", 26 | "codecvt": "cpp", 27 | "compare": "cpp", 28 | "concepts": "cpp", 29 | "cstdarg": "cpp", 30 | "cstddef": "cpp", 31 | "cstdint": "cpp", 32 | "cstdio": "cpp", 33 | "cstdlib": "cpp", 34 | "cstring": "cpp", 35 | "ctime": "cpp", 36 | "cwchar": "cpp", 37 | "cwctype": "cpp", 38 | "deque": "cpp", 39 | "list": "cpp", 40 | "map": "cpp", 41 | "string": "cpp", 42 | "unordered_map": "cpp", 43 | "vector": "cpp", 44 | "exception": "cpp", 45 | "algorithm": "cpp", 46 | "functional": "cpp", 47 | "iterator": "cpp", 48 | "memory": "cpp", 49 | "memory_resource": "cpp", 50 | "optional": "cpp", 51 | "random": "cpp", 52 | "ratio": "cpp", 53 | "string_view": "cpp", 54 | "tuple": "cpp", 55 | "type_traits": "cpp", 56 | "utility": "cpp", 57 | "initializer_list": "cpp", 58 | "iomanip": "cpp", 59 | "iosfwd": "cpp", 60 | "limits": "cpp", 61 | "numbers": "cpp", 62 | "span": "cpp", 63 | "sstream": "cpp", 64 | "stdexcept": "cpp", 65 | "streambuf": "cpp", 66 | "cinttypes": "cpp" 67 | } 68 | } -------------------------------------------------------------------------------- /src/blfwk/GlobMatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: GlobMatcher.h 3 | * 4 | * Copyright (c) 2015 Freescale Semiconductor, Inc. 5 | * All rights reserved. 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | #if !defined(_GlobMatcher_h_) 10 | #define _GlobMatcher_h_ 11 | 12 | #include "StringMatcher.h" 13 | 14 | namespace blfwk 15 | { 16 | /*! 17 | * \brief This class uses glob pattern matching to match strings. 18 | * 19 | * Glob patterns: 20 | * - * matches zero or more characters 21 | * - ? matches any single character 22 | * - [set] matches any character in the set 23 | * - [^set] matches any character NOT in the set 24 | * where a set is a group of characters or ranges. a range 25 | * is written as two characters seperated with a hyphen: a-z denotes 26 | * all characters between a to z inclusive. 27 | * - [-set] set matches a literal hypen and any character in the set 28 | * - []set] matches a literal close bracket and any character in the set 29 | * 30 | * - char matches itself except where char is '*' or '?' or '[' 31 | * - \\char matches char, including any pattern character 32 | * 33 | * Examples: 34 | * - a*c ac abc abbc ... 35 | * - a?c acc abc aXc ... 36 | * - a[a-z]c aac abc acc ... 37 | * - a[-a-z]c a-c aac abc ... 38 | */ 39 | class GlobMatcher : public StringMatcher 40 | { 41 | public: 42 | //! \brief Constructor. 43 | GlobMatcher(const std::string &pattern) 44 | : StringMatcher() 45 | , m_pattern(pattern) 46 | { 47 | } 48 | 49 | //! \brief Returns whether \a testValue matches the glob pattern. 50 | virtual bool match(const std::string &testValue); 51 | 52 | protected: 53 | std::string m_pattern; //!< The glob pattern to match against. 54 | 55 | //! \brief Glob implementation. 56 | bool globMatch(const char *str, const char *p); 57 | }; 58 | 59 | }; // namespace blfwk 60 | 61 | #endif // _GlobMatcher_h_ 62 | -------------------------------------------------------------------------------- /src/blfwk/Blob.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_Blob_h_) 8 | #define _Blob_h_ 9 | 10 | #include "stdafx.h" 11 | 12 | //! \class Blob 13 | //! 14 | //! \brief Manages a binary object of arbitrary length. 15 | //! 16 | //! The data block is allocated with malloc() instead of the new 17 | //! operator so that we can use realloc() to resize it. 18 | //! 19 | class Blob 20 | { 21 | public: 22 | //! \brief Default constructor. 23 | Blob(); 24 | 25 | //! \brief Constructor. 26 | Blob(const uint8_t *data, unsigned length); 27 | 28 | //! \brief Copy constructor. 29 | Blob(const Blob &other); 30 | 31 | //! \brief Destructor. 32 | virtual ~Blob(); 33 | 34 | //! \name Operations 35 | //@{ 36 | //! \brief Replaces the blob's data. 37 | void setData(const uint8_t *data, unsigned length); 38 | 39 | //! \brief Change the size of the blob's data. 40 | void setLength(unsigned length); 41 | 42 | //! \brief Adds data to the end of the blob. 43 | void append(const uint8_t *newData, unsigned newDataLength); 44 | 45 | //! \brief Disposes of the data. 46 | void clear(); 47 | 48 | //! \brief Tell the blob that it no longer owns its data. 49 | void relinquish(); 50 | //@} 51 | 52 | //! \name Accessors 53 | //@{ 54 | uint8_t *getData() { return m_data; } 55 | const uint8_t *getData() const { return m_data; } 56 | unsigned getLength() const { return m_length; } 57 | //@} 58 | 59 | //! \name Operators 60 | //@{ 61 | operator uint8_t *() { return m_data; } 62 | operator const uint8_t *() const { return m_data; } 63 | //@} 64 | 65 | protected: 66 | uint8_t *m_data; //!< The binary data held by this object. 67 | unsigned m_length; //!< Number of bytes pointed to by #m_data. 68 | }; 69 | 70 | #endif // _Blob_h_ 71 | -------------------------------------------------------------------------------- /src/blfwk/src/DataTarget.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #include "blfwk/DataTarget.h" 10 | #include "blfwk/DataSource.h" 11 | #include "blfwk/BlfwkErrors.h" 12 | #include 13 | 14 | using namespace blfwk; 15 | 16 | //! \exception blfwk::semantic_error Thrown if the source has multiple segments. 17 | DataTarget::AddressRange ConstantDataTarget::getRangeForSegment(DataSource &source, DataSource::Segment &segment) 18 | { 19 | // can't handle multi-segment data sources 20 | if (source.getSegmentCount() > 1) 21 | { 22 | throw semantic_error("constant targets only support single-segment sources"); 23 | } 24 | 25 | // always relocate the segment to our begin address 26 | AddressRange range; 27 | range.m_begin = m_begin; 28 | 29 | if (isBounded()) 30 | { 31 | // we have an end address. trim the result range to the segment size 32 | // or let the end address crop the segment. 33 | range.m_end = std::min(m_end, m_begin + segment.getLength()); 34 | } 35 | else 36 | { 37 | // we have no end address, so the segment size determines it. 38 | range.m_end = m_begin + segment.getLength(); 39 | } 40 | 41 | return range; 42 | } 43 | 44 | //! If the \a segment has a natural location, the returned address range extends 45 | //! from the segment's base address to its base address plus its length. 46 | //! 47 | //! \exception blfwk::semantic_error This exception is thrown if the \a segment 48 | //! does not have a natural location associated with it. 49 | DataTarget::AddressRange NaturalDataTarget::getRangeForSegment(DataSource &source, DataSource::Segment &segment) 50 | { 51 | if (!segment.hasNaturalLocation()) 52 | { 53 | throw semantic_error("source has no natural location"); 54 | } 55 | 56 | AddressRange range; 57 | range.m_begin = segment.getBaseAddress(); 58 | range.m_end = segment.getBaseAddress() + segment.getLength(); 59 | return range; 60 | } 61 | -------------------------------------------------------------------------------- /src/crc/crc16.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #ifndef _CRC16_H_ 8 | #define _CRC16_H_ 9 | 10 | #include 11 | 12 | //! @addtogroup crc16 13 | //! @{ 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // Definitions 17 | //////////////////////////////////////////////////////////////////////////////// 18 | 19 | //! @brief State information for the CRC16 algorithm. 20 | typedef struct Crc16Data 21 | { 22 | uint16_t currentCrc; //!< Current CRC value. 23 | } crc16_data_t; 24 | 25 | //////////////////////////////////////////////////////////////////////////////// 26 | // API 27 | //////////////////////////////////////////////////////////////////////////////// 28 | 29 | #if __cplusplus 30 | extern "C" { 31 | #endif 32 | 33 | //! @name CRC16 34 | //@{ 35 | 36 | //! @brief Initializes the parameters of the crc function, must be called first. 37 | //! 38 | //! @param crc16Config Instantiation of the data structure of type crc16_data_t. 39 | void crc16_init(crc16_data_t *crc16Config); 40 | 41 | //! @brief A "running" crc calculator that updates the crc value after each call. 42 | //! 43 | //! @param crc16Config Instantiation of the data structure of type crc16_data_t. 44 | //! @param src Pointer to the source buffer of data. 45 | //! @param lengthInBytes The length, given in bytes (not words or long-words). 46 | void crc16_update(crc16_data_t *crc16Config, const uint8_t *src, uint32_t lengthInBytes); 47 | 48 | //! @brief Calculates the final crc value, padding with zeros if necessary, must be called last. 49 | //! 50 | //! @param crc16Config Instantiation of the data structure of type crc16_data_t. 51 | //! @param hash Pointer to the value returned for the final calculated crc value. 52 | void crc16_finalize(crc16_data_t *crc16Config, uint16_t *hash); 53 | 54 | //@} 55 | 56 | #if __cplusplus 57 | } 58 | #endif 59 | 60 | //! @} 61 | 62 | #endif 63 | //////////////////////////////////////////////////////////////////////////////// 64 | // EOF 65 | //////////////////////////////////////////////////////////////////////////////// 66 | -------------------------------------------------------------------------------- /src/include/bootloader_hid_report_ids.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(__BOOTLOADER_HID_REPORT_IDS_H__) 8 | #define __BOOTLOADER_HID_REPORT_IDS_H__ 9 | 10 | #include "packet/command_packet.h" 11 | #ifndef BOOTLOADER_HOST 12 | #include "usb_descriptor.h" 13 | #endif 14 | //////////////////////////////////////////////////////////////////////////////// 15 | // Definitions 16 | //////////////////////////////////////////////////////////////////////////////// 17 | 18 | //! @brief Report IDs to use for the bootloader. 19 | enum _hid_report_ids 20 | { 21 | kBootloaderReportID_CommandOut = 1, 22 | kBootloaderReportID_DataOut = 2, 23 | kBootloaderReportID_CommandIn = 3, 24 | kBootloaderReportID_DataIn = 4 25 | }; 26 | 27 | //! @brief Structure of a bootloader HID header. 28 | typedef struct _bl_hid_header 29 | { 30 | uint8_t reportID; //!< The report ID. 31 | uint8_t _padding; //!< Pad byte necessary so that the length is 2-byte aligned and the data is 4-byte aligned. Set 32 | //! to zero. 33 | uint8_t packetLengthLsb; //!< Low byte of the packet length in bytes. 34 | uint8_t packetLengthMsb; //!< High byte of the packet length in bytes. 35 | } bl_hid_header_t; 36 | 37 | //! @brief Structure of a bootloader HID report. 38 | typedef struct _bl_hid_report 39 | { 40 | bl_hid_header_t header; //!< Header of the report. 41 | #ifdef BOOTLOADER_HOST 42 | uint8_t packet[kMaxHostPacketSize]; //!< Used by blhost. Always set to the max size. 43 | #else 44 | uint8_t packet[kMinUsbHidPacketBufferSize]; //!< The packet data that is transferred in the report. 45 | #if BL_CONFIG_HS_USB_HID && (((BL_MIN_PACKET_SIZE + BL_PACKET_SIZE_HEADER_SIZE) % BL_CONFIG_REPORT_SIZE_MULTIPLER)) 46 | uint8_t padding[BL_HS_REPORT_SIZE * BL_CONFIG_REPORT_SIZE_MULTIPLER - BL_FS_REPORT_SIZE]; 47 | #endif 48 | #endif 49 | } bl_hid_report_t; 50 | 51 | #endif // __BOOTLOADER_HID_REPORT_IDS_H__ 52 | //////////////////////////////////////////////////////////////////////////////// 53 | // EOF 54 | //////////////////////////////////////////////////////////////////////////////// 55 | -------------------------------------------------------------------------------- /src/blfwk/src/format_string.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #include "blfwk/format_string.h" 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | //! Size of the temporary buffer to hold the formatted output string. 16 | #define WIN32_FMT_BUF_LEN (512) 17 | 18 | /*! 19 | * \brief Simple template class to free a pointer. 20 | */ 21 | template 22 | class free_ptr 23 | { 24 | public: 25 | //! \brief Constructor. 26 | free_ptr(T ptr) 27 | : m_p(ptr) 28 | { 29 | } 30 | 31 | //! \brief Destructor. 32 | ~free_ptr() 33 | { 34 | if (m_p) 35 | { 36 | free(m_p); 37 | } 38 | } 39 | 40 | protected: 41 | T m_p; //!< The value to free. 42 | }; 43 | 44 | //! The purpose of this function to provide a convenient way of generating formatted 45 | //! STL strings inline. This is especially useful when throwing exceptions that take 46 | //! a std::string for a message. The length of the formatted output string is limited 47 | //! only by memory. Memory temporarily allocated for the output string is disposed of 48 | //! before returning. 49 | //! 50 | //! Example usage: 51 | //! \code 52 | //! throw std::runtime_error(format_string("error on line %d", line)); 53 | //! \endcode 54 | //! 55 | //! \param fmt Format string using printf-style format markers. 56 | //! \return An STL string object of the formatted output. 57 | std::string format_string(const char *fmt, ...) 58 | { 59 | char *buf = 0; 60 | va_list vargs; 61 | va_start(vargs, fmt); 62 | int result = -1; 63 | #if WIN32 64 | buf = (char *)malloc(WIN32_FMT_BUF_LEN); 65 | if (buf) 66 | { 67 | result = _vsnprintf(buf, WIN32_FMT_BUF_LEN, fmt, vargs); 68 | } 69 | #else // WIN32 70 | result = vasprintf(&buf, fmt, vargs); 71 | #endif // WIN32 72 | va_end(vargs); 73 | if (result != -1 && buf) 74 | { 75 | free_ptr freebuf(buf); 76 | return std::string(buf); 77 | } 78 | return ""; 79 | } 80 | -------------------------------------------------------------------------------- /src/blfwk/BusPalPeripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _BusPalPeripheral_h_ 9 | #define _BusPalPeripheral_h_ 10 | 11 | #include "UartPeripheral.h" 12 | #include "BusPal.h" 13 | 14 | //! @addtogroup bus_pal_peripheral 15 | //! @{ 16 | 17 | namespace blfwk 18 | { 19 | /*! 20 | * @brief Peripheral that talks to the target device over BusPal UART hardware. 21 | */ 22 | class BusPalUartPeripheral : public UartPeripheral 23 | { 24 | public: 25 | //! @brief Parameterized constructor that opens the serial port. 26 | //! 27 | //! Opens and configures the port. Throws exception if port configuration fails. 28 | //! 29 | //! Note: following COM port configuration is assumed: 8 bits, 1 stop bit, no parity. 30 | //! 31 | //! @param port OS file path for COM port. For example "COM1" on Windows. 32 | //! @param speed Port speed, e.g. 9600. 33 | BusPalUartPeripheral(const char *port, long speed, const BusPal::BusPalConfigData &config); 34 | 35 | //! @brief Destructor. 36 | virtual ~BusPalUartPeripheral(); 37 | 38 | //! @brief configure the bus pal with the passed in options 39 | void configure(const BusPal::BusPalConfigData &config); 40 | 41 | //! @brief Read bytes. 42 | //! 43 | //! @param buffer Pointer to buffer 44 | //! @param requestedBytes Number of bytes to read 45 | virtual status_t read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t timeoutMs); 46 | 47 | //! @brief Write bytes. 48 | //! 49 | //! @param buffer Pointer to buffer to write 50 | //! @param byteCount Number of bytes to write 51 | virtual status_t write(const uint8_t *buffer, uint32_t byteCount); 52 | 53 | virtual _host_peripheral_types get_type(void) { return kHostPeripheralType_BUSPAL_UART; } 54 | 55 | protected: 56 | BusPal *m_busPal; //!< Represents Bus Pal hardware. 57 | }; 58 | 59 | } // namespace blfwk 60 | 61 | //! @} 62 | 63 | #endif // _BusPalPeripheral_h_ 64 | 65 | //////////////////////////////////////////////////////////////////////////////// 66 | // EOF 67 | //////////////////////////////////////////////////////////////////////////////// 68 | -------------------------------------------------------------------------------- /src/blfwk/ExcludesListMatcher.h: -------------------------------------------------------------------------------- 1 | /* 2 | * File: ExcludesListMatcher.h 3 | * 4 | * Copyright (c) 2015 Freescale Semiconductor, Inc. 5 | * All rights reserved. 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | #if !defined(_ExcludesListMatcher_h_) 10 | #define _ExcludesListMatcher_h_ 11 | 12 | #include "GlobMatcher.h" 13 | #include 14 | #include 15 | 16 | namespace blfwk 17 | { 18 | /*! 19 | * \brief Matches strings using a series of include and exclude glob patterns. 20 | * 21 | * This string matcher class uses a sequential, ordered list of glob patterns to 22 | * determine whether a string matches. Attached to each pattern is an include/exclude 23 | * action. The patterns in the list effectively form a Boolean expression. Includes 24 | * act as an OR operator while excludes act as an AND NOT operator. 25 | * 26 | * Examples (plus prefix is include, minus prefix is exclude): 27 | * - +foo: foo 28 | * - -foo: !foo 29 | * - +foo, +bar: foo || bar 30 | * - +foo, -bar: foo && !bar 31 | * - +foo, -bar, +baz: foo && !bar || baz 32 | * 33 | * The only reason for inheriting from GlobMatcher is so we can access the protected 34 | * globMatch() method. 35 | */ 36 | class ExcludesListMatcher : public GlobMatcher 37 | { 38 | public: 39 | //! \brief Default constructor. 40 | ExcludesListMatcher(); 41 | 42 | //! \brief Destructor. 43 | ~ExcludesListMatcher(); 44 | 45 | //! \name Pattern list 46 | //@{ 47 | //! \brief Add one include or exclude pattern to the end of the match list. 48 | void addPattern(bool isInclude, const std::string &pattern); 49 | //@} 50 | 51 | //! \brief Performs a single string match test against testValue. 52 | virtual bool match(const std::string &testValue); 53 | 54 | protected: 55 | //! \brief Information about one glob pattern entry in a match list. 56 | struct glob_list_item_t 57 | { 58 | bool m_isInclude; //!< True if include, false if exclude. 59 | std::string m_glob; //!< The glob pattern to match. 60 | }; 61 | 62 | typedef std::vector glob_list_t; 63 | glob_list_t m_patterns; //!< Ordered list of include and exclude patterns. 64 | }; 65 | 66 | }; // namespace blfwk 67 | 68 | #endif // _ExcludesListMatcher_h_ 69 | -------------------------------------------------------------------------------- /src/blfwk/stdafx.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #ifndef stdafx_h_ 8 | #define stdafx_h_ 9 | 10 | // stdafx.h : include file for standard system include files, 11 | // or project specific include files that are used frequently, but 12 | // are changed infrequently 13 | // 14 | 15 | // Default to external release. 16 | #ifndef SGTL_INTERNAL 17 | #define SGTL_INTERNAL 0 18 | #endif 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #if defined(WIN32) 25 | //#include 26 | 27 | // define this macro for use in VC++ 28 | #if !defined(__LITTLE_ENDIAN__) 29 | #define __LITTLE_ENDIAN__ 1 30 | #endif // !defined(__LITTLE_ENDIAN__) 31 | #endif // defined(WIN32) 32 | 33 | #if defined(LINUX) 34 | // For Linux systems only, types.h only defines the signed 35 | // integer types. This is not professional code. 36 | // Update: They are defined in the header files in the more recent version of redhat enterprise gcc. 37 | //#include "/usr/include/sys/types.h" 38 | //#include 39 | // typedef unsigned long uint32_t; 40 | // typedef unsigned short uint16_t; 41 | // typedef unsigned char uint8_t; 42 | 43 | //#define TCHAR char 44 | //#define _tmain main 45 | 46 | // give a default endian in case one is not defined on Linux (it should be, though) 47 | #if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) 48 | #define __LITTLE_ENDIAN__ 1 49 | #endif // !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) 50 | 51 | #endif // defined(Linux) 52 | 53 | // gcc on Mac OS X 54 | #if defined(__GNUC__) && (defined(__APPLE_CPP__) || defined(__APPLE_CC__) || defined(__MACOS_CLASSIC__)) 55 | #include 56 | 57 | #if defined(TARGET_RT_LITTLE_ENDIAN) && TARGET_RT_LITTLE_ENDIAN 58 | #if !defined(__LITTLE_ENDIAN__) 59 | #define __LITTLE_ENDIAN__ 60 | #endif 61 | #elif defined(TARGET_RT_BIG_ENDIAN) && TARGET_RT_BIG_ENDIAN 62 | #if !defined(__BIG_ENDIAN__) 63 | #define __BIG_ENDIAN__ 64 | #endif 65 | #endif 66 | #endif 67 | 68 | #if !defined(TRUE) 69 | #define TRUE 1 70 | #endif // !defined(TRUE) 71 | 72 | #if !defined(FALSE) 73 | #define FALSE 0 74 | #endif // !defined(FALSE) 75 | 76 | #endif // stdafx_h_ 77 | -------------------------------------------------------------------------------- /src/blfwk/i2c.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #ifndef __I2C_H__ 10 | #define __I2C_H__ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | //! @addtogroup i2c 23 | //! @{ 24 | 25 | /******************************************************************************* 26 | * API 27 | ******************************************************************************/ 28 | 29 | #if __cplusplus 30 | extern "C" 31 | { 32 | #endif 33 | 34 | //! @name I2C 35 | //@{ 36 | 37 | //! @brief Configure the opened device port. 38 | //! 39 | //! @param fd Device port handler. 40 | //! @param speed Device clock frequency. 41 | //! @param address Slave device address. 42 | int i2c_setup(int fd, uint32_t speed, uint8_t address); 43 | 44 | //! @brief Set the transfer timeout. 45 | //! 46 | //! @param fd Device port handler. 47 | //! @param miliseconds Transfer timeout. 48 | int i2c_set_timeout(int fd, uint32_t miliseconds); 49 | 50 | //! @brief Write bytes. 51 | //! 52 | //! @param fd Device port handler. 53 | //! @param buf Pointer to buffer. 54 | //! @param size Number of bytes to write. 55 | int i2c_write(int fd, char *buf, int size); 56 | 57 | //! @brief Read bytes. 58 | //! 59 | //! @param fd Device port handler. 60 | //! @param buf Pointer to buffer. 61 | //! @param size Number of bytes to read. 62 | int i2c_read(int fd, char *buf, int size); 63 | 64 | //! @brief Open the device port. 65 | //! 66 | //! @param port Device port string. 67 | int i2c_open(char *port); 68 | 69 | //! @brief Close the device port. 70 | //! 71 | //! @param fd Device port handler. 72 | int i2c_close(int fd); 73 | 74 | //@} 75 | 76 | #if __cplusplus 77 | } 78 | #endif 79 | 80 | //! @} 81 | 82 | #endif //__I2C_H__ 83 | 84 | //////////////////////////////////////////////////////////////////////////////// 85 | // EOF 86 | //////////////////////////////////////////////////////////////////////////////// 87 | -------------------------------------------------------------------------------- /src/crc/crc32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #ifndef _CRC_H_ 8 | #define _CRC_H_ 9 | 10 | #include 11 | 12 | //! @addtogroup crc32 13 | //! @{ 14 | 15 | //////////////////////////////////////////////////////////////////////////////// 16 | // Definitions 17 | //////////////////////////////////////////////////////////////////////////////// 18 | 19 | //! @brief State information for the CRC32 algorithm. 20 | typedef struct Crc32Data 21 | { 22 | uint32_t currentCrc; //!< Current CRC value. 23 | uint32_t byteCountCrc; //!< Number of bytes processed. 24 | } crc32_data_t; 25 | 26 | //////////////////////////////////////////////////////////////////////////////// 27 | // API 28 | //////////////////////////////////////////////////////////////////////////////// 29 | 30 | #if __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | //! @name CRC32 35 | //@{ 36 | 37 | //! @brief Initializes the parameters of the crc function, must be called first 38 | //! 39 | //! @param crc32Config Instantiation of the data structure of type crc32_data_t 40 | //! @retval kStatus_Success 41 | void crc32_init(crc32_data_t *crc32Config); 42 | 43 | //! @brief A "running" crc calculator that updates the crc value after each call 44 | //! 45 | //! @param crc32Config Instantiation of the data structure of type crc32_data_t 46 | //! @param src Pointer to the source buffer of data 47 | //! @param lengthInBytes The length, given in bytes (not words or long-words) 48 | //! @retval kStatus_Success 49 | void crc32_update(crc32_data_t *crc32Config, const uint8_t *src, uint32_t lengthInBytes); 50 | 51 | //! @brief Calculates the final crc value, padding with zeros if necessary, must be called last 52 | //! 53 | //! @param crc32Config Instantiation of the data structure of type crc32_data_t 54 | //! @param hash Pointer to the value returned for the final calculated crc value 55 | //! @retval kStatus_Success 56 | void crc32_finalize(crc32_data_t *crc32Config, uint32_t *hash); 57 | 58 | //@} 59 | 60 | #if __cplusplus 61 | } 62 | #endif 63 | 64 | //! @} 65 | 66 | #endif 67 | //////////////////////////////////////////////////////////////////////////////// 68 | // EOF 69 | //////////////////////////////////////////////////////////////////////////////// 70 | -------------------------------------------------------------------------------- /src/blfwk/spi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | #ifndef __SPI_H__ 9 | #define __SPI_H__ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | 21 | //! @addtogroup spi 22 | //! @{ 23 | 24 | /******************************************************************************* 25 | * API 26 | ******************************************************************************/ 27 | 28 | #if __cplusplus 29 | extern "C" 30 | { 31 | #endif 32 | 33 | //! @name SPI 34 | //@{ 35 | 36 | //! @brief Configure the opened device port. 37 | //! 38 | //! @param fd Device port handler. 39 | //! @param speed Device clock frequency. 40 | //! @param mode Polarity and phase mode. 41 | //! @param bits_per_word Transfer size. 42 | int spi_setup(int fd, uint32_t speed, uint32_t mode, uint32_t bits_per_word); 43 | 44 | //! @brief Set the transfer timeout. 45 | //! 46 | //! @param fd Device port handler. 47 | //! @param miliseconds Transfer timeout. 48 | int spi_set_timeout(int fd, uint32_t miliseconds); 49 | 50 | //! @brief Write bytes. 51 | //! 52 | //! @param fd Device port handler. 53 | //! @param buf Pointer to buffer. 54 | //! @param size Number of bytes to write. 55 | int spi_write(int fd, char *buf, int size); 56 | 57 | //! @brief Read bytes. 58 | //! 59 | //! @param fd Device port handler. 60 | //! @param buf Pointer to buffer. 61 | //! @param size Number of bytes to read. 62 | int spi_read(int fd, char *buf, int size); 63 | 64 | //! @brief Open the device port. 65 | //! 66 | //! @param port Device port string. 67 | int spi_open(char *port); 68 | 69 | //! @brief Close the device port. 70 | //! 71 | //! @param fd Device port handler. 72 | int spi_close(int fd); 73 | 74 | //@} 75 | 76 | #if __cplusplus 77 | } 78 | #endif 79 | 80 | //! @} 81 | 82 | #endif //__SPI_H__ 83 | 84 | //////////////////////////////////////////////////////////////////////////////// 85 | // EOF 86 | //////////////////////////////////////////////////////////////////////////////// 87 | -------------------------------------------------------------------------------- /meson.build: -------------------------------------------------------------------------------- 1 | project('blhost', ['cpp', 'c'], default_options: ['cpp_std=c++11']) 2 | 3 | add_project_arguments('-DLINUX', language: 'c') 4 | add_project_arguments('-DLINUX', language: 'cpp') 5 | add_project_arguments('-D__ARM__', language: 'c') 6 | add_project_arguments('-D__ARM__', language: 'cpp') 7 | 8 | add_project_arguments('-DBOOTLOADER_HOST', language: 'cpp') 9 | add_project_arguments('-DBOOTLOADER_HOST', language: 'c') 10 | 11 | cc = meson.get_compiler('c') 12 | libusb_dep = cc.find_library('usb-1.0', required: true) 13 | pthread_dep = dependency('threads') 14 | src_files = [ 15 | 'src/blfwk/src/SRecordSourceFile.cpp', 16 | 'src/blfwk/src/StExecutableImage.cpp', 17 | 'src/blfwk/src/SearchPath.cpp', 18 | 'src/blfwk/src/BusPalPeripheral.cpp', 19 | 'src/blfwk/src/GlobMatcher.cpp', 20 | 'src/blfwk/src/SBSourceFile.cpp', 21 | 'src/blfwk/src/options.cpp', 22 | 'src/blfwk/src/IntelHexSourceFile.cpp', 23 | 'src/blfwk/src/utils.cpp', 24 | 'src/blfwk/src/ELFSourceFile.cpp', 25 | 'src/blfwk/src/StSRecordFile.cpp', 26 | 'src/blfwk/src/DataSourceImager.cpp', 27 | 'src/blfwk/src/DataSource.cpp', 28 | 'src/blfwk/src/DataTarget.cpp', 29 | 'src/blfwk/src/Blob.cpp', 30 | 'src/blfwk/src/SourceFile.cpp', 31 | 'src/blfwk/src/Logging.cpp', 32 | 'src/blfwk/src/GHSSecInfo.cpp', 33 | 'src/blfwk/src/UsbHidPacketizer.cpp', 34 | 'src/blfwk/src/format_string.cpp', 35 | 'src/blfwk/src/ExcludesListMatcher.cpp', 36 | 'src/blfwk/src/UsbHidPeripheral.cpp', 37 | 'src/blfwk/src/StELFFile.cpp', 38 | 'src/blfwk/src/Bootloader.cpp', 39 | 'src/blfwk/src/Updater.cpp', 40 | 'src/blfwk/src/UartPeripheral.cpp', 41 | 'src/blfwk/src/I2cPeripheral.cpp', 42 | 'src/blfwk/src/BusPal.cpp', 43 | 'src/blfwk/src/SerialPacketizer.cpp', 44 | 'src/blfwk/src/SpiPeripheral.cpp', 45 | 'src/blfwk/src/StIntelHexFile.cpp', 46 | 'src/blfwk/src/Value.cpp', 47 | 'src/blfwk/src/jsoncpp.cpp', 48 | 'src/blfwk/src/Command.cpp', 49 | 'tools/blhost/src/blhost.cpp', 50 | 'src/blfwk/src/serial.c', 51 | 'src/blfwk/src/i2c.c', 52 | 'src/blfwk/src/hid-usb.c', 53 | 'src/blfwk/src/spi.c', 54 | 'src/crc/src/crc32.c', 55 | 'src/crc/src/crc16.c' 56 | ] 57 | 58 | inc_dirs = [ 59 | 'src/include', 60 | 'src/blfwk', 61 | 'src' 62 | ] 63 | 64 | executable( 65 | 'blhost', 66 | src_files, 67 | include_directories: inc_dirs, 68 | dependencies: [libusb_dep, pthread_dep], 69 | install: true, 70 | install_dir: get_option('bindir') 71 | ) 72 | 73 | 74 | -------------------------------------------------------------------------------- /src/blfwk/GHSSecInfo.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_GHSSecInfo_h_) 8 | #define _GHSSecInfo_h_ 9 | 10 | #include "StELFFile.h" 11 | #include "smart_ptr.h" 12 | 13 | namespace blfwk 14 | { 15 | /*! 16 | * \brief Wrapper around the GHS-specific .secinfo ELF section. 17 | * 18 | * ELF files produced by the Green Hills MULTI toolset will have a 19 | * special .secinfo section. For the most part, this section contains 20 | * a list of address 21 | * ranges that should be filled by the C runtime startup code. The 22 | * address ranges correspond to those of ELF sections whose type is 23 | * #SHT_NOBITS. The GHS runtime uses this table instead of just filling 24 | * all #SHT_NOBITS sections because the linker command file can 25 | * be used to optionally not fill individual sections. 26 | * 27 | * The isSectionFilled() methods let calling code determine if an ELF 28 | * section is found in the .secinfo table. If the section is found, 29 | * then it should be filled. 30 | */ 31 | class GHSSecInfo 32 | { 33 | public: 34 | //! \brief Default constructor. 35 | GHSSecInfo(StELFFile *elf); 36 | 37 | //! \brief Returns true if there is a .secinfo section present in the ELF file. 38 | bool hasSecinfo() const { return m_hasInfo; } 39 | //! \brief Determines if a section should be filled. 40 | bool isSectionFilled(uint32_t addr, uint32_t length); 41 | 42 | //! \brief Determines if \a section should be filled. 43 | bool isSectionFilled(const Elf32_Shdr §ion); 44 | 45 | protected: 46 | #pragma pack(1) 47 | 48 | /*! 49 | * \brief The structure of one .secinfo entry. 50 | */ 51 | struct ghs_secinfo_t 52 | { 53 | uint32_t m_clearAddr; //!< Address to start filling from. 54 | uint32_t m_clearValue; //!< Value to fill with. 55 | uint32_t m_numBytesToClear; //!< Number of bytes to fill. 56 | }; 57 | 58 | #pragma pack() 59 | 60 | protected: 61 | StELFFile *m_elf; //!< The parser object for our ELF file. 62 | bool m_hasInfo; //!< Whether .secinfo is present in the ELF file. 63 | smart_array_ptr 64 | m_info; //!< Pointer to the .secinfo entries. Will be NULL if there is no .secinfo section in the file. 65 | unsigned m_entryCount; //!< Number of entries in #m_info. 66 | }; 67 | 68 | }; // namespace blfwk 69 | 70 | #endif // _GHSSecInfo_h_ 71 | -------------------------------------------------------------------------------- /src/blfwk/IntelHexSourceFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_IntelHexSourceFile_h_) 8 | #define _IntelHexSourceFile_h_ 9 | 10 | #include "SourceFile.h" 11 | #include "StIntelHexFile.h" 12 | #include "StExecutableImage.h" 13 | 14 | namespace blfwk 15 | { 16 | /*! 17 | * \brief Executable file in the Intel Hex format. 18 | * 19 | * Instead of presenting each Intel Hex in the file separately, this class 20 | * builds up a memory image of all of the records. Records next to each other 21 | * in memory are coalesced into a single memory region. The data source that 22 | * is returned from createDataSource() exposes these regions as its segments. 23 | */ 24 | class IntelHexSourceFile : public SourceFile 25 | { 26 | public: 27 | //! \brief Default constructor. 28 | IntelHexSourceFile(const std::string &path); 29 | 30 | //! \brief Destructor. 31 | virtual ~IntelHexSourceFile() {} 32 | //! \brief Test whether the \a stream contains a valid Intel Hex file. 33 | static bool isIntelHexFile(std::istream &stream); 34 | 35 | //! \name Opening and closing 36 | //@{ 37 | //! \brief Opens the file. 38 | virtual void open(); 39 | 40 | //! \brief Closes the file. 41 | virtual void close(); 42 | //@} 43 | 44 | //! \name Format capabilities 45 | //@{ 46 | virtual bool supportsNamedSections() const { return false; } 47 | virtual bool supportsNamedSymbols() const { return false; } 48 | //@} 49 | 50 | //! \name Data sources 51 | //@{ 52 | //! \brief Returns data source for the entire file. 53 | virtual DataSource *createDataSource(); 54 | //@} 55 | 56 | //! \name Entry point 57 | //@{ 58 | //! \brief Returns true if an entry point was set in the file. 59 | virtual bool hasEntryPoint(); 60 | 61 | //! \brief Returns the entry point address. 62 | virtual uint32_t getEntryPointAddress(); 63 | //@} 64 | 65 | protected: 66 | StIntelHexFile *m_file; //!< Intel Hex parser instance. 67 | StExecutableImage *m_image; //!< Memory image of the Intel Hex file.. 68 | bool m_hasEntryRecord; //!< Whether a type 03 or 05 record was found. 69 | StIntelHexFile::IntelHex m_entryRecord; //!< Record for the entry point. 70 | 71 | protected: 72 | //! \brief Build memory image of the Intel Hex file. 73 | void buildMemoryImage(); 74 | }; 75 | 76 | }; // namespace blfwk 77 | 78 | #endif // _IntelHexSourceFile_h_ 79 | -------------------------------------------------------------------------------- /src/blfwk/Progress.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _Progress_h_ 9 | #define _Progress_h_ 10 | 11 | #pragma once 12 | 13 | #include "blfwk/host_types.h" 14 | 15 | /*! 16 | * @brief Contains the callback function for progress and abort phase. 17 | * 18 | */ 19 | class Progress 20 | { 21 | public: 22 | //! @brief Default constructor. 23 | Progress() 24 | : m_segmentIndex(1) 25 | , m_segmentCount(1) 26 | , m_progressCallback(NULL) 27 | , m_abortPhase(NULL) 28 | { 29 | } 30 | 31 | //! @brief Constructor with initial callback. 32 | Progress(void(*callback)(int, int, int), bool *abortPhase) 33 | : m_segmentIndex(1) 34 | , m_segmentCount(1) 35 | , m_progressCallback(callback) 36 | , m_abortPhase(abortPhase) 37 | { 38 | } 39 | 40 | //! @brief Default destructor. 41 | ~Progress() {} 42 | //! @brief execute the progress callback function. 43 | //! 44 | //! @param percentage the percentage of current executed progress. 45 | void progressCallback(int percentage) 46 | { 47 | if (m_progressCallback != NULL) 48 | { 49 | m_progressCallback(percentage, m_segmentIndex, m_segmentCount); 50 | } 51 | } 52 | 53 | //! @brief Check whether the data phase is canceled. 54 | bool abortPhase(void) 55 | { 56 | if ((m_abortPhase) && (*m_abortPhase == true)) 57 | { 58 | return true; 59 | } 60 | else 61 | { 62 | return false; 63 | } 64 | } 65 | 66 | //! @biref initialized the progress callback function and the variable of controlling data phase. 67 | //! 68 | //! @param callback The progress callback function. 69 | //! 70 | //! @param abortPhase The pointer pointing to a variable controlling whether abort current data phase. 71 | void registerCallback(void(*callback)(int, int, int), bool *abortPhase) 72 | { 73 | m_progressCallback = callback; 74 | m_abortPhase = abortPhase; 75 | } 76 | 77 | public: 78 | int m_segmentIndex; //!< Index of data segment in progressing. 79 | int m_segmentCount; //!< The number of data segments. 80 | 81 | private: 82 | void(*m_progressCallback)(int percentage, int segmentIndex, int segmentCount); //!< The progress callback function. 83 | bool *m_abortPhase; //!< The pointer pointing to a variable controlling whether abort current data phase. 84 | }; 85 | 86 | #endif // _Progress_h_ 87 | -------------------------------------------------------------------------------- /src/blfwk/src/ExcludesListMatcher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: ExcludesListMatcher.cpp 3 | * 4 | * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 | * See included license file (SW-Content-Register.txt at project root) for license details. 6 | */ 7 | 8 | #include "blfwk/ExcludesListMatcher.h" 9 | 10 | using namespace blfwk; 11 | 12 | ExcludesListMatcher::ExcludesListMatcher() 13 | : GlobMatcher("") 14 | { 15 | } 16 | 17 | ExcludesListMatcher::~ExcludesListMatcher() 18 | { 19 | } 20 | 21 | //! \param isInclude True if this pattern is an include, false if it is an exclude. 22 | //! \param pattern String containing the glob pattern. 23 | void ExcludesListMatcher::addPattern(bool isInclude, const std::string &pattern) 24 | { 25 | glob_list_item_t item; 26 | item.m_isInclude = isInclude; 27 | item.m_glob = pattern; 28 | 29 | // add to end of list 30 | m_patterns.push_back(item); 31 | } 32 | 33 | //! If there are no entries in the match list, the match fails. 34 | //! 35 | //! \param testValue The string to match against the pattern list. 36 | //! \retval true The \a testValue argument matches. 37 | //! \retval false No match was made against the argument. 38 | bool ExcludesListMatcher::match(const std::string &testValue) 39 | { 40 | if (!m_patterns.size()) 41 | { 42 | return false; 43 | } 44 | 45 | // Iterate over the match list. Includes act as an OR operator, while 46 | // excludes act as an AND operator. 47 | bool didMatch = false; 48 | bool isFirstItem = true; 49 | glob_list_t::iterator it = m_patterns.begin(); 50 | for (; it != m_patterns.end(); ++it) 51 | { 52 | glob_list_item_t &item = *it; 53 | 54 | // if this pattern is an include and it doesn't match, or 55 | // if this pattern is an exclude and it does match, then the match fails 56 | bool didItemMatch = globMatch(testValue.c_str(), item.m_glob.c_str()); 57 | 58 | if (item.m_isInclude) 59 | { 60 | // Include 61 | if (isFirstItem) 62 | { 63 | didMatch = didItemMatch; 64 | } 65 | else 66 | { 67 | didMatch = didMatch || didItemMatch; 68 | } 69 | } 70 | else 71 | { 72 | // Exclude 73 | if (isFirstItem) 74 | { 75 | didMatch = !didItemMatch; 76 | } 77 | else 78 | { 79 | didMatch = didMatch && !didItemMatch; 80 | } 81 | } 82 | 83 | isFirstItem = false; 84 | } 85 | 86 | return didMatch; 87 | } 88 | -------------------------------------------------------------------------------- /src/blfwk/SRecordSourceFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_SRecordSourceFile_h_) 8 | #define _SRecordSourceFile_h_ 9 | 10 | #include "SourceFile.h" 11 | #include "StSRecordFile.h" 12 | #include "StExecutableImage.h" 13 | 14 | namespace blfwk 15 | { 16 | /*! 17 | * \brief Executable file in the Motorola S-record format. 18 | * 19 | * Instead of presenting each S-record in the file separately, this class 20 | * builds up a memory image of all of the records. Records next to each other 21 | * in memory are coalesced into a single memory region. The data source that 22 | * is returned from createDataSource() exposes these regions as its segments. 23 | * 24 | * Because the S-record format does not support the concepts, no support is 25 | * provided for named sections or symbols. 26 | */ 27 | class SRecordSourceFile : public SourceFile 28 | { 29 | public: 30 | //! \brief Default constructor. 31 | SRecordSourceFile(const std::string &path); 32 | 33 | //! \brief Destructor. 34 | virtual ~SRecordSourceFile() {} 35 | //! \brief Test whether the \a stream contains a valid S-record file. 36 | static bool isSRecordFile(std::istream &stream); 37 | 38 | //! \name Opening and closing 39 | //@{ 40 | //! \brief Opens the file. 41 | virtual void open(); 42 | 43 | //! \brief Closes the file. 44 | virtual void close(); 45 | //@} 46 | 47 | //! \name Format capabilities 48 | //@{ 49 | virtual bool supportsNamedSections() const { return false; } 50 | virtual bool supportsNamedSymbols() const { return false; } 51 | //@} 52 | 53 | //! \name Data sources 54 | //@{ 55 | //! \brief Returns data source for the entire file. 56 | virtual DataSource *createDataSource(); 57 | //@} 58 | 59 | //! \name Entry point 60 | //@{ 61 | //! \brief Returns true if an entry point was set in the file. 62 | virtual bool hasEntryPoint(); 63 | 64 | //! \brief Returns the entry point address. 65 | virtual uint32_t getEntryPointAddress(); 66 | //@} 67 | 68 | protected: 69 | StSRecordFile *m_file; //!< S-record parser instance. 70 | StExecutableImage *m_image; //!< Memory image of the S-record file. 71 | bool m_hasEntryRecord; //!< Whether an S7,8,9 record was found. 72 | StSRecordFile::SRecord m_entryRecord; //!< Record for the entry point. 73 | 74 | protected: 75 | //! \brief Build memory image of the S-record file. 76 | void buildMemoryImage(); 77 | }; 78 | 79 | }; // namespace blfwk 80 | 81 | #endif // _SRecordSourceFile_h_ 82 | -------------------------------------------------------------------------------- /src/blfwk/UsbHidPeripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _UsbHidPeripheral_h_ 9 | #define _UsbHidPeripheral_h_ 10 | 11 | #include "Peripheral.h" 12 | #include "hidapi.h" 13 | 14 | //! @addtogroup host_usb_hid_peripheral 15 | //! @{ 16 | 17 | namespace blfwk 18 | { 19 | /*! 20 | * @brief Represents a USB HID peripheral. 21 | * 22 | * Interface class for objects that provide the source for commands or sink for responses. 23 | */ 24 | class UsbHidPeripheral : public Peripheral 25 | { 26 | public: 27 | //! @brief Constants 28 | enum _usbhid_contants 29 | { 30 | kDefault_Vid = 0x15a2, //!< Freescale VID 31 | kDefault_Pid = 0x0073, //!< PID for KL25Z48M 32 | //kK32H_Pid = 0x0083 //!< PID for K32H (Ultra) 33 | kK32H_Pid = 0x0052 //!< test pid (mx50) 34 | }; 35 | 36 | public: 37 | UsbHidPeripheral(const nv::UsbPeripheralConfigData& cfg); 38 | 39 | //! @brief Destructor. 40 | virtual ~UsbHidPeripheral(); 41 | 42 | //! @brief Read bytes. 43 | //! 44 | //! @param buffer Pointer to buffer 45 | //! @param requestedBytes Number of bytes to read 46 | //! @param timeoutMs Time in milliseconds to wait for read to complete. 47 | //! @param actualBytes Number of bytes actually read. 48 | virtual status_t read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t timeoutMS); 49 | 50 | //! @brief Write bytes. This is a do nothing function implemented here to satisfy abstract base class 51 | //! requirements. This function is not used. The write(buffer, count, timeout) function is used 52 | //! in this child class instead of the write(buffer, cout) function declared in the base class. 53 | virtual status_t write(const uint8_t *buffer, uint32_t byteCount) { return kStatus_Success; } 54 | 55 | //! @brief Return peripheral Type 56 | virtual _host_peripheral_types get_type(void) { return kHostPeripheralType_USB_HID; } 57 | 58 | //! @brief Write bytes. 59 | //! 60 | //! @param buffer Pointer to buffer to write 61 | //! @param byteCount Number of bytes to write 62 | //! @param timeoutMs Time in milliseconds to wait for write to complete. 63 | status_t write(const uint8_t *buffer, uint32_t byteCount, uint32_t timeoutMS); 64 | private: 65 | //! @brief Initialize. 66 | //! 67 | //! Opens the HID device. 68 | bool init(); 69 | 70 | 71 | nv::UsbPeripheralConfigData cfg; 72 | hid_device *m_device; //!< Device handle. 73 | }; 74 | 75 | } // namespace blfwk 76 | 77 | //! @} 78 | 79 | #endif // _UsbHidPeripheral_h_ 80 | 81 | //////////////////////////////////////////////////////////////////////////////// 82 | // EOF 83 | //////////////////////////////////////////////////////////////////////////////// 84 | -------------------------------------------------------------------------------- /src/blfwk/src/SBSourceFile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #include 10 | #include 11 | #include "string.h" 12 | #include "blfwk/stdafx.h" 13 | #include "blfwk/EndianUtilities.h" 14 | #include "blfwk/GHSSecInfo.h" 15 | #include "blfwk/Logging.h" 16 | #include "blfwk/SBSourceFile.h" 17 | 18 | using namespace blfwk; 19 | 20 | SBSourceFile::SBSourceFile(const std::string &path) 21 | : BinarySourceFile(path, kSBSourceFile) 22 | { 23 | } 24 | 25 | SBSourceFile::~SBSourceFile() 26 | { 27 | } 28 | 29 | bool SBSourceFile::isSBFile(std::istream &stream) 30 | { 31 | try 32 | { 33 | boot_image_header_t header; //!< Header from the SB boot image. 34 | 35 | // readImageHeader 36 | // seek to beginning of the stream/file and read the plaintext header 37 | stream.seekg(0, std::ios_base::beg); 38 | if (stream.read((char *)&header, sizeof(header)).bad()) 39 | { 40 | throw SBFileException("failed to read SB image header"); 41 | } 42 | 43 | header.m_flags = ENDIAN_LITTLE_TO_HOST_U16(header.m_flags); 44 | header.m_imageBlocks = ENDIAN_LITTLE_TO_HOST_U32(header.m_imageBlocks); 45 | header.m_firstBootTagBlock = ENDIAN_LITTLE_TO_HOST_U32(header.m_firstBootTagBlock); 46 | header.m_firstBootableSectionID = ENDIAN_LITTLE_TO_HOST_U32(header.m_firstBootableSectionID); 47 | header.m_keyCount = ENDIAN_LITTLE_TO_HOST_U16(header.m_keyCount); 48 | header.m_keyDictionaryBlock = ENDIAN_LITTLE_TO_HOST_U16(header.m_keyDictionaryBlock); 49 | header.m_headerBlocks = ENDIAN_LITTLE_TO_HOST_U16(header.m_headerBlocks); 50 | header.m_sectionCount = ENDIAN_LITTLE_TO_HOST_U16(header.m_sectionCount); 51 | header.m_sectionHeaderSize = ENDIAN_LITTLE_TO_HOST_U16(header.m_sectionHeaderSize); 52 | header.m_timestamp = ENDIAN_LITTLE_TO_HOST_U64(header.m_timestamp); 53 | 54 | // check header signature 1 55 | if (header.m_signature[0] != 'S' || header.m_signature[1] != 'T' || header.m_signature[2] != 'M' || 56 | header.m_signature[3] != 'P') 57 | { 58 | throw SBFileException("invalid SB signature 1"); 59 | } 60 | 61 | // check header signature 2 for version 1.1 and greater 62 | if ((header.m_majorVersion > 1 || (header.m_majorVersion == 1 && header.m_minorVersion >= 1)) && 63 | (header.m_signature2[0] != 's' || header.m_signature2[1] != 'g' || header.m_signature2[2] != 't' || 64 | header.m_signature2[3] != 'l')) 65 | { 66 | Log::log(Logger::kWarning, "warning: invalid SB signature 2\n"); 67 | } 68 | 69 | return true; 70 | } 71 | catch (...) 72 | { 73 | return false; 74 | } 75 | } 76 | 77 | DataSource *SBSourceFile::createDataSource() 78 | { 79 | throw std::runtime_error("SBSourceFile::createDataSource() has not been implemented."); 80 | } 81 | -------------------------------------------------------------------------------- /src/blfwk/src/Blob.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: Blob.cpp 3 | * 4 | * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 | * See included license file (SW-Content-Register.txt at project root) for license details. 6 | */ 7 | 8 | #include "blfwk/Blob.h" 9 | #include 10 | #include 11 | #include 12 | 13 | Blob::Blob() 14 | : m_data(0) 15 | , m_length(0) 16 | { 17 | } 18 | 19 | //! Makes a local copy of the \a data argument. 20 | //! 21 | Blob::Blob(const uint8_t *data, unsigned length) 22 | : m_data(0) 23 | , m_length(length) 24 | { 25 | m_data = reinterpret_cast(malloc(length)); 26 | memcpy(m_data, data, length); 27 | } 28 | 29 | //! Makes a local copy of the data owned by \a other. 30 | //! 31 | Blob::Blob(const Blob &other) 32 | : m_data(0) 33 | , m_length(other.m_length) 34 | { 35 | m_data = reinterpret_cast(malloc(m_length)); 36 | memcpy(m_data, other.m_data, m_length); 37 | } 38 | 39 | //! Disposes of the binary data associated with this object. 40 | Blob::~Blob() 41 | { 42 | if (m_data) 43 | { 44 | free(m_data); 45 | } 46 | } 47 | 48 | //! Copies \a data onto the blob's data. The blob does not assume ownership 49 | //! of \a data. 50 | //! 51 | //! \param data Pointer to a buffer containing the data which will be copied 52 | //! into the blob. 53 | //! \param length Number of bytes pointed to by \a data. 54 | void Blob::setData(const uint8_t *data, unsigned length) 55 | { 56 | setLength(length); 57 | memcpy(m_data, data, length); 58 | } 59 | 60 | //! Sets the #m_length member variable to \a length and resizes #m_data to 61 | //! the new length. The contents of #m_data past any previous contents are undefined. 62 | //! If the new \a length is 0 then the data will be freed and a subsequent call 63 | //! to getData() will return NULL. 64 | //! 65 | //! \param length New length of the blob's data in bytes. 66 | void Blob::setLength(unsigned length) 67 | { 68 | if (length == 0) 69 | { 70 | clear(); 71 | return; 72 | } 73 | 74 | // Allocate new block. 75 | if (!m_data) 76 | { 77 | m_data = reinterpret_cast(malloc(length)); 78 | if (!m_data) 79 | { 80 | throw std::runtime_error("failed to allocate memory"); 81 | } 82 | } 83 | // Reallocate previous block. 84 | else 85 | { 86 | void *newBlob = realloc(m_data, length); 87 | if (!newBlob) 88 | { 89 | throw std::runtime_error("failed to reallocate memory"); 90 | } 91 | m_data = reinterpret_cast(newBlob); 92 | } 93 | 94 | // Set length. 95 | m_length = length; 96 | } 97 | 98 | void Blob::append(const uint8_t *newData, unsigned newDataLength) 99 | { 100 | unsigned oldLength = m_length; 101 | 102 | setLength(m_length + newDataLength); 103 | 104 | memcpy(m_data + oldLength, newData, newDataLength); 105 | } 106 | 107 | void Blob::clear() 108 | { 109 | if (m_data) 110 | { 111 | free(m_data); 112 | m_data = NULL; 113 | } 114 | 115 | m_length = 0; 116 | } 117 | 118 | void Blob::relinquish() 119 | { 120 | m_data = NULL; 121 | m_length = 0; 122 | } 123 | -------------------------------------------------------------------------------- /src/blfwk/UartPeripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * Copyright 2015-2020 NXP 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #ifndef _uart_peripheral_h_ 10 | #define _uart_peripheral_h_ 11 | 12 | #include "Peripheral.h" 13 | #include "packet/command_packet.h" 14 | 15 | //! @addtogroup uart_peripheral 16 | //! @{ 17 | 18 | namespace blfwk 19 | { 20 | /*! 21 | * @brief Peripheral that talks to the target device over COM port hardware. 22 | */ 23 | class UartPeripheral : public Peripheral 24 | { 25 | public: 26 | //! @breif Constants. 27 | enum _uart_peripheral_constants 28 | { 29 | // The read() implementation for the UartPeripheral does not use this the timeout parameter. 30 | kUartPeripheral_UnusedTimeout = 0, 31 | // Serial timeout is set to this default during init(). 32 | kUartPeripheral_DefaultReadTimeoutMs = 1000, 33 | kUartPeripheral_DefaultBaudRate = 9600 34 | }; 35 | 36 | public: 37 | //! @brief Parameterized constructor that opens the serial port. 38 | //! 39 | //! Opens and configures the port. Throws exception if port configuration fails. 40 | //! 41 | //! Note: following COM port configuration is assumed: 8 bits, 1 stop bit, no parity. 42 | //! 43 | //! @param port OS file path for COM port. For example "COM1" on Windows. 44 | //! @param speed Port speed, e.g. 9600. 45 | UartPeripheral(const char *port, long speed = kUartPeripheral_DefaultBaudRate); 46 | 47 | //! @brief Destructor. 48 | virtual ~UartPeripheral(); 49 | 50 | //! @brief Flush. 51 | //! 52 | //! should be called on an open COM port in order to flush any remaining data in the UART RX buffer 53 | void flushRX(); 54 | 55 | //! @brief Read bytes. 56 | //! 57 | //! @param buffer Pointer to buffer. 58 | //! @param requestedBytes Number of bytes to read. 59 | //! @param actualBytes Number of bytes actually read. 60 | //! @param timeoutMs Time in milliseconds to wait for read to complete. 61 | virtual status_t read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t unused_timeoutMs); 62 | 63 | //! @brief Write bytes. 64 | //! 65 | //! @param buffer Pointer to buffer to write 66 | //! @param byteCount Number of bytes to write 67 | virtual status_t write(const uint8_t *buffer, uint32_t byteCount); 68 | 69 | //! @brief Return peripheral Type 70 | virtual _host_peripheral_types get_type(void) { return kHostPeripheralType_UART; } 71 | 72 | protected: 73 | //! @brief Initialize. 74 | //! 75 | //! Opens and configures the port. 76 | //! 77 | //! Note: following COM port configuration is assumed: 8 bits, 1 stop bit, no parity. 78 | //! 79 | //! @param port OS file path for COM port. For example "COM1" on Windows. 80 | //! @param speed Port speed, e.g. 9600. 81 | bool init(const char *port, long speed); 82 | char *port_name; //!< Port name 83 | int m_fileDescriptor; //!< Port file descriptor. 84 | uint8_t m_buffer[kDefaultMaxPacketSize]; //!< Buffer for bytes used to build read packet. 85 | }; 86 | 87 | } // namespace blfwk 88 | 89 | //! @} 90 | 91 | #endif // _uart_peripheral_h_ 92 | 93 | //////////////////////////////////////////////////////////////////////////////// 94 | // EOF 95 | //////////////////////////////////////////////////////////////////////////////// 96 | -------------------------------------------------------------------------------- /src/blfwk/UsbHidPacketizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * Copyright 2015-2020 NXP. 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #ifndef _usb_hid_packetizer_h_ 10 | #define _usb_hid_packetizer_h_ 11 | 12 | #include "Packetizer.h" 13 | #include "UsbHidPeripheral.h" 14 | #include "hidapi.h" 15 | 16 | #include "bootloader_common.h" 17 | 18 | #include "bootloader_hid_report_ids.h" 19 | 20 | //! @addtogroup usb_hid_packetizer 21 | //! @{ 22 | 23 | namespace blfwk 24 | { 25 | /*! 26 | * @brief Provides source and sink for packets that go over USB HID class. 27 | */ 28 | class UsbHidPacketizer : public Packetizer 29 | { 30 | public: 31 | //! @brief Constants 32 | enum _usbhid_contants 33 | { 34 | kReadFlushTimeoutMs = 100000, 35 | kPollAbortTimeoutMs = 10, 36 | kPollPacketMaxRetryCnt = 50, 37 | kContinuousReadMargin = 2, 38 | }; 39 | public: 40 | //! @brief Default Constructor. 41 | UsbHidPacketizer(UsbHidPeripheral *peripheral, uint32_t readPacketTimeoutMs); 42 | 43 | //! @brief Destructor. 44 | virtual ~UsbHidPacketizer(); 45 | 46 | //! @brief Read a packet. 47 | //! 48 | //! Provides the address of a buffer containing the packet. 49 | //! 50 | //! @param packet Pointer location to write packet pointer 51 | //! @param packetLength Number of bytes in returned packet 52 | virtual status_t readPacket(uint8_t **packet, uint32_t *packetLength, packet_type_t packetType); 53 | 54 | //! @brief Write a packet. 55 | //! 56 | //! @param packet Pointer to packet to write 57 | //! @param byteCount Number of bytes in packet 58 | virtual status_t writePacket(const uint8_t *packet, uint32_t byteCount, packet_type_t packetType); 59 | 60 | //! @brief Abort data phase. 61 | virtual void abortPacket(); 62 | 63 | //! @brief Send framing packet ack/nak. 64 | virtual void sync(){}; 65 | 66 | //! @brief Finalize. 67 | virtual void finalize(){}; 68 | 69 | //! @brief Enable simulator command processor pump. 70 | virtual void enableSimulatorPump() {} 71 | //! @brief Pump simulator command processor. 72 | virtual void pumpSimulator() {} 73 | //! @brief Set aborted flag. 74 | virtual void setAborted(bool aborted) {} 75 | //! @brief Returns the max packet size supported 76 | virtual uint32_t getMaxPacketSize(); 77 | 78 | //! @brief Peripheral accessor. 79 | virtual UsbHidPeripheral *getPeripheral() { return (UsbHidPeripheral *)m_peripheral; } 80 | protected: 81 | //! @brief Flush input from device. 82 | virtual void flushInput(); 83 | 84 | //! @brief Poll overlapped read for receiver data phase abort. 85 | bool pollForAbortPacket(); 86 | 87 | protected: 88 | bl_hid_report_t m_report; //!< Used for building and receiving the report. 89 | bl_hid_report_t m_abortReport; //!< Used for received abort report. 90 | 91 | private: 92 | uint32_t 93 | m_continuousReadCount; //!< Used for distinguish abort report for write-memory/receive-sb-file or read-memory 94 | }; 95 | 96 | } // namespace blfwk 97 | 98 | //! @} 99 | 100 | #endif // _usb_hid_packetizer_h_ 101 | 102 | //////////////////////////////////////////////////////////////////////////////// 103 | // EOF 104 | //////////////////////////////////////////////////////////////////////////////// 105 | -------------------------------------------------------------------------------- /src/blfwk/I2cPeripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #ifndef _i2c_peripheral_h_ 10 | #define _i2c_peripheral_h_ 11 | 12 | #include "Peripheral.h" 13 | #include "blfwk/i2c.h" 14 | #include "packet/command_packet.h" 15 | 16 | //! @addtogroup i2c_peripheral 17 | //! @{ 18 | 19 | namespace blfwk 20 | { 21 | /*! 22 | * @brief Peripheral that talks to the target device over I2C port hardware. 23 | */ 24 | class I2cPeripheral : public Peripheral 25 | { 26 | public: 27 | //! @breif Constants. 28 | enum _i2c_peripheral_constants 29 | { 30 | // The read() implementation for the I2cPeripheral does not use this the timeout parameter. 31 | kI2cPeripheral_UnusedTimeout = 0, 32 | // Serial timeout is set to this default during init(). 33 | kI2cPeripheral_DefaultReadTimeoutMs = 10, 34 | kI2cPeripheral_DefaultSpeedKHz = 100, 35 | kI2cPeripheral_DefaultAddress = 0x10 36 | }; 37 | 38 | public: 39 | //! @brief Parameterized constructor that opens the serial port. 40 | //! 41 | //! Opens and configures the port. Throws exception if port configuration fails. 42 | //! 43 | //! @param port OS file path for I2C port. For example "/dev/i2c-0.0" on Linux. 44 | //! @param speed Port speed, e.g. 9600. 45 | //! @param address I2C slave's address 46 | I2cPeripheral(const char *port, 47 | long speed = kI2cPeripheral_DefaultSpeedKHz, 48 | uint8_t address = kI2cPeripheral_DefaultAddress); 49 | 50 | //! @brief Destructor. 51 | virtual ~I2cPeripheral(); 52 | 53 | //! @brief Flush. 54 | //! 55 | //! should be called on an open I2C port in order to flush any remaining data in the I2C RX buffer 56 | void flushRX(); 57 | 58 | //! @brief Read bytes. 59 | //! 60 | //! @param buffer Pointer to buffer. 61 | //! @param requestedBytes Number of bytes to read. 62 | //! @param actualBytes Number of bytes actually read. 63 | //! @param timeoutMs Time in milliseconds to wait for read to complete. 64 | virtual status_t read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t unused_timeoutMs); 65 | 66 | //! @brief Write bytes. 67 | //! 68 | //! @param buffer Pointer to buffer to write 69 | //! @param byteCount Number of bytes to write 70 | virtual status_t write(const uint8_t *buffer, uint32_t byteCount); 71 | 72 | //! @brief Return peripheral Type 73 | virtual _host_peripheral_types get_type(void) { return kHostPeripheralType_I2C; } 74 | 75 | protected: 76 | //! @brief Initialize. 77 | //! 78 | //! Opens and configures the port. 79 | //! 80 | //! Note: following COM port configuration is assumed: 8 bits, 1 stop bit, no parity. 81 | //! 82 | //! @param port OS file path for I2C port. For example "/dev/i2c-0.0" on Linux. 83 | //! @param speed Port speed, e.g. 9600. 84 | //! @param address I2C slave's address 85 | bool init(const char *port, long speed, uint8_t address); 86 | 87 | int m_fileDescriptor; //!< Port file descriptor. 88 | uint8_t m_buffer[kDefaultMaxPacketSize]; //!< Buffer for bytes used to build read packet. 89 | uint32_t m_current_ReadTimeout; //!< The last value sent to serial_set_read_timeout(). 90 | }; 91 | 92 | } // namespace blfwk 93 | 94 | //! @} 95 | 96 | #endif // _i2c_peripheral_h_ 97 | 98 | //////////////////////////////////////////////////////////////////////////////// 99 | // EOF 100 | //////////////////////////////////////////////////////////////////////////////// 101 | -------------------------------------------------------------------------------- /src/blfwk/Packetizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _Packetizer_h_ 9 | #define _Packetizer_h_ 10 | 11 | #include "bootloader_common.h" 12 | #include "bootloader/bl_peripheral.h" 13 | 14 | #include 15 | 16 | //! @addtogroup host_packetizers 17 | //! @{ 18 | 19 | namespace blfwk 20 | { 21 | // Forward declarations. 22 | class Peripheral; 23 | 24 | //! @brief Packetizer status codes. 25 | enum _packetizer_status 26 | { 27 | kStatus_NoPingResponse = MAKE_STATUS(kStatusGroup_Packetizer, 0), 28 | kStatus_InvalidPacketType = MAKE_STATUS(kStatusGroup_Packetizer, 1), 29 | kStatus_InvalidCRC = MAKE_STATUS(kStatusGroup_Packetizer, 2), 30 | kStatus_NoCommandResponse = MAKE_STATUS(kStatusGroup_Packetizer, 3) 31 | }; 32 | 33 | /*! 34 | * @brief Interface class for packetization of commands and data. 35 | */ 36 | class Packetizer 37 | { 38 | public: 39 | Packetizer(Peripheral *peripheral, uint32_t packetTimeoutMs) 40 | : m_peripheral(peripheral) 41 | , m_packetTimeoutMs(packetTimeoutMs) 42 | , m_version() 43 | , m_options(0) 44 | , m_isAbortEnabled(false) 45 | , m_readCount(0) 46 | { 47 | } 48 | 49 | virtual ~Packetizer(){}; 50 | 51 | //! @brief Read a packet. 52 | virtual status_t readPacket(uint8_t **packet, uint32_t *packetLength, packet_type_t packetType) = 0; 53 | 54 | //! @brief Write a packet. 55 | virtual status_t writePacket(const uint8_t *packet, uint32_t byteCount, packet_type_t packetType) = 0; 56 | 57 | //! @brief Abort data phase. 58 | virtual void abortPacket() = 0; 59 | 60 | //! @brief Send framing packet ack. 61 | virtual void sync() = 0; 62 | 63 | //! @brief Finalize. 64 | virtual void finalize() = 0; 65 | 66 | //! @brief Enable simulator command processor pump. 67 | virtual void enableSimulatorPump() = 0; 68 | 69 | //! @brief Pump simulator command processor. 70 | virtual void pumpSimulator() = 0; 71 | 72 | //! @brief Set aborted flag. 73 | //! 74 | //! Used for out-of-band flow control for simulator. 75 | virtual void setAborted(bool aborted) = 0; 76 | 77 | //! @brief Return the max packet size. 78 | virtual uint32_t getMaxPacketSize() = 0; 79 | 80 | //! @brieif Optional control of number of bytes requested from peripheral by readPacket(). 81 | virtual void setReadCount(uint32_t byteCount) { m_readCount = byteCount; } 82 | //! @brief Peripheral accessor. 83 | virtual Peripheral *getPeripheral() { return m_peripheral; } 84 | //! @brief Get Framing Protocol Version 85 | standard_version_t getVersion() { return m_version; } 86 | //! @brief Get Framing Protocol Options 87 | uint16_t getOptions() { return m_options; } 88 | //! @brief Set abort packet check enable. 89 | void setAbortEnabled(bool isEnabled) { m_isAbortEnabled = isEnabled; } 90 | //! @biref Check if abort data phase is enabled. 91 | bool isAbortEnabled() { return m_isAbortEnabled; } 92 | protected: 93 | Peripheral *m_peripheral; //!< Peripheral to send/receive bytes on. 94 | standard_version_t m_version; //!< Framing protocol version. 95 | uint16_t m_options; //!< Framing protocol options bitfield. 96 | uint32_t m_packetTimeoutMs; 97 | bool m_isAbortEnabled; //!< True if allowing abort packet. Not used by all packetizers. 98 | uint32_t m_readCount; //!< Optional control of number of bytes requested by readPacket(). 99 | }; 100 | 101 | } // namespace blfwk 102 | 103 | //! @} 104 | 105 | #endif // _Packetizer_h_ 106 | 107 | //////////////////////////////////////////////////////////////////////////////// 108 | // EOF 109 | //////////////////////////////////////////////////////////////////////////////// 110 | -------------------------------------------------------------------------------- /SW-Content-Register.txt: -------------------------------------------------------------------------------- 1 | Release Name: blhost 2 | Release Version: 2.6.7 3 | Package License: LA_OPT_NXP_Software_License.htm - Production Use, Section 2.3 applies 4 | 5 | Host tools Source Description: Source code for blhost 6 | Author: NXP 7 | License: Open Source - BSD-3-Clause 8 | Format: source code 9 | Location: https://www.nxp.com/webapp/Download?colCode=blhost_2.6.7&appType=license 10 | 11 | Host tools - Serial support Description: Windows Serial peripheral support 12 | Author: Bus Pirate Project 13 | License: Open Source - CC0-1.0 (Creative Commons Zero) 14 | URL: http://code.google.com/p/the-bus-pirate/ 15 | Format: source code 16 | Location: 17 | src/blfwk/serial.h, 18 | src/blfwk/src/serial.c 19 | 20 | Host tools - USB HID Description: Windows USB HID support 21 | support Author: HIDAPI 22 | License: Open Source - BSD-3-Clause 23 | URL: http://github.com/signal11/hidapi 24 | Format: source code 25 | Location: 26 | src/blfwk/hidapi.h, 27 | src/blfwk/src/hid-*.c 28 | 29 | Host tools - JSON support Description: Windows JSON support 30 | Author: JSONCPP 31 | License: Open Source - MIT 32 | Format: source code 33 | Location: 34 | src/blfwk/json.h, 35 | src/jsoncpp.cpp 36 | 37 | Host tools - options Description: Command line parsing utility 38 | support Author: bradapp@enteract.com 39 | License: Open Source - MIT 40 | URL: http://www.bradapp.com 41 | Format: source code 42 | Location: 43 | src/blfwk/options.h, 44 | src/options.cpp 45 | 46 | Host tools - blfwk.lib Description: C++ interface to the Vincent Rijmen's 47 | Rijndael block cipher 48 | Author: Szymon Stefanek (stefanek@tin.it) 49 | License: Public Domain 50 | URL: 51 | http://www.pragmaware.net/software/rijndael/index.php 52 | Format: source code 53 | Location: 54 | src/blfwk/rijndael.h, 55 | src/blfwk/src/rijndael.cpp 56 | -------------------------------------------------------------------------------- /src/blfwk/Bootloader.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _Bootloader_h_ 9 | #define _Bootloader_h_ 10 | 11 | #include "Command.h" 12 | #include "Packetizer.h" 13 | #include "Peripheral.h" 14 | #include "Logging.h" 15 | 16 | #include 17 | #include 18 | 19 | //! @addtogroup blfwk 20 | //! @{ 21 | 22 | namespace blfwk 23 | { 24 | /*! 25 | * @brief Represents the host bootloader. 26 | * 27 | * This class provides a convenient way to access other bootloader 28 | * framework objects. 29 | */ 30 | class Bootloader 31 | { 32 | public: 33 | //! @brief Default Constructor for Simulator. 34 | Bootloader(); 35 | 36 | //! @brief Constructor. 37 | Bootloader(const Peripheral::PeripheralConfigData &config); 38 | 39 | //! @brief Destructor. 40 | virtual ~Bootloader(); 41 | 42 | //! @brief Inject a command into the bootloader. 43 | //! 44 | //! @param cmd The command to send 45 | void inject(Command &cmd) 46 | { 47 | clock_t start = clock(); 48 | cmd.sendTo(*m_hostPacketizer); 49 | clock_t finish = clock(); 50 | Log::debug(" - took %2.3f seconds\n", (double)(finish - start) / CLOCKS_PER_SEC); 51 | } 52 | 53 | //! @brief Flush state. 54 | void flush(); 55 | 56 | //! \brief Execute the execute command. 57 | void execute(uint32_t entry_point, uint32_t param = 0, uint32_t stack_pointer = 0); 58 | 59 | //! \brief Execute the reset command. 60 | void reset(); 61 | 62 | //! \brief get Device's property by using get-property command. 63 | //! 64 | //! \exception std::runtime_error Thrown if an error occurred while sending the 65 | //! GetProperty(property) bootloader command. 66 | //! 67 | //! \param property tag The property tag 68 | //! 69 | //! \param memoryIdorIndex memoryId is required by GetProperty 25(External attribute) 70 | //! Index is required by GetProperty 14/15(RAM start addr/RAM size) 71 | //! 72 | //! \return vector of the response values. 73 | uint32_vector_t getProperty(property_t tag, uint32_t memoryIdorIndex = kMemoryInternal); 74 | 75 | //! \brief Checks if Bootloader device supports a given command. 76 | //! 77 | //! \exception std::runtime_error Thrown if an error occurred while sending the 78 | //! GetProperty(kProperty_AvailableCommands) bootloader command. 79 | //! 80 | //! \param command The command to check. 81 | //! 82 | //! \return true if command is supported, false if not. 83 | bool isCommandSupported(const cmd_t &command); 84 | 85 | //! \brief Execute the get-property(current-version) command. 86 | standard_version_t getVersion(); 87 | 88 | //! \brief Execute the get-property(flash-security-state) command. 89 | uint32_t getSecurityState(); 90 | 91 | //! \brief Execute the get-property(max-supported-packet-size) command. 92 | uint32_t getDataPacketSize(); 93 | 94 | //! \brief Send a ping if applicable. 95 | void ping(int retries, unsigned int delay, int comSpeed, int* actualComSpeed); 96 | 97 | //! @name Accessors. 98 | //@{ 99 | 100 | //! @brief Get the host packetizer. 101 | Packetizer *getPacketizer() const { return m_hostPacketizer; } 102 | //@} 103 | 104 | protected: 105 | Packetizer *m_hostPacketizer; //!< Packet interface to send commands on. 106 | FileLogger *m_logger; //!< Singleton logger instance. 107 | }; 108 | 109 | } // namespace blfwk 110 | 111 | //! @} 112 | 113 | #endif // _Bootloader_h_ 114 | 115 | //////////////////////////////////////////////////////////////////////////////// 116 | // EOF 117 | //////////////////////////////////////////////////////////////////////////////// 118 | -------------------------------------------------------------------------------- /src/blfwk/src/GHSSecInfo.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: GHSSecInfo.cpp 3 | * 4 | * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 | * See included license file (SW-Content-Register.txt at project root) for license details. 6 | */ 7 | 8 | #include "blfwk/GHSSecInfo.h" 9 | #include 10 | #include "blfwk/Logging.h" 11 | #include "blfwk/EndianUtilities.h" 12 | 13 | //! The name of the GHS-specific section info table ELF section. 14 | const char *const kSecInfoSectionName = ".secinfo"; 15 | 16 | using namespace blfwk; 17 | 18 | //! The ELF file passed into this constructor as the \a elf argument must remain 19 | //! valid for the life of this object. 20 | //! 21 | //! \param elf The ELF file parser. An assertion is raised if this is NULL. 22 | GHSSecInfo::GHSSecInfo(StELFFile *elf) 23 | : m_elf(elf) 24 | , m_hasInfo(false) 25 | , m_info(0) 26 | , m_entryCount(0) 27 | { 28 | assert(elf); 29 | 30 | // look up the section. if it's not there just leave m_info and m_entryCount to 0 31 | unsigned sectionIndex = m_elf->getIndexOfSectionWithName(kSecInfoSectionName); 32 | if (sectionIndex == SHN_UNDEF) 33 | { 34 | return; 35 | } 36 | 37 | // get the section data 38 | const Elf32_Shdr &secInfo = m_elf->getSectionAtIndex(sectionIndex); 39 | if (secInfo.sh_type != SHT_PROGBITS) 40 | { 41 | // .secinfo section isn't the right type, so something is wrong 42 | return; 43 | } 44 | 45 | m_hasInfo = true; 46 | m_info = (ghs_secinfo_t *)m_elf->getSectionDataAtIndex(sectionIndex); 47 | m_entryCount = secInfo.sh_size / sizeof(ghs_secinfo_t); 48 | } 49 | 50 | //! Looks up \a addr for \a length in the .secinfo array. Only if that address is in the 51 | //! .secinfo array does this section need to be filled. If the section is found but the 52 | //! length does not match the \a length argument, a message is logged at the 53 | //! #Logger::kWarning level. 54 | //! 55 | //! If the .secinfo section is not present in the ELF file, this method always returns 56 | //! true. 57 | //! 58 | //! \param addr The start address of the section to query. 59 | //! \param length The length of the section. If a section with a start address matching 60 | //! \a addr is found, its length must match \a length to be considered. 61 | //! 62 | //! \retval true The section matching \a addr and \a length was found and should be filled. 63 | //! True is also returned when the ELF file does not have a .secinfo section. 64 | //! \retval false The section was not found and should not be filled. 65 | bool GHSSecInfo::isSectionFilled(uint32_t addr, uint32_t length) 66 | { 67 | if (!m_hasInfo) 68 | { 69 | return true; 70 | } 71 | 72 | unsigned i; 73 | for (i = 0; i < m_entryCount; ++i) 74 | { 75 | // byte swap these values into host endianness 76 | uint32_t clearAddr = ENDIAN_LITTLE_TO_HOST_U32(m_info[i].m_clearAddr); 77 | uint32_t numBytesToClear = ENDIAN_LITTLE_TO_HOST_U32(m_info[i].m_numBytesToClear); 78 | 79 | // we only consider non-zero length clear regions 80 | if ((addr == clearAddr) && (numBytesToClear != 0)) 81 | { 82 | // it is an error if the address matches but the length does not 83 | if (length != numBytesToClear) 84 | { 85 | Log::log(Logger::kWarning, "ELF Error: Size mismatch @ sect=%u, .secinfo=%u at addr 0x%08X\n", length, 86 | numBytesToClear, addr); 87 | } 88 | return true; 89 | } 90 | } 91 | 92 | return false; 93 | } 94 | 95 | //! Simply calls through to isSectionFilled(uint32_t, uint32_t) to determine 96 | //! if \a section should be filled. 97 | //! 98 | //! If the .secinfo section is not present in the ELF file, this method always returns 99 | //! true. 100 | bool GHSSecInfo::isSectionFilled(const Elf32_Shdr §ion) 101 | { 102 | return isSectionFilled(section.sh_addr, section.sh_size); 103 | } 104 | -------------------------------------------------------------------------------- /src/blfwk/src/SearchPath.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #include 10 | #include "blfwk/SearchPath.h" 11 | 12 | #if defined(WIN32) 13 | #define PATH_SEP_CHAR '\\' 14 | #define PATH_SEP_STRING "\\" 15 | #else 16 | #define PATH_SEP_CHAR '/' 17 | #define PATH_SEP_STRING "/" 18 | #endif 19 | 20 | PathSearcher *PathSearcher::s_searcher = NULL; 21 | 22 | //! This function will create the global path search object if it has 23 | //! not already been created. 24 | PathSearcher &PathSearcher::getGlobalSearcher() 25 | { 26 | if (!s_searcher) 27 | { 28 | s_searcher = new PathSearcher; 29 | } 30 | 31 | return *s_searcher; 32 | } 33 | 34 | void PathSearcher::addSearchPath(std::string &path) 35 | { 36 | m_paths.push_back(path); 37 | } 38 | 39 | //! The \a base path argument can be either a relative or absolute path. If the path 40 | //! is relative, then it is joined with search paths one after another until a matching 41 | //! file is located or all search paths are exhausted. If the \a base is absolute, 42 | //! only that path is tested and if invalid false is returned. 43 | //! 44 | //! \param base A path to the file that is to be found. 45 | //! \param targetType Currently ignored. In the future it will let you select whether to 46 | //! find a file or directory. 47 | //! \param searchCwd If set to true, the current working directory is searched before using 48 | //! any of the search paths. Otherwise only the search paths are considered. 49 | //! \param[out] result When true is returned this string is set to the first path at which 50 | //! a valid file was found. 51 | //! 52 | //! \retval true A matching file was found among the search paths. The contents of \a result 53 | //! are a valid path. 54 | //! \retval false No match could be made. \a result has been left unmodified. 55 | bool PathSearcher::search(const std::string &base, target_type_t targetType, bool searchCwd, std::string &result) 56 | { 57 | FILE *tempFile; 58 | bool absolute = isAbsolute(base); 59 | 60 | // Try cwd first if requested. Same process applies to absolute paths. 61 | if (absolute || searchCwd) 62 | { 63 | tempFile = fopen(base.c_str(), "r"); 64 | if (tempFile) 65 | { 66 | fclose(tempFile); 67 | result = base; 68 | return true; 69 | } 70 | } 71 | 72 | // If the base path is absolute and the previous test failed, then we don't go any further. 73 | if (absolute) 74 | { 75 | return false; 76 | } 77 | 78 | // Iterate over all search paths. 79 | string_list_t::const_iterator it = m_paths.begin(); 80 | for (; it != m_paths.end(); ++it) 81 | { 82 | std::string searchPath = joinPaths(*it, base); 83 | 84 | tempFile = fopen(searchPath.c_str(), "r"); 85 | if (tempFile) 86 | { 87 | fclose(tempFile); 88 | result = searchPath; 89 | return true; 90 | } 91 | } 92 | 93 | // Couldn't find anything matching the base path. 94 | return false; 95 | } 96 | 97 | bool PathSearcher::isAbsolute(const std::string &path) 98 | { 99 | #if __WIN32__ 100 | return path.size() >= 3 && path[1] == ':' && path[2] == '\\'; 101 | #else 102 | return path.size() >= 1 && path[0] == '/'; 103 | #endif 104 | } 105 | 106 | std::string PathSearcher::joinPaths(const std::string &first, const std::string &second) 107 | { 108 | // Start with first string. 109 | std::string result = first; 110 | 111 | // Add path separator if needed 112 | if ((first[first.size() - 1] != PATH_SEP_CHAR) && (second[0] != PATH_SEP_CHAR)) 113 | { 114 | result += PATH_SEP_STRING; 115 | } 116 | 117 | // Append the second string. 118 | result += second; 119 | 120 | // And return the whole mess. 121 | return result; 122 | } 123 | -------------------------------------------------------------------------------- /src/blfwk/src/I2cPeripheral.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #include "blfwk/I2cPeripheral.h" 10 | #include "blfwk/Logging.h" 11 | #include "blfwk/format_string.h" 12 | #include "blfwk/i2c.h" 13 | 14 | using namespace blfwk; 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // Code 18 | //////////////////////////////////////////////////////////////////////////////// 19 | 20 | // See I2cPeripheral.h for documentation of this method. 21 | I2cPeripheral::I2cPeripheral(const char *port, long speed, uint8_t address) 22 | : m_fileDescriptor(-1) 23 | { 24 | if (!init(port, address, speed)) 25 | { 26 | throw std::runtime_error(format_string("Error: Cannot open I2C port(%s), speed(%d Hz).\n", port, speed)); 27 | } 28 | } 29 | 30 | // See I2cPeripheral.h for documentation of this method. 31 | bool I2cPeripheral::init(const char *port, long speed, uint8_t address) 32 | { 33 | assert(port); 34 | 35 | // Open the port. 36 | m_fileDescriptor = i2c_open(const_cast(port)); 37 | if (m_fileDescriptor == -1) 38 | { 39 | return false; 40 | } 41 | 42 | i2c_setup(m_fileDescriptor, speed, address); 43 | 44 | // Flush garbage from receive buffer before setting read timeout. 45 | flushRX(); 46 | 47 | // Set host serial timeout to 10 milliseconds. Higherlevel timeouts are implemented in 48 | // SerialPacketizer.cpp 49 | i2c_set_timeout(m_fileDescriptor, kI2cPeripheral_DefaultReadTimeoutMs); 50 | 51 | return true; 52 | } 53 | 54 | // See I2cPeripheral.h for documentation of this method. 55 | I2cPeripheral::~I2cPeripheral() 56 | { 57 | if (m_fileDescriptor != -1) 58 | { 59 | i2c_close(m_fileDescriptor); 60 | } 61 | } 62 | 63 | // See I2cPeripheral.h for documentation of this method. 64 | status_t I2cPeripheral::read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t unused_timeoutMs) 65 | { 66 | assert(buffer); 67 | 68 | // Read the requested number of bytes. 69 | int count = i2c_read(m_fileDescriptor, reinterpret_cast(buffer), requestedBytes); 70 | if (actualBytes) 71 | { 72 | *actualBytes = count; 73 | } 74 | 75 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 76 | { 77 | // Log bytes read in hex 78 | Log::debug2("<"); 79 | for (int i = 0; i < (int)count; i++) 80 | { 81 | Log::debug2("%02x", buffer[i]); 82 | if (i != (count - 1)) 83 | { 84 | Log::debug2(" "); 85 | } 86 | } 87 | Log::debug2(">\n"); 88 | } 89 | 90 | if (count < (int)requestedBytes) 91 | { 92 | // Anything less than requestedBytes is a timeout error. 93 | return kStatus_Timeout; 94 | } 95 | 96 | return kStatus_Success; 97 | } 98 | 99 | // See I2cPeripheral.h for documentation of this method. 100 | void I2cPeripheral::flushRX() {} 101 | 102 | // See I2cPeripheral.h for documentation of this method. 103 | status_t I2cPeripheral::write(const uint8_t *buffer, uint32_t byteCount) 104 | { 105 | assert(buffer); 106 | 107 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 108 | { 109 | // Log bytes written in hex 110 | Log::debug2("["); 111 | for (int i = 0; i < (int)byteCount; i++) 112 | { 113 | Log::debug2("%02x", buffer[i]); 114 | if (i != (byteCount - 1)) 115 | { 116 | Log::debug2(" "); 117 | } 118 | } 119 | Log::debug2("]\n"); 120 | } 121 | 122 | if (i2c_write(m_fileDescriptor, reinterpret_cast(const_cast(buffer)), byteCount) == byteCount) 123 | return kStatus_Success; 124 | else 125 | return kStatus_Fail; 126 | } 127 | 128 | //////////////////////////////////////////////////////////////////////////////// 129 | // EOF 130 | //////////////////////////////////////////////////////////////////////////////// 131 | -------------------------------------------------------------------------------- /src/blfwk/StSRecordFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_StSRecordFile_h_) 8 | #define _StSRecordFile_h_ 9 | 10 | //#include 11 | #include "stdafx.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | enum 18 | { 19 | //! The required first character of an S-record. 20 | SRECORD_START_CHAR = 'S', 21 | 22 | //! The minimum length of a S-record. This is the type (2) + count (2) + addr (4) + cksum (2). 23 | SRECORD_MIN_LENGTH = 10, 24 | 25 | //! Index of the first character of the address field. 26 | SRECORD_ADDRESS_START_CHAR_INDEX = 4 27 | }; 28 | 29 | /*! 30 | * \brief S-record parser. 31 | * 32 | * This class takes an input stream and parses it as an S-record file. While 33 | * the individual records that comprise the file are available for access, the 34 | * class also provides a higher-level view of the contents. It processes the 35 | * individual records and builds an image of what the memory touched by the 36 | * file looks like. Then you can access the contiguous sections of memory. 37 | */ 38 | class StSRecordFile 39 | { 40 | public: 41 | /*! 42 | * Structure representing each individual line of the S-record input data. 43 | */ 44 | struct SRecord 45 | { 46 | unsigned m_type; //!< Record number type, such as 9 for "S9", 3 for "S3" and so on. 47 | unsigned m_count; //!< Number of character pairs (bytes) from address through checksum. 48 | uint32_t m_address; //!< The address specified as part of the S-record. 49 | unsigned m_dataCount; //!< Number of bytes of data. 50 | uint8_t *m_data; //!< Pointer to data, or NULL if no data for this record type. 51 | uint8_t m_checksum; //!< The checksum byte present in the S-record. 52 | }; 53 | 54 | //! Iterator type. 55 | typedef std::vector::const_iterator const_iterator; 56 | 57 | public: 58 | //! \brief Constructor. 59 | StSRecordFile(std::istream &inStream); 60 | 61 | //! \brief Destructor. 62 | virtual ~StSRecordFile(); 63 | 64 | //! \name File name 65 | //@{ 66 | virtual void setName(const std::string &inName) { m_name = inName; } 67 | virtual std::string getName() const { return m_name; } 68 | //@} 69 | 70 | //! \name Parsing 71 | //@{ 72 | //! \brief Determine if the file is an S-record file. 73 | virtual bool isSRecordFile(); 74 | 75 | //! \brief Parses the entire S-record input stream. 76 | virtual void parse(); 77 | //@} 78 | 79 | //! \name Record access 80 | //@{ 81 | //! \return the number of S-records that have been parsed from the input stream. 82 | inline unsigned getRecordCount() const { return static_cast(m_records.size()); } 83 | //! \return iterator for 84 | inline const_iterator getBegin() const { return m_records.begin(); } 85 | inline const_iterator getEnd() const { return m_records.end(); } 86 | //@} 87 | 88 | //! \name Operators 89 | //@{ 90 | inline const SRecord &operator[](unsigned inIndex) { return m_records[inIndex]; } 91 | //@} 92 | 93 | protected: 94 | std::istream &m_stream; //!< The input stream for the S-record data. 95 | std::vector m_records; //!< Vector of S-records in the input data. 96 | 97 | std::string m_name; //!< File name. (optional) 98 | 99 | //! \name Parsing utilities 100 | //@{ 101 | virtual void parseLine(std::string &inLine); 102 | 103 | bool isHexDigit(char c); 104 | int hexDigitToInt(char digit); 105 | int readHexByte(std::string &inString, int inIndex); 106 | //@} 107 | }; 108 | 109 | /*! 110 | * \brief Simple exception thrown to indicate an error in the input SRecord data format. 111 | */ 112 | class StSRecordParseException : public std::runtime_error 113 | { 114 | public: 115 | //! \brief Default constructor. 116 | StSRecordParseException(const std::string &inMessage) 117 | : std::runtime_error(inMessage) 118 | { 119 | } 120 | }; 121 | 122 | #endif // _StSRecordFile_h_ 123 | -------------------------------------------------------------------------------- /src/blfwk/src/spi.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #include "spi.h" 10 | 11 | /******************************************************************************* 12 | * Definitions 13 | ******************************************************************************/ 14 | 15 | #define DEFAULT_BITS_PER_WORD (8) 16 | 17 | /******************************************************************************* 18 | * Variables 19 | ******************************************************************************/ 20 | 21 | static struct spi_ioc_transfer spi_data; 22 | 23 | /******************************************************************************* 24 | * Codes 25 | ******************************************************************************/ 26 | 27 | // See spi.h for documentation of this method. 28 | int spi_setup(int fd, uint32_t speed, uint32_t mode, uint32_t bits_per_word) 29 | { 30 | int ret = -1; 31 | 32 | if (fd < 0) 33 | { 34 | return -1; 35 | } 36 | 37 | // Set phase, polarity chipselect active state and bit order 38 | ret = ioctl(fd, SPI_IOC_WR_MODE, &mode); 39 | if (ret < 0) 40 | { 41 | return ret; 42 | } 43 | 44 | // Set bits per word 45 | spi_data.bits_per_word = (bits_per_word != 8) && (bits_per_word != 9) ? DEFAULT_BITS_PER_WORD : bits_per_word; 46 | ret = ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, (unsigned long)&spi_data.bits_per_word); 47 | if (ret < 0) 48 | { 49 | return ret; 50 | } 51 | 52 | // Set Max speed and current speed 53 | spi_data.speed_hz = speed; // current speed 54 | return ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, (unsigned long)&speed); 55 | } 56 | 57 | // See spi.h for documentation of this method. 58 | int spi_set_timeout(int fd, uint32_t milliseconds) 59 | { 60 | /* 61 | * Linux SPI-DEV doesn't support to set timeout from user space. 62 | * The timeout is maintained within the device driver. 63 | * Different SPI drivers have different default timeout values. 64 | */ 65 | 66 | return 0; 67 | } 68 | 69 | // See spi.h for documentation of this method. 70 | int spi_write(int fd, char *buf, int size) 71 | { 72 | if (fd < 0) 73 | { 74 | return -1; 75 | } 76 | 77 | /* 78 | * Do not convert a pointer type to __u64 directly. It will lead an issue for 32bit archtectures 79 | */ 80 | spi_data.tx_buf = (intptr_t)buf; 81 | spi_data.rx_buf = (intptr_t)NULL; 82 | spi_data.len = size; 83 | spi_data.cs_change = 0; 84 | 85 | return ioctl(fd, SPI_IOC_MESSAGE(1), &spi_data); 86 | } 87 | 88 | // See spi.h for documentation of this method. 89 | int spi_read(int fd, char *buf, int size) 90 | { 91 | if (fd < 0) 92 | { 93 | return -1; 94 | } 95 | 96 | /* 97 | * Do not convert a pointer type to __u64 directly. It will lead an issue for 32bit archtectures 98 | */ 99 | spi_data.tx_buf = (intptr_t)NULL; 100 | spi_data.rx_buf = (intptr_t)buf; 101 | spi_data.len = size; 102 | spi_data.cs_change = 0; 103 | 104 | return ioctl(fd, SPI_IOC_MESSAGE(1), &spi_data); 105 | } 106 | 107 | // See spi.h for documentation of this method. 108 | int spi_open(char *port) 109 | { 110 | int fd = -1; 111 | 112 | if (port == NULL) 113 | { 114 | return -1; 115 | } 116 | 117 | fd = open(port, O_RDWR); 118 | if (fd < 0) 119 | { 120 | fprintf(stderr, "Failed to open SPI port(%s).\n", port); 121 | } 122 | 123 | return fd; 124 | } 125 | 126 | // See spi.h for documentation of this method. 127 | int spi_close(int fd) 128 | { 129 | int ret; 130 | if (fd < 0) 131 | { 132 | return -1; 133 | } 134 | 135 | ret = close(fd); 136 | if (ret < 0) 137 | { 138 | fprintf(stderr, "Failed to close SPI port.\n"); 139 | } 140 | else 141 | { 142 | fd = -1; 143 | } 144 | 145 | return ret; 146 | } 147 | 148 | //////////////////////////////////////////////////////////////////////////////// 149 | // EOF 150 | //////////////////////////////////////////////////////////////////////////////// 151 | -------------------------------------------------------------------------------- /mk/common.mk: -------------------------------------------------------------------------------- 1 | #------------------------------------------------------------------------------- 2 | # Copyright (c) 2012 Freescale Semiconductor, Inc. 3 | # All rights reserved. 4 | # 5 | # SPDX-License-Identifier: BSD-3-Clause 6 | #------------------------------------------------------------------------------- 7 | 8 | #------------------------------------------------------------------------------- 9 | # Utility 10 | #------------------------------------------------------------------------------- 11 | 12 | # Kludge to create a variable equal to a single space. 13 | empty := 14 | space := $(empty) $(empty) 15 | 16 | #------------------------------------------------------------------------------- 17 | # OS 18 | #------------------------------------------------------------------------------- 19 | 20 | # Get the OS name. Known values are "Linux", "CYGWIN_NT-5.1", and "Darwin". 21 | os_name := $(shell uname -s) 22 | 23 | # Set to 1 if running on cygwin. 24 | is_cygwin := $(and $(findstring CYGWIN,$(os_name)),1) 25 | 26 | # Set to 1 if running on cygwin. 27 | is_mingw := $(and $(findstring MINGW,$(os_name)),1) 28 | 29 | # Set to 1 if running on redhat. 30 | is_redhat := $(shell if [ -f /etc/redhat-release ]; then echo 1 ; fi) 31 | 32 | # Disable parallel builds for cygwin since they hang. 33 | ifeq "$(is_cygwin)" "1" 34 | .NOTPARALLEL: 35 | endif 36 | 37 | ifeq "$(is_mingw)" "1" 38 | .NOTPARALLEL: 39 | endif 40 | 41 | #------------------------------------------------------------------------------- 42 | # Logging options 43 | #------------------------------------------------------------------------------- 44 | 45 | # Enable color output by default. 46 | BUILD_SDK_COLOR ?= 1 47 | 48 | # MAKE 49 | MAKE := make 50 | ifeq "$(is_cygwin)" "1" 51 | MAKE := mingw32-make 52 | endif 53 | 54 | ifeq "$(is_mingw)" "1" 55 | MAKE := mingw32-make 56 | endif 57 | 58 | # Normally, commands in recipes are prefixed with '@' so the command itself 59 | # is not echoed by make. But if VERBOSE is defined (set to anything non-empty), 60 | # then the '@' is removed from recipes. The 'at' variable is used to control 61 | # this. Similarly, 'silent_make' is used to pass the -s option to child make 62 | # invocations when not in VERBOSE mode. 63 | ifeq "$(VERBOSE)" "1" 64 | at := 65 | silent_make := 66 | else 67 | at := @ 68 | silent_make := -s 69 | endif 70 | 71 | # These colors must be printed with the printf command. echo won't handle the 72 | # escape sequences. 73 | color_default = \033[00m 74 | color_bold = \033[01m 75 | color_red = \033[31m 76 | color_green = \033[32m 77 | color_yellow = \033[33m 78 | color_blue = \033[34m 79 | color_magenta = \033[35m 80 | color_cyan = \033[36m 81 | color_orange = \033[38;5;172m 82 | color_light_blue = \033[38;5;039m 83 | color_gray = \033[38;5;008m 84 | color_purple = \033[38;5;097m 85 | 86 | ifeq "$(BUILD_SDK_COLOR)" "1" 87 | color_build := $(color_light_blue) 88 | color_c := $(color_green) 89 | color_cxx := $(color_green) 90 | color_cpp := $(color_orange) 91 | color_asm := $(color_magenta) 92 | color_ar := $(color_yellow) 93 | color_link := $(color_purple) 94 | endif 95 | 96 | # Used in printmessage if the color args are not present. 97 | color_ := 98 | 99 | # Use in recipes to print color messages if printing to a terminal. If 100 | # BUILD_SDK_COLOR is not set to 1, this reverts to a simple uncolorized printf. 101 | # A newline is added to the end of the printed message. 102 | # 103 | # Arguments: 104 | # 1 - name of the color variable (see above), minus the "color_" prefix 105 | # 2 - first colorized part of the message 106 | # 3 - first uncolorized part of the message 107 | # 4 - color name for second colorized message 108 | # 5 - second colorized message 109 | # 6 - second uncolorized part of the message 110 | # 7 - uncolorized prefix on the whole line; this is last because it is expected to be used rarely 111 | # 112 | # All arguments are optional. 113 | # 114 | # Use like: 115 | # $(call printmessage,cyan,Building, remainder of the message...) 116 | ifeq "$(BUILD_SDK_COLOR)" "1" 117 | define printmessage 118 | if [ -t 1 ]; then printf "$(7)$(color_$(1))$(2)$(color_default)$(3)$(color_$(4))$(5)$(color_default)$(6)\n" ; \ 119 | else printf "$(7)$(2)$(3)$(5)$(6)\n" ; fi 120 | endef 121 | else 122 | define printmessage 123 | printf "$(7)$(2)$(3)$(5)$(6)\n" ; fi 124 | endef 125 | endif 126 | 127 | -------------------------------------------------------------------------------- /src/blfwk/SpiPeripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #ifndef _spi_peripheral_h_ 10 | #define _spi_peripheral_h_ 11 | 12 | #include "Peripheral.h" 13 | #include "blfwk/spi.h" 14 | #include "packet/command_packet.h" 15 | 16 | //! @addtogroup spi_peripheral 17 | //! @{ 18 | 19 | namespace blfwk 20 | { 21 | /*! 22 | * @brief Peripheral that talks to the target device over SPI port hardware. 23 | */ 24 | class SpiPeripheral : public Peripheral 25 | { 26 | public: 27 | //! @breif Constants. 28 | enum _spi_peripheral_constants 29 | { 30 | // The read() implementation for the SpiPeripheral does not use this the timeout parameter. 31 | kSpiPeripheral_UnusedTimeout = 0, 32 | // Serial timeout is set to this default during init(). 33 | kSpiPeripheral_DefaultReadTimeoutMs = 1, 34 | kSpiPeripheral_DefaultSpeedKHz = 100, 35 | kSpiPeripheral_DefaultClockPolarity = 1, 36 | kSpiPeripheral_DefaultClockPhase = 1, 37 | kSpiPeripheral_DefaultBitSequence = 1, 38 | kSpiPeripheral_DefaultBitsPerWord = 8, 39 | }; 40 | 41 | public: 42 | //! @brief Parameterized constructor that opens the serial port. 43 | //! 44 | //! Opens and configures the port. Throws exception if port configuration fails. 45 | //! 46 | //! @param port OS file path for SPI port. For example "/dev/spidev-0.0" on Linux. 47 | //! @param speed Port speed in KHz, e.g. 100(means 100KHz). 48 | //! @param polarity SPI clock polarity, 1 for active-high, 0 for active-low. 49 | //! @param phase SPI clock phase, 1 for second clock edge, 0 for first clock edge. 50 | //! @param sequence SPI data transfer bits sequence. 1 for LSB, 0 for MSB. 51 | SpiPeripheral(const char *port, 52 | long speed = kSpiPeripheral_DefaultSpeedKHz, 53 | uint8_t polarity = kSpiPeripheral_DefaultClockPolarity, 54 | uint8_t phase = kSpiPeripheral_DefaultClockPhase, 55 | uint8_t sequence = kSpiPeripheral_DefaultBitSequence); 56 | 57 | //! @brief Destructor. 58 | virtual ~SpiPeripheral(); 59 | 60 | //! @brief Flush. 61 | //! 62 | //! should be called on an open SPI port in order to flush any remaining data in the SPI RX buffer 63 | void flushRX(); 64 | 65 | //! @brief Read bytes. 66 | //! 67 | //! @param buffer Pointer to buffer. 68 | //! @param requestedBytes Number of bytes to read. 69 | //! @param actualBytes Number of bytes actually read. 70 | //! @param timeoutMs Time in milliseconds to wait for read to complete. 71 | virtual status_t read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t unused_timeoutMs); 72 | 73 | //! @brief Write bytes. 74 | //! 75 | //! @param buffer Pointer to buffer to write 76 | //! @param byteCount Number of bytes to write 77 | virtual status_t write(const uint8_t *buffer, uint32_t byteCount); 78 | 79 | //! @brief Return peripheral Type 80 | virtual _host_peripheral_types get_type(void) { return kHostPeripheralType_SPI; } 81 | 82 | protected: 83 | //! @brief Initialize. 84 | //! 85 | //! Opens and configures the port. 86 | //! 87 | //! Note: following COM port configuration is assumed: 8 bits, 1 stop bit, no parity. 88 | //! 89 | //! @param port OS file path for SPI port. For example "/dev/spidev-0.0" on Linux. 90 | //! @param speed Port speed in KHz, e.g. 100(means 100KHz). 91 | //! @param polarity SPI clock polarity, 1 for active-high, 0 for active-low. 92 | //! @param phase SPI clock phase, 1 for second clock edge, 0 for first clock edge. 93 | //! @param direction SPI data transfer bits direction. 1 for LSB, 0 for MSB. 94 | bool init(const char *port, long speed, uint8_t polarity, uint8_t phase, uint8_t direction); 95 | 96 | int m_fileDescriptor; //!< Port file descriptor. 97 | uint8_t m_buffer[kDefaultMaxPacketSize]; //!< Buffer for bytes used to build read packet. 98 | uint32_t m_current_ReadTimeout; //!< The last value sent to serial_set_read_timeout(). 99 | }; 100 | 101 | } // namespace blfwk 102 | 103 | //! @} 104 | 105 | #endif // _spi_peripheral_h_ 106 | 107 | //////////////////////////////////////////////////////////////////////////////// 108 | // EOF 109 | //////////////////////////////////////////////////////////////////////////////// 110 | -------------------------------------------------------------------------------- /src/blfwk/src/i2c.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #include "blfwk/i2c.h" 10 | 11 | /******************************************************************************* 12 | * Definitions 13 | ******************************************************************************/ 14 | 15 | /******************************************************************************* 16 | * Variables 17 | ******************************************************************************/ 18 | 19 | static struct i2c_rdwr_ioctl_data i2c_data = { 0 }; 20 | 21 | /******************************************************************************* 22 | * Codes 23 | ******************************************************************************/ 24 | 25 | // See i2c.h for documentation of this method. 26 | static unsigned long i2c_check_functionality(int fd) 27 | { 28 | unsigned long funcs = 0; 29 | 30 | if (fd < 0) 31 | { 32 | return 0; 33 | } 34 | 35 | if (ioctl(fd, I2C_FUNCS, &funcs) < 0) 36 | { 37 | return 0; 38 | } 39 | 40 | return funcs & I2C_FUNC_I2C; 41 | } 42 | 43 | // See i2c.h for documentation of this method. 44 | int i2c_setup(int fd, uint32_t speed, uint8_t address) 45 | { 46 | if (fd < 0) 47 | { 48 | return -1; 49 | } 50 | 51 | i2c_data.nmsgs = 1; 52 | i2c_data.msgs = (struct i2c_msg *)malloc(i2c_data.nmsgs * sizeof(struct i2c_msg)); 53 | if (i2c_data.msgs == NULL) 54 | { 55 | return -1; 56 | } 57 | i2c_data.msgs[0].addr = (uint16_t)address; 58 | 59 | /* 60 | * I2C speed setting is not supported. 61 | */ 62 | 63 | return 0; 64 | } 65 | 66 | // See i2c.h for documentation of this method. 67 | int i2c_set_timeout(int fd, uint32_t milliseconds) 68 | { 69 | if (fd < 0) 70 | { 71 | return -1; 72 | } 73 | 74 | /* For historical reasons, user-space sets the timeout 75 | * value in units of 10 ms. 76 | */ 77 | return ioctl(fd, I2C_TIMEOUT, (unsigned long)milliseconds / 10); 78 | } 79 | 80 | // See i2c.h for documentation of this method. 81 | int i2c_write(int fd, char *buf, int size) 82 | { 83 | int ret = -1; 84 | 85 | if ((fd < 0) || (i2c_data.msgs == NULL)) 86 | { 87 | return 0; 88 | } 89 | 90 | i2c_data.msgs[0].flags = 0; // write command 91 | i2c_data.msgs[0].buf = (unsigned char *)buf; 92 | i2c_data.msgs[0].len = size; 93 | ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data); 94 | if (ret < 0) 95 | { 96 | return 0; 97 | } 98 | 99 | return size; 100 | } 101 | 102 | // See i2c.h for documentation of this method. 103 | int i2c_read(int fd, char *buf, int size) 104 | { 105 | int ret = -1; 106 | 107 | i2c_set_timeout(fd, 500); 108 | if ((fd < 0) || (i2c_data.msgs == NULL)) 109 | { 110 | return 0; 111 | } 112 | 113 | i2c_data.msgs[0].flags = I2C_M_RD; // read command 114 | i2c_data.msgs[0].buf = (unsigned char *)buf; 115 | i2c_data.msgs[0].len = size; 116 | ret = ioctl(fd, I2C_RDWR, (unsigned long)&i2c_data); 117 | if (ret < 0) 118 | { 119 | return 0; 120 | } 121 | 122 | return size; 123 | } 124 | 125 | // See i2c.h for documentation of this method. 126 | int i2c_open(char *port) 127 | { 128 | int fd; 129 | 130 | fd = open(port, O_RDWR); 131 | if (fd < 0) 132 | { 133 | fprintf(stderr, "Failed to open I2C port(%s).\n", port); 134 | return fd; 135 | } 136 | 137 | if (!i2c_check_functionality(fd)) 138 | { 139 | fprintf(stderr, "Not an I2C port(%s).\n", port); 140 | return -1; 141 | } 142 | 143 | return fd; 144 | } 145 | 146 | // See i2c.h for documentation of this method. 147 | int i2c_close(int fd) 148 | { 149 | int ret; 150 | if (i2c_data.msgs != NULL) 151 | { 152 | free(i2c_data.msgs); 153 | i2c_data.msgs = NULL; 154 | } 155 | 156 | ret = close(fd); 157 | if (ret < 0) 158 | { 159 | fprintf(stderr, "Failed to close I2C port.\n"); 160 | } 161 | else 162 | { 163 | fd = -1; 164 | } 165 | 166 | return ret; 167 | } 168 | 169 | //////////////////////////////////////////////////////////////////////////////// 170 | // EOF 171 | //////////////////////////////////////////////////////////////////////////////// 172 | -------------------------------------------------------------------------------- /src/blfwk/src/GlobMatcher.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: GlobMatcher.cpp 3 | * 4 | * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 | * See included license file (SW-Content-Register.txt at project root) for license details. 6 | */ 7 | 8 | #include "blfwk/GlobMatcher.h" 9 | 10 | #ifndef NEGATE 11 | #define NEGATE '^' // std cset negation char 12 | #endif 13 | 14 | using namespace blfwk; 15 | 16 | //! The glob pattern must match the \e entire test value argument in order 17 | //! for the match to be considered successful. Thus, even if, for example, 18 | //! the pattern matches all but the last character the result will be false. 19 | //! 20 | //! \retval true The test value does match the glob pattern. 21 | //! \retval false The test value does not match the glob pattern. 22 | bool GlobMatcher::match(const std::string &testValue) 23 | { 24 | return globMatch(testValue.c_str(), m_pattern.c_str()); 25 | } 26 | 27 | //! \note This glob implementation was originally written by ozan s. yigit in 28 | //! December 1994. This is public domain source code. 29 | bool GlobMatcher::globMatch(const char *str, const char *p) 30 | { 31 | int negate; 32 | int match; 33 | int c; 34 | 35 | while (*p) 36 | { 37 | if (!*str && *p != '*') 38 | return false; 39 | 40 | switch (c = *p++) 41 | { 42 | case '*': 43 | while (*p == '*') 44 | p++; 45 | 46 | if (!*p) 47 | return true; 48 | 49 | if (*p != '?' && *p != '[' && *p != '\\') 50 | while (*str && *p != *str) 51 | str++; 52 | 53 | while (*str) 54 | { 55 | if (globMatch(str, p)) 56 | return true; 57 | str++; 58 | } 59 | return false; 60 | 61 | case '?': 62 | if (*str) 63 | break; 64 | return false; 65 | 66 | // set specification is inclusive, that is [a-z] is a, z and 67 | // everything in between. this means [z-a] may be interpreted 68 | // as a set that contains z, a and nothing in between. 69 | case '[': 70 | if (*p != NEGATE) 71 | negate = false; 72 | else 73 | { 74 | negate = true; 75 | p++; 76 | } 77 | 78 | match = false; 79 | 80 | while (!match && (c = *p++)) 81 | { 82 | if (!*p) 83 | return false; 84 | if (*p == '-') 85 | { // c-c 86 | if (!*++p) 87 | return false; 88 | if (*p != ']') 89 | { 90 | if (*str == c || *str == *p || (*str > c && *str < *p)) 91 | match = true; 92 | } 93 | else 94 | { // c-] 95 | if (*str >= c) 96 | match = true; 97 | break; 98 | } 99 | } 100 | else 101 | { // cc or c] 102 | if (c == *str) 103 | match = true; 104 | if (*p != ']') 105 | { 106 | if (*p == *str) 107 | match = true; 108 | } 109 | else 110 | break; 111 | } 112 | } 113 | 114 | if (negate == match) 115 | return false; 116 | // if there is a match, skip past the cset and continue on 117 | while (*p && *p != ']') 118 | p++; 119 | if (!*p++) // oops! 120 | return false; 121 | break; 122 | 123 | case '\\': 124 | if (*p) 125 | c = *p++; 126 | default: 127 | if (c != *str) 128 | return false; 129 | break; 130 | } 131 | str++; 132 | } 133 | 134 | return !*str; 135 | } 136 | -------------------------------------------------------------------------------- /src/blfwk/DataTarget.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_DataTarget_h_) 8 | #define _DataTarget_h_ 9 | 10 | #include "stdafx.h" 11 | #include "DataSource.h" 12 | 13 | namespace blfwk 14 | { 15 | // Forward declaration 16 | class DataSource; 17 | 18 | /*! 19 | * \brief Abstract base class for the target address or range of data. 20 | * 21 | * Targets at the most basic level have a single address, and potentially 22 | * an address range. Unbounded targets have a beginning address but no 23 | * specific end address, while bounded targets do have an end address. 24 | * 25 | * Users of a data target can access the begin and end addresses directly. 26 | * However, the most powerful way to use a target is with the 27 | * getRangeForSegment() method. This method returns the target address range 28 | * for a segment of a data source. The value of the resulting range can be 29 | * completely dependent upon the segment's properties, those of its data 30 | * source, and the type of data target. 31 | * 32 | * \see blfwk::DataSource 33 | */ 34 | class DataTarget 35 | { 36 | public: 37 | //! \brief Simple structure that describes an addressed region of memory. 38 | //! \todo Decide if the end address is inclusive or not. 39 | struct AddressRange 40 | { 41 | uint32_t m_begin; 42 | uint32_t m_end; 43 | }; 44 | 45 | public: 46 | //! \brief Default constructor. 47 | DataTarget() 48 | : m_source(0) 49 | { 50 | } 51 | 52 | //! \brief Destructor. 53 | virtual ~DataTarget() {} 54 | //! \brief Whether the target is just a single address or has an end to it. 55 | virtual bool isBounded() { return false; } 56 | virtual uint32_t getBeginAddress() { return 0; } 57 | virtual uint32_t getEndAddress() { return 0; } 58 | //! \brief Return the address range for a segment of a data source. 59 | virtual DataTarget::AddressRange getRangeForSegment(DataSource &source, DataSource::Segment &segment) = 0; 60 | 61 | inline void setSource(DataSource *source) { m_source = source; } 62 | inline DataSource *getSource() const { return m_source; } 63 | protected: 64 | DataSource *m_source; //!< Corresponding data source for this target. 65 | }; 66 | 67 | /*! 68 | * \brief Target with a constant values for the addresses. 69 | * 70 | * This target type supports can be both bounded and unbounded. It always has 71 | * at least one address, the beginning address. The end address is optional, 72 | * and if not provided makes the target unbounded. 73 | */ 74 | class ConstantDataTarget : public DataTarget 75 | { 76 | public: 77 | //! \brief Constructor taking only a begin address. 78 | ConstantDataTarget(uint32_t start) 79 | : DataTarget() 80 | , m_begin(start) 81 | , m_end(0) 82 | , m_hasEnd(false) 83 | { 84 | } 85 | 86 | //! \brief Constructor taking both begin and end addresses. 87 | ConstantDataTarget(uint32_t start, uint32_t end) 88 | : DataTarget() 89 | , m_begin(start) 90 | , m_end(end) 91 | , m_hasEnd(true) 92 | { 93 | } 94 | 95 | //! \brief The target is bounded if an end address was specified. 96 | virtual bool isBounded() { return m_hasEnd; } 97 | virtual uint32_t getBeginAddress() { return m_begin; } 98 | virtual uint32_t getEndAddress() { return m_end; } 99 | //! \brief Return the address range for a segment of a data source. 100 | virtual DataTarget::AddressRange getRangeForSegment(DataSource &source, DataSource::Segment &segment); 101 | 102 | protected: 103 | uint32_t m_begin; //!< Start address. 104 | uint32_t m_end; //!< End address. 105 | bool m_hasEnd; //!< Was an end address specified? 106 | }; 107 | 108 | /*! 109 | * \brief Target address that is the "natural" location of whatever the source data is. 110 | * 111 | * The data source used with the target must have a natural location. If 112 | * getRangeForSegment() is called with a segment that does not have a natural 113 | * location, a semantic_error will be thrown. 114 | */ 115 | class NaturalDataTarget : public DataTarget 116 | { 117 | public: 118 | //! \brief Default constructor. 119 | NaturalDataTarget() 120 | : DataTarget() 121 | { 122 | } 123 | 124 | //! \brief Natural data targets are bounded by their source's segment lengths. 125 | virtual bool isBounded() { return true; } 126 | //! \brief Return the address range for a segment of a data source. 127 | virtual DataTarget::AddressRange getRangeForSegment(DataSource &source, DataSource::Segment &segment); 128 | }; 129 | 130 | }; // namespace blfwk 131 | 132 | #endif // _DataTarget_h_ 133 | -------------------------------------------------------------------------------- /src/blfwk/src/DataSourceImager.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * File: DataSourceImager.cpp 3 | * 4 | * Copyright (c) Freescale Semiconductor, Inc. All rights reserved. 5 | * See included license file (SW-Content-Register.txt at project root) for license details. 6 | */ 7 | 8 | #include "blfwk/DataSourceImager.h" 9 | #include 10 | #include 11 | 12 | using namespace blfwk; 13 | 14 | DataSourceImager::DataSourceImager() 15 | : Blob() 16 | , m_fill(0) 17 | , m_baseAddress(0) 18 | , m_isBaseAddressSet(false) 19 | { 20 | } 21 | 22 | void DataSourceImager::setBaseAddress(uint32_t address) 23 | { 24 | m_baseAddress = address; 25 | m_isBaseAddressSet = true; 26 | } 27 | 28 | void DataSourceImager::setFillPattern(uint8_t pattern) 29 | { 30 | m_fill = pattern; 31 | } 32 | 33 | void DataSourceImager::reset() 34 | { 35 | clear(); 36 | 37 | m_fill = 0; 38 | m_baseAddress = 0; 39 | m_isBaseAddressSet = false; 40 | } 41 | 42 | //! \param dataSource Pointer to an instance of a concrete data source subclass. 43 | //! 44 | void DataSourceImager::addDataSource(DataSource *source) 45 | { 46 | unsigned segmentCount = source->getSegmentCount(); 47 | unsigned index = 0; 48 | for (; index < segmentCount; ++index) 49 | { 50 | addDataSegment(source->getSegmentAt(index)); 51 | } 52 | } 53 | 54 | //! \param segment The segment to add. May be any type of data segment, including 55 | //! a pattern segment. 56 | void DataSourceImager::addDataSegment(DataSource::Segment *segment) 57 | { 58 | DataSource::PatternSegment *patternSegment = dynamic_cast(segment); 59 | 60 | unsigned segmentLength = segment->getLength(); 61 | bool segmentHasLocation = segment->hasNaturalLocation(); 62 | uint32_t segmentAddress = segment->getBaseAddress(); 63 | 64 | uint8_t *toPtr = NULL; 65 | unsigned addressDelta; 66 | unsigned newLength; 67 | 68 | // If a pattern segment's length is 0 then make it as big as the fill pattern. 69 | // This needs to be done before the buffer is adjusted. 70 | if (patternSegment && segmentLength == 0) 71 | { 72 | SizedIntegerValue &pattern = patternSegment->getPattern(); 73 | segmentLength = pattern.getSize(); 74 | } 75 | 76 | if (segmentLength) 77 | { 78 | if (segmentHasLocation) 79 | { 80 | // Make sure a base address is set. 81 | if (!m_isBaseAddressSet) 82 | { 83 | m_baseAddress = segmentAddress; 84 | m_isBaseAddressSet = true; 85 | } 86 | 87 | // The segment is located before our buffer's first address. 88 | // toPtr is not set in this if, but in the else branch of the next if. 89 | // Unless the segment completely overwrite the current data. 90 | if (segmentAddress < m_baseAddress) 91 | { 92 | addressDelta = m_baseAddress - segmentAddress; 93 | 94 | uint8_t *newData = (uint8_t *)malloc(m_length + addressDelta); 95 | memcpy(&newData[addressDelta], m_data, m_length); 96 | free(m_data); 97 | 98 | m_data = newData; 99 | m_length += addressDelta; 100 | m_baseAddress = segmentAddress; 101 | } 102 | 103 | // This segment is located or extends outside of our buffer. 104 | if (segmentAddress + segmentLength > m_baseAddress + m_length) 105 | { 106 | newLength = segmentAddress + segmentLength - m_baseAddress; 107 | 108 | m_data = (uint8_t *)realloc(m_data, newLength); 109 | 110 | // Clear any bytes between the old data and the new segment. 111 | addressDelta = segmentAddress - (m_baseAddress + m_length); 112 | if (addressDelta) 113 | { 114 | memset(m_data + m_length, 0, addressDelta); 115 | } 116 | 117 | toPtr = m_data + (segmentAddress - m_baseAddress); 118 | m_length = newLength; 119 | } 120 | else 121 | { 122 | toPtr = m_data + (segmentAddress - m_baseAddress); 123 | } 124 | } 125 | // Segment has no natural location, so just append it to the end of our buffer. 126 | else 127 | { 128 | newLength = m_length + segmentLength; 129 | m_data = (uint8_t *)realloc(m_data, newLength); 130 | toPtr = m_data + m_length; 131 | m_length = newLength; 132 | } 133 | } 134 | 135 | // A loop is used because getData() may fill in less than the requested 136 | // number of bytes per call. 137 | unsigned offset = 0; 138 | while (offset < segmentLength) 139 | { 140 | offset += segment->getData(offset, segmentLength - offset, toPtr + offset); 141 | } 142 | } 143 | -------------------------------------------------------------------------------- /src/blfwk/Peripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * Copyright 2020 - 2022 NXP 4 | * All rights reserved. 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #ifndef _Peripheral_h_ 10 | #define _Peripheral_h_ 11 | 12 | #include 13 | #include 14 | #include 15 | #include "BusPal.h" 16 | #if defined(LPCUSBSIO) 17 | #include "LpcUsbSio.h" 18 | #endif 19 | #include "bootloader_common.h" 20 | 21 | #include "blfwk/utils.h" 22 | 23 | //! @addtogroup host_peripherals 24 | //! @{ 25 | 26 | namespace nv { 27 | // bus:device.interface representation 28 | struct NV_UsbBDI { 29 | uint8_t bus; 30 | uint8_t device; 31 | uint8_t interface = 0; 32 | bool valid = false; // no std::optional :( 33 | 34 | std::string formatted() const { 35 | constexpr size_t len = sizeof("xxx:xxx.xx"); 36 | char cstr[len]; 37 | 38 | snprintf(cstr, len, "%03u:%03u.%02u", bus, device, interface); 39 | return std::string{cstr}; 40 | } 41 | }; 42 | 43 | // vendor_id:product_id 44 | struct NV_UsbID { 45 | uint16_t vendor_id; 46 | uint16_t product_id; 47 | bool valid = false; 48 | 49 | std::string formatted() const { 50 | constexpr size_t len = sizeof("xxxx:xxxx"); 51 | char cstr[len]; 52 | 53 | snprintf(cstr, len, "%04x:%04x", vendor_id, product_id); 54 | 55 | return std::string{cstr}; 56 | } 57 | }; 58 | 59 | struct UsbPeripheralConfigData { 60 | NV_UsbBDI bdi; 61 | NV_UsbID usb_id; 62 | 63 | std::string formatted() const { 64 | std::stringstream sstream; 65 | 66 | sstream << "USB Info: "; 67 | if (bdi.valid) { 68 | sstream << "bus:device.interface = " << bdi.formatted(); 69 | } 70 | 71 | if (usb_id.valid) { 72 | if (bdi.valid) sstream << ", "; 73 | sstream << "vendor:device = " << usb_id.formatted(); 74 | } 75 | 76 | return sstream.str(); 77 | } 78 | }; 79 | 80 | } // namespace nv 81 | 82 | namespace blfwk 83 | { 84 | /*! 85 | * @brief Represents a peripheral. 86 | * 87 | * Interface class for objects that provide the source for commands or sink for responses. 88 | */ 89 | class Peripheral 90 | { 91 | public: 92 | enum _host_peripheral_types 93 | { 94 | kHostPeripheralType_None, 95 | kHostPeripheralType_UART, 96 | kHostPeripheralType_BUSPAL_UART, 97 | kHostPeripheralType_LPCUSBSIO, 98 | kHostPeripheralType_USB_HID, 99 | kHostPeripheralType_SIM, 100 | kHostPeripheralType_I2C, 101 | kHostPeripheralType_SPI, 102 | }; 103 | 104 | // Why is this defined within Peripheral???? makes no sense... 105 | struct PeripheralConfigData 106 | { 107 | _host_peripheral_types peripheralType; 108 | bool ping; 109 | std::string comPortName; 110 | long comPortSpeed; 111 | uint32_t packetTimeoutMs; 112 | nv::UsbPeripheralConfigData usb_cfg; 113 | #if defined(LINUX) && defined(__ARM__) 114 | unsigned char i2cAddress; 115 | unsigned char spiPolarity; 116 | unsigned char spiPhase; 117 | unsigned char spiSequence; 118 | #endif // #if defined(LINUX) && defined(__ARM__) 119 | BusPal::BusPalConfigData busPalConfig; 120 | #if defined(LPCUSBSIO) 121 | LpcUsbSio::LpcUsbSioConfigData lpcUsbSioConfig; 122 | #endif 123 | 124 | std::string str() const { 125 | std::string str{"PeripheralConfigData"}; 126 | 127 | switch (this->peripheralType) { 128 | case _host_peripheral_types::kHostPeripheralType_USB_HID: { 129 | std::stringstream stream; 130 | stream << "(" << this->usb_cfg.formatted() << ")"; 131 | str.append(stream.str()); 132 | } 133 | break; 134 | default: 135 | break; 136 | } 137 | 138 | return str; 139 | } 140 | 141 | }; 142 | 143 | virtual ~Peripheral(){}; 144 | 145 | //! @brief Read bytes. 146 | //! 147 | //! @param buffer Pointer to buffer 148 | //! @param requestedBytes Number of bytes to read 149 | //! @param timeoutMs Time in milliseconds to wait for read to complete. 150 | //! @param actualBytes Number of bytes actually read. 151 | virtual status_t read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t timeout) = 0; 152 | 153 | //! @brief Write bytes. 154 | virtual status_t write(const uint8_t *buffer, uint32_t byteCount) = 0; 155 | 156 | //! @brief Return peripheral Type 157 | virtual _host_peripheral_types get_type(void) = 0; 158 | }; 159 | 160 | } // namespace blfwk 161 | 162 | //! @} 163 | 164 | #endif // _Peripheral_h_ 165 | 166 | //////////////////////////////////////////////////////////////////////////////// 167 | // EOF 168 | //////////////////////////////////////////////////////////////////////////////// 169 | -------------------------------------------------------------------------------- /src/blfwk/src/SpiPeripheral.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 - 2022 NXP 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | * 7 | */ 8 | 9 | #include "blfwk/Logging.h" 10 | #include "blfwk/SpiPeripheral.h" 11 | #include "blfwk/format_string.h" 12 | #include "blfwk/spi.h" 13 | 14 | using namespace blfwk; 15 | 16 | //////////////////////////////////////////////////////////////////////////////// 17 | // Code 18 | //////////////////////////////////////////////////////////////////////////////// 19 | 20 | // See SpiPeripheral.h for documentation of this method. 21 | SpiPeripheral::SpiPeripheral(const char *port, long speed, uint8_t polarity, uint8_t phase, uint8_t sequence) 22 | : m_fileDescriptor(-1) 23 | { 24 | if (!init(port, speed, polarity, phase, sequence)) 25 | { 26 | throw std::runtime_error( 27 | format_string("Error: Cannot open SPI port(%s), speed(%d Hz), polarity(%d), phase(%d), %s.\n", port, speed, 28 | polarity, phase, sequence ? "LSB" : "MSB")); 29 | } 30 | } 31 | 32 | // See SpiPeripheral.h for documentation of this method. 33 | bool SpiPeripheral::init(const char *port, long speed, uint8_t polarity, uint8_t phase, uint8_t sequence) 34 | { 35 | assert(port); 36 | 37 | // Open the port. 38 | m_fileDescriptor = spi_open(const_cast(port)); 39 | if (m_fileDescriptor == -1) 40 | { 41 | return false; 42 | } 43 | 44 | uint32_t mode = 0x0; 45 | if (polarity == 0) 46 | { 47 | mode &= ~SPI_CPOL; 48 | } 49 | else if (polarity == 1) 50 | { 51 | mode |= SPI_CPOL; 52 | } 53 | else 54 | { 55 | return false; 56 | } 57 | 58 | if (phase == 0) 59 | { 60 | mode &= ~SPI_CPHA; 61 | } 62 | else if (phase == 1) 63 | { 64 | mode |= SPI_CPHA; 65 | } 66 | else 67 | { 68 | return false; 69 | } 70 | 71 | if (sequence == 0) 72 | { 73 | mode &= ~SPI_LSB_FIRST; 74 | } 75 | else if (sequence == 1) 76 | { 77 | mode |= SPI_LSB_FIRST; 78 | } 79 | else 80 | { 81 | return false; 82 | } 83 | 84 | spi_setup(m_fileDescriptor, speed * 1000, mode, kSpiPeripheral_DefaultBitsPerWord); 85 | 86 | // Flush garbage from receive buffer before setting read timeout. 87 | flushRX(); 88 | 89 | // Set host serial timeout to 10 milliseconds. Higherlevel timeouts are implemented in 90 | // SerialPacketizer.cpp 91 | spi_set_timeout(m_fileDescriptor, kSpiPeripheral_DefaultReadTimeoutMs); 92 | 93 | return true; 94 | } 95 | 96 | // See SpiPeripheral.h for documentation of this method. 97 | SpiPeripheral::~SpiPeripheral() 98 | { 99 | if (m_fileDescriptor != -1) 100 | { 101 | spi_close(m_fileDescriptor); 102 | } 103 | } 104 | 105 | // See SpiPeripheral.h for documentation of this method. 106 | status_t SpiPeripheral::read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t unused_timeoutMs) 107 | { 108 | assert(buffer); 109 | 110 | // Read the requested number of bytes. 111 | int count = spi_read(m_fileDescriptor, reinterpret_cast(buffer), requestedBytes); 112 | if (actualBytes) 113 | { 114 | *actualBytes = count; 115 | } 116 | 117 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 118 | { 119 | // Log bytes read in hex 120 | Log::debug2("<"); 121 | for (int i = 0; i < (int)count; i++) 122 | { 123 | Log::debug2("%02x", buffer[i]); 124 | if (i != (count - 1)) 125 | { 126 | Log::debug2(" "); 127 | } 128 | } 129 | Log::debug2(">\n"); 130 | } 131 | 132 | if (count < (int)requestedBytes) 133 | { 134 | // Anything less than requestedBytes is a timeout error. 135 | return kStatus_Timeout; 136 | } 137 | 138 | return kStatus_Success; 139 | } 140 | 141 | // See SpiPeripheral.h for documentation of this method. 142 | void SpiPeripheral::flushRX() {} 143 | 144 | // See SpiPeripheral.h for documentation of this method. 145 | status_t SpiPeripheral::write(const uint8_t *buffer, uint32_t byteCount) 146 | { 147 | assert(buffer); 148 | 149 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 150 | { 151 | // Log bytes written in hex 152 | Log::debug2("["); 153 | for (int i = 0; i < (int)byteCount; i++) 154 | { 155 | Log::debug2("%02x", buffer[i]); 156 | if (i != (byteCount - 1)) 157 | { 158 | Log::debug2(" "); 159 | } 160 | } 161 | Log::debug2("]\n"); 162 | } 163 | 164 | if (spi_write(m_fileDescriptor, reinterpret_cast(const_cast(buffer)), byteCount) == byteCount) 165 | return kStatus_Success; 166 | else 167 | return kStatus_Fail; 168 | } 169 | 170 | //////////////////////////////////////////////////////////////////////////////// 171 | // EOF 172 | //////////////////////////////////////////////////////////////////////////////// 173 | -------------------------------------------------------------------------------- /src/blfwk/src/UsbHidPeripheral.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * Copyright 2019 NXP 4 | * All rights reserved. 5 | * 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | #include 10 | 11 | #include "blfwk/UsbHidPeripheral.h" 12 | #include "blfwk/format_string.h" 13 | #include "blfwk/smart_ptr.h" 14 | #include "blfwk/Logging.h" 15 | 16 | #include "bootloader_hid_report_ids.h" 17 | 18 | using namespace blfwk; 19 | 20 | //////////////////////////////////////////////////////////////////////////////// 21 | // Code 22 | //////////////////////////////////////////////////////////////////////////////// 23 | 24 | UsbHidPeripheral::UsbHidPeripheral(const nv::UsbPeripheralConfigData& cfg) : cfg(cfg) { 25 | const std::unordered_map blhost2hid_log_levels{ 26 | {Logger::log_level_t::kError, HID_API_LOG_ERROR}, 27 | {Logger::log_level_t::kDebug, HID_API_LOG_DEBUG}, 28 | {Logger::log_level_t::kDebug2, HID_API_LOG_DEBUG2}, 29 | }; 30 | const auto blhostlvl = Log::getLogger()->getFilterLevel(); 31 | 32 | hid_api_log_lvl = (blhost2hid_log_levels.count(blhostlvl) > 0) 33 | ? blhost2hid_log_levels.at(blhostlvl) 34 | : HID_API_LOG_ERROR; 35 | 36 | if (!init()) { 37 | throw std::runtime_error(format_string("ERROR: UsbHidPeripheral() cannot open USB HID device (%s)\n", cfg.formatted().c_str())); 38 | } 39 | 40 | hid_api_log_lvl = HID_API_LOG_ERROR; 41 | } 42 | 43 | // See UsbHidPeripheral.h for documentation of this method. 44 | bool UsbHidPeripheral::init() 45 | { 46 | hid_device_cfg hid_cfg; 47 | 48 | hid_cfg.bdi.bus = this->cfg.bdi.bus; 49 | hid_cfg.bdi.device = this->cfg.bdi.device; 50 | hid_cfg.bdi.interface = this->cfg.bdi.interface; 51 | hid_cfg.bdi.valid = this->cfg.bdi.valid; 52 | 53 | hid_cfg.id.vendor_id = this->cfg.usb_id.vendor_id; 54 | hid_cfg.id.product_id = this->cfg.usb_id.product_id; 55 | hid_cfg.id.valid = this->cfg.usb_id.valid; 56 | 57 | m_device = hid_open(&hid_cfg); 58 | if (!m_device) 59 | { 60 | return false; 61 | } 62 | 63 | return true; 64 | } 65 | 66 | // See UsbHidPeripheral.h for documentation of this method. 67 | UsbHidPeripheral::~UsbHidPeripheral() 68 | { 69 | if (m_device) 70 | { 71 | hid_close(m_device); 72 | /* Free static HIDAPI objects. */ 73 | hid_exit(); 74 | } 75 | } 76 | 77 | // See UsbHidPeripheral.h for documentation of this method. 78 | status_t UsbHidPeripheral::read(uint8_t *buffer, uint32_t requestedBytes, uint32_t *actualBytes, uint32_t timeout) 79 | { 80 | assert(buffer); 81 | 82 | // Read the requested number of bytes. 83 | int count = hid_read_timeout(m_device, buffer, requestedBytes, timeout); 84 | if (actualBytes) 85 | { 86 | *actualBytes = count; 87 | } 88 | 89 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 90 | { 91 | // Log bytes read in hex 92 | Log::debug2("<"); 93 | for (int i = 0; i < (int)count; i++) 94 | { 95 | Log::debug2("%02x", buffer[i]); 96 | if (i != (count - 1)) 97 | { 98 | Log::debug2(" "); 99 | } 100 | } 101 | Log::debug2(">\n"); 102 | } 103 | 104 | // Bail if we got an error (-1), or if the number of bytes read was less than 105 | // the report header. 106 | if (count < (int)sizeof(bl_hid_header_t)) 107 | { 108 | if (count == -1) 109 | { 110 | return kStatus_Fail; 111 | } 112 | else 113 | { 114 | return kStatus_Timeout; 115 | } 116 | } 117 | 118 | return kStatus_Success; 119 | } 120 | 121 | // See UsbHidPeripheral.h for documentation of this method. 122 | status_t UsbHidPeripheral::write(const uint8_t *buffer, uint32_t byteCount, uint32_t timeoutMS) 123 | { 124 | assert(buffer); 125 | 126 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 127 | { 128 | // Log bytes written in hex 129 | Log::debug2("["); 130 | for (uint32_t i = 0; i < byteCount; i++) 131 | { 132 | Log::debug2("%02x", buffer[i]); 133 | if (i != (byteCount - 1)) 134 | { 135 | Log::debug2(" "); 136 | } 137 | } 138 | Log::debug2("]\n"); 139 | } 140 | 141 | int count = hid_write_timeout(m_device, buffer, byteCount, timeoutMS); 142 | if (count < 0) 143 | { 144 | const wchar_t *errorMessage = hid_error(m_device); 145 | if (errorMessage) 146 | { 147 | int len = wcslen(errorMessage); 148 | char *msg = new char[len + 1]; 149 | wcstombs(msg, errorMessage, len + 1); 150 | Log::error("%s", msg); 151 | delete[] msg; 152 | } 153 | return kStatus_Fail; 154 | } 155 | 156 | return kStatus_Success; 157 | } 158 | 159 | //////////////////////////////////////////////////////////////////////////////// 160 | // EOF 161 | //////////////////////////////////////////////////////////////////////////////// 162 | -------------------------------------------------------------------------------- /src/blfwk/EndianUtilities.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_EndianUtilities_h_) 8 | #define _EndianUtilities_h_ 9 | 10 | //! \name Swap macros 11 | //! These macros always swap the data. 12 | //@{ 13 | 14 | //! Byte swap 16-bit value. 15 | #define _BYTESWAP16(value) (((((uint16_t)value) << 8) & 0xFF00) | ((((uint16_t)value) >> 8) & 0x00FF)) 16 | 17 | //! Byte swap 32-bit value. 18 | #define _BYTESWAP32(value) \ 19 | (((((uint32_t)value) << 24) & 0xFF000000) | ((((uint32_t)value) << 8) & 0x00FF0000) | \ 20 | ((((uint32_t)value) >> 8) & 0x0000FF00) | ((((uint32_t)value) >> 24) & 0x000000FF)) 21 | 22 | //! Byte swap 64-bit value. 23 | #define _BYTESWAP64(value) \ 24 | (((((uint64_t)value) << 56) & 0xFF00000000000000ULL) | ((((uint64_t)value) << 40) & 0x00FF000000000000ULL) | \ 25 | ((((uint64_t)value) << 24) & 0x0000FF0000000000ULL) | ((((uint64_t)value) << 8) & 0x000000FF00000000ULL) | \ 26 | ((((uint64_t)value) >> 8) & 0x00000000FF000000ULL) | ((((uint64_t)value) >> 24) & 0x0000000000FF0000ULL) | \ 27 | ((((uint64_t)value) >> 40) & 0x000000000000FF00ULL) | ((((uint64_t)value) >> 56) & 0x00000000000000FFULL)) 28 | 29 | //@} 30 | 31 | //! \name Inline swap functions 32 | //@{ 33 | 34 | inline uint16_t _swap_u16(uint16_t value) 35 | { 36 | return _BYTESWAP16(value); 37 | } 38 | inline int16_t _swap_s16(int16_t value) 39 | { 40 | return (int16_t)_BYTESWAP16((uint16_t)value); 41 | } 42 | 43 | inline uint32_t _swap_u32(uint32_t value) 44 | { 45 | return _BYTESWAP32(value); 46 | } 47 | inline int32_t _swap_s32(int32_t value) 48 | { 49 | return (int32_t)_BYTESWAP32((uint32_t)value); 50 | } 51 | 52 | inline uint64_t _swap_u64(uint64_t value) 53 | { 54 | return _BYTESWAP64(value); 55 | } 56 | inline int64_t _swap_s64(int64_t value) 57 | { 58 | return (uint64_t)_BYTESWAP64((uint64_t)value); 59 | } 60 | 61 | //@} 62 | 63 | #if defined(__LITTLE_ENDIAN__) 64 | 65 | /* little endian host */ 66 | 67 | #define ENDIAN_BIG_TO_HOST_U16(value) (_swap_u16(value)) 68 | #define ENDIAN_HOST_TO_BIG_U16(value) (_swap_u16(value)) 69 | 70 | #define ENDIAN_BIG_TO_HOST_S16(value) (_swap_s16(value)) 71 | #define ENDIAN_HOST_TO_BIG_S16(value) (_swap_s16(value)) 72 | 73 | #define ENDIAN_BIG_TO_HOST_U32(value) (_swap_u32(value)) 74 | #define ENDIAN_HOST_TO_BIG_U32(value) (_swap_u32(value)) 75 | 76 | #define ENDIAN_BIG_TO_HOST_S32(value) (_swap_s32(value)) 77 | #define ENDIAN_HOST_TO_BIG_S32(value) (_swap_s32(value)) 78 | 79 | #define ENDIAN_BIG_TO_HOST_U64(value) (_swap_u64(value)) 80 | #define ENDIAN_HOST_TO_BIG_U64(value) (_swap_u64(value)) 81 | 82 | #define ENDIAN_BIG_TO_HOST_S64(value) (_swap_s64(value)) 83 | #define ENDIAN_HOST_TO_BIG_S64(value) (_swap_s64(value)) 84 | 85 | /* no-ops */ 86 | 87 | #define ENDIAN_LITTLE_TO_HOST_U16(value) (value) 88 | #define ENDIAN_HOST_TO_LITTLE_U16(value) (value) 89 | 90 | #define ENDIAN_LITTLE_TO_HOST_S16(value) (value) 91 | #define ENDIAN_HOST_TO_LITTLE_S16(value) (value) 92 | 93 | #define ENDIAN_LITTLE_TO_HOST_U32(value) (value) 94 | #define ENDIAN_HOST_TO_LITTLE_U32(value) (value) 95 | 96 | #define ENDIAN_LITTLE_TO_HOST_S32(value) (value) 97 | #define ENDIAN_HOST_TO_LITTLE_S32(value) (value) 98 | 99 | #define ENDIAN_LITTLE_TO_HOST_U64(value) (value) 100 | #define ENDIAN_HOST_TO_LITTLE_U64(value) (value) 101 | 102 | #define ENDIAN_LITTLE_TO_HOST_S64(value) (value) 103 | #define ENDIAN_HOST_TO_LITTLE_S64(value) (value) 104 | 105 | #elif defined(__BIG_ENDIAN__) 106 | 107 | /* big endian host */ 108 | 109 | #define ENDIAN_LITTLE_TO_HOST_U16(value) (_swap_u16(value)) 110 | #define ENDIAN_HOST_TO_LITTLE_U16(value) (_swap_u16(value)) 111 | 112 | #define ENDIAN_LITTLE_TO_HOST_S16(value) (_swap_s16(value)) 113 | #define ENDIAN_HOST_TO_LITTLE_S16(value) (_swap_s16(value)) 114 | 115 | #define ENDIAN_LITTLE_TO_HOST_U32(value) (_swap_u32(value)) 116 | #define ENDIAN_HOST_TO_LITTLE_U32(value) (_swap_u32(value)) 117 | 118 | #define ENDIAN_LITTLE_TO_HOST_S32(value) (_swap_s32(value)) 119 | #define ENDIAN_HOST_TO_LITTLE_S32(value) (_swap_s32(value)) 120 | 121 | #define ENDIAN_LITTLE_TO_HOST_U64(value) (_swap_u64(value)) 122 | #define ENDIAN_HOST_TO_LITTLE_U64(value) (_swap_u64(value)) 123 | 124 | #define ENDIAN_LITTLE_TO_HOST_S64(value) (_swap_s64(value)) 125 | #define ENDIAN_HOST_TO_LITTLE_S64(value) (_swap_s64(value)) 126 | 127 | /* no-ops */ 128 | 129 | #define ENDIAN_BIG_TO_HOST_U16(value) (value) 130 | #define ENDIAN_HOST_TO_BIG_U16(value) (value) 131 | 132 | #define ENDIAN_BIG_TO_HOST_S16(value) (value) 133 | #define ENDIAN_HOST_TO_BIG_S16(value) (value) 134 | 135 | #define ENDIAN_BIG_TO_HOST_U32(value) (value) 136 | #define ENDIAN_HOST_TO_BIG_U32(value) (value) 137 | 138 | #define ENDIAN_BIG_TO_HOST_S32(value) (value) 139 | #define ENDIAN_HOST_TO_BIG_S32(value) (value) 140 | 141 | #define ENDIAN_BIG_TO_HOST_U64(value) (value) 142 | #define ENDIAN_HOST_TO_BIG_U64(value) (value) 143 | 144 | #define ENDIAN_BIG_TO_HOST_S64(value) (value) 145 | #define ENDIAN_HOST_TO_BIG_S64(value) (value) 146 | 147 | #endif 148 | 149 | #endif // _EndianUtilities_h_ 150 | -------------------------------------------------------------------------------- /src/blfwk/src/UartPeripheral.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * Copyright 2015-2020 NXP 4 | * All rights reserved. 5 | * 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | 10 | #include "blfwk/Logging.h" 11 | #include "blfwk/UartPeripheral.h" 12 | #include "blfwk/format_string.h" 13 | #include "blfwk/serial.h" 14 | 15 | using namespace blfwk; 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | // Code 19 | //////////////////////////////////////////////////////////////////////////////// 20 | 21 | // See uart_peripheral.h for documentation of this method. 22 | UartPeripheral::UartPeripheral(const char *port, long speed) 23 | : m_fileDescriptor(-1) 24 | { 25 | if (!init(port, speed)) 26 | { 27 | throw std::runtime_error( 28 | format_string("Error: UartPeripheral() cannot open PC UART port(%s), speed(%d Hz).", port, speed)); 29 | } 30 | } 31 | 32 | // See uart_peripheral.h for documentation of this method. 33 | bool UartPeripheral::init(const char *port, long speed) 34 | { 35 | assert(port); 36 | 37 | port_name = (char *)malloc(strlen(port) + 1 /*'\0'*/); 38 | strcpy(port_name, const_cast(port)); 39 | 40 | if (m_fileDescriptor != -1) 41 | { 42 | serial_close(m_fileDescriptor); 43 | } 44 | // Open the port. 45 | m_fileDescriptor = serial_open(port_name); 46 | if (m_fileDescriptor == -1) 47 | { 48 | return false; 49 | } 50 | 51 | serial_setup(m_fileDescriptor, speed); 52 | 53 | // Flush garbage from receive buffer before setting read timeout. 54 | flushRX(); 55 | 56 | // Set host serial timeout to 10 milliseconds. Higherlevel timeouts are implemented in 57 | // SerialPacketizer.cpp 58 | serial_set_read_timeout(m_fileDescriptor, kUartPeripheral_DefaultReadTimeoutMs); 59 | 60 | return true; 61 | } 62 | 63 | // See host_peripheral.h for documentation of this method. 64 | UartPeripheral::~UartPeripheral() 65 | { 66 | if (m_fileDescriptor != -1) 67 | { 68 | serial_close(m_fileDescriptor); 69 | } 70 | if (port_name) 71 | { 72 | free(port_name); 73 | } 74 | } 75 | 76 | // See host_peripheral.h for documentation of this method. 77 | status_t UartPeripheral::read(uint8_t *buffer, 78 | uint32_t requestedBytes, 79 | uint32_t *actualBytes, 80 | uint32_t unused_timeoutMs) 81 | { 82 | assert(buffer); 83 | 84 | // Read the requested number of bytes. 85 | int count = serial_read(m_fileDescriptor, reinterpret_cast(buffer), requestedBytes); 86 | if (actualBytes) 87 | { 88 | *actualBytes = count; 89 | } 90 | 91 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 92 | { 93 | // Log bytes read in hex 94 | Log::debug2("<"); 95 | for (int i = 0; i < (int)count; i++) 96 | { 97 | Log::debug2("%02x", buffer[i]); 98 | if (i != (count - 1)) 99 | { 100 | Log::debug2(" "); 101 | } 102 | } 103 | Log::debug2(">\n"); 104 | } 105 | 106 | if (count < (int)requestedBytes) 107 | { 108 | // Anything less than requestedBytes is a timeout error. 109 | return kStatus_Timeout; 110 | } 111 | 112 | return kStatus_Success; 113 | } 114 | 115 | // See uart_peripheral.h for documentation of this method. 116 | void UartPeripheral::flushRX() 117 | { 118 | // An attempt was made on win32 to use a serial_flush function 119 | // which would call PurgeComm(hCom, PURGE_RXABORT | PURGE_TXABORT | PURGE_RXCLEAR | PURGE_TXCLEAR) 120 | // even though the function returned success there were still errant data in the RX buffer. Using reads 121 | // to empty the RX buffer has worked 122 | 123 | // This read loop never exits on the Mac, and doesn't appear to be necessary. 124 | #if (defined(WIN32) || defined(LINUX)) 125 | // Read up to the requested number of bytes. 126 | char *readBuf = reinterpret_cast(m_buffer); 127 | while (serial_read(m_fileDescriptor, readBuf, 16)) 128 | { 129 | readBuf = reinterpret_cast(m_buffer); 130 | } 131 | #endif // defined(WIN32) || defined(LINUX) 132 | } 133 | 134 | // See host_peripheral.h for documentation of this method. 135 | status_t UartPeripheral::write(const uint8_t *buffer, uint32_t byteCount) 136 | { 137 | assert(buffer); 138 | 139 | if (Log::getLogger()->getFilterLevel() == Logger::kDebug2) 140 | { 141 | // Log bytes written in hex 142 | Log::debug2("["); 143 | for (int i = 0; i < (int)byteCount; i++) 144 | { 145 | Log::debug2("%02x", buffer[i]); 146 | if (i != (byteCount - 1)) 147 | { 148 | Log::debug2(" "); 149 | } 150 | } 151 | Log::debug2("]\n"); 152 | } 153 | 154 | if (serial_write(m_fileDescriptor, reinterpret_cast(const_cast(buffer)), byteCount) == byteCount) 155 | return kStatus_Success; 156 | else 157 | return kStatus_Fail; 158 | } 159 | 160 | //////////////////////////////////////////////////////////////////////////////// 161 | // EOF 162 | //////////////////////////////////////////////////////////////////////////////// 163 | -------------------------------------------------------------------------------- /src/blfwk/src/Logging.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * Copyright 2015-2020 NXP. 4 | * All rights reserved. 5 | * 6 | * 7 | * SPDX-License-Identifier: BSD-3-Clause 8 | */ 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | #include "blfwk/Logging.h" 15 | 16 | // init global logger to null 17 | Logger *Log::s_logger = NULL; 18 | 19 | void Logger::log(const char *fmt, ...) 20 | { 21 | va_list args; 22 | va_start(args, fmt); 23 | log(m_level, fmt, args); 24 | va_end(args); 25 | } 26 | 27 | void Logger::log(log_level_t level, const char *fmt, ...) 28 | { 29 | va_list args; 30 | va_start(args, fmt); 31 | log(level, fmt, args); 32 | va_end(args); 33 | } 34 | 35 | void Logger::log(const char *fmt, va_list args) 36 | { 37 | log(m_level, fmt, args); 38 | } 39 | 40 | //! Allocates a temporary 1KB buffer which is used to hold the 41 | //! formatted string. 42 | void Logger::log(log_level_t level, const char *fmt, va_list args) 43 | { 44 | if (level <= m_filter) 45 | { 46 | char *buffer = NULL; 47 | 48 | #if WIN32 49 | int l = _vscprintf(fmt, args); // Does not include final NULL char. 50 | buffer = reinterpret_cast(malloc(l + 1)); 51 | if (!buffer) 52 | { 53 | return; 54 | } 55 | vsprintf(buffer, fmt, args); 56 | #else // WIN32 57 | vasprintf(&buffer, fmt, args); 58 | #endif // WIN32 59 | 60 | if (buffer) 61 | { 62 | _log(buffer); 63 | free(buffer); 64 | } 65 | } 66 | } 67 | 68 | void Log::log(const char *fmt, ...) 69 | { 70 | if (s_logger) 71 | { 72 | va_list args; 73 | va_start(args, fmt); 74 | s_logger->log(fmt, args); 75 | va_end(args); 76 | } 77 | } 78 | 79 | void Log::log(const std::string &msg) 80 | { 81 | if (s_logger) 82 | { 83 | s_logger->log(msg); 84 | } 85 | } 86 | 87 | void Log::log(Logger::log_level_t level, const char *fmt, ...) 88 | { 89 | if (s_logger) 90 | { 91 | va_list args; 92 | va_start(args, fmt); 93 | s_logger->log(level, fmt, args); 94 | va_end(args); 95 | } 96 | } 97 | 98 | void Log::log(Logger::log_level_t level, const std::string &msg) 99 | { 100 | if (s_logger) 101 | { 102 | s_logger->log(level, msg); 103 | } 104 | } 105 | 106 | void Log::urgent(const char *fmt, ...) 107 | { 108 | if (s_logger) 109 | { 110 | va_list args; 111 | va_start(args, fmt); 112 | s_logger->log(Logger::kUrgent, fmt, args); 113 | va_end(args); 114 | } 115 | } 116 | 117 | void Log::json(const char *fmt, ...) 118 | { 119 | if (s_logger && s_logger->getFilterLevel() == Logger::kJson) 120 | { 121 | va_list args; 122 | va_start(args, fmt); 123 | s_logger->log(Logger::kJson, fmt, args); 124 | va_end(args); 125 | } 126 | } 127 | 128 | void Log::error(const char *fmt, ...) 129 | { 130 | if (s_logger) 131 | { 132 | va_list args; 133 | va_start(args, fmt); 134 | s_logger->log(Logger::kError, fmt, args); 135 | va_end(args); 136 | } 137 | } 138 | 139 | void Log::warning(const char *fmt, ...) 140 | { 141 | if (s_logger) 142 | { 143 | va_list args; 144 | va_start(args, fmt); 145 | s_logger->log(Logger::kWarning, fmt, args); 146 | va_end(args); 147 | } 148 | } 149 | 150 | void Log::info(const char *fmt, ...) 151 | { 152 | if (s_logger) 153 | { 154 | va_list args; 155 | va_start(args, fmt); 156 | s_logger->log(Logger::kInfo, fmt, args); 157 | va_end(args); 158 | } 159 | } 160 | 161 | void Log::info2(const char *fmt, ...) 162 | { 163 | if (s_logger) 164 | { 165 | va_list args; 166 | va_start(args, fmt); 167 | s_logger->log(Logger::kInfo2, fmt, args); 168 | va_end(args); 169 | } 170 | } 171 | 172 | void Log::debug(const char *fmt, ...) 173 | { 174 | if (s_logger) 175 | { 176 | va_list args; 177 | va_start(args, fmt); 178 | s_logger->log(Logger::kDebug, fmt, args); 179 | va_end(args); 180 | } 181 | } 182 | 183 | void Log::debug2(const char *fmt, ...) 184 | { 185 | if (s_logger) 186 | { 187 | va_list args; 188 | va_start(args, fmt); 189 | s_logger->log(Logger::kDebug2, fmt, args); 190 | va_end(args); 191 | } 192 | } 193 | 194 | void StdoutLogger::_log(const char *msg) 195 | { 196 | printf("%s", msg); 197 | } 198 | 199 | FileLogger::FileLogger(const char *file_path) 200 | : m_file_path(file_path) 201 | , m_logFile(file_path) 202 | { 203 | } 204 | 205 | FileLogger::~FileLogger() 206 | { 207 | try 208 | { 209 | m_logFile.close(); 210 | } 211 | catch (std::ios_base::failure &e) 212 | { 213 | printf("Error: Failed to close the log file(%s)", e.what()); 214 | } 215 | } 216 | 217 | void FileLogger::_log(const char *msg) 218 | { 219 | m_logFile << msg; 220 | try 221 | { 222 | m_logFile.flush(); 223 | } 224 | catch (std::ios_base::failure &e) 225 | { 226 | printf("Error: Failed to write the log file(%s)", e.what()); 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /src/crc/src/crc32.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #include "crc/crc32.h" 8 | #include 9 | 10 | //////////////////////////////////////////////////////////////////////////////// 11 | // Variables 12 | //////////////////////////////////////////////////////////////////////////////// 13 | 14 | //! Table of CRC-32's of all single byte values. The values in 15 | //! this table are those used in the Ethernet CRC algorithm. 16 | static const uint32_t s_crc32Table[] = { 17 | 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, 0x2608edb8, 18 | 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, 19 | 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 20 | 0x675a1011, 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, 21 | 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, 0xad2f2d84, 22 | 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, 23 | 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 24 | 0xec7dd02d, 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, 25 | 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 26 | 0x7c56b6b0, 0x71159069, 0x75d48dde, 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, 27 | 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, 0xaca5c697, 0xa864db20, 0xa527fdf9, 28 | 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, 29 | 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 30 | 0xf771768c, 0xfa325055, 0xfef34de2, 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, 31 | 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, 0x7a089632, 0x7ec98b85, 0x738aad5c, 32 | 0x774bb0eb, 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, 33 | 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 34 | 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, 35 | 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 36 | 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, 37 | 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, 0x8832161a, 38 | 0x8cf30bad, 0x81b02d74, 0x857130c3, 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, 39 | 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, 0x68860bfd, 0x6c47164a, 0x61043093, 40 | 0x65c52d24, 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, 41 | 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 42 | 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, 43 | 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, 0x89b8fd09, 0x8d79e0be, 0x803ac667, 44 | 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, 45 | 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 46 | }; 47 | 48 | //////////////////////////////////////////////////////////////////////////////// 49 | // Code 50 | //////////////////////////////////////////////////////////////////////////////// 51 | 52 | // initialize the members of the allocated crc32_data_t struct 53 | void crc32_init(crc32_data_t *crc32Config) 54 | { 55 | // initialize running crc and byte count 56 | crc32Config->currentCrc = 0xFFFFFFFF; 57 | crc32Config->byteCountCrc = 0; 58 | } 59 | 60 | // "running" crc32 calculation 61 | void crc32_update(crc32_data_t *crc32Config, const uint8_t *src, uint32_t lengthInBytes) 62 | { 63 | assert(src); 64 | uint32_t crc = crc32Config->currentCrc; 65 | crc32Config->byteCountCrc += lengthInBytes; 66 | 67 | while (lengthInBytes--) 68 | { 69 | uint8_t c = *src++ & 0xff; 70 | crc = (crc << 8) ^ s_crc32Table[(crc >> 24) ^ c]; 71 | } 72 | 73 | crc32Config->currentCrc = crc; 74 | } 75 | 76 | // finalize the crc32 calculation for non-word-aligned counts 77 | void crc32_finalize(crc32_data_t *crc32Config, uint32_t *hash) 78 | { 79 | uint32_t crc = crc32Config->currentCrc; 80 | uint32_t byteCount = crc32Config->byteCountCrc; 81 | 82 | // pad with zeroes 83 | if (byteCount % 4) 84 | { 85 | uint32_t i; 86 | for (i = byteCount % 4; i < 4; i++) 87 | { 88 | crc = (crc << 8) ^ s_crc32Table[(crc >> 24) ^ 0]; 89 | } 90 | } 91 | 92 | crc32Config->currentCrc = crc; 93 | 94 | *hash = crc32Config->currentCrc; 95 | } 96 | //////////////////////////////////////////////////////////////////////////////// 97 | // EOF 98 | //////////////////////////////////////////////////////////////////////////////// 99 | -------------------------------------------------------------------------------- /src/bootloader/bl_peripheral.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _peripheral_h 9 | #define _peripheral_h 10 | 11 | #include 12 | #include "bootloader_common.h" 13 | 14 | //! @addtogroup peripheral 15 | //! @{ 16 | 17 | //////////////////////////////////////////////////////////////////////////////// 18 | // Declarations 19 | //////////////////////////////////////////////////////////////////////////////// 20 | 21 | //! @brief Peripheral type bit mask definitions. 22 | //! 23 | //! These bit mask constants serve multiple purposes. They are each a unique value that identifies 24 | //! a peripheral type. They are also the mask for the bits used in the bootloader configuration 25 | //! flash region to list available peripherals and control which peripherals are enabled. 26 | enum _peripheral_types 27 | { 28 | kPeripheralType_UART = (1 << 0), 29 | kPeripheralType_I2CSlave = (1 << 1), 30 | kPeripheralType_SPISlave = (1 << 2), 31 | kPeripheralType_CAN = (1 << 3), 32 | kPeripheralType_USB_HID = (1 << 4), 33 | kPeripheralType_USB_CDC = (1 << 5), 34 | kPeripheralType_USB_DFU = (1 << 6), 35 | kPeripheralType_USB_MSC = (1 << 7) 36 | }; 37 | 38 | //! @brief Pinmux types. 39 | typedef enum _pinmux_types 40 | { 41 | kPinmuxType_Default = 0, 42 | kPinmuxType_PollForActivity = 1, 43 | kPinmuxType_Peripheral = 2, 44 | kPinmuxType_RestoreForActivity = 3 45 | } pinmux_type_t; 46 | 47 | // Forward declaration. 48 | typedef struct PeripheralDescriptor peripheral_descriptor_t; 49 | 50 | typedef void (*serial_byte_receive_func_t)(uint8_t); 51 | 52 | //! @brief Peripheral control interface. 53 | typedef struct _peripheral_control_interface 54 | { 55 | bool (*pollForActivity)(const peripheral_descriptor_t *self); 56 | status_t (*init)(const peripheral_descriptor_t *self, serial_byte_receive_func_t function); 57 | void (*shutdown)(const peripheral_descriptor_t *self); 58 | void (*pump)(const peripheral_descriptor_t *self); 59 | } peripheral_control_interface_t; 60 | 61 | //! @brief Peripheral abstract byte interface. 62 | typedef struct _peripheral_byte_inteface 63 | { 64 | status_t (*init)(const peripheral_descriptor_t *self); 65 | #ifdef BOOTLOADER_HOST 66 | status_t (*read)(const peripheral_descriptor_t *self, uint8_t *buffer, uint32_t requestedBytes); 67 | #endif // #ifdef BOOTLOADER_HOST 68 | status_t (*write)(const peripheral_descriptor_t *self, const uint8_t *buffer, uint32_t byteCount); 69 | } peripheral_byte_inteface_t; 70 | 71 | //! @brief Packet types. 72 | typedef enum _packet_type 73 | { 74 | kPacketType_Command, //!< Send or expect a command packet 75 | kPacketType_Data //!< Send or expect a data packet 76 | } packet_type_t; 77 | 78 | //! @brief Peripheral Packet Interface. 79 | typedef struct _peripheral_packet_interface 80 | { 81 | status_t (*init)(const peripheral_descriptor_t *self); 82 | status_t (*readPacket)(const peripheral_descriptor_t *self, 83 | uint8_t **packet, 84 | uint32_t *packetLength, 85 | packet_type_t packetType); 86 | status_t (*writePacket)(const peripheral_descriptor_t *self, 87 | const uint8_t *packet, 88 | uint32_t byteCount, 89 | packet_type_t packetType); 90 | void (*abortDataPhase)(const peripheral_descriptor_t *self); 91 | status_t (*finalize)(const peripheral_descriptor_t *self); 92 | uint32_t (*getMaxPacketSize)(const peripheral_descriptor_t *self); 93 | void (*byteReceivedCallback)(uint8_t byte); 94 | } peripheral_packet_interface_t; 95 | 96 | //! @brief Peripheral descriptor. 97 | //! 98 | //! Instances of this struct describe a particular instance of a peripheral that is 99 | //! available for bootloading. 100 | struct PeripheralDescriptor 101 | { 102 | //! @brief Bit mask identifying the peripheral type. 103 | //! 104 | //! See #_peripheral_types for a list of valid bits. 105 | uint32_t typeMask; 106 | 107 | //! @brief The instance number of the peripheral. 108 | uint32_t instance; 109 | 110 | //! @brief Configure pinmux setting for the peripheral. 111 | void (*pinmuxConfig)(uint32_t instance, pinmux_type_t pinmux); 112 | 113 | //! @brief Control interface for the peripheral. 114 | const peripheral_control_interface_t *controlInterface; 115 | 116 | //! @brief Byte-level interface for the peripheral. 117 | //! 118 | //! May be NULL since not all periperhals support this interface. 119 | const peripheral_byte_inteface_t *byteInterface; 120 | 121 | //! @brief Packet level interface for the peripheral. 122 | const peripheral_packet_interface_t *packetInterface; 123 | }; 124 | 125 | //////////////////////////////////////////////////////////////////////////////// 126 | // Externs 127 | //////////////////////////////////////////////////////////////////////////////// 128 | 129 | //! @brief Array of all peripherals available in this device. 130 | extern const peripheral_descriptor_t g_peripherals[]; 131 | 132 | //! @} 133 | 134 | #endif // _peripheral_h 135 | //////////////////////////////////////////////////////////////////////////////// 136 | // EOF 137 | //////////////////////////////////////////////////////////////////////////////// 138 | -------------------------------------------------------------------------------- /src/blfwk/SerialPacketizer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | 8 | #ifndef _serial_packetizer_h_ 9 | #define _serial_packetizer_h_ 10 | 11 | #include "Packetizer.h" 12 | #include "UartPeripheral.h" 13 | #include "bootloader_common.h" 14 | #include "packet/serial_packet.h" 15 | 16 | //! @addtogroup serial_packetizer 17 | //! @{ 18 | 19 | namespace blfwk 20 | { 21 | // Forward declarations. 22 | class Peripheral; 23 | 24 | /*! 25 | * @brief Provides source and sink for packets that go over the serial peripherals. 26 | */ 27 | class SerialPacketizer : public Packetizer 28 | { 29 | public: 30 | //! @brief Constructor. 31 | SerialPacketizer(Peripheral *peripheral, uint32_t packetTimeoutMs); 32 | 33 | //! @brief Destructor. 34 | virtual ~SerialPacketizer(); 35 | 36 | //! @brief Peripheral accessor. 37 | virtual UartPeripheral *getPeripheral() { return dynamic_cast(m_peripheral); } 38 | //! @brief Read a packet. 39 | //! 40 | //! Provides the address of a buffer containing the packet. 41 | //! 42 | //! @param packet Pointer location to write packet pointer 43 | //! @param packetLength Number of bytes in returned packet. 44 | virtual status_t readPacket(uint8_t **packet, uint32_t *packetLength, packet_type_t packetType); 45 | 46 | //! @brief Write a packet. 47 | //! 48 | //! @param packet Pointer to packet to write. 49 | //! @param byteCount Number of bytes in packet. 50 | virtual status_t writePacket(const uint8_t *packet, uint32_t byteCount, packet_type_t packetType); 51 | 52 | //! @brief Abort data phase. 53 | virtual void abortPacket(); 54 | 55 | //! @brief Send framing packet ack. 56 | virtual void sync(); 57 | 58 | //! @brief Finalize. 59 | virtual void finalize(); 60 | 61 | //! @brief Enable simulator command processor pump. 62 | virtual void enableSimulatorPump() {} 63 | //! @brief Pump simulator command processor. 64 | virtual void pumpSimulator() {} 65 | //! @brief Set aborted flag. 66 | virtual void setAborted(bool aborted) {} 67 | //! @brief Return the max packet size. 68 | virtual uint32_t getMaxPacketSize(); 69 | 70 | //! @brief Delay milliseconds. 71 | void host_delay(uint32_t milliseconds); 72 | 73 | //! @brief Send a ping packet and receive an ack. 74 | //! 75 | //! This is a method for host only side pinging of the target. The reponse from the 76 | //! target to a ping packet is a ping response packet. Since the target may or may 77 | //! not be online there is optionally a series of retries to make the best attempt 78 | //! at communication possible 79 | //! 80 | //! @param retries The number of attempts that should be made. 81 | //! @param delay The time in milliseconds between each attempt. 82 | //! @param comSpeed The peripheral baud rate. Used in order to calculate the 83 | //! receive delay in the case of low com speeds such as 100 and 300 which need 84 | //! nearly a second to complete 85 | virtual status_t ping( 86 | int retries, unsigned int delay, ping_response_t *response, int comSpeed, int *actualComSpeed); 87 | 88 | protected: 89 | //! @brief Send ACK if needed. 90 | status_t send_deferred_ack(); 91 | 92 | //! @brief Read packet using serial framing. 93 | //! 94 | //! On return, caller must call flow control method to send AckContinue or AckWait followed by Continue. 95 | status_t serial_packet_read(uint8_t **packet, uint32_t *packetLength, packet_type_t packetType); 96 | 97 | //! @brief Write packet using serial framing. 98 | status_t serial_packet_write(const uint8_t *packet, uint32_t byteCount, packet_type_t packetType); 99 | 100 | //! @brief Abort data phase. 101 | //! 102 | //! Respond to next host data packet with AckAbort instead of Ack 103 | //! (i.e. receiver data phase abort). 104 | void serial_packet_abort(); 105 | 106 | //! @brief Get max packet size. 107 | uint32_t serial_packet_get_max_packet_size(); 108 | 109 | //! @brief Send a sync packet of the specified type. 110 | status_t serial_packet_send_sync(uint8_t framingPacketType); 111 | 112 | //! @brief Send a ping message back in response to a ping. 113 | status_t serial_send_ping_response(); 114 | 115 | //! @brief Wait for an ACK, handling NAKs as needed. 116 | status_t wait_for_ack_packet(); 117 | 118 | //! @brief Read from peripheral until entire data framing packet read. 119 | status_t read_data_packet(framing_data_packet_t *packet, uint8_t *data, packet_type_t packetType); 120 | 121 | //! @brief Read from peripheral until start byte found. 122 | status_t read_start_byte(framing_header_t *header); 123 | 124 | //! @brief Read from peripheral until packet header found. 125 | status_t read_header(framing_header_t *header); 126 | 127 | //! @brief Read from peripheral until packet length found. 128 | status_t read_length(framing_data_packet_t *packet); 129 | 130 | //! @brief Read from peripheral until crc16 is found. 131 | status_t read_crc16(framing_data_packet_t *packet); 132 | 133 | //! @brief Calculate crc over framing data packet. 134 | uint16_t calculate_framing_crc16(framing_data_packet_t *packet, const uint8_t *data); 135 | 136 | serial_data_t m_serialContext; 137 | }; 138 | 139 | } // namespace blfwk 140 | 141 | //! @} 142 | 143 | #endif // _serial_packetizer_h_ 144 | 145 | //////////////////////////////////////////////////////////////////////////////// 146 | // EOF 147 | //////////////////////////////////////////////////////////////////////////////// 148 | -------------------------------------------------------------------------------- /src/blfwk/Value.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_Value_h_) 8 | #define _Value_h_ 9 | 10 | #include 11 | #include "blfwk/stdafx.h" 12 | #include "blfwk/int_size.h" 13 | #include "blfwk/Blob.h" 14 | 15 | namespace blfwk 16 | { 17 | /*! 18 | * \brief Abstract base class for values of arbitrary types. 19 | */ 20 | class Value 21 | { 22 | public: 23 | Value() {} 24 | virtual ~Value() {} 25 | virtual std::string getTypeName() const = 0; 26 | virtual size_t getSize() const = 0; 27 | }; 28 | 29 | /*! 30 | * \brief 32-bit signed integer value. 31 | */ 32 | class IntegerValue : public Value 33 | { 34 | public: 35 | IntegerValue() 36 | : m_value(0) 37 | { 38 | } 39 | IntegerValue(uint32_t value) 40 | : m_value(value) 41 | { 42 | } 43 | IntegerValue(const IntegerValue &other) 44 | : m_value(other.m_value) 45 | { 46 | } 47 | 48 | virtual std::string getTypeName() const { return "integer"; } 49 | virtual size_t getSize() const { return sizeof(m_value); } 50 | inline uint32_t getValue() const { return m_value; } 51 | inline operator uint32_t() const { return m_value; } 52 | inline IntegerValue &operator=(uint32_t value) 53 | { 54 | m_value = value; 55 | return *this; 56 | } 57 | 58 | protected: 59 | uint32_t m_value; //!< The integer value. 60 | }; 61 | 62 | /*! 63 | * \brief Adds a word size attribute to IntegerValue. 64 | * 65 | * The word size really only acts as an attribute that is carried along 66 | * with the integer value. It doesn't affect the actual value at all. 67 | * However, you can use the getWordSizeMask() method to mask off bits 68 | * that should not be there. 69 | * 70 | * The word size defaults to a 32-bit word. 71 | */ 72 | class SizedIntegerValue : public IntegerValue 73 | { 74 | public: 75 | SizedIntegerValue() 76 | : IntegerValue() 77 | , m_size(kWordSize) 78 | { 79 | } 80 | SizedIntegerValue(uint32_t value, int_size_t size = kWordSize) 81 | : IntegerValue(value) 82 | , m_size(size) 83 | { 84 | } 85 | SizedIntegerValue(uint16_t value) 86 | : IntegerValue(value) 87 | , m_size(kHalfWordSize) 88 | { 89 | } 90 | SizedIntegerValue(uint8_t value) 91 | : IntegerValue(value) 92 | , m_size(kByteSize) 93 | { 94 | } 95 | SizedIntegerValue(const SizedIntegerValue &other) 96 | : IntegerValue(other) 97 | , m_size(other.m_size) 98 | { 99 | } 100 | 101 | virtual std::string getTypeName() const { return "sized integer"; } 102 | virtual size_t getSize() const; 103 | 104 | inline int_size_t getWordSize() const { return m_size; } 105 | inline void setWordSize(int_size_t size) { m_size = size; } 106 | //! \brief Returns a 32-bit mask value dependant on the word size attribute. 107 | uint32_t getWordSizeMask() const; 108 | 109 | //! \name Assignment operators 110 | //! These operators set the word size as well as the integer value. 111 | //@{ 112 | SizedIntegerValue &operator=(uint8_t value) 113 | { 114 | m_value = value; 115 | m_size = kByteSize; 116 | return *this; 117 | } 118 | SizedIntegerValue &operator=(uint16_t value) 119 | { 120 | m_value = value; 121 | m_size = kHalfWordSize; 122 | return *this; 123 | } 124 | SizedIntegerValue &operator=(uint32_t value) 125 | { 126 | m_value = value; 127 | m_size = kWordSize; 128 | return *this; 129 | } 130 | //@} 131 | 132 | protected: 133 | int_size_t m_size; //!< Size of the integer. 134 | }; 135 | 136 | /*! 137 | * \brief String value. 138 | * 139 | * Simply wraps the STL std::string class. 140 | */ 141 | class StringValue : public Value 142 | { 143 | public: 144 | StringValue() 145 | : m_value() 146 | { 147 | } 148 | StringValue(const std::string &value) 149 | : m_value(value) 150 | { 151 | } 152 | StringValue(const std::string *value) 153 | : m_value(*value) 154 | { 155 | } 156 | StringValue(const StringValue &other) 157 | : m_value(other.m_value) 158 | { 159 | } 160 | 161 | virtual std::string getTypeName() const { return "string"; } 162 | virtual size_t getSize() const { return m_value.size(); } 163 | operator const char *() const { return m_value.c_str(); } 164 | operator const std::string &() const { return m_value; } 165 | operator std::string &() { return m_value; } 166 | operator const std::string *() { return &m_value; } 167 | operator std::string *() { return &m_value; } 168 | StringValue &operator=(const StringValue &other) 169 | { 170 | m_value = other.m_value; 171 | return *this; 172 | } 173 | StringValue &operator=(const std::string &value) 174 | { 175 | m_value = value; 176 | return *this; 177 | } 178 | StringValue &operator=(const char *value) 179 | { 180 | m_value = value; 181 | return *this; 182 | } 183 | 184 | protected: 185 | std::string m_value; 186 | }; 187 | 188 | /*! 189 | * \brief Binary object value of arbitrary size. 190 | */ 191 | class BinaryValue : public Value, public Blob 192 | { 193 | public: 194 | BinaryValue() 195 | : Value() 196 | , Blob() 197 | { 198 | } 199 | 200 | virtual std::string getTypeName() const { return "binary"; } 201 | virtual size_t getSize() const { return getLength(); } 202 | }; 203 | 204 | }; // namespace blfwk 205 | 206 | #endif // _Value_h_ 207 | -------------------------------------------------------------------------------- /src/blfwk/SBSourceFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_SBSourceFile_h_) 8 | #define _SBSourceFile_h_ 9 | 10 | #include "blfwk/SourceFile.h" 11 | #include "blfwk/StELFFile.h" 12 | #include "blfwk/smart_ptr.h" 13 | #include "blfwk/DataSource.h" 14 | #include "blfwk/DataTarget.h" 15 | 16 | namespace blfwk 17 | { 18 | /*! 19 | * \brief SB Format (SB) source file. 20 | */ 21 | class SBSourceFile : public BinarySourceFile 22 | { 23 | public: 24 | //! \brief Default constructor. 25 | SBSourceFile(const std::string &path); 26 | 27 | //! \brief Destructor. 28 | virtual ~SBSourceFile(); 29 | 30 | //! \brief Identifies whether the stream contains an SB file. 31 | static bool isSBFile(std::istream &stream); 32 | 33 | //! \name Data source creation 34 | //@{ 35 | //! \brief Creates an unmapped data source from the entire file. 36 | virtual DataSource *createDataSource(); 37 | //@} 38 | 39 | protected: 40 | //! An AES-128 cipher block is 16 bytes. 41 | typedef uint8_t cipher_block_t[16]; 42 | 43 | //! A SHA-1 digest is 160 bits, or 20 bytes. 44 | typedef uint8_t sha1_digest_t[20]; 45 | 46 | //! Unique identifier type for a section. 47 | typedef uint32_t section_id_t; 48 | 49 | // All of these structures are packed to byte alignment in order to match 50 | // the structure on disk. 51 | #pragma pack(1) 52 | 53 | //! Same version struct used for 3600 boot image. 54 | struct version_t 55 | { 56 | uint16_t m_major; 57 | uint16_t m_pad0; 58 | uint16_t m_minor; 59 | uint16_t m_pad1; 60 | uint16_t m_revision; 61 | uint16_t m_pad2; 62 | }; 63 | 64 | //! \brief Header for the entire boot image. 65 | //! 66 | //! Fields of this header are arranged so that those used by the bootloader ROM all come 67 | //! first. They are also set up so that all fields are not split across cipher block 68 | //! boundaries. The fields not used by the bootloader are not subject to this 69 | //! restraint. 70 | //! 71 | //! Image header size is always a round number of cipher blocks. The same also applies to 72 | //! the boot image itself. The padding, held in #blfwk::EncoreBootImage::boot_image_header_t::m_padding0 73 | //! and #blfwk::EncoreBootImage::boot_image_header_t::m_padding1 is filled with random bytes. 74 | //! 75 | //! The DEK dictionary, section table, and each section data region must all start on 76 | //! cipher block boundaries. 77 | //! 78 | //! This header is not encrypted in the image file. 79 | //! 80 | //! The m_digest field contains a SHA-1 digest of the fields of the header that follow it. 81 | //! It is the first field in the header so it doesn't change position or split the header 82 | //! in two if fields are added to the header. 83 | struct boot_image_header_t 84 | { 85 | union 86 | { 87 | sha1_digest_t m_digest; //!< SHA-1 digest of image header. Also used as the crypto IV. 88 | struct 89 | { 90 | cipher_block_t m_iv; //!< The first 16 bytes of the digest form the initialization vector. 91 | uint8_t m_extra[4]; //!< The leftover top four bytes of the SHA-1 digest. 92 | }; 93 | }; 94 | uint8_t m_signature[4]; //!< 'STMP', see #ROM_IMAGE_HEADER_SIGNATURE. 95 | uint8_t m_majorVersion; //!< Major version for the image format, see #ROM_BOOT_IMAGE_MAJOR_VERSION. 96 | uint8_t m_minorVersion; //!< Minor version of the boot image format, see #ROM_BOOT_IMAGE_MINOR_VERSION. 97 | uint16_t m_flags; //!< Flags or options associated with the entire image. 98 | uint32_t m_imageBlocks; //!< Size of entire image in blocks. 99 | uint32_t m_firstBootTagBlock; //!< Offset from start of file to the first boot tag, in blocks. 100 | section_id_t m_firstBootableSectionID; //!< ID of section to start booting from. 101 | uint16_t m_keyCount; //!< Number of entries in DEK dictionary. 102 | uint16_t m_keyDictionaryBlock; //!< Starting block number for the key dictionary. 103 | uint16_t m_headerBlocks; //!< Size of this header, including this size word, in blocks. 104 | uint16_t m_sectionCount; //!< Number of section headers in this table. 105 | uint16_t m_sectionHeaderSize; //!< Size in blocks of a section header. 106 | uint8_t m_padding0[2]; //!< Padding to align #m_timestamp to long word. 107 | uint8_t m_signature2[4]; //!< Second signature to distinguish this .sb format from the 36xx format, see 108 | //!#ROM_IMAGE_HEADER_SIGNATURE2. 109 | uint64_t m_timestamp; //!< Timestamp when image was generated in microseconds since 1-1-2000. 110 | version_t m_productVersion; //!< Product version. 111 | version_t m_componentVersion; //!< Component version. 112 | uint16_t m_driveTag; //!< Drive tag for the system drive which this boot image belongs to. 113 | uint8_t m_padding1[6]; //!< Padding to round up to next cipher block. 114 | }; 115 | 116 | #pragma pack() 117 | 118 | public: 119 | /*! 120 | * \brief Simple exception thrown to indicate an error in the input SB file format. 121 | */ 122 | class SBFileException : public std::runtime_error 123 | { 124 | public: 125 | //! \brief Default constructor. 126 | SBFileException(const std::string &inMessage) 127 | : std::runtime_error(inMessage) 128 | { 129 | } 130 | }; 131 | }; 132 | 133 | }; // namespace blfwk 134 | 135 | #endif // _SBSourceFile_h_ 136 | -------------------------------------------------------------------------------- /src/blfwk/StIntelHexFile.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2015 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * SPDX-License-Identifier: BSD-3-Clause 6 | */ 7 | #if !defined(_StIntelHexFile_h_) 8 | #define _StIntelHexFile_h_ 9 | 10 | #include "stdafx.h" 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | enum 17 | { 18 | //! The required first character of a Intel Hex 19 | INTELHEX_START_CHAR = ':', 20 | 21 | //! The minimum length of a Hex. This is the start char (1) + datacount (2) + 22 | //! addr (4) + type (2) + check sum (2). 23 | INTELHEX_MIN_LENGTH = 11, 24 | 25 | //! Index of the first character of the address field. 26 | INTELHEX_ADDRESS_START_CHAR_INDEX = 3, 27 | 28 | //! Index of the first character of the record type field. 29 | INTELHEX_TYPE_START_CHAR_INDEX = 7, 30 | 31 | //! Index of the first character of the record type field. 32 | INTELHEX_DATA_START_CHAR_INDEX = 9 33 | }; 34 | 35 | //! Intel Hex Record Type 36 | enum 37 | { 38 | //! Data Record, which contains data and a 16-bit start address for the data. 39 | INTELHEX_RECORD_DATA = 0x00, 40 | 41 | //! End of File Record, which specifies the end of the hex file, and 42 | //! must occur exactly once per file in the last line of the file. 43 | INTELHEX_RECORD_END_OF_FILE = 0x01, 44 | 45 | //! Extended Segment Address Record, which is used to specify bits 4- 19 of the Segment Base Address. 46 | INTELHEX_RECORD_EXTENDED_SEGMENT_ADDRESS = 0x02, 47 | 48 | //! Start Segment Address Record, which is used to specify the execution start address for the object file. 49 | INTELHEX_RECORD_START_SEGMENT_ADDRESS = 0x03, 50 | 51 | //! Extended Linear Address Record, which is used to specify bits 16- 31 of the Linear Base Address. 52 | INTELHEX_RECORD_EXTENDED_LINEAR_ADDRESS = 0x04, 53 | 54 | //! Start Linear Address Record, which is used to specify the execution start address for the object file. 55 | INTELHEX_RECORD_START_LINEAR_ADDRESS = 0x05 56 | }; 57 | 58 | /*! 59 | * \brief Intel Hex parser. 60 | * 61 | * This class takes an input stream and parses it as a Intel Hex file. While 62 | * the individual records that comprise the file are available for access, the 63 | * class also provides a higher-level view of the contents. It processes the 64 | * individual records and builds an image of what the memory touched by the 65 | * file looks like. Then you can access the contiguous sections of memory. 66 | */ 67 | class StIntelHexFile 68 | { 69 | public: 70 | /*! 71 | * Structure representing each individual line of the Intel Hex input data. 72 | */ 73 | struct IntelHex 74 | { 75 | unsigned m_dataCount; //!< The number of bytes in the data field. 76 | uint32_t m_address; //!< The address offset of the data. 77 | unsigned m_type; //!< Type of the data field. 00: Data 78 | //!< 01: End of File 79 | //!< 02: Extended Segment Address 80 | //!< 03: Start Segment Address 81 | //!< 04: Extended Linear Address 82 | //!< 05: Start Linear Address 83 | uint8_t *m_data; //!< Pointer to data, or NULL if no data for this record. 84 | uint8_t m_checksum; //!< The checksum byte used to verify the record. 85 | }; 86 | 87 | //! Iterator type. 88 | typedef std::vector::const_iterator const_iterator; 89 | 90 | public: 91 | //! \brief Constructor. 92 | StIntelHexFile(std::istream &inStream); 93 | 94 | //! \brief Destructor. 95 | virtual ~StIntelHexFile(); 96 | 97 | //! \name File name 98 | //@{ 99 | virtual void setName(const std::string &inName) { m_name = inName; } 100 | virtual std::string getName() const { return m_name; } 101 | //@} 102 | 103 | //! \name Parsing 104 | //@{ 105 | //! \brief Determine if the file is a Intel Hex file. 106 | virtual bool isIntelHexFile(); 107 | 108 | //! \brief Parse the entire IntelHex input stream. 109 | virtual void parse(); 110 | //@} 111 | 112 | //! \name Record access 113 | //@{ 114 | //! \return the number of Intel Hex that have been parsed from the input stream. 115 | inline unsigned getRecordCount() const { return static_cast(m_records.size()); } 116 | //! \return iterator for 117 | inline const_iterator getBegin() const { return m_records.begin(); } 118 | inline const_iterator getEnd() const { return m_records.end(); } 119 | //@} 120 | 121 | //! \name Operators 122 | //@{ 123 | inline const IntelHex &operator[](unsigned inIndex) { return m_records[inIndex]; } 124 | //@} 125 | 126 | protected: 127 | std::istream &m_stream; //!< The input stream for the Intel Hex data. 128 | std::vector m_records; //!< Vector of Intel Hex in the input data. 129 | 130 | std::string m_name; //!< File name. (optional) 131 | 132 | //! \name Parsing utilities 133 | //@{ 134 | virtual void parseLine(std::string &inLine); 135 | 136 | bool isHexDigit(char c); 137 | int hexDigitToInt(char digit); 138 | int readHexByte(std::string &inString, int inIndex); 139 | //@} 140 | }; 141 | 142 | /*! 143 | * \brief Simple exception thrown to indicate an error in the input Intel Hex data format. 144 | */ 145 | class StIntelHexParseException : public std::runtime_error 146 | { 147 | public: 148 | //! \brief Default constructor. 149 | StIntelHexParseException(const std::string &inMessage) 150 | : std::runtime_error(inMessage) 151 | { 152 | } 153 | }; 154 | 155 | #endif // _StIntelHexFile_h_ 156 | -------------------------------------------------------------------------------- /src/blfwk/src/SourceFile.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2013-2014 Freescale Semiconductor, Inc. 3 | * All rights reserved. 4 | * 5 | * 6 | * SPDX-License-Identifier: BSD-3-Clause 7 | */ 8 | 9 | #include 10 | 11 | #include "blfwk/ELFSourceFile.h" 12 | #include "blfwk/EndianUtilities.h" 13 | #include "blfwk/IntelHexSourceFile.h" 14 | #include "blfwk/SBSourceFile.h" 15 | #include "blfwk/SRecordSourceFile.h" 16 | #include "blfwk/SearchPath.h" 17 | #include "blfwk/SourceFile.h" 18 | #include "blfwk/format_string.h" 19 | 20 | using namespace blfwk; 21 | 22 | //! The supported file types are currently: 23 | //! - ELF files 24 | //! - Motorola S-record files 25 | //! - Binary files 26 | //! - SB files 27 | //! - Intel Hex files 28 | //! 29 | //! Any file that is not picked up by the other subclasses will result in a 30 | //! an instance of BinaryDataFile. 31 | //! 32 | //! \return An instance of the correct subclass of SourceFile for the given path. 33 | //! 34 | //! \exception std::runtime_error Thrown if the file cannot be opened. 35 | //! 36 | //! \see blfwk::ELFSourceFile 37 | //! \see blfwk::SRecordSourceFile 38 | //! \see blfwk::BinarySourceFile 39 | //! \see blfwk::SBSourceFile 40 | //! \see blfwk::IntelHexSourceFile 41 | SourceFile *SourceFile::openFile(const std::string &path) 42 | { 43 | // Search for file using search paths 44 | std::string actualPath; 45 | bool found = PathSearcher::getGlobalSearcher().search(path, PathSearcher::kFindFile, true, actualPath); 46 | if (!found) 47 | { 48 | throw std::runtime_error(format_string("unable to find file %s\n", path.c_str())); 49 | } 50 | 51 | std::ifstream testStream(actualPath.c_str(), std::ios_base::in | std::ios_base::binary); 52 | if (!testStream.is_open()) 53 | { 54 | throw std::runtime_error(format_string("failed to open file: %s", actualPath.c_str())); 55 | } 56 | 57 | // catch exceptions so we can close the file stream 58 | try 59 | { 60 | if (ELFSourceFile::isELFFile(testStream)) 61 | { 62 | testStream.close(); 63 | return new ELFSourceFile(actualPath); 64 | } 65 | else if (SRecordSourceFile::isSRecordFile(testStream)) 66 | { 67 | testStream.close(); 68 | return new SRecordSourceFile(actualPath); 69 | } 70 | else if (SBSourceFile::isSBFile(testStream)) 71 | { 72 | testStream.close(); 73 | return new SBSourceFile(actualPath); 74 | } 75 | else if (IntelHexSourceFile::isIntelHexFile(testStream)) 76 | { 77 | testStream.close(); 78 | return new IntelHexSourceFile(actualPath); 79 | } 80 | 81 | // treat it as a binary file 82 | testStream.close(); 83 | return new BinarySourceFile(actualPath); 84 | } 85 | catch (...) 86 | { 87 | testStream.close(); 88 | throw; 89 | } 90 | } 91 | 92 | SourceFile::SourceFile(const std::string &path, source_file_t filetype) 93 | : m_path(path) 94 | , m_filetype(filetype) 95 | , m_stream() 96 | { 97 | // Initialize m_size 98 | open(); 99 | assert(m_stream); 100 | m_stream->seekg(0, std::ios_base::end); 101 | m_size = (unsigned)m_stream->tellg(); 102 | close(); 103 | } 104 | 105 | //! The file is closed if it had been left opened. 106 | //! 107 | SourceFile::~SourceFile() 108 | { 109 | if (isOpen()) 110 | { 111 | m_stream->close(); 112 | } 113 | } 114 | 115 | //! \exception std::runtime_error Raised if the file could not be opened successfully. 116 | void SourceFile::open() 117 | { 118 | assert(!isOpen()); 119 | m_stream = new std::ifstream(m_path.c_str(), std::ios_base::in | std::ios_base::binary); 120 | if (!m_stream->is_open()) 121 | { 122 | throw std::runtime_error(format_string("failed to open file: %s", m_path.c_str())); 123 | } 124 | } 125 | 126 | void SourceFile::close() 127 | { 128 | assert(isOpen()); 129 | 130 | m_stream->close(); 131 | m_stream.safe_delete(); 132 | } 133 | 134 | //! If the file does not support named sections, or if there is not a 135 | //! section with the given name, this method may return NULL. 136 | //! 137 | //! This method is just a small wrapper that creates an 138 | //! FixedMatcher string matcher instance and uses the createDataSource() 139 | //! that takes a reference to a StringMatcher. 140 | DataSource *SourceFile::createDataSource(const std::string §ion) 141 | { 142 | FixedMatcher matcher(section); 143 | return createDataSource(matcher); 144 | } 145 | 146 | DataTarget *SourceFile::createDataTargetForEntryPoint() 147 | { 148 | if (!hasEntryPoint()) 149 | { 150 | return NULL; 151 | } 152 | 153 | return new ConstantDataTarget(getEntryPointAddress()); 154 | } 155 | 156 | BinarySourceFile::BinarySourceFile(const std::string &path, source_file_t sourceFileType) 157 | : SourceFile(path, sourceFileType) 158 | , m_entry_point(0xffffffff) 159 | , m_stack_pointer(0xffffffff) 160 | { 161 | } 162 | 163 | void BinarySourceFile::guessEntryPointAndStackPointer() 164 | { 165 | open(); 166 | 167 | uint32_t data[] = { 0xffffffff, 0xffffffff }; 168 | 169 | // seek to beginning of the stream/file and read the plaintext header 170 | m_stream->seekg(0, std::ios_base::beg); 171 | if (m_stream->read((char *)&data, sizeof(data)).bad()) 172 | { 173 | close(); 174 | throw std::runtime_error(format_string("failed to read image header from file: %s", m_path.c_str())); 175 | } 176 | 177 | close(); 178 | 179 | m_stack_pointer = ENDIAN_LITTLE_TO_HOST_U32(data[0]); 180 | m_entry_point = ENDIAN_LITTLE_TO_HOST_U32(data[1]); 181 | } 182 | 183 | DataSource *BinarySourceFile::createDataSource() 184 | { 185 | std::istream *fileStream = getStream(); 186 | assert(fileStream); 187 | 188 | // get stream size 189 | fileStream->seekg(0, std::ios_base::end); 190 | int length = (int)fileStream->tellg(); 191 | 192 | // allocate buffer 193 | smart_array_ptr data = new uint8_t[length]; 194 | 195 | // read entire file into the buffer 196 | fileStream->seekg(0, std::ios_base::beg); 197 | if (fileStream->read((char *)data.get(), length).bad()) 198 | { 199 | throw std::runtime_error(format_string("unexpected end of file: %s", m_path.c_str())); 200 | } 201 | 202 | // create the data source. the buffer is copied, so we can dispose of it. 203 | return new UnmappedDataSource(data, length); 204 | } 205 | --------------------------------------------------------------------------------