pax_global_header00006660000000000000000000000064125571001600014507gustar00rootroot0000000000000052 comment=d3d7b4b2d9ca74052f31442f7a5be43bb17e5315 esptool-ck-0.4.6/000077500000000000000000000000001255710016000135765ustar00rootroot00000000000000esptool-ck-0.4.6/.gitignore000066400000000000000000000000321255710016000155610ustar00rootroot00000000000000esptool esptool.exe build/esptool-ck-0.4.6/.travis.yml000066400000000000000000000007741255710016000157170ustar00rootroot00000000000000language: cpp compiler: - gcc script: make dist notifications: email: recipients: - igrr@users.noreply.github.com on_success: change on_failure: always deploy: provider: releases api_key: secure: Lg/Po5YFRcnrpqjgrdHcyGdxhRe8iB01Og8hvTmhhDxew1mpVHCfcZxO1VMpBxWnLS3ud4UdMjC3RBpcCWTvt0w9g35Vt9cj7XgnBEBHrBBA5DL+E5cAj/5Sf63pztc85m/kB0WODNG2NQiTpjonszrFHpmWdmXp3mqP95mZVBw= file: esptool-$TRAVIS_TAG-linux64.tar.gz on: repo: igrr/esptool-ck tags: true all_branches: true esptool-ck-0.4.6/LICENSE000066400000000000000000000432541255710016000146130ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. esptool-ck-0.4.6/Makefile000066400000000000000000000035401255710016000152400ustar00rootroot00000000000000CFLAGS += -std=gnu99 -Os -Wall CXXFLAGS += -std=c++11 -Os -Wall ifeq ($(OS),Windows_NT) TARGET_OS := WINDOWS DIST_SUFFIX := windows ARCHIVE_CMD := 7z a ARCHIVE_EXTENSION := zip else UNAME_S := $(shell uname -s) ifeq ($(UNAME_S),Linux) TARGET_OS := LINUX UNAME_M := $(shell uname -m) ifeq ($(UNAME_M),x86_64) DIST_SUFFIX := linux64 endif ifeq ($(UNAME_M),i686) DIST_SUFFIX := linux32 endif ifeq ($(UNAME_M),armv6l) DIST_SUFFIX := linux-armhf endif endif ifeq ($(UNAME_S),Darwin) TARGET_OS := OSX DIST_SUFFIX := osx endif ARCHIVE_CMD := tar czf ARCHIVE_EXTENSION := tar.gz endif VERSION ?= $(shell git describe --always) MODULES := infohelper elf binimage argparse serialport espcomm -include local/Makefile.local.$(TARGET_OS) OBJECTS := \ argparse/argparse.o \ argparse/argparse_binimagecmd.o \ argparse/argparse_commcmd.o \ argparse/argparse_elfcmd.o \ binimage/esptool_binimage.o \ elf/esptool_elf.o \ elf/esptool_elf_object.o \ espcomm/delay.o \ espcomm/espcomm.o \ espcomm/espcomm_boards.o \ infohelper/infohelper.o \ serialport/serialport.o \ main.o INCLUDES := $(addprefix -I,$(MODULES)) CFLAGS += $(TARGET_CFLAGS) CXXFLAGS += $(TARGET_CXXFLAGS) LDFLAGS += $(TARGET_LDFLAGS) CPPFLAGS += $(INCLUDES) $(SDK_INCLUDES) -D$(TARGET_OS) -DVERSION=\"$(VERSION)\" DIST_NAME := esptool-$(VERSION)-$(DIST_SUFFIX) DIST_DIR := $(DIST_NAME) DIST_ARCHIVE := $(DIST_NAME).$(ARCHIVE_EXTENSION) .PHONY: all checkdirs clean dist all: $(TARGET) dist: $(TARGET) $(DIST_DIR) cp $(TARGET) $(DIST_DIR)/ $(ARCHIVE_CMD) $(DIST_ARCHIVE) $(DIST_DIR) $(TARGET): $(OBJECTS) $(CC) $^ -o $@ $(LDFLAGS) strip $(TARGET) $(BUILD_DIR): @mkdir -p $@ $(DIST_DIR): @mkdir -p $@ clean: @rm -f $(OBJECTS) @rm -f $(TARGET) @rm -rf esptool-* esptool-ck-0.4.6/README.md000066400000000000000000000105471255710016000150640ustar00rootroot00000000000000**Esptool** is a tool to create firmware files for the ESP8266 chip and flash the firmware to the chip over serial port. Esptool runs on Windows, Linux and Mac OS X. Esptool reads the compiled program in ELF format, extracts code and data sections, and either dumps a section to a file or assembles the firmware file from several segments. Esptool also communicates with the ESP8266 bootloader to upload firmware files to flash. Esptool can automatically put the board into UART bootloader mode using a variety of methods. Linux|Windows ----- | ------ [![Linux build status](http://img.shields.io/travis/igrr/esptool-ck.svg)](https://travis-ci.org/igrr/esptool-ck) | [![Windows build status](http://img.shields.io/appveyor/ci/igrr/esptool-ck.svg)](https://ci.appveyor.com/project/igrr/esptool-ck) Usage ----- ``` esptool ``` The program interprets the arguments given on the command line, and in the order they are given. The following commands are currently available: Argument | Description ---------|------------- ```-eo ``` | Opens an ELF object file, parses it and caches some of the information found therein. Only works if there is no ELF file currently opened. ```-es
``` | Reads the given section from the ELF file and makes a raw dump into the specified file. ```-ec``` | Closes the currently opened ELF file ```-bo ```| Prepares an firmware file in the format that is understood by the ESP chip. Only works if an ELF file is opened, and if no firmware file is prepared yet. Upon -bo the tool will start out with an empty image where only the main header is set up. The result of the operations done on the firmware image are saved when the it is finally closed using -bc command. ```-bm ``` | Set the flash chip interface mode. Default is QIO. This parameter is stored in the binary image header, along with the flash size and flash frequency. The ROM bootloader in the ESP8266 uses the value of these parameters in order to know how to talk to the flash chip. ```-bz <512K|256K|1M|2M|4M|8M|16M|32M>``` | Set the flash chip size. Default is 512K. ```-bf <40|26|20|80>``` | Set the flash chip frequency, in MHz. Default is 40M. ```-bs
``` | Reads the specified section from the ELF file and appends it to the firmware image. Sections will appear in the firmware image in the exact same order as the -bs commands are executed. ```-bc``` | Closes the firmware image and saves the result as file to disk. ```-v``` | Increase verbosity level of the tool. Add more v's to increase it even more, e.g. -vv, -vvv. ```-q``` | Disable most of the output. ```-cp ``` | Select the serial port device to use for communicating with the ESP. Default is /dev/ttyUSB0 on Linux, COM1 on Windows, /dev/tty.usbserial on Mac OS X. ```-cd ``` | Select the reset method to use for resetting the board. Currently supported methods are listed below. ```-cb ``` | Select the baudrate to use, default is 115200. ```-ca
``` | Address in flash memory to upload the data to. This address is interpreted as hexadecimal. Default is 0x00000000. ```-cf ``` | Upload the file to flash. Parameters that set the port, baud rate, and address must preceed the -cf command. Supported boards ---------------- Name | Description -----------|------------- none | No DTR/RTS manipulation ck | RTS controls RESET or CH_PD, DTR controls GPIO0 wifio | TXD controls GPIO0 via PNP transistor and DTR controls RESET via a capacitor nodemcu | GPIO0 and RESET controlled using two NPN transistors as in [NodeMCU devkit](https://raw.githubusercontent.com/nodemcu/nodemcu-devkit/master/Documents/NODEMCU_DEVKIT_SCH.png). Examples -------- ##### Create firmware files from the ELF output Input: ```app.elf```, output: ```app_00000.bin```, ```app_40000.bin```. Note the option for 4M flash size. ``` esptool -bz 4M -eo app.elf -bo app_00000.bin -bs .text -bs .data -bs .rodata -bc -ec -eo app.elf -es .irom0.text app_40000.bin -ec ``` ##### Upload the firmware to the board connected to COM5 port at 115200 baud, using manual reset method. ``` esptool -cp COM5 -cd none -cb 115200 -ca 0x00000 -cf 00000.bin -ca 0x40000 -cf 40000.bin ``` or, equivalent: ``` esptool -cp COM5 -cf 00000.bin -ca 0x40000 -cf 40000.bin ``` License ------- Copyright (C) 2014 Christian Klippel . This code is licensed under GPL v2. esptool-ck-0.4.6/TODO000066400000000000000000000003571255710016000142730ustar00rootroot00000000000000- clean up the code, it's a real mess - better documentation - rework the info/error message stuff - refine functionality to up/download firmware/memory to/from the chip so that it can use the internally generated images if wanted - ... esptool-ck-0.4.6/appveyor.yml000066400000000000000000000022041255710016000161640ustar00rootroot00000000000000version: 0.0.{build} platform: - x86 skip_commits: message: /\[ci skip\]/ matrix: fast_finish: true build_script: - SET PATH=C:\MinGW\bin;C:\MinGW\msys\1.0\bin;%PATH% - make all - for /f %%i in ('git describe --always') do set PRODUCT_VERSION=%%i - SET PRODUCT_NAME=esptool-%PRODUCT_VERSION% - SET PLATFORM_NAME=win32 - SET PRODUCT_DIST_NAME=%PRODUCT_NAME%-%PLATFORM_NAME% - echo %PRODUCT_NAME% - echo %PRODUCT_DIST_NAME% - mkdir %PRODUCT_DIST_NAME% - cp esptool.exe %PRODUCT_DIST_NAME%\esptool.exe - SET PRODUCT_ZIP=%PRODUCT_DIST_NAME%.zip - 7z a %PRODUCT_ZIP% %PRODUCT_DIST_NAME% - appveyor PushArtifact %PRODUCT_ZIP% - SET PRODUCT_ZIP_SHA=%PRODUCT_ZIP%.sha - ps: Get-FileHash $env:PRODUCT_ZIP -Algorithm SHA1 | Out-File $env:PRODUCT_ZIP_SHA - type %PRODUCT_ZIP_SHA% - appveyor PushArtifact %PRODUCT_ZIP_SHA% deploy: release: $(PRODUCT_VERSION) provider: GitHub auth_token: secure: 'PGg5fnoBpP1Omzr6f3KIYDiD8J30rretQjSl/MITRpzvSCmN88kM6VDMz1TBGZTA' artifact: /.*\.zip/ draft: true prerelease: false on: appveyor_repo_tag: true esptool-ck-0.4.6/argparse/000077500000000000000000000000001255710016000154025ustar00rootroot00000000000000esptool-ck-0.4.6/argparse/argparse.c000066400000000000000000000047151255710016000173610ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse.c *** - simple parser for command line arguments *** checks which command submodule an argument is for and then dispatches *** processing to the apropriate parser *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include "infohelper.h" #include "argparse_binimagecmd.h" #include "argparse_commcmd.h" #include "argparse_elfcmd.h" // main parser state machine, returns the number of arguments used by // the called sub-parser #include "argparse.h" int parse_arg(int num_args, char **arg_ptr) { if(arg_ptr[0][0] == '-' && num_args) { switch(arg_ptr[0][1]) { // ELF file related commands case 'd': LOGWARN("USING -d IS DEPRECATED, USE -es INSTEAD. FIXING COMMAND"); arg_ptr[0][1] = 'e'; arg_ptr[0][2] = 's'; case 'e': return argparse_elfcmd(num_args, arg_ptr); break; // binary flash image related commands case 'b': return argparse_binimagecmd(num_args, arg_ptr); break; // comms related commands (flash upload, etc.) case 'c': return argparse_commcmd(num_args, arg_ptr); break; // verbosity setting commands case 'v': return 1; break; default: return 0; break; } } return 0; } esptool-ck-0.4.6/argparse/argparse.h000066400000000000000000000025031255710016000173570ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparese.h *** - header file for argparse.c *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ARGPARSE_H #define ARGPARSE_H int parse_arg(int num_args, char **arg_ptr); int argparse_elfcmd(int num_args, char **arg_ptr); int argparse_binimagecmd(int num_args, char **arg_ptr); int argparse_commcmd(int num_args, char **arg_ptr); #endif esptool-ck-0.4.6/argparse/argparse_binimagecmd.c000066400000000000000000000110271255710016000216720ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse_binimagecmd.c *** - parsing of command related to binary flash image functions *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include #include "infohelper.h" #include "esptool_elf.h" #include "esptool_elf_object.h" #include "esptool_binimage.h" static int argparse_binimagecmd_add_segment(const char *sname, uint32_t padsize) { uint32_t snum; uint32_t addr; uint32_t size; uint32_t pad; snum = get_elf_secnum_by_name(sname); addr = get_elf_section_addr(snum); size = get_elf_section_size(snum); if(snum) { print_elf_section_info(snum); pad = get_elf_section_size(snum); padsize--; while(pad & padsize) { pad++; } if(pad > size) { binimage_add_segment(get_elf_section_addr(snum), pad, get_elf_section_bindata(snum, pad)); LOGINFO("added section %s at 0x%08X size 0x%08X with padding 0x%08X", get_elf_section_name(snum), addr, size, pad-size); } else { binimage_add_segment(get_elf_section_addr(snum), size, get_elf_section_bindata(snum, size)); LOGINFO("added section %s at 0x%08X size 0x%08X", get_elf_section_name(snum), addr, size); } } return snum; } int argparse_binimagecmd(int num_args, char **arg_ptr) { char *cur_cmd; uint32_t addr; if(arg_ptr[0][1] == 'b' && num_args--) { cur_cmd = &arg_ptr[0][2]; arg_ptr++; switch(*cur_cmd++) { case 'o': if(num_args < 1) { return 0; } if(binimage_prepare(arg_ptr[0], get_elf_entry())) { return 2; } break; case 's': if(num_args < 1) { return 0; } if(argparse_binimagecmd_add_segment(arg_ptr[0], 4)) { bimage_set_entry(get_elf_entry()); return 2; } break; case 'c': if(binimage_write_close(16)) { return 1; } break; case 'p': if(num_args < 1) { return 0; } addr = (unsigned) atoi(arg_ptr[0]); if(binimage_write_padto(16, addr)) { return 2; } break; case 'm': if (num_args < 1) { return 0; } if (binimage_set_flash_mode(arg_ptr[0]) == 0) { return 0; } return 2; case 'z': if (num_args < 1) { return 0; } if (binimage_set_flash_size(arg_ptr[0]) == 0) { return 0; } return 2; case 'f': if (num_args < 1) { return 0; } if (binimage_set_flash_freq(arg_ptr[0]) == 0) { return 0; } return 2; default: return 0; break; } } return 0; } esptool-ck-0.4.6/argparse/argparse_binimagecmd.h000066400000000000000000000023611255710016000217000ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse_binimagecmd.h *** - include file for the flash image commands argument parser *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ARGPARSE_BINIMAGECMD_H #define ARGPARSE_BINIMAGECMD_H int argparse_binimagecmd(int num_args, char **arg_ptr); #endif esptool-ck-0.4.6/argparse/argparse_commcmd.c000066400000000000000000000056231255710016000210570ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse_commcmd.c *** - parsing of comms related commands (flash upload, etc) *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include #include "infohelper.h" #include "esptool_elf.h" #include "esptool_elf_object.h" #include "esptool_binimage.h" #include "espcomm.h" int argparse_commcmd(int num_args, char **arg_ptr) { char *cur_cmd; if(arg_ptr[0][1] == 'c' && num_args--) { cur_cmd = &arg_ptr[0][2]; arg_ptr++; switch(*cur_cmd++) { case 'p': if(num_args < 1) { return 0; } if(espcomm_set_port(arg_ptr[0])) { return 2; } break; case 'b': if(num_args < 1) { return 0; } if(espcomm_set_baudrate(arg_ptr[0])) { return 2; } break; case 'a': if(num_args < 1) { return 0; } if(espcomm_set_address(arg_ptr[0])) { return 2; } break; case 'f': if(num_args < 1) { return 0; } if(espcomm_upload_file(arg_ptr[0])) { return 2; } break; case 'd': if (num_args < 1) { return 0; } if (espcomm_set_board(arg_ptr[0])) { return 2; } default: return 0; break; } } return 0; } esptool-ck-0.4.6/argparse/argparse_commcmd.h000066400000000000000000000023321255710016000210560ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse_commcmd.h *** - include file for the comm-commands argument parser *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ARGPARSE_COMMCMD_H #define ARGPARSE_COMMCMD_H int argparse_commcmd(int num_args, char **arg_ptr); #endif esptool-ck-0.4.6/argparse/argparse_elfcmd.c000066400000000000000000000045221255710016000206670ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse_elfcmd.c *** - parsing of ELF file related commands *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include "argparse_elfcmd.h" #include "esptool_elf.h" #include "esptool_elf_object.h" int argparse_elfcmd(int num_args, char **arg_ptr) { char *cur_cmd; if(arg_ptr[0][1] == 'e' && num_args--) { cur_cmd = &arg_ptr[0][2]; arg_ptr++; switch(*cur_cmd++) { // open ELF file case 'o': if(num_args < 1) { return 0; } else if(create_elf_object(arg_ptr[0])) { return 2; } break; // command to save a section from the ELF to a new file case 's': if(num_args < 2) { return 0; } else if(save_elf_section_bindata(arg_ptr[0], arg_ptr[1])) { return 3; } break; // close ELF file case 'c': if(close_elf_object()) { return 1; } break; default: return 0; break; } } return 0; } esptool-ck-0.4.6/argparse/argparse_elfcmd.h000066400000000000000000000023341255710016000206730ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** argparse_elfcmd.h *** - include file for the ELF object commands argument parser *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ARGPARSE_ELFCMD_H #define ARGPARSE_ELFCMD_H int argparse_elfcmd(int num_args, char **arg_ptr); #endif esptool-ck-0.4.6/binimage/000077500000000000000000000000001255710016000153515ustar00rootroot00000000000000esptool-ck-0.4.6/binimage/esptool_binimage.c000066400000000000000000000244041255710016000210410ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool_binimage.c *** - implementation of functions to handle firmware files for the ESP8266 *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include #include "infohelper.h" #include "esptool_binimage.h" static bin_image b_image = { .magic = 0xe9, .num_segments = 0, .flash_mode = FLASH_MODE_QIO, .flash_size_freq = FLASH_SIZE_512K | FLASH_FREQ_40 }; unsigned int total_size = 0; int binimage_add_segment(uint32_t address, uint32_t size, unsigned char *data) { if(!data) { LOGERR("no data for binimage segment #%i", b_image.num_segments); return 0; } if(b_image.segments == 0) { b_image.segments = malloc(size); if(b_image.segments == NULL) { LOGERR("can't allocate 0x%08X bytes for binimage segment #%i", b_image.segments[b_image.num_segments].size, b_image.num_segments); return 0; } } else { b_image.segments = realloc(b_image.segments, (b_image.num_segments+1)*sizeof(binary_segment)); if(b_image.segments == NULL) { LOGERR("can't allocate 0x%08X more bytes for binimage segment #%i", b_image.segments[b_image.num_segments].size, b_image.num_segments); return 0; } } b_image.segments[b_image.num_segments].address = address; b_image.segments[b_image.num_segments].size = size; b_image.segments[b_image.num_segments].data = data; LOGINFO("added segment #%i to binimage for address 0x%08X with size 0x%08X", b_image.num_segments, b_image.segments[b_image.num_segments].address, b_image.segments[b_image.num_segments].size); b_image.num_segments++; return 1; } int binimage_prepare(const char *fname, uint32_t entry) { if(b_image.image_file) { return 0; } b_image.entry = entry; if(fname[0]) { b_image.image_file = fopen(fname, "wb"); if(b_image.image_file == NULL) { LOGERR("cant open binimage file \"%s\" for writing, aborting", fname); return 0; } } else { return 0; } b_image.segments = 0; b_image.num_segments = 0; total_size = 0; LOGINFO("created structure for binimage \"%s\" with entry address 0x%08X", fname, b_image.entry); return 1; } void bimage_set_entry(uint32_t entry) { b_image.entry = entry; LOGINFO("set bimage entry to 0x%08X", b_image.entry); } int binimage_write(uint32_t padsize, bool close) { unsigned int cnt, cnt2; unsigned char chksum; chksum = 0xEF; if(b_image.image_file == 0) { return 0; } if(fwrite((unsigned char*)&b_image, 1, 8, b_image.image_file) != 8) { LOGERR("cant write main header to binimage file, aborting"); fclose(b_image.image_file); b_image.image_file = 0; return 0; } total_size = 8; for(cnt = 0; cnt < b_image.num_segments; cnt++) { if(fwrite((unsigned char*)&b_image.segments[cnt], 1, 8, b_image.image_file) != 8) { LOGERR("cant write header for segment #%i to binimage file, aborting", cnt); fclose(b_image.image_file); b_image.image_file = 0; return 0; } total_size += 8; if(fwrite(b_image.segments[cnt].data, 1, b_image.segments[cnt].size, b_image.image_file) != b_image.segments[cnt].size) { LOGERR("cant write data block for segment #%i to binimage file, aborting", cnt); fclose(b_image.image_file); b_image.image_file = 0; return 0; } total_size += b_image.segments[cnt].size; for(cnt2 = 0; cnt2 < b_image.segments[cnt].size; cnt2++) { chksum ^= b_image.segments[cnt].data[cnt2]; } } padsize--; while(++total_size & padsize) { if(fputc(0x00, b_image.image_file) == EOF) { LOGERR("cant write padding byte 0x00 at 0x%08X to binimage file, aborting", total_size); fclose(b_image.image_file); b_image.image_file = 0; return 0; } cnt++; } if(fputc(chksum, b_image.image_file) == EOF) { LOGERR("cant write checksum byte 0x%02X at 0x%08X to binimage file, aborting", chksum, total_size); fclose(b_image.image_file); b_image.image_file = 0; return 0; } LOGINFO("saved binimage file, total size is %i bytes, checksum byte is 0x%02X", total_size, chksum); if (close) { fclose(b_image.image_file); b_image.image_file = 0; } if(b_image.segments) { for(cnt = 0; cnt < b_image.num_segments; cnt++) { if(b_image.segments[cnt].data) { LOGDEBUG("releasing memory used for segment %i in binimage", cnt); free(b_image.segments[cnt].data); } } if(b_image.segments) { LOGDEBUG("releasing memory used for binimage segment pointers"); free(b_image.segments); b_image.segments = 0; b_image.num_segments = 0; } } return 1; } int binimage_write_close(uint32_t padsize) { return binimage_write(padsize, true); } int binimage_write_padto(uint32_t padsize, uint32_t address) { if (binimage_write(padsize, false) == 0) return 0; LOGDEBUG("binimage_write_padto: total:%x addr:%x", total_size, address); if (address < total_size) { LOGERR("binimage_write_padto: address is less than size written"); return 0; } while (total_size < address) { if (fputc(0xaa, b_image.image_file) == EOF) return 0; ++total_size; } return 1; } #define INVALID_VAL 0xff unsigned char binimage_parse_flash_mode(const char* str); unsigned char binimage_parse_flash_size(const char* str); unsigned char binimage_parse_flash_freq(const char* str); const char* binimage_flash_mode_to_str(unsigned char mode); const char* binimage_flash_size_to_str(unsigned char size); const char* binimage_flash_freq_to_str(unsigned char freq); int binimage_set_flash_mode(const char* modestr) { unsigned char mode = binimage_parse_flash_mode(modestr); if (mode == INVALID_VAL) { LOGERR("invalid flash mode value: %s", modestr); return 0; } LOGINFO("setting flash mode from %s to %s", binimage_flash_mode_to_str(b_image.flash_mode), binimage_flash_mode_to_str(mode)); b_image.flash_mode = mode; return 1; } int binimage_set_flash_size(const char* sizestr) { unsigned char size = binimage_parse_flash_size(sizestr); if (size == INVALID_VAL) { LOGERR("invalid flash size value: %s", sizestr); return 0; } LOGINFO("setting flash size from %s to %s", binimage_flash_size_to_str(b_image.flash_size_freq & 0xf0), binimage_flash_size_to_str(size)); b_image.flash_size_freq = size | (b_image.flash_size_freq & 0x0f); return 1; } int binimage_set_flash_freq(const char* freqstr) { unsigned char freq = binimage_parse_flash_freq(freqstr); if (freq == INVALID_VAL) { LOGERR("invalid flash frequency value: %s", freqstr); return 0; } LOGINFO("setting flash frequency from %s to %s", binimage_flash_freq_to_str(b_image.flash_size_freq & 0x0f), binimage_flash_freq_to_str(freq)); b_image.flash_size_freq = (b_image.flash_size_freq & 0xf0) | freq; return 1; } static const char* flash_mode_str[] = {"qio", "qout", "dio", "dout"}; static const char* flash_size_str[] = {"512K", "256K", "1M", "2M", "4M", "8M", "16M", "32M"}; unsigned char binimage_parse_flash_mode(const char* str) { const int n = sizeof(flash_mode_str)/sizeof(const char*); for (int i = 0; i < n; ++i) { if (strcasecmp(str, flash_mode_str[i]) == 0) { return (unsigned char) i; } } return INVALID_VAL; } unsigned char binimage_parse_flash_size(const char* str) { const int n = sizeof(flash_size_str)/sizeof(const char*); for (int i = 0; i < n; ++i) { if (strcasecmp(str, flash_size_str[i]) == 0) { return (unsigned char) i << 4; } } return INVALID_VAL; } unsigned char binimage_parse_flash_freq(const char* str) { int val = atoi(str); switch (val) { case 40: return FLASH_FREQ_40; case 26: return FLASH_FREQ_26; case 20: return FLASH_FREQ_20; case 80: return FLASH_FREQ_80; default: return INVALID_VAL; } } const char* binimage_flash_mode_to_str(unsigned char mode) { if (mode > FLASH_MODE_DOUT) return ""; return flash_mode_str[mode]; } const char* binimage_flash_size_to_str(unsigned char size) { if ((size >> 4) > FLASH_SIZE_32M) return ""; return flash_size_str[size >> 4]; } const char* binimage_flash_freq_to_str(unsigned char freq) { switch (freq) { case FLASH_FREQ_40: return "40"; case FLASH_FREQ_26: return "26"; case FLASH_FREQ_20: return "20"; case FLASH_FREQ_80: return "80"; default: return ""; } } esptool-ck-0.4.6/binimage/esptool_binimage.h000066400000000000000000000101401255710016000210360ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool_binimage.h *** - defines and prototypes for handling firmware files for the ESP8266 *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ESPTOOL_BINIMAGE_H #define ESPTOOL_BINIMAGE_H #include #include #include /* ** structs used to build and maintain internal representation ** of the binary firmware image */ /* ** structure holding a given chunk of binary data */ typedef struct { uint32_t address; uint32_t size; unsigned char *data; } binary_segment; /* ** structure specifying the binary firmware image ** also stores the list of chunks used */ typedef struct { unsigned char magic; unsigned char num_segments; /* SPI Flash Interface (0 = QIO, 1 = QOUT, 2 = DIO, 0x3 = DOUT) */ unsigned char flash_mode; /* High four bits: 0 = 512K, 1 = 256K, 2 = 1M, 3 = 2M, 4 = 4M, Low four bits: 0 = 40MHz, 1= 26MHz, 2 = 20MHz, 0xf = 80MHz */ unsigned char flash_size_freq; uint32_t entry; FILE *image_file; binary_segment *segments; } bin_image; #define FLASH_MODE_QIO 0 #define FLASH_MODE_QOUT 1 #define FLASH_MODE_DIO 2 #define FLASH_MODE_DOUT 3 #define FLASH_SIZE_512K 0 << 4 #define FLASH_SIZE_256K 1 << 4 #define FLASH_SIZE_1M 2 << 4 #define FLASH_SIZE_2M 3 << 4 #define FLASH_SIZE_4M 4 << 4 #define FLASH_SIZE_8M 5 << 4 #define FLASH_SIZE_16M 6 << 4 #define FLASH_SIZE_32M 7 << 4 // flash frequency in MHz #define FLASH_FREQ_40 0x0 #define FLASH_FREQ_26 0x1 #define FLASH_FREQ_20 0x2 #define FLASH_FREQ_80 0xf /* ** function prototypes */ /* ** initializes the internal firmware image representation ** fname: the file name to which the image will finally be saved ** entry: the code entry point address ** returns 1 on success, 0 on failure */ int binimage_prepare(const char *fname, uint32_t entry); /* ** specify a new code entry address */ void bimage_set_entry(uint32_t entry); /* ** write the binary firmware image to disk ** padsize: specifies to what power-of-two blocksize the image needs to be padded ** returns 1 on success, 0 on failure */ int binimage_write_close(uint32_t padsize); int binimage_write_padto(uint32_t padsize, uint32_t address); /* ** add a new segment to the firmware image ** address: specifies the load address of the given segment ** size: specifies the size of the binary data segment in bytes ** data: a pointer to an array of bytes containing the binary segment data ** returns 1 on success, 0 on failure */ int binimage_add_segment(uint32_t address, uint32_t size, unsigned char *data); /* ** update the image header which specifies flash chip configuration ** mode: one of "qio", "qout", "dio", "dout" (case-insensitive) ** size: one of "512K", "256K", "1M", "2M", "4M" (case-insensitive) ** freq: one of "40", "26", "20", "80" ** if these methods are not called, the binary image will use the following parameters: ** QIO, 512K, 40MHz ** return 1 on success, 0 on failure */ int binimage_set_flash_mode(const char* mode); int binimage_set_flash_size(const char* size); int binimage_set_flash_freq(const char* freq); #endif esptool-ck-0.4.6/elf/000077500000000000000000000000001255710016000143445ustar00rootroot00000000000000esptool-ck-0.4.6/elf/esptool_elf.c000066400000000000000000000004731255710016000170270ustar00rootroot00000000000000#include "esptool_elf.h" #include "esptool_elf_enums.h" unsigned long elf_hash(const unsigned char *name) { unsigned long h = 0, g; while(*name) { h = (h << 4) + *name++; if((g = h & 0xF0000000)) { h ^= g >> 24; } h &= ~g; } return h; } esptool-ck-0.4.6/elf/esptool_elf.h000066400000000000000000000070131255710016000170310ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool_elf.h *** - defines, structs and other stuff to access ELF files *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ESPTOOL_ELF_H #define ESPTOOL_ELF_H #include #define Elf32_Addr uint32_t #define Elf32_Half uint16_t #define Elf32_Off uint32_t #define Elf32_Sword int32_t #define Elf32_Word uint32_t #define ELF32_ST_BIND(i) ((i)>>4) #define ELF32_ST_TYPE(i) ((i)&0x0F) #define ELF32_ST_INFO(b,t) (((b)<<4)+((t)&0x0F)) #define ELF32_R_SYM(i) ((i)>>8) #define ELF32_R_TYPE(i) ((unsigned char)(i)) #define ELF32_R_INFO(s,t) ((s)<<8)+(unsigned char)(t)) #define SIZE_EI_NIDENT 16 typedef struct { unsigned char e_ident[SIZE_EI_NIDENT]; Elf32_Half e_type; Elf32_Half e_machine; Elf32_Word e_version; Elf32_Addr e_entry; Elf32_Off e_phoff; Elf32_Off e_shoff; Elf32_Word e_flags; Elf32_Half e_ehsize; Elf32_Half e_phentsize; Elf32_Half e_phnum; Elf32_Half e_shentsize; Elf32_Half e_shnum; Elf32_Half e_shstrndx; } Elf32_Ehdr; typedef struct { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; Elf32_Addr sh_addr; Elf32_Off sh_offset; Elf32_Word sh_size; Elf32_Word sh_link; Elf32_Word sh_info; Elf32_Word sh_addralign; Elf32_Word sh_entsize; } Elf32_Shdr; typedef struct { Elf32_Word st_name; Elf32_Addr st_value; Elf32_Word st_size; unsigned char st_info; unsigned char st_other; Elf32_Half st_shndx; } Elf32_Sym; typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; } Elf32_Rel; typedef struct { Elf32_Addr r_offset; Elf32_Word r_info; Elf32_Sword r_addend; } Elf32_Rela; typedef struct { Elf32_Word p_type; Elf32_Off p_offset; Elf32_Addr p_vaddr; Elf32_Addr p_paddr; Elf32_Word p_filesz; Elf32_Word p_memsz; Elf32_Word p_flags; Elf32_Word p_align; } Elf32_Phdr; typedef struct { Elf32_Sword d_tag; union { Elf32_Word d_val; Elf32_Addr d_ptr; } d_un; } Elf32_Dyn; unsigned long elf_hash(const unsigned char *name); #endifesptool-ck-0.4.6/elf/esptool_elf_enums.h000066400000000000000000000114261255710016000202430ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool_elf_enums.h *** - various enumerations that appear in ELF formatted files *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ESPTOOL_ELF_ENUMS_H #define ESPTOOL_ELF_ENUMS_H enum { ET_NONE = 0, ET_REL = 1, ET_EXEC = 2, ET_DYN = 3, ET_CORE = 4, ET_LOPROC = 0xFF00, ET_HIPROC = 0xFFFF }; enum { EM_NONE = 0, EM_M32 = 1, EM_SPARC = 2, EM_386 = 3, EM_68K = 4, EM_88K = 5, EM_860 = 7, EM_MIPS = 8 }; enum { EV_NONE = 0, EV_CURRENT = 1 }; enum { EI_MAG0 = 0, EI_MAG1 = 1, EI_MAG2 = 2, EI_MAG3 = 3, EI_CLASS = 4, EI_DATA = 5, EI_VERSION = 6, EI_PAD = 7, EI_NIDENT = 16 }; enum { ELFCLASSNONE = 0, ELFCLASS32 = 1, ELFCLASS64 = 2 }; enum { ELFDATANONE = 0, ELFDATA2LSB = 1, ELFDATA2MSB = 2 }; enum { SHN_UNDEF = 0, SHN_LORESERVE = 0xFF00, SHN_LOPROC = 0xFF00, SHN_HIPROC = 0xFF1F, SHN_ABS = 0xFFF1, SHN_COMMON = 0xFFF2, SHN_HIRESERVE = 0xFFFF }; enum { SHT_NULL = 0, SHT_PROGBITS = 1, SHT_SYMTAB = 2, SHT_STRTAB = 3, SHT_RELA = 4, SHT_HASH = 5, SHT_DYNAMIC = 6, SHT_NOTE = 7, SHT_NOBITS = 8, SHT_REL = 9, SHT_SHLIB = 10, SHT_DYNSYM = 11, SHT_LOPROC = 0x70000000, SHT_HIPROC = 0x7FFFFFFF, SHT_LOUSER = 0x80000000, SHT_HIUSER = 0xFFFFFFFF }; enum { SHF_WRITE = 0x1, SHF_ALLOC = 0x2, SHF_EXECINSTR = 0x4, SHF_MASKPROC = 0xF0000000 }; enum { STB_LOCAL = 0, STB_GLOBAL = 1, STB_WEAK = 2, STB_LOPROC = 13, STB_HIPROC = 15 }; enum { STT_NOTYPE = 0, STT_OBJECT = 1, STT_FUNC = 2, STT_SECTION = 3, STT_FILE = 4, STT_LOPROC = 13, STT_HIPROC = 15 }; enum { R_386_NONE = 0, R_386_32 = 1, R_386_PC32 = 2, R_386_GOT32 = 3, R_386_PLT32 = 4, R_386_COPY = 5, R_386_GLOB_DAT = 6, R_386_JMP_SLOT = 7, R_386_RELATIVE = 8, R_386_GOTOFF = 9, R_386_GOTPC = 10, }; enum { PT_NULL = 0, PT_LOAD = 1, PT_DYNAMIC = 2, PT_INTERP = 3, PT_NOTE = 4, PT_SHLIB = 5, PT_PHDR = 6, PT_LOPROC = 0x70000000, PT_HIPROC = 0x7FFFFFFF, }; enum { DT_NULL = 0, DT_NEEDED = 1, DT_PLTRELSZ = 2, DT_PLTGOT = 3, DT_HASH = 4, DT_STRTAB = 5, DT_SYMTAB = 6, DT_RELA = 7, DT_RELASZ = 8, DT_RELAENT = 9, DT_STRSZ = 10, DT_SYMENT = 11, DT_INIT = 12, DT_FINI = 13, DT_SONAME = 14, DT_RPATH = 15, DT_SYMBOLIC = 16, DT_REL = 17, DT_RELSZ = 18, DT_RELENT = 19, DT_PLTREL = 20, DT_DEBUG = 21, DT_TEXTREL = 22, DT_JMPREL = 23, DT_LOPROC = 0x70000000, DT_HIPROC = 0x7FFFFFFF }; #endif esptool-ck-0.4.6/elf/esptool_elf_object.c000066400000000000000000000314611255710016000203560ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool_elf_object.c *** - implementation of various functions to access ELF object/executable files *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include "infohelper.h" #include "esptool_elf.h" #include "esptool_elf_object.h" #include "esptool_elf_enums.h" static ELF_Object e_object; static int check_elf_header(void) { if(fread( (char*) &e_object.header, 1, sizeof(Elf32_Ehdr), e_object.e_file) != sizeof(Elf32_Ehdr)) { LOGERR("can't read ELF file header"); return 0; } if(e_object.header.e_ident[EI_MAG0] == 0x7F && e_object.header.e_ident[EI_MAG1] == 'E' && e_object.header.e_ident[EI_MAG2] == 'L' && e_object.header.e_ident[EI_MAG3] == 'F') { return 1; } return 0; } void get_elf_strings(void) { if(e_object.header.e_shstrndx) { if(fseek(e_object.e_file, e_object.header.e_shoff+(e_object.header.e_shstrndx*e_object.header.e_shentsize), SEEK_SET) != 0) { LOGERR("can't seek to stringtable section info in ELF file"); return; } if(fread((char*)&e_object.section, 1, sizeof(Elf32_Shdr), e_object.e_file) != sizeof(Elf32_Shdr) ) { LOGERR("can't read stringtable section info from ELF file!"); return; } if(e_object.section.sh_size) { LOGDEBUG("loading string table from ELF file"); e_object.strings = malloc(e_object.section.sh_size); if(e_object.strings == NULL) { LOGERR("can't malloc memory for stringtable of ELF file"); return; } if(fseek(e_object.e_file, e_object.section.sh_offset, SEEK_SET) != 0) { LOGERR("can't seek to stringtable section info in ELF file"); return; } if( fread(e_object.strings, 1, e_object.section.sh_size, e_object.e_file) != e_object.section.sh_size) { LOGERR("can't read stringtable from ELF file!"); return; } } } } void collect_elf_sections(void) { unsigned int cnt; e_object.sections = malloc(e_object.header.e_shnum*sizeof(ELF_section)); if(e_object.sections == NULL) { LOGERR("can't malloc memory for ELF section list"); return; } if(e_object.sections) { if(e_object.header.e_shnum) { LOGDEBUG("building ELF section list"); for(cnt = 1; cnt < e_object.header.e_shnum; cnt++) { if(fseek(e_object.e_file, e_object.header.e_shoff+(cnt*e_object.header.e_shentsize), SEEK_SET) != 0) { LOGERR("can't seek to ELF file section info #%i", cnt); return; } if(fread((char*)&e_object.section, 1, sizeof(Elf32_Shdr), e_object.e_file) != sizeof(Elf32_Shdr)) { LOGERR("can't read section info #%i from ELF file", cnt); return; } if(e_object.section.sh_name) { e_object.sections[cnt-1].name = e_object.strings+e_object.section.sh_name; } else { e_object.sections[cnt-1].name = 0; } e_object.sections[cnt-1].offset = e_object.section.sh_offset; e_object.sections[cnt-1].address = e_object.section.sh_addr; e_object.sections[cnt-1].size = e_object.section.sh_size; } LOGDEBUG("ELF section list created: %i entries", e_object.header.e_shnum-1); } else { LOGDEBUG("no sections in ELF object"); } } else { LOGERR("can't malloc memory for ELF sections list"); } } void list_elf_sections(void) { unsigned int cnt; for(cnt = 1; cnt < e_object.header.e_shnum; cnt++) { LOGVERBOSE("ADDR: 0x%08X - SIZE: 0x%08X - OFFSET: 0x%08X - Name: %s", e_object.sections[cnt-1].address, e_object.sections[cnt-1].size, e_object.sections[cnt-1].offset, e_object.sections[cnt-1].name); } } void print_elf_section_info(Elf32_Half secnum) { if(secnum && secnum < e_object.header.e_shnum) { if(fseek(e_object.e_file, e_object.header.e_shoff+(secnum*e_object.header.e_shentsize), SEEK_SET) != 0) { LOGERR("can't seek to ELF file section info %i", secnum); return; } if(fread((char*)&e_object.section, 1, sizeof(Elf32_Shdr), e_object.e_file) != sizeof(Elf32_Shdr)) { LOGERR("can't read ELF file section info %i", secnum); return; } if(e_object.section.sh_name) { LOGVERBOSE("section name : %s", e_object.strings+e_object.section.sh_name); } else { LOGVERBOSE("section name : "); } LOGVERBOSE("sh_name : 0x%08X", e_object.section.sh_name); LOGVERBOSE("sh_type : 0x%08X", e_object.section.sh_type); LOGVERBOSE("sh_flags : 0x%08X", e_object.section.sh_flags); LOGVERBOSE("sh_addr : 0x%08X", e_object.section.sh_addr); LOGVERBOSE("sh_offset : 0x%08X", e_object.section.sh_offset); LOGVERBOSE("sh_size : 0x%08X", e_object.section.sh_size); LOGVERBOSE("sh_link : 0x%08X", e_object.section.sh_link); LOGVERBOSE("sh_info : 0x%08X", e_object.section.sh_info); LOGVERBOSE("sh_addralign : 0x%08X", e_object.section.sh_addralign); LOGVERBOSE("sh_entsize : 0x%08X", e_object.section.sh_entsize); } } int get_elf_num_sections(void) { return e_object.header.e_shnum; } int get_elf_secnum_by_name(const char *secname) { unsigned int cnt; for(cnt = 1; cnt < e_object.header.e_shnum; cnt++) { if( strcmp(e_object.sections[cnt-1].name, secname) == 0) { LOGVERBOSE("found section %s at index %i", secname, cnt); return cnt; } } return 0; } unsigned char* get_elf_section_bindata(Elf32_Half secnum, uint32_t pad_to) { unsigned char *bindata; uint32_t pad_pos; if(secnum && secnum < e_object.header.e_shnum) { if(e_object.sections[secnum-1].size) { if(e_object.sections[secnum-1].size < pad_to) { LOGVERBOSE("padding section #%i binary data (size 0x%08X) with %i bytes", secnum, e_object.sections[secnum-1].size, (pad_to-e_object.sections[secnum-1].size)); bindata = malloc(pad_to); } else { bindata = malloc(e_object.sections[secnum-1].size); } if(bindata == NULL) { LOGERR("can't malloc memory for ELF section %d binary data", secnum); return 0; } if(fseek(e_object.e_file, e_object.sections[secnum-1].offset, SEEK_SET) != 0) { LOGERR("can't seek to ELF file section %i binary datai", secnum); return 0; } if(fread(bindata, 1, e_object.sections[secnum-1].size, e_object.e_file) != e_object.sections[secnum-1].size) { LOGERR("can't read section #%i binary data from ELF file", secnum); return 0; } for(pad_pos = e_object.sections[secnum-1].size; pad_pos < pad_to; pad_pos++) { bindata[pad_pos] = 0x00; } return bindata; } } return 0; } int save_elf_section_bindata( const char *secname, const char *fname ) { FILE *f; unsigned char *binblob; uint32_t secnum; secnum = get_elf_secnum_by_name(secname); binblob = get_elf_section_bindata(secnum, 0); if(binblob) { f = fopen( fname, "wb" ); if(f == NULL) { LOGERR("can't open file \"%s\" to save binary dump of ELF section \"%s\"", fname, e_object.sections[secnum-1].name); free(binblob); return 0; } if( fwrite(binblob, 1, e_object.sections[secnum-1].size, f) != e_object.sections[secnum-1].size) { LOGERR("can't open file \"%s\" to save binary dump of ELF section \"%s\"", fname, e_object.sections[secnum-1].name); fclose(f); free(binblob); return 0; } fclose(f); free(binblob); LOGINFO("saved section \"%s\" to file \"%s\"", e_object.sections[secnum-1].name, fname); } return 1; } Elf32_Word get_elf_section_size(Elf32_Half secnum) { if(secnum && secnum < e_object.header.e_shnum) { return e_object.sections[secnum-1].size; } return 0; } Elf32_Word get_elf_section_addr(Elf32_Half secnum) { if(secnum && secnum < e_object.header.e_shnum) { return e_object.sections[secnum-1].address; } return 0; } const char* get_elf_section_name(Elf32_Half secnum) { if(secnum && secnum < e_object.header.e_shnum) { return e_object.sections[secnum-1].name; } return 0; } Elf32_Word get_elf_entry(void) { return e_object.header.e_entry; } int create_elf_object(const char *filename) { if(e_object.e_file) { return 0; } e_object.strings = 0; e_object.e_file = 0; e_object.e_file = fopen(filename, "rb"); if(e_object.e_file) { LOGINFO("using ELF file \"%s\"", filename); if( check_elf_header() ) { LOGDEBUG("ELF header OK"); LOGVERBOSE("e_type : 0x%04X", e_object.header.e_type); LOGVERBOSE("e_machine : 0x%04X", e_object.header.e_machine); LOGVERBOSE("e_version : 0x%08X", e_object.header.e_version); LOGVERBOSE("e_entry : 0x%08X", e_object.header.e_entry); LOGVERBOSE("e_phoff : 0x%08X", e_object.header.e_phoff); LOGVERBOSE("e_shoff : 0x%08X", e_object.header.e_shoff); LOGVERBOSE("e_flags : 0x%08X", e_object.header.e_flags); LOGVERBOSE("e_ehsize : 0x%04X", e_object.header.e_ehsize); LOGVERBOSE("e_phentsize : 0x%04X", e_object.header.e_phentsize); LOGVERBOSE("e_phnum : 0x%04X", e_object.header.e_phnum); LOGVERBOSE("e_shentsize : 0x%04X", e_object.header.e_shentsize); LOGVERBOSE("e_shnum : 0x%04X", e_object.header.e_shnum); LOGVERBOSE("e_shstrndx : 0x%04X", e_object.header.e_shstrndx); get_elf_strings(); collect_elf_sections(); return 1; } else { LOGERR("wrong header for ELF file!"); } } else { LOGERR("can't open ELF file %s", filename); } return 0; } int close_elf_object(void) { if(e_object.strings) { LOGDEBUG("releasing memory from ELF file stringtable"); free(e_object.strings); e_object.strings = 0; } if(e_object.sections) { LOGDEBUG("releasing memory from ELF file section info"); free(e_object.sections); e_object.sections = 0; } if(e_object.e_file) { LOGDEBUG("closing ELF file"); fclose(e_object.e_file); e_object.e_file = 0; } else { return 0; } return 1; } esptool-ck-0.4.6/elf/esptool_elf_object.h000066400000000000000000000076571255710016000203750ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool_elf_object.h *** - defines and prototypes for accessing ELF object/executable files *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ESPTOOL_ELF_OBJECT_H #define ESPTOOL_ELF_OBJECT_H #include #include /* ** structs used to hold a local ELF cache object of the informations ** retrieved from the firmware ELF file */ /* ** struct holding the information of a given section according to ** what is found in the ELF file */ typedef struct { const char *name; Elf32_Word offset; Elf32_Addr address; Elf32_Word size; } ELF_section; /* ** struct defining the local ELF cache object and whatever sections it has */ typedef struct { FILE *e_file; Elf32_Ehdr header; Elf32_Shdr section; ELF_section *sections; char *strings; } ELF_Object; /* ** creates a local ELF cache object ** filename: the name of the ELF file on disk */ int create_elf_object(const char *filename); /* ** cleanup and release allocated memory for the ELF cahce object ** also closes the the ELF file on disk */ int close_elf_object(void); /* ** list of all section information that is in the ELF cache object */ void list_elf_sections(void); /* ** print the information of a given section header in the ELF cache object ** secnum: the index position of the section header to query */ void print_elf_section_info( Elf32_Half secnum ); /* ** return the number of section header stored in the ELF cache object */ int get_elf_num_sections(void); /* ** retrieve the index position of a section, searched for by the sections name ** secname: the neame of the section to look up */ int get_elf_secnum_by_name(const char *secname); /* ** retrieve the binary data of a section ** allocates the memory required for this and returns a pointer to that byte array ** secnum: index number of the section from which the binary data should be retrieved ** pad_to: minimum blocksize in-powers-of-two to pad the resulting array to */ unsigned char* get_elf_section_bindata(Elf32_Half secnum, uint32_t pad_to); /* ** dump the binary data of a section into a file on disk ** secname: the name of the section to read and write out ** fname: the name of the file to write to */ int save_elf_section_bindata(const char *secname, const char *fname); /* ** retrieve the size of the binary data for a section ** secnum: index position of the section */ Elf32_Word get_elf_section_size(Elf32_Half secnum); /* ** retrieve the memory addres as specified in the ELF cache object of the binary data for a section ** secnum: index position of the section */ Elf32_Word get_elf_section_addr(Elf32_Half secnum); /* ** retrieve the code entry point of the ELF file */ Elf32_Word get_elf_entry(void); /* ** retrieve the name of a section ** secnum: index position of the section ** returns a pointer to a string representing the name */ const char* get_elf_section_name(Elf32_Half secnum); #endif esptool-ck-0.4.6/espcomm/000077500000000000000000000000001255710016000152415ustar00rootroot00000000000000esptool-ck-0.4.6/espcomm/delay.c000066400000000000000000000023271255710016000165070ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** delay.c *** - cross-platform delay function *** *** Copyright (C) 2015 Ivan Grokhotkov *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #if defined (WINDOWS) #include void espcomm_delay_ms(int ms) { Sleep(ms); } #else void espcomm_delay_ms(int ms) { usleep(ms * 1000); } #endif esptool-ck-0.4.6/espcomm/delay.h000066400000000000000000000022021255710016000165040ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** delay.h *** - cross-platform delay function *** *** Copyright (C) 2015 Ivan Grokhotkov *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef DELAY_H #define DELAY_H void espcomm_delay_ms(int ms); #endif//DELAY_H esptool-ck-0.4.6/espcomm/espcomm.c000066400000000000000000000350471255710016000170610ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** espcomm.c *** - routines to access the bootloader in the ESP *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include #include #include #include #include #include #include "infohelper.h" #include "espcomm.h" #include "serialport.h" #include "espcomm_boards.h" #include "delay.h" bootloader_packet send_packet; bootloader_packet receive_packet; static espcomm_board_t* espcomm_board = 0; static bool sync_stage = false; static bool upload_stage = false; static bool espcomm_is_open = false; static const char *espcomm_port = #if defined(LINUX) "/dev/ttyUSB0"; #elif defined(WINDOWS) "COM1"; #elif defined(OSX) "/dev/tty.usbserial"; #else ""; #endif static unsigned int espcomm_baudrate = 115200; static uint32_t espcomm_address = 0x00000; static unsigned char sync_frame[36] = { 0x07, 0x07, 0x12, 0x20, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55, 0x55 }; static uint32_t flash_packet[BLOCKSIZE_FLASH+32]; //static uint32_t ram_packet[BLOCKSIZE_RAM+32]; static int file_uploaded = 0; static void espcomm_enter_boot(void) { espcomm_board_reset_into_bootloader(espcomm_board); } static void espcomm_reset_to_exec(void) { espcomm_board_reset_into_app(espcomm_board); } uint32_t espcomm_calc_checksum(unsigned char *data, uint16_t data_size) { uint16_t cnt; uint32_t result; result = 0xEF; for(cnt = 0; cnt < data_size; cnt++) { result ^= data[cnt]; } return result; } static uint32_t espcomm_send_command(unsigned char command, unsigned char *data, uint16_t data_size, int reply_timeout) { uint32_t result; uint32_t cnt; result = 0; if (command != NO_COMMAND) { send_packet.direction = 0x00; send_packet.command = command; send_packet.size = data_size; serialport_send_C0(); if (!upload_stage) LOGDEBUG("espcomm_send_command: sending command header"); else LOGVERBOSE("espcomm_send_command: sending command header"); serialport_send_slip((unsigned char*) &send_packet, 8); if(data_size) { if (!upload_stage) LOGDEBUG("espcomm_send_command: sending command payload"); else LOGVERBOSE("espcomm_send_command: sending command payload"); serialport_send_slip(data, data_size); } else { LOGDEBUG("espcomm_send_command: no payload"); } serialport_send_C0(); } espcomm_delay_ms(5); serialport_drain(); int old_timeout = 0; if (reply_timeout) { old_timeout = serialport_get_timeout(); serialport_set_timeout(reply_timeout); } if(serialport_receive_C0()) { if (old_timeout) serialport_set_timeout(old_timeout); if(serialport_receive_slip((unsigned char*) &receive_packet, 8)) { if(receive_packet.size) { if (!upload_stage) LOGDEBUG("espcomm_send_command: receiving %i bytes of data", receive_packet.size); else LOGVERBOSE("espcomm_send_command: receiving %i bytes of data", receive_packet.size); if(receive_packet.data) { free(receive_packet.data); receive_packet.data = NULL; } receive_packet.data = malloc(receive_packet.size); if(serialport_receive_slip(receive_packet.data, receive_packet.size) == 0) { LOGWARN("espcomm_send_command: cant receive slip payload data"); return 0; } else { LOGVERBOSE("espcomm_send_command: received %x bytes: ", receive_packet.size); for(cnt = 0; cnt < receive_packet.size; cnt++) { LOGVERBOSE("0x%02X ", receive_packet.data[cnt]); } } } if(serialport_receive_C0()) { if(receive_packet.direction == 0x01 && (command == NO_COMMAND || receive_packet.command == command)) { result = receive_packet.response; } else { LOGWARN("espcomm_send_command: wrong direction/command: 0x%02X 0x%02X, expected 0x%02X 0x%02X", receive_packet.direction, receive_packet.command, 1, command); return 0; } } else { if (!sync_stage) LOGWARN("espcomm_send_command: no final C0"); else LOGVERBOSE("espcomm_send_command: no final C0"); return 0; } } else { LOGWARN("espcomm_send_command: can't receive command response header"); return 0; } } else { if (old_timeout) serialport_set_timeout(old_timeout); if (!sync_stage) LOGWARN("espcomm_send_command: didn't receive command response"); else LOGVERBOSE("espcomm_send_command: didn't receive command response"); return 0; } LOGVERBOSE("espcomm_send_command: response 0x%08X", result); return result; } static int espcomm_sync(void) { sync_stage = true; for (int retry_boot = 0; retry_boot < 3; ++retry_boot) { LOGINFO("resetting board"); espcomm_enter_boot(); for (int retry_sync = 0; retry_sync < 3; ++retry_sync) { LOGINFO("trying to connect"); espcomm_delay_ms(100); serialport_flush(); send_packet.checksum = espcomm_calc_checksum((unsigned char*)&sync_frame, 36); if(espcomm_send_command(SYNC_FRAME, (unsigned char*) &sync_frame, 36, 0) == 0x20120707) { bool error = false; for (int i = 0; i < 7; ++i) { if (espcomm_send_command(NO_COMMAND, 0, 0, 0) != 0x20120707) { error = true; break; } } if (!error) { sync_stage = false; return 1; } } } } sync_stage = false; LOGWARN("espcomm_sync failed"); return 0; } int espcomm_open(void) { if (espcomm_is_open) return 1; if(serialport_open(espcomm_port, espcomm_baudrate)) { LOGINFO("opening bootloader"); if (espcomm_sync()) { espcomm_is_open = true; return 1; } } return 0; } void espcomm_close(void) { LOGINFO("closing bootloader"); serialport_close(); } int espcomm_start_flash(uint32_t size, uint32_t address) { uint32_t res; LOGDEBUG("size: %06x address: %06x", size, address); const int sector_size = 4096; const int sectors_per_block = 16; const int first_sector_index = address / sector_size; LOGDEBUG("first_sector_index: %d", first_sector_index); const int total_sector_count = ((size % sector_size) == 0) ? (size / sector_size) : (size / sector_size + 1); LOGDEBUG("total_sector_count: %d", total_sector_count); const int max_head_sector_count = sectors_per_block - (first_sector_index % sectors_per_block); const int head_sector_count = (max_head_sector_count > total_sector_count) ? total_sector_count : max_head_sector_count; LOGDEBUG("head_sector_count: %d", head_sector_count); // SPIEraseArea function in the esp8266 ROM has a bug which causes extra area to be erased. // If the address range to be erased crosses the block boundary, // then extra head_sector_count sectors are erased. // If the address range doesn't cross the block boundary, // then extra total_sector_count sectors are erased. const int adjusted_sector_count = (total_sector_count > 2 * head_sector_count) ? (total_sector_count - head_sector_count): (total_sector_count + 1) / 2; LOGDEBUG("adjusted_sector_count: %d", adjusted_sector_count); const int adjusted_size = adjusted_sector_count * sector_size; LOGDEBUG("adjusted_size: %06x", adjusted_size); flash_packet[0] = adjusted_size; flash_packet[1] = 0x00000200; flash_packet[2] = BLOCKSIZE_FLASH; flash_packet[3] = address; send_packet.checksum = espcomm_calc_checksum((unsigned char*) flash_packet, 16); // int timeout_ms = size / erase_block_size * delay_per_erase_block_ms + 250; int timeout_ms = 10000; // LOGDEBUG("calculated erase delay: %dms", timeout_ms); res = espcomm_send_command(FLASH_DOWNLOAD_BEGIN, (unsigned char*) &flash_packet, 16, timeout_ms); return res; } int espcomm_upload_file(char *name) { LOGDEBUG("espcomm_upload_file"); FILE *f; struct stat st; uint32_t fsize; uint32_t fdone; uint32_t write_size; uint32_t cnt; uint32_t res; if(stat(name, &st) == 0) { LOGDEBUG("stat %s success", name); if(espcomm_open()) { LOGDEBUG("espcomm_open"); fsize = (uint32_t) st.st_size; f = fopen( name, "rb"); cnt = 0; flash_packet[0] = 0; flash_packet[1] = 0; flash_packet[2] = 0; flash_packet[3] = 0; if(f) { fdone = 0; INFO("Uploading %i bytes from %s to flash at 0x%08X\n", fsize, name, espcomm_address); LOGDEBUG("erasing flash"); res = espcomm_start_flash(fsize, espcomm_address); if (res == 0) { LOGWARN("espcomm_send_command(FLASH_DOWNLOAD_BEGIN) failed"); fclose(f); espcomm_close(); return 0; } LOGDEBUG("writing flash"); upload_stage = true; while(fsize) { memset(&flash_packet[4], 0xff, BLOCKSIZE_FLASH); write_size = (uint32_t) fread(&flash_packet[4], 1, BLOCKSIZE_FLASH, f); fsize -= write_size; flash_packet[0] = BLOCKSIZE_FLASH; flash_packet[1] = cnt; flash_packet[2] = 0; flash_packet[3] = 0; send_packet.checksum = espcomm_calc_checksum((unsigned char *) &flash_packet[4], flash_packet[0]); res = espcomm_send_command(FLASH_DOWNLOAD_DATA, (unsigned char*) &flash_packet, flash_packet[0]+16, 0); if(res == 0) { LOGWARN("espcomm_send_command(FLASH_DOWNLOAD_DATA) failed"); res = espcomm_send_command(FLASH_DOWNLOAD_DONE, (unsigned char*) &flash_packet, 4, 0); fclose(f); espcomm_close(); upload_stage = false; return 0; } cnt++; fdone += write_size; INFO("."); fflush(stdout); } upload_stage = false; INFO("\n"); } file_uploaded = 1; fclose(f); //espcomm_close(); return 1; } else { LOGERR("espcomm_open failed"); } } else { LOGERR("stat %s failed", name); } return 0; } int espcomm_start_app(int reboot) { if(!espcomm_open()) { LOGDEBUG("espcomm_open failed"); } if (reboot) { LOGINFO("starting app with reboot"); flash_packet[0] = 0; } else { LOGINFO("starting app without reboot"); flash_packet[0] = 1; } espcomm_send_command(FLASH_DOWNLOAD_DONE, (unsigned char*) &flash_packet, 4, 0); file_uploaded = 0; espcomm_close(); return 1; } int espcomm_file_uploaded() { return file_uploaded; } int espcomm_set_port(char *port) { LOGDEBUG("setting port from %s to %s", espcomm_port, port); espcomm_port = port; return 1; } int espcomm_set_baudrate(const char *baudrate) { uint32_t new_baudrate = (uint32_t) strtol(baudrate, NULL, 10); LOGDEBUG("setting baudrate from %i to %i", espcomm_baudrate, new_baudrate); espcomm_baudrate = new_baudrate; return 1; } int espcomm_set_address(const char *address) { uint32_t new_address = (uint32_t) strtol(address, NULL, 16); LOGDEBUG("setting address from 0x%08X to 0x%08X", espcomm_address, new_address); espcomm_address = new_address; return 1; } int espcomm_set_board(const char* name) { LOGDEBUG("setting board to %s", name); espcomm_board = espcomm_board_by_name(name); if (!espcomm_board) { LOGERR("unknown board: %s", name); INFO("known boards are: "); for (espcomm_board_t* b = espcomm_board_first(); b; b = espcomm_board_next(b)) { INFO("%s ", espcomm_board_name(b)); } INFO("\n"); } return 1; } esptool-ck-0.4.6/espcomm/espcomm.h000066400000000000000000000043261255710016000170620ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** espcomm.h *** - include file for espcomm.c *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ESPCOMM_H #define ESPCOMM_H enum { CMD0 = 0x00, CMD1 = 0x01, FLASH_DOWNLOAD_BEGIN = 0x02, FLASH_DOWNLOAD_DATA = 0x03, FLASH_DOWNLOAD_DONE = 0x04, RAM_DOWNLOAD_BEGIN = 0x05, RAM_DOWNLOAD_END = 0x06, RAM_DOWNLOAD_DATA = 0x07, SYNC_FRAME = 0x08, WRITE_REGISTER = 0x09, READ_REGISTER = 0x0A, NO_COMMAND = 0xFF }; typedef struct { uint8_t direction; uint8_t command; uint16_t size; union { uint32_t checksum; uint32_t response; }; unsigned char *data; } bootloader_packet; #define BLOCKSIZE_FLASH 0x0400 #define BLOCKSIZE_RAM 0x1800 int espcomm_set_port(char *port); int espcomm_set_baudrate(const char *baudrate); int espcomm_set_address(const char *address); int espcomm_set_board(const char* name); int espcomm_open(void); void espcomm_close(void); int espcomm_upload_file(char *name); int espcomm_file_uploaded(); int espcomm_start_app(int reboot); #endif esptool-ck-0.4.6/espcomm/espcomm_boards.c000066400000000000000000000054621255710016000204110ustar00rootroot00000000000000#include #include #include "espcomm_boards.h" #include "serialport.h" #include "delay.h" struct espcomm_board_ { const char* name; void (*reset_into_bootloader)(void); void (*reset_into_app)(void); }; static espcomm_board_t s_boards[]; static size_t s_boards_count; espcomm_board_t* espcomm_board_by_name(const char* name) { for (size_t i = 0; i < s_boards_count; ++i) { espcomm_board_t* board = s_boards + i; if (strcmp(board->name, name) == 0) return board; } return 0; } espcomm_board_t* espcomm_board_first() { return s_boards; } espcomm_board_t* espcomm_board_next(espcomm_board_t* board) { if (++board < s_boards + s_boards_count) return board; return 0; } const char* espcomm_board_name(espcomm_board_t* board) { return (board)?board->name:""; } void espcomm_board_reset_into_bootloader(espcomm_board_t* board) { if (board && board->reset_into_bootloader) (*board->reset_into_bootloader)(); } void espcomm_board_reset_into_app(espcomm_board_t* board) { if (board && board->reset_into_app) (*board->reset_into_app)(); } /// board definitions go below // // _rb = reset into bootloader // _ra = reset into app // // // "ck" board: dtr pulls down gpio0, rts pulls down reset // also supports reset with RC circuit triggered by break signal void board_ck_rb() { serialport_set_rts(1); serialport_set_dtr(1); serialport_send_break(); espcomm_delay_ms(5); serialport_set_rts(0); espcomm_delay_ms(250); // wait for break to finish serialport_set_dtr(0); } void board_ck_ra() { serialport_set_dtr(0); serialport_set_rts(1); espcomm_delay_ms(5); serialport_set_rts(0); } // WIFIO board, rev 2: TXD controls gpio0 via a pnp, and DTR controls rst via a capacitor void board_wifio_rb() { serialport_set_dtr(0); espcomm_delay_ms(5); serialport_set_dtr(1); espcomm_delay_ms(5); serialport_set_dtr(0); serialport_send_break(); } void board_wifio_ra() { serialport_set_dtr(0); espcomm_delay_ms(5); serialport_set_dtr(1); } void board_nodemcu_rb() { serialport_set_rts(1); serialport_set_dtr(0); espcomm_delay_ms(5); serialport_set_rts(0); serialport_set_dtr(1); espcomm_delay_ms(50); serialport_set_rts(0); } void board_nodemcu_ra() { serialport_set_dtr(0); serialport_set_rts(1); espcomm_delay_ms(5); serialport_set_rts(0); } /// list of all boards static espcomm_board_t s_boards[] = { { "none", 0, 0 }, { "ck", &board_ck_rb, &board_ck_ra }, { "wifio", &board_wifio_rb, &board_wifio_ra}, { "nodemcu", &board_nodemcu_rb, &board_nodemcu_ra}, }; static size_t s_boards_count = sizeof(s_boards) / sizeof(espcomm_board_t); esptool-ck-0.4.6/espcomm/espcomm_boards.h000066400000000000000000000030541255710016000204110ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** espcomm_boards.h *** - board-specific upload methods interface *** *** Copyright (C) 2015 Ivan Grokhotkov *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef ESPCOMM_BOARDS_H #define ESPCOMM_BOARDS_H struct espcomm_board_; typedef struct espcomm_board_ espcomm_board_t; espcomm_board_t* espcomm_board_by_name(const char* name); espcomm_board_t* espcomm_board_first(); espcomm_board_t* espcomm_board_next(espcomm_board_t* board); const char* espcomm_board_name(espcomm_board_t* board); void espcomm_board_reset_into_bootloader(espcomm_board_t* board); void espcomm_board_reset_into_app(espcomm_board_t* board); #endif//ESPCOMM_BOARDS_H esptool-ck-0.4.6/infohelper/000077500000000000000000000000001255710016000157315ustar00rootroot00000000000000esptool-ck-0.4.6/infohelper/infohelper.c000066400000000000000000000047511255710016000202370ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** infohelper.c *** - implementation of a crude verbosity-controllabe info system *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include "infohelper.h" static char infolevel = 0; void infohelper_set_infolevel(char lvl) { infolevel = lvl; } void infohelper_increase_infolevel(void) { if(infolevel < 20) { infolevel++; } } void infohelper_set_argverbosity(int num_args, char **arg_ptr) { char *cur_arg; while(num_args--) { cur_arg = arg_ptr[num_args]; if(*cur_arg++ == '-') { if(*cur_arg == 'q') { infolevel = 0; return; } else while(*cur_arg++ == 'v') { infolevel++; } } } } void infohelper_output(int loglevel, const char* format, ...) { if (infolevel < loglevel) return; const char* log_level_names[] = {"error: ", "warning: ", "", "\t", "\t\t"}; const int log_level_names_count = sizeof(log_level_names) / sizeof(const char*); if (loglevel >= log_level_names_count) loglevel = log_level_names_count - 1; va_list v; printf("%s", log_level_names[loglevel]); va_start(v, format); vprintf(format, v); va_end(v); printf("\n"); } void infohelper_output_plain(int loglevel, const char* format, ...) { if (infolevel < loglevel) return; va_list v; va_start(v, format); vprintf(format, v); va_end(v); } esptool-ck-0.4.6/infohelper/infohelper.h000066400000000000000000000040251255710016000202360ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** infohelper.h *** - defines and prototypes for a crude verbositiy-controllabe info output *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef INFOHELPER_H #define INFOHELPER_H /* ** set verbositiy level ** 0 = only error messages ** 1 = warnings ** 2 = information messages (default) ** 3 = debugging info ** 4 = extra debugging info */ void infohelper_set_infolevel(char lvl); /* ** increase verbositylevel by 1 */ void infohelper_increase_infolevel(void); /* ** set verbosity level according to arguments given */ void infohelper_set_argverbosity(int num_args, char **arg_ptr); void infohelper_output(int loglevel, const char* format, ...); void infohelper_output_plain(int loglevel, const char* format, ...); #define LOGERR(...) infohelper_output(0, __VA_ARGS__) #define LOGWARN(...) infohelper_output(1, __VA_ARGS__) #define LOGINFO(...) infohelper_output(2, __VA_ARGS__) #define LOGDEBUG(...) infohelper_output(3, __VA_ARGS__) #define LOGVERBOSE(...) infohelper_output(4, __VA_ARGS__) #define INFO(...) infohelper_output_plain(0, __VA_ARGS__) #endif esptool-ck-0.4.6/local/000077500000000000000000000000001255710016000146705ustar00rootroot00000000000000esptool-ck-0.4.6/local/Makefile.local.LINUX000066400000000000000000000001231255710016000203130ustar00rootroot00000000000000TARGET = esptool INSTALLDIR_BIN = /usr/local/bin TARGET_FLAGS = TARGET_CFLAGS = esptool-ck-0.4.6/local/Makefile.local.OSX000066400000000000000000000004111255710016000200650ustar00rootroot00000000000000TARGET = esptool INSTALLDIR_BIN = /usr/local/bin CC=clang CXX=clang++ TARGET_FLAGS = TARGET_CFLAGS = -mmacosx-version-min=10.6 -arch i386 -arch x86_64 TARGET_CXXFLAGS = -mmacosx-version-min=10.6 -arch i386 -arch x86_64 TARGET_LDFLAGS = -arch i386 -arch x86_64 esptool-ck-0.4.6/local/Makefile.local.WINDOWS000066400000000000000000000001441255710016000205510ustar00rootroot00000000000000TARGET = esptool.exe INSTALLDIR_BIN = ~ TARGET_FLAGS = -Wl,-static -static-libgcc TARGET_CFLAGS = esptool-ck-0.4.6/main.c000066400000000000000000000044071255710016000146730ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** esptool main routine *** - parses the command line parameters and executes the given commands *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include #include #include "infohelper.h" #include "argparse.h" #include "espcomm.h" #include "elf/esptool_elf.h" #include "elf/esptool_elf_object.h" #include "binimage/esptool_binimage.h" int main(int argc, char **argv) { int num_args; int num_args_parsed; char **arg_ptr; num_args = argc-1; arg_ptr = argv; arg_ptr++; if(argc < 2) { LOGERR("No arguments given"); return 0; } infohelper_set_infolevel(1); infohelper_set_argverbosity(num_args, arg_ptr); LOGINFO("esptool v" VERSION " - (c) 2014 Ch. Klippel "); while(num_args) { num_args_parsed = parse_arg(num_args, arg_ptr); if(num_args_parsed == 0) { goto EXITERROR; } num_args -= num_args_parsed; arg_ptr += num_args_parsed; } if (espcomm_file_uploaded()) { espcomm_start_app(0); } close_elf_object(); binimage_write_close(16); return 0; EXITERROR: close_elf_object(); binimage_write_close(16); return -1; } esptool-ck-0.4.6/serialport/000077500000000000000000000000001255710016000157625ustar00rootroot00000000000000esptool-ck-0.4.6/serialport/serialport.c000066400000000000000000000352361255710016000203230ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** serialport.c *** - low level functions to access the serial port *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #include #include #include #include #if defined (_WIN32) #include #else #include #include #include #include #include #include #endif #include "serialport.h" #include "infohelper.h" #if defined (_WIN32) static HANDLE sPort = NULL; static DCB sDCB; static COMMTIMEOUTS sTIMEOUTS; #else static int serial_port = -1; static struct termios term; static unsigned int timeout; #endif #ifdef _WIN32 #ifndef CBR_230400 #define CBR_230400 230400 #endif #ifndef CBR_460800 #define CBR_460800 460800 #endif #ifndef CBR_512000 #define CBR_512000 512000 #endif #ifndef CBR_921600 #define CBR_921600 921600 #endif void serialport_setbaudrate(unsigned int baudrate) { DWORD br = 0; switch(baudrate) { case 9600: br = CBR_9600; break; case 14400: br = CBR_14400; break; case 19200: br = CBR_19200; break; case 38400: br = CBR_38400; break; case 56000: br = CBR_56000; break; case 57600: br = CBR_57600; break; case 115200: br = CBR_115200; break; case 128000: br = CBR_128000; break; case 230400: br = CBR_230400; break; case 256000: br = CBR_256000; break; case 512000: br = CBR_512000; break; case 460800: br = CBR_460800; break; case 921600: br = CBR_921600; break; } if (br == 0) { LOGWARN("unsupported baud rate: %d, using 115200", baudrate); br = CBR_115200; } memset(&sDCB, 0, sizeof(DCB)); BuildCommDCB("baud=9600 parity=N data=8 stop=1",&sDCB); sDCB.DCBlength = sizeof(DCB); sDCB.BaudRate = br; sDCB.fBinary = TRUE; sDCB.fParity = FALSE; // sDCB.fOutxCtsFlow = TRUE; sDCB.fDtrControl = DTR_CONTROL_DISABLE; sDCB.fDsrSensitivity= FALSE; sDCB.fRtsControl = RTS_CONTROL_DISABLE; sDCB.ByteSize = 8; sDCB.StopBits = ONESTOPBIT; sDCB.fAbortOnError = FALSE; sDCB.fOutX = FALSE; sDCB.fInX = FALSE; if (!SetCommState(sPort, &sDCB)) { LOGDEBUG("SetCommState call failed"); } } int serialport_open(const char *device, unsigned int baudrate) { char portName[40]; sprintf(portName,"\\\\.\\%s", device); sPort = CreateFile(portName, GENERIC_WRITE|GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (sPort == INVALID_HANDLE_VALUE) { LOGERR("Failed to open %s", device); return 0; } SetupComm(sPort, 256, 256); serialport_setbaudrate(baudrate); serialport_set_timeout(1000); return 1; } void serialport_set_timeout(unsigned int timeout) { LOGDEBUG("setting serial port timeouts to %d ms", timeout); sTIMEOUTS.ReadIntervalTimeout = 0; sTIMEOUTS.ReadTotalTimeoutConstant = timeout; sTIMEOUTS.ReadTotalTimeoutMultiplier = 0; sTIMEOUTS.WriteTotalTimeoutConstant = timeout; sTIMEOUTS.WriteTotalTimeoutMultiplier = 0; if (!SetCommTimeouts(sPort,&sTIMEOUTS)) { LOGDEBUG("SetCommTimeouts call failed"); } SetCommMask(sPort, EV_TXEMPTY); } unsigned serialport_get_timeout() { return sTIMEOUTS.ReadTotalTimeoutConstant; } unsigned serialport_read(unsigned char* data, unsigned int size) { unsigned long cb; ReadFile(sPort, data, size, &cb, NULL); if (cb != size) { LOGDEBUG("read %d, requested %d", cb, size); } return (unsigned) cb; } unsigned serialport_write(const unsigned char* data, unsigned int size) { unsigned long cb; WriteFile(sPort, data, size, &cb, NULL); if (cb != size) { LOGDEBUG("wrote %d, requested %d", cb, size); } return (unsigned) cb; } void serialport_flush(void) { unsigned char tmp[512]; if(sPort) { LOGDEBUG("flush start"); unsigned old_timeout = sTIMEOUTS.ReadTotalTimeoutConstant; serialport_set_timeout(1); ClearCommError(sPort, NULL, NULL); PurgeComm(sPort, PURGE_TXCLEAR|PURGE_RXCLEAR); unsigned long cb; int result; do { result = ReadFile(sPort, tmp, 512, &cb, NULL); LOGVERBOSE("flushed %lu bytes", cb); } while(cb && result == 0); serialport_set_timeout(old_timeout); LOGDEBUG("flush complete"); } } void serialport_drain(void) { if(sPort) { FlushFileBuffers(sPort); } } int serialport_close(void) { if(!sPort) return 0; serialport_drain(); serialport_flush(); CloseHandle(sPort); sPort = NULL; return 1; } void serialport_set_dtr(unsigned char val) { if(sPort) { EscapeCommFunction(sPort,((val)?SETDTR:CLRDTR)); } } void serialport_set_rts(unsigned char val) { if(sPort) { EscapeCommFunction(sPort,((val)?SETRTS:CLRRTS)); } } void serialport_send_break() { if (sPort) { EscapeCommFunction(sPort, SETBREAK); Sleep(250); EscapeCommFunction(sPort, CLRBREAK); } } #else void serialport_set_baudrate(unsigned int baudrate) { switch(baudrate) { case 2400: cfsetispeed(&term,B2400); cfsetospeed(&term,B2400); break; case 4800: cfsetispeed(&term,B4800); cfsetospeed(&term,B4800); break; case 9600: cfsetispeed(&term,B9600); cfsetospeed(&term,B9600); break; case 19200: cfsetispeed(&term,B19200); cfsetospeed(&term,B19200); break; case 38400: cfsetispeed(&term,B38400); cfsetospeed(&term,B38400); break; case 57600: cfsetispeed(&term,B57600); cfsetospeed(&term,B57600); break; case 115200: cfsetispeed(&term,B115200); cfsetospeed(&term,B115200); break; case 230400: cfsetispeed(&term,B230400); cfsetospeed(&term,B230400); break; #ifndef __APPLE__ case 460800: cfsetispeed(&term,B460800); cfsetospeed(&term,B460800); break; case 921600: cfsetispeed(&term,B921600); cfsetospeed(&term,B921600); break; #endif default: LOGWARN("serialport_set_baudrate: baud rate %d may not work", baudrate); cfsetispeed(&term,baudrate); cfsetospeed(&term,baudrate); break; } } void serialport_set_character_timeout_0_1s(unsigned int t) { if (t > 255) t = 255; term.c_cc[VMIN] = 0; term.c_cc[VTIME] = t; // VTIME is measured in 0.1s LOGDEBUG("setting character timeout %i", t); if (tcsetattr(serial_port, TCSANOW, &term)!=0) { LOGDEBUG("set timeout failed"); } LOGDEBUG("done"); timeout = t; } unsigned serialport_get_character_timeout_0_1s() { return term.c_cc[VTIME]; } void serialport_set_timeout(unsigned int t) { if(t != timeout) { LOGDEBUG("setting timeout %i", t); serialport_set_character_timeout_0_1s((t + 99)/100); timeout = t; } } unsigned serialport_get_timeout() { return timeout; } int serialport_open(const char *device, unsigned int baudrate) { LOGINFO("opening port %s at %d", device, baudrate); int flags = O_RDWR | O_NOCTTY; #ifdef __APPLE__ flags |= O_NONBLOCK; #endif serial_port = open(device, flags); if(serial_port<0) { LOGERR("cannot access %s\n",device); return 0; } #ifdef __APPLE__ flags = fcntl(serial_port, F_GETFL, 0); fcntl(serial_port, F_SETFL, flags & (~O_NONBLOCK)); #endif serialport_set_dtr(0); LOGDEBUG("tcgetattr"); tcgetattr(serial_port,&term); serialport_set_baudrate(baudrate); term.c_cflag = (term.c_cflag & ~CSIZE) | CS8; term.c_cflag |= CLOCAL | CREAD; term.c_cflag &= ~(PARENB | PARODD); term.c_cflag &= ~CSTOPB; term.c_iflag = IGNBRK; term.c_iflag &= ~(IXON | IXOFF); term.c_lflag = 0; term.c_oflag = 0; term.c_cc[VMIN]=0; term.c_cc[VTIME]=1; timeout = 100; LOGDEBUG("tcsetattr"); if (tcsetattr(serial_port, TCSANOW, &term)!=0) { LOGERR("setattr stage 1 failed"); return 0; } if (tcgetattr(serial_port, &term)!=0) { LOGERR("getattr failed"); return 0; } term.c_cflag &= ~CRTSCTS; if (tcsetattr(serial_port, TCSANOW, &term)!=0) { LOGERR("setattr stage 2 failed"); return 0; } LOGDEBUG("serial open"); return serial_port; } unsigned serialport_read(unsigned char* data, unsigned int size) { struct timeval tv0, tv1; gettimeofday(&tv0, NULL); unsigned n = 0; unsigned time_spent = 0; do { unsigned cb = read(serial_port, data + n, size - n); n += cb; gettimeofday(&tv1, NULL); time_spent = (tv1.tv_sec - tv0.tv_sec) * 1000 + tv1.tv_usec / 1000 - tv0.tv_usec / 1000; } while (n < size && time_spent < timeout); return n; } unsigned serialport_write(const unsigned char* data, unsigned int size) { return write(serial_port, data, size); } void serialport_flush(void) { static unsigned char b; unsigned int t; if(serial_port) { t = serialport_get_character_timeout_0_1s(); serialport_set_character_timeout_0_1s(0); tcdrain(serial_port); while(read(serial_port, &b, 1) > 0); serialport_set_character_timeout_0_1s(t); } } void serialport_drain(void) { if(serial_port) { tcdrain(serial_port); } } int serialport_close(void) { if(serial_port) { tcdrain(serial_port); tcflush(serial_port, TCIOFLUSH); close(serial_port); return 1; } else { return 0; } } void serialport_set_dtr(unsigned char val) { int mcs; if(serial_port) { ioctl (serial_port, TIOCMGET, &mcs); if(val) { mcs |= TIOCM_DTR; ioctl (serial_port, TIOCMSET, &mcs); } else { mcs &= ~TIOCM_DTR; ioctl (serial_port, TIOCMSET, &mcs); } } } void serialport_set_rts(unsigned char val) { int mcs; if(serial_port) { ioctl (serial_port, TIOCMGET, &mcs); if(val) { mcs |= TIOCM_RTS; ioctl (serial_port, TIOCMSET, &mcs); } else { mcs &= ~TIOCM_RTS; ioctl (serial_port, TIOCMSET, &mcs); } } } void serialport_send_break() { tcsendbreak(serial_port, 0); } #endif static unsigned char subst_C0[2] = { 0xDB, 0xDC }; static unsigned char subst_DB[2] = { 0xDB, 0xDD }; #define STATIC_SLIP_BUF_SIZE 4096 int serialport_send_slip_static(unsigned char *data, unsigned int size) { unsigned char buf[STATIC_SLIP_BUF_SIZE]; unsigned out_pos = 0; for (int i = 0; i < size; ++i) { unsigned char cur = data[i]; if (cur == 0xC0) { buf[out_pos++] = subst_C0[0]; buf[out_pos++] = subst_C0[1]; } else if (cur == 0xDB) { buf[out_pos++] = subst_DB[0]; buf[out_pos++] = subst_DB[1]; } else buf[out_pos++] = cur; } if(serialport_write(buf, out_pos) != out_pos) { LOGERR("failed sending %d bytes", out_pos); return 0; } serialport_drain(); return size; } int serialport_send_slip(unsigned char *data, unsigned int size) { unsigned int sent; unsigned char cur_byte; if (size < STATIC_SLIP_BUF_SIZE / 2) return serialport_send_slip_static(data, size); sent = 0; while(sent != size) { cur_byte = *data++; if(cur_byte == 0xC0) { if(serialport_write(subst_C0, 2) != 2) { LOGERR("failed substituting 0xC0"); return 0; } } else if(cur_byte == 0xDB) { if(serialport_write(subst_DB, 2) != 2) { LOGERR("failed substituting 0xDB"); return 0; } } else { if(serialport_write(&cur_byte, 1) != 1) { LOGERR("failed sending byte %i", sent); return 0; } } sent++; } serialport_drain(); return sent; } int serialport_receive_slip(unsigned char *data, unsigned int size) { unsigned int received; unsigned char cur_byte; received = 0; while(received != size) { if(serialport_read(&cur_byte, 1) != 1) { LOGERR("failed reading byte"); return 0; } if(cur_byte == 0xDB) { if(serialport_read(&cur_byte, 1) != 1) { LOGERR("failed reading byte for unslip"); return 0; } if(cur_byte == 0xDC) { *data++ = 0xC0; } else if(cur_byte == 0xDD) { *data++ = 0xDB; } else { LOGERR("unslip sequence wrong"); return 0; } } else { *data++ = cur_byte; } received++; } return received; } int serialport_send_C0(void) { unsigned char b; b = 0xC0; if(serialport_write(&b, 1) != 1) { LOGERR("failed sending 0xC0"); return 0; } serialport_drain(); return 1; } int serialport_receive_C0(void) { unsigned char b; b = 0x00; if(serialport_read(&b, 1) != 1) { return 0; } if(b != 0xC0) { LOGDEBUG("serialport_receive_C0: %02X instead of C0", b); return 0; } return 1; } esptool-ck-0.4.6/serialport/serialport.h000066400000000000000000000034611255710016000203230ustar00rootroot00000000000000/********************************************************************************** ********************************************************************************** *** *** serialport.h *** - include file for serialport.c *** *** Copyright (C) 2014 Christian Klippel *** *** This program is free software; you can redistribute it and/or modify *** it under the terms of the GNU General Public License as published by *** the Free Software Foundation; either version 2 of the License, or *** (at your option) any later version. *** *** This program is distributed in the hope that it will be useful, *** but WITHOUT ANY WARRANTY; without even the implied warranty of *** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *** GNU General Public License for more details. *** *** You should have received a copy of the GNU General Public License along *** with this program; if not, write to the Free Software Foundation, Inc., *** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *** **/ #ifndef SERIALPORT_H #define SERIALPORT_H int serialport_open(const char *dev, unsigned int baudrate); int serialport_close(void); void serialport_set_dtr(unsigned char val); void serialport_set_rts(unsigned char val); void serialport_send_break(); void serialport_set_timeout(unsigned int timeout); unsigned serialport_get_timeout(); void serialport_drain(void); void serialport_flush(void); unsigned serialport_read(unsigned char* data, unsigned int size); unsigned serialport_write(const unsigned char* data, unsigned int size); int serialport_send_slip(unsigned char *data, unsigned int size); int serialport_receive_slip(unsigned char *data, unsigned int size); int serialport_send_C0(void); int serialport_receive_C0(void); #endif