diff options
Diffstat (limited to 'docs/source/bootloader.rst')
-rw-r--r-- | docs/source/bootloader.rst | 716 |
1 files changed, 0 insertions, 716 deletions
diff --git a/docs/source/bootloader.rst b/docs/source/bootloader.rst deleted file mode 100644 index ec4fe73..0000000 --- a/docs/source/bootloader.rst +++ /dev/null @@ -1,716 +0,0 @@ -.. highlight:: sh - -.. _bootloader: - -Maple Bootloader(s) -=================== - -The firmware which allows the Maple to be reprogrammed via a USB -connection. Every Maple board comes programmed with this by default, -and it is not overwritten by regular programs (it lives lower in the -Flash memory and only runs when the chip is reset). - -**Check out the latest source code version:** :: - - git clone git://github.com/leaflabs/maple-bootloader.git - -**Visit the github development project**: https://github.com/leaflabs/maple-bootloader - -.. contents:: Contents - :local: - -Bootloader Schemes Explained ----------------------------- - -Maple Rev 3 and Rev 5 (Rev 5 is the version currently shipping) -represents a drastic remake of the core library as well as the upload -process. Thes changes to the bootloader, were implemented to resolve -platform-specific issues on Windows. Before delving into how the Rev -1 bootloader worked and how the Rev 5 bootloader works now, we'll -discuss the features common to each and touch a bit on the Arduino -setup. - -This is a fairly involved explanation, with a lot of details that are -likely only interesting to a few. If you just want to get the rough -idea, skim this article. If you want to start hacking on the -bootloader, get in touch with us to get even more info on how this all -works. And finally, you can always `check out the code at github -<https://github.com/leaflabs/libmaple>`_! - -Arduino -------- - -Arduino is based off of AVR series microcontrollers, most of which -lack USB support. Thus, boards like the Duemilanove add USB capability -via an FTDI USB-to-Serial converter chip. This chip interfaces with -the AVR over an RS-232 serial interface. When you plug an Arduino into -a computer, only an FTDI driver is needed. Since the FTDI chip is -separate from the AVR, you can reset the Arduino without closing this -USB connection with the FTDI chip. - -To program an Arduino, the host machine sends a command over the USB -pipe (reset DTR) which in turn resets the AVR. The AVR will boot into -a bootloader, which waits for a second for any upload commands over -serial. The host machine can either send those commands, or do -nothing. If it does nothing, the AVR will quickly jump to user code -and off you go. The whole process is quick, the bootloader doesn’t -live for very long, and will exit almost immediately if no upload -commands are received. - -Maple Rev 1 ------------ - -Maple is based off the STM32 (ARM cortex M3) series chips, which do -have embedded USB support. Thus, Maple doesn’t need the extra FTDI -chip. Firmware is uploaded via the standard DFU protocol (also used by -iPhone and openMoko). Since DFU is a standard, there is no need for -custom software running on the host to upload the firmware. Any DFU -compliant program will work. The Maple IDE is based around -:command:`dfu-util`, openMoko’s DFU utility. Using DFU came at a cost, -however. The USB port must additionally implement a separate serial -port at the same time (we use the CDC ACM class for serial -functionality). - -Maple Rev 1 attempted to run both DFU and CDC ACM devices -simultaneously on the USB peripheral. On Linux, this worked great. The -OS would service the DFU driver during uploads, and the CDC ACM for -serial port transactions. There was no reset necessary for uploads. No -waiting. The bootloader was always running the background, ready to -receive commands. - -The problem was that *only* Linux did this. Windows refused to attach -more than one driver to a single USB device without repackaging the -DFU and CDC ACM into a single IAD Compound Device. It's not terribly -important what this means, except for two things. - -1. Four drivers were necessary to make everything work. -2. IAD is not supported by OS X. - -Mac OS X, on the other hand, only supported Compound USB, a different -trick that is not supported by Windows. While a perpetual background -bootloader was attractive, it became clear, after much toiling, we -were going to have to write custom drivers across several platforms to -make everything work this way. - -.. _bootloader-rev3: - -Maple Rev3/Rev5 - DFU ---------------------- - -Maple Rev 3 takes a completely different tack, more along the lines of -Arduino. In Rev 3, the device resets into bootloader mode, which -stays alive for a few moments to receive commands, and then jumps to -user code. The bootloader is implemented as a DFU device -- just a DFU -device, no serial port. This requires one driver for Windows -(:file:`drivers/mapleDrv/dfu` in the Windows IDE directory). - -As part of the :ref:`libmaple <libmaple>` library, user code is -automatically supplied with serial support via some behind the scenes -work (``setupUSB()`` is called from ``init()``). This user mode code -only implements a CDC ACM class USB device, giving you functions like -:ref:`SerialUSB.read() <lang-serialusb-read>`. Separating these two -modes fixed the driver issues and works well across platforms, -requiring only two drivers (serial and DFU) on Windows. - -However, it is no longer possible to upload code at will, since there -is no bootloader quietly listening in the background. Instead, you -must reset the board, then initiate a DFU transaction. The IDE -performs this reset automatically by performing a special sequence of -changes on the USB serial port: - -1. Pulse DTR (high and then low, so that you've created a negative - edge) -2. Write "1EAF" in ASCII over the serial pipe. This will cause Maple - to reset. Only the first 4 bytes after a negative edge of DTR are - checked for this command, so it's important you actually create a - negative edge, rather than just ensuring DTR is low. - -After the reset, the host OS takes a few moments (.5-2 seconds) to -re-enumerate the device as DFU. This delay is unpredictable, and is -the reason the bootloader on Maple Rev 3/Rev 5 stays alive for so -long. (Sometimes, the bootloader was exiting before the OS had even -enumerated the device.) - -Once in bootloader mode, :command:`dfu-util` uploads your sketch into -either flash or RAM (DFU alternate setting 0 or 1, respectively) and -resets the board again. This time, however, no DFU transaction is -initiated, and the bootloader gives way to user code, closing down the -DFU pipe and bringing up the USB serial port. - -.. .. _bootloader-rev6: - -.. Maple Rev6 - The Serial Bootloader (Tentative) -.. ---------------------------------------------- - -.. .. note:: This section documents an in-progress version of the Maple -.. bootloader. **No Maples yet sold use this bootloader protocol**. -.. It has not been yet been publicly released, and its interface is -.. not stable. - -.. The bootloader in Rev3/Rev5 works well on Linux, acceptably on Mac, -.. but was unsatisfactory on Windows. Unlike the other operating systems, -.. Windows needed to be manually pointed to both the driver to use for -.. programming (DFU, via `libusb <http://www.libusb.org/>`_) and the -.. driver to use for serial communication (usbser.sys, built in to -.. Windows). Since Maple operates in only one of these modes at a time, -.. driver installation was unnecessarily complicated. It was necessary to -.. bring Maple into the correct mode before installing each of the -.. drivers. Furthermore, because libusb is not bundled with Windows, and -.. its driver is not signed, Windows 7 users have been forced to -.. laboriously disable driver signing checks. Finally, Windows hates the -.. constant switching of the device between Serial and DFU modes (during -.. programming), and often prompts users to install drivers that are -.. already installed. We have therefore decided to abandon DFU. - -.. In our new bootloader scheme, Maple is simply a serial device. -.. Windows comes bundled with usbser.sys, so no driver signing is -.. required. The IDE installation process is greatly simplified, there -.. is no more switching back and forth between "modes", and we can build -.. in new functionality outside the DFU spec. - -.. The first incarnation of this serial-only bootloader leaves libmaple -.. and user code untouched. However, during programming, instead of -.. calling :command:`dfu-util` to upload code we will now call a newly -.. written utility script similar to `avr-dude -.. <http://savannah.nongnu.org/projects/avrdude/>`_. The high level -.. operation of the bootloader will remain the same - come on at startup, -.. wait for an upload operation or timeout, and jump to user code. - -.. The second version of this bootloader will eliminate this dependence -.. on resetting and timing out by having the bootloader run in the -.. background. It will additionally own the serial port. In this scheme, -.. sending data over the COM port while DTR is pulled low results in that -.. packet being captured by the bootloader and interpreted as a -.. bootloader command. When the user uploads a new program, the -.. bootloader will overwrite the old one, reset the various peripheral -.. registers, and jump to user code. All of this will occur without -.. resetting the chip and thus causing Maple to connect and disconnect -.. from your computer (which seems to cause many problems). - -.. The final version of this bootloader scheme will involve a separate -.. microcontroller, whose responsibilities are to drive the USB port, -.. program the main processor, and offer some amount of debugging -.. capability. This will allow user sketches to run on the bare metal of -.. the main processor, without any bootloader hiding underneath. This -.. approach is similar to the approaches taken by mbed and the Arduino -.. Uno. - -.. Regardless of which generation of the new serial bootloader you are -.. working with, the command interface is the same. The low level -.. communication protocol is inspired by STK-500, the protocol used to -.. program many AVR-based development boards. The protocol is a -.. packetized query-response scheme. The host PC initiates every -.. transaction, and for every query sent to the bootloader, a single -.. response will be returned (or the system times out). Data is -.. transmitted over 115.2kbps, 8 data bits, 1 stop bit, no parity -.. bit. Every query or response follows the same packet format that looks -.. like this: - -.. .. _bootloader-packet-structure: - -.. Packet Structure -.. ^^^^^^^^^^^^^^^^ - -.. A bootloader packet is composed of a sequence of fields, as follows. - -.. .. list-table:: -.. :header-rows: 1 - -.. * - Field -.. - Length (bytes) -.. - Value -.. - Description - -.. * - START -.. - 1 -.. - 0x1B -.. - Magic constant, indicates bootloader packet - -.. * - SEQUENCE_NUM -.. - 1 -.. - 0--0xFF -.. - Queries and responses must have the same sequence number; rolls -.. over to 0 after 0xFF - -.. * - MESSAGE_SIZE -.. - 2 -.. - 0--0xFFFF -.. - Size of message body, currently limited to a 1024B=1KB maximum - -.. * - TOKEN -.. - 1 -.. - 0x7F -.. - Differs from STK500 value of 0x0E - -.. * - MESSAGE_BODY -.. - Variable, determined by MESSAGE_SIZE field -.. - Command query or response -.. - See :ref:`next section <bootloader-commands>` - -.. * - CHECKSUM -.. - 4 -.. - XOR of all other 32-bit words in packet -.. - See :ref:`below <bootloader-checksum>` - -.. .. _bootloader-checksum: - -.. .. highlight:: cpp - -.. .. note:: When computing the checksum, the words in a packet are -.. interpreted big-endian (as if the packet were a sequence of 32-bit, -.. big-endian unsigned integers). If the end of the MESSAGE_BODY is -.. not aligned with a four-byte boundary, then the checksum will treat -.. it as if it was padded with zero bytes to a four-byte boundary. - -.. As a concrete example, an entire GET_INFO query (see :ref:`below -.. <bootloader-get-info>`), including the packet structure, is -.. comprised of the byte sequence :: - -.. {0x1B, 0x7F, 0x00, 0x01, 0x7F, 0x00, 0x64, 0x7F, 0x00, 0x01} - -.. The SEQUENCE_NUM of this query is 0x7F. - -.. .. highlight:: sh - -.. .. _bootloader-commands: - -.. Commands -.. ^^^^^^^^ - -.. The packet structure overhead is for reliability. The actual queries -.. and responses are transacted inside of the message body. Following -.. the STK-500 protocol, each query or response begins with the single -.. byte command field. For each query, the resultant response must begin -.. with the same CMD byte. For each type of command, the structure of -.. queries and responses is of fixed size. - -.. Also following STK-500, fields longer than 1 byte are transmitted MSB -.. first (big-endian). However, READ and WRITE commands operate byte-wise -.. (not word-wise); it is up to the host PC to ensure that alignment and -.. ordering issues are handled appropriately. - -.. .. _bootloader-get-info: - -.. GET_INFO -.. """""""" - -.. Used to query device characteristics. - -.. GET_INFO Query: - -.. .. list-table:: -.. :header-rows: 1 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - GET_INFO -.. - 1 -.. - Value 0 - -.. GET_INFO Response: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 4 2 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - GET_INFO -.. - 1 -.. - Value 0 - -.. * - Endianness -.. - 1 -.. - 0 indicates little-endian, 1 indicates big-endian. -.. (Currently returns 0; this field allows for future -.. expansion). - -.. * - Available Ram -.. - 4 -.. - In bytes - -.. * - Available Flash -.. - 4 -.. - In bytes - -.. * - Flash Page Size -.. - 2 -.. - In bytes - -.. * - Starting Address (FLASH) -.. - 4 -.. - Usually 0x08005000 - -.. * - Starting Address (RAM) -.. - 4 -.. - Usually 0x200000C0 - -.. * - Bootloader Version -.. - 4 -.. - Current version 0x00060000 (MAJ,MIN) - -.. .. _bootloader-erase-page: - -.. ERASE_PAGE -.. """""""""" - -.. Used to erase flash pages. - -.. ERASE_PAGE query: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 4 2 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - ERASE_PAGE -.. - 1 -.. - Value 1 - -.. * - ADDRESS -.. - 4 -.. - Will erase whichever page contains ADDRESS - -.. ERASE_PAGE response: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 3 2 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - ERASE_PAGE -.. - 1 -.. - Value 1 - -.. * - SUCCESS -.. - 1 -.. - Either 0 (failure) or 1 (success) - -.. WRITE_BYTES -.. """"""""""" - -.. Used to write to RAM or flash. - -.. WRITE_BYTES query: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 4 4 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - WRITE_BYTES -.. - 1 -.. - Value 2 - -.. * - Starting Address -.. - 4 -.. - Can address arbitrary RAM, or :ref:`cleared -.. <bootloader-erase-page>` flash pages. - -.. * - DATA -.. - MESSAGE_SIZE - 5 -.. - See :ref:`Packet Structure <bootloader-packet-structure>` - -.. WRITE_BYTES response: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 2 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - WRITE_BYTES -.. - 1 -.. - Value 2 - -.. * - SUCCESS -.. - 1 -.. - Either 0 (failure) or 1 (success). Will fail if writes were -.. made to uncleared pages. Does not clean up failed writes -.. (memory will be left in an undefined state). - -.. READ_BYTES -.. """""""""" - -.. Used to read from RAM or flash. - -.. READ_BYTES query: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 2 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - READ_BYTES -.. - 1 -.. - Value 3 - -.. * - ADDRESS -.. - 4 -.. - Start of block to read. Must be a multiple of 4. - -.. * - LENGTH -.. - 2 -.. - Maximum number of bytes to read (currently, this may be at most -.. 1024 = 1KB). Must be a multiple of 4. - -.. READ_BYTES response: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 2 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - READ_BYTES -.. - 1 -.. - Value 3 - -.. * - DATA -.. - MESSAGE_SIZE - 1 -.. - Contains read bytes. The actual number of bytes read may be -.. less than the LENGTH field of the corresponding READ_BYTES -.. query. If this section is of length 0, this should be -.. interpreted as a read failure. See -.. :ref:`bootloader-packet-structure`. - -.. JUMP_TO_USER -.. """""""""""" - -.. Causes the bootloader to jump to user code's starting address. - -.. JUMP_TO_USER query: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 1 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - JUMP_TO_USER -.. - 1 -.. - Value 4 - -.. * - Location -.. - 1 -.. - 0 means jump to flash starting address, 1 means jump to RAM -.. starting address. See the :ref:`bootloader-get-info` command -.. for more information. - -.. JUMP_TO_USER response: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 1 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - JUMP_TO_USER -.. - 1 -.. - Value 4 - -.. * - SUCCESS -.. - 1 -.. - Either 0 (failure) or 1 (success). If successful, after the -.. response is sent, the bootloader ends this session and jumps to -.. the user code in flash or RAM as specified in the query's -.. Location field. - - -.. SOFT_RESET -.. """""""""" - -.. Engages a full software reset. - -.. SOFT_RESET query: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 1 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - SOFT_RESET -.. - 1 -.. - Value 5 - -.. SOFT_RESET response: - -.. .. list-table:: -.. :header-rows: 1 -.. :widths: 2 1 10 - -.. * - Field -.. - Bytes -.. - Comments - -.. * - SOFT_RESET -.. - 1 -.. - Value 5 - -.. * - SUCCESS -.. - 1 -.. - Either 0 or 1 (FAILED and OK, respectively). Will end this -.. bootloader session and reset the processor. - -.. _bootloader-reflashing: - -Flashing A Custom Bootloader ----------------------------- - -.. warning:: This section is for users who want to put a fresh or - custom bootloader on their board. It's possible to make a mistake - in this process and e.g. render your Maple unable to communicate - with the IDE. Know what you're doing, and proceed with caution. - -The STM32 microprocessor on the Maple comes with a built-in serial -bootloader that can be used to flash a new (software) bootloader onto -the chip. While the Maple bootloader is just a program, the built-in -serial bootloader is part of the STM32 hardware, so it's always -available. - -This means that you can **always** follow these instructions to put a -new bootloader program on your board; it **doesn't matter** if there's -already a copy of the Maple bootloader on it or not. - -This section applies to Maple Rev 3 or higher. If you have a Maple -Rev 1; you don't have a BUT button, and won't be able to follow these -directions. A workaround is detailed in `this forum posting -<http://forums.leaflabs.com/topic.php?id=32#post-126>`_. - -.. highlight:: sh - -Setup -^^^^^ - -In order to follow these instructions, you will need: - -- A binary of the bootloader you want to upload -- Hardware for communicating between the Maple and your computer over - serial. -- `Python <http://python.org>`_ version 2.5 or higher, with the - `PySerial <http://pyserial.sourceforge.net/>`_ library installed. - -**Step 1: Obtain a bootloader binary**. The first thing you'll need to -do is to compile your bootloader binary. Note that an ASCII -representation of the binary, such as the Intel .hex format, won't -work. - -.. FIXME [Mini, Native] links to precompiled bootloaders - -If you just want to flash the default Maple bootloader (the one that -was installed on your Maple when it arrived), we host a `pre-compiled -copy -<http://static.leaflabs.com/pub/leaflabs/maple-bootloader/maple_boot-rev3-9c5f8e.bin>`_, -which works on all Maple Revs. - -To obtain the latest development version, you can run (on a -:ref:`suitably configured system <unix-toolchain>`) the following to -obtain a binary of the bootloader currently used on the Maple:: - - $ git checkout git://github.com/leaflabs/maple-bootloader.git - $ cd maple-bootloader - $ make - $ ls -lh build/maple-boot.bin # this is the compiled bootloader binary - -**Step 2: Connect Maple Serial1 to your computer**. -There are a variety of ways of doing this. We use Sparkfun's `FTDI -breakout boards <http://www.sparkfun.com/products/718>`_, but you -could use another Maple, an Arduino, etc. -- anything that allows your -computer to communicate with the Maple you want to reprogram over a -serial interface. - -.. FIXME [Maple-specific values] - -If you do use an FTDI breakout board, first make sure your Maple is -disconnected from an external power source, be it battery, USB, or -barrel jack. Then, connect the FTDI board's TX pin to ``Serial1``\ 's -RX pin (pin 8), FTDI RX to ``Serial1`` TX (pin 7), FTDI ground to -Maple's GND, and its 3.3V pin to Maple's Vin (use the Maple's -silkscreen for help locating these pins). - -More information on ``Serial1`` is available :ref:`here -<lang-serial>`. - -At this point, you're ready to plug the FTDI board into your computer -(via USB). - -**Step 3: Put your Maple into serial bootloader mode**. Do this by -pressing the RESET button, then *while RESET is held down*, pressing -and holding the BUT button. Next, *making sure to keep BUT held -down*, release the RESET button and wait for a few seconds before -releasing BUT. - -**Step 4: Get stm32loader.py**. You can download it directly from -`libmaple's github page -<https://github.com/leaflabs/libmaple/raw/master/support/stm32loader.py>`_ -(click the link, then save the file somewhere on your system). If you -have set up the :ref:`Unix toolchain <unix-toolchain>`, it's the file -libmaple/support/stm32loader.py. - -Flashing the new Bootloader -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -We'll use ``maple_boot.bin`` as the path to the bootloader binary from -Step 1, and ``ser-port`` as the Maple's serial port device file or COM -port. - -* On **Linux**, ``ser-port`` will probably be something like - ``/dev/ttyUSB0``, although the exact number could be different (it - could be ``/dev/ttyUSB1``, ``/dev/ttyUSB2``, etc.). - -* On **OS X**, ``ser-port`` will probably look like - ``/dev/tty.usbserialXXXX``, where ``XXXX`` is some random string of - characters. - -* On **Windows**, ``ser-port`` will be something like ``COM1``, ``COM2``, etc. - -.. highlight:: sh - -To upload a bootloader binary, run this command from the Unix shell:: - - python stm32loader.py -p ser-port -evw maple_boot.bin - -Or this command from the Windows command prompt:: - - python.exe stm32loader.py -p ser-port -evw maple_boot.bin - -You can also run the following to get usage information:: - - # Unix: - python stm32loader.py -h - - # Windows: - python.exe stm32loader.py -h - -If all goes well, you'll see a bunch of output, then "Verification -OK". If something goes wrong, the `forum`_ is probably your best bet -for obtaining help, with IRC (server irc.freenode.net, channel -#leafblowers) being another option. If all else fails, you can always -`contact us directly`_! |