work on thesis

master
Ondřej Hruška 6 years ago
parent 08f498f952
commit 56be653f17
  1. 42
      ch.existing_solutions.tex
  2. 3
      ch.fat16.tex
  3. 40
      ch.freertos.tex
  4. 99
      ch.fw_structure.tex
  5. 39
      ch.hw_buses.tex
  6. 18
      ch.introduction.tex
  7. 84
      ch.requirement_analysis.tex
  8. 48
      ch.usb.tex
  9. 17
      sec_abstract.tex
  10. BIN
      thesis.pdf
  11. 23
      thesis.tex

@ -1,6 +1,6 @@
\chapter{Existing Solutions}
\chapter{\label{sec:prior-art}Existing Solutions}
The idea of making it easier to interact with low level hardware from a PC is not new. Several solutions to this problem have been developed over the past years, each with its own advantages and drawbacks. Some of the existing solutions will be presented in this chapter to give the reader some idea about the current possibilities.
The idea of making it easier to interact with low level hardware from a PC is not new. Several solutions to this problem have been developed, each with its own advantages and drawbacks. Some examples will be presented in this chapter.
\section{Bus Pirate}
@ -8,45 +8,39 @@ The idea of making it easier to interact with low level hardware from a PC is no
%http://dangerousprototypes.com/blog/about/
Bus Pirate, developed by \todo{link}Ian Lesnet at Dangerous Prototypes and manufactured by Seeed Studio\todo{link}, is a USB-attached device providing access to hardware interfaces like SPI, I$^2$C, USART and 1-Wire (those will be described later \todo{link to actual place}), as well as frequency measurement and direct pin access.
Bus Pirate, developed by \todo{link}Ian Lesnet at Dangerous Prototypes and manufactured by Seeed Studio\todo{link}, is a USB-attached device providing access to hardware interfaces like SPI, I$^2$C, USART and 1-Wire, as well as frequency measurement and direct pin access.
The board aims to make it easy for the users to familiarize themselves with new chips and modules; it also provides a range of programming interfaces for flashing microcontroller firmwares and memories. It communicates with the PC using a FTDI USB-serial bridge
The board aims to make it easy for users to familiarize themselves with new chips and modules; it also provides a range of programming interfaces for flashing microcontroller firmwares and memories. It communicates with the PC using a FTDI USB-serial bridge.
Bus Pirate is open source and in scope it is similar to what we want to achieve here. It can be scripted and controlled from languages like Python or Perl, connects to USB and provides a wide selection of hardware interfaces.
Bus Pirate is open source and in scope it's similar to GEX. It can be scripted and controlled from languages like Python or Perl, connects to USB and provides a good selection of hardware interfaces.
The board is based on a PIC16 microcontroller running at 32\,MHz. Its analog/digital converter (ADC) only has a resolution of 10 bits (1024 levels). There is no digital/analog converter (DAC) available on the chip, making applications that require a varied output voltage more difficult. Another limitation of the board is its low number of GPIO pins, which may be insufficient for certain applications, such as multi-channel sampling, parallel interfaces, or connecting multiple different devices at once. The Bus Pirate, at the time of writing, can be purchased for a price similar to some Raspberry Pi models.
The board is based on a PIC16 microcontroller running at 32\,MHz. Its analog/digital converter (ADC) only has a resolution of 10 bits (1024 levels). There is no digital/analog converter (DAC) available on the chip, making applications that require a varied output voltage more difficult. Another limitation of the board is its low number of GPIO pins which may be insufficient for certain applications. The Bus Pirate, at the time of writing, can be purchased for a price similar to some Raspberry Pi models.
\section{Raspberry Pi}
\todo[inline]{link, pictures}
Another device worth mentioning, albeit of a different kind, is the Raspberry Pi. All models of the Raspberry Pi include a GPIO header which can be directly controlled by user applications. The pins broken out to this header can be used as general purpose I/O and some have alternate functions such as SPI or I$^2$C.
The Raspberry Pi's GPIO header, which can be directly controlled by user applications, was one of the primary inspirations behind GEX. It can be controlled using C and Python (among others) and offers general purpose I\O, SPI, I2C, UART and PWM, with other protocols being easy to emulate thanks to the high speed of the system processor.
The responsibility of controlling the attached external hardware lies on the user application, which also commonly provides the user interface, which greatly simplifies the development process. The control application can be written in almost any programming language. Python is a popular choice thanks to its simplicity, but it's by no means the only way to interact with the pins.
The Raspberry Pi is commonly used in schools as a low-cost PC alternative that encourage students' interest in electronics, programming and science. The board is often built into more permanent projects that make use of its powerful processor, such as wildlife camera traps or home automation projects.
The Raspberry Pi is commonly used in primary schools as a low-cost PC alternative that encourage students' interest in electronics and science. The board is, further, often built into more permanent projects that make use of its powerful processor, such as camera traps for wildlife observations.
The Raspberry Pi could be used for the same quick evaluations or experiments we want to perform with GEX, however they would either have to be performed directly on the mini-computer itself with attached monitor and keyboard, or use some form of remote access (e.g. SSH). When we have a more powerful computer available, a USB device like GEX would be more convenient.
The Raspberry Pi could be used for the quick evaluations or experiments we want to perform with GEX, however they would either have to be performed directly on the mini-computer itself (with attached monitor and keyboard), or use some form of remote access.
\section{Professional DAQ Modules}
\section{The Firmata protocol}
Various professional tools that would fulfill our needs exist on the market, but their high price makes them inaccessible for users with a limited budget, such as hobbyists or students who would like to keep such a device for personal use. An example is the National Instruments "I²C/SPI Interface Device", which also includes several GPIO lines, or some of the Total Phase I²C/SPI gadgets which sell for about \$300 a piece.
\todo[inline]{links}
\todo[inline]{Move this elsewhere}
Firmata is a serial communication protocol based on MIDI (\textit{Musical Instrument Digital Interface}) for passing data to and from embedded microcontrollers. MIDI is primarily used for attaching electronic musical instruments, such as synthesizers, keyboards, mixers etc., to each other or to a PC.
The performance GEX can provide may be inferior to those professional tools, but in many cases it'll be a sufficient substitute at a fraction of the cost.
Firmata was designed for use with the Arduino firmware to allow easy construction of user programs (called \textit{sketches} in the Arduino environment) that communicate with a client application running on the PC without having to worry about technical details.\todo{citation}
Implementing the Firmata protocol in a universal hardware interfacing module would make it possible to use existing Firmata client libraries. However, it is constricted by the limitations of the encompassing MIDI protocol and offers little flexibility.
\todo[inline]{http://www.ni.com/en-gb/shop/select/i2c-spi-interface-device}
\section{Professional DAQ modules}
\todo[inline]{pictures}
A range of professional tools that would fulfill our needs exist on the market,
however their common property is a high price. This makes them inaccessible for users with a limited budget, such as hobbyists or students who would like to keep such a device for personal use. An example falling into this category is the National Instruments "I²C/SPI Interface Device", which also includes several GPIO lines, or some of the Total Phase I²C/SPI gadgets which sell for about \$300 a piece.
\section{The Firmata Protocol}
The performance GEX can provide will certainly be far inferior to those professional tools, however this drawback is balanced by its greater flexibility and for most applications it should be perfectly sufficient, and at a fraction of the cost.
\todo[inline]{links}
\todo[inline]{http://www.ni.com/en-gb/shop/select/i2c-spi-interface-device}
Firmata is a communication protocol based on MIDI (\textit{Musical Instrument Digital Interface}) for passing data to and from embedded microcontrollers. MIDI is mainly used for attaching electronic musical instruments, such as synthesizers, keyboards, mixers etc., to each other or to a PC. Firmata was designed for Arduino as a high level abstraction for its connection to the PC, typically using a FTDI chip or equivalent.
\todo[inline]{pictures}
Implementing Firmata in the GEX firmware would make it possible to use existing Firmata libraries on the PC side. However, the protocol is limited by the encompassing MIDI format and isn't very flexible.

@ -0,0 +1,3 @@
\chapter{The FAT16 Filesystem and Its Emulation}
...

@ -1,2 +1,42 @@
\chapter{FreeRTOS}
FreeRTOS is a free, open-source real time operating system kernel that has been ported to over 30 microcontroller architectures. The kernel provides a scheduler and implements queues, semaphores and mutexes that are used for message passing between concurrent tasks and for synchronization. FreeRTOS is compact designed to be easy to understand; it's written in C with the exception of some architecture-specific routines that use assembly.
FreeRTOS is used in GEX for its synchronization objects and queues that make it easy to safely pass messages from USB interrupts to a working thread that processes them and sends back responses. Similar mechanism is used to handle external interrupts.
\section{Basic FreeRTOS Concepts and Functions}
\subsection{Tasks}
Threads in FreeRTOS are called \textit{tasks}. Each task is assigned a memory area to use as its stack space, and a structure with it's name, saved context and other metadata used by the kernel. A context includes the program counter, stack pointer and other register values. Task switching is done by saving and restoring this context by manipulating the values on stack before leaving and interrupt.
At start-up the firmware initializes the kernel, registers tasks to run and starts the scheduler. From this point onward the scheduler is in control and runs the tasks using a round robin scheme. Which task should run is primarily determined by their priority numbers, but there are other factors. FreeRTOS supports both static and dynamic object creation, including registering new tasks at run-time.
\subsubsection{Task Run States}
Tasks can be in one of four states: Suspended, Ready, Blocked, Running. The Suspended state does not normally occur in a task's life cycle, it's entered and left using API calls on demand. A task is in the Ready state when it can run, but is currently paused because a higher priority task is running. It enters the Running state when the scheduler switches to it. A Running task can wait for a synchronization object (e.g. a mutex) to be available. At this point it enters a Blocked state and the scheduler runs the next Ready task. When no tasks can run, the Idle Task takes control; it can either enter a sleep state to save power, or wait in an infinite loop until another task is available.
\subsubsection{Task Switching and Interrupts}
Task switching occurs periodically in a SysTick interrupt, usually every 1\,ms. After one tick of run time, the running task is paused (enters Ready state), or continues to run if no higher priority task is available. If a high priority task waits for an object and this is made available in an interrupt, the previously running task is paused and the waiting task is resumed immediately (enters the Running state).
Only a subset of the FreeRTOS API can be accessed from interrupt routines, for example it's not possible to use the delay function or wait for an object with a timeout, because the SysTick interrupt which increments the tick counter has the lowest priority and couldn't run. This is by design to prevent unexpected context switching in nested interrupts.
FreeRTOS uses a \textit{priority inheritance} mechanism to prevent situations where a high priority task waits for an object held by a lower priority task (called \textit{priority inversion}). The blocking task's priority is temporarily raised to the level of the blocked high priority task so it can finish faster and release the held object. Its priority is then degraded back to the original value. When the lower priority task itself is blocked, the same process can be repeated.
\subsection{Synchronization Objects}
FreeRTOS provides binary and counting semaphores, mutexes and queues.
Binary semaphores can be used for task notifications, e.g. a task waits for a semaphore to be set by an interrupt when a byte is received on the serial port. This makes the task Ready and if it has a higher priority than the previously running task, it's immediately resumed to process the event.
Counting semaphores are used to represent available resources. A pool of resources (e.g. DMA channels) is accompanied by a counting semaphore, so that tasks can wait for a resource to become available in the pool and then subtract the semaphore value. After finishing with a resource, the semaphore is incremented again and another task can use it.
Mutexes, unlike semaphores, must be taken and released in the same thread (task). They're used to guard exclusive access to a resource, such as transmitting on the serial port. When a mutex is taken, a task that wishes to use it enters Blocked state and is resumed once the mutex becomes available and it can take it.
Queues are used for passing messages between tasks, or from interrupts to tasks. Both sending and receiving queue messages can block until the operation becomes possible.
In GEX, mutexes and semaphores are used for sending messages to the PC, and a queue is used for processing received bytes and to send messages from interrupts, because it's not possible to block on a mutex or semaphore while inside an interrupt routine.
% TODO diagrams, figures

@ -0,0 +1,99 @@
\chapter{Application Structure}
GEX was designed to be modular and easy to extend. At its core lies a general framework that provides services to the functional blocks configured and used by the user script running on the host PC. Functional blocks, or internally called \textit{units}, implement functions like SPI, I2C, GPIO access etc.
In this chapter we'll focus on the general function of the GEX module, look at implementation details of the core framework, and in the next chapter some space will be given to each of the functional blocks.
\textit{A writing style note:} This and the following parts were written after implementing and evaluating the first hardware prototype and its firmware, therefore rather than describing the development process, it tends to talk about the completed solution. All design choices will nevertheless be explained as well as possible.
\section{User's View of GEX}
Before going into implementation details, we'll have a look at GEX from the outside, how an end user will see it. This should give the reader some context to better orient themselves in the following sections and chapters investigating the internal structure of the firmware and the communication protocol.
The GEX firmware can be flashed to a STM32 Nucleo or Discovery board or a custom PCB. It's equipped with a USB connector to connect to the host PC. GEX loads its configuration from the non-volatile memory, configures its peripherals, sets up the function blocks and enables the selected communication interface(s). When USB is connected to the board, the PC enumerates it and either recognizes the communication interface as CDC/ACM (Virtual serial port), or leaves it without a software driver attached, to be accessed directly as raw USB endpoints. This can be configured. The user can now access the functional blocks using the client library and the serial protocol, as well as modify the configuration files.
The board is equipped with a button or a jumper labeled LOCK. When the button is pressed or the jumper removed, the Mass Storage USB interface is enabled. For the user this means a new disk will be detected by their PC's operating system that they can open in a file manager. This disk provides read and write access to configuration INI files and other files with useful information, like a list of supported features and available hardware resources. The user now edits a configuration file and saves it back to the disk. GEX processes the new content, tries to apply the changes and generates an updated version of the file that includes error messages if there was a problem. For the PC OS to recognize this change, the Mass Storage device momentarily reports that the media is unavailable to force the OS to reload it. This is a similar mechanism to what happens when a memory card is removed from a reader. Now the user must reload the file in their editor, inspect the updated content and perform any changes needed. The settings, when applied successfully, should now be available to test using the communication interface. When everything is to the user's satisfaction, the updated settings are committed to the device's non-volatile memory by pressing the LOCK button again, or replacing the jumper.
For boards without a USB re-enumeration capability (notably with older microcontrollers like the STM32F103) that use a jumper, this must be removed before plugging the board to the host USB so that the Mass Storage is enabled immediately at start-up and a re-enumeration is not needed.
In the case when a wireless communication module is installed on the PCB and GEX is configured to use it, this will be used as a fallback when the USB peripheral does not receive an address (get enumerated) within a short time after start-up. The wireless link works in the same way as any other communication interface: it can be used to read and modify the configuration files and to access the functional blocks. To use it, the user needs to connect a wireless gateway module to their host PC and use the radio link instead of a USB cable. The gateway could support more than once GEX board at once.
Now that GEX is connected and configured, the user can start using it. This involves writing a program in C or Python that uses the GEX client library, using the Python library from MATLAB, or controlling GEX using a GUI front-end built on those libraries. The configuration can be stored in the module, but it's also possible to temporarily (or permanently) replace it using the communication API. This way the settings can be loaded automatically when the user's program starts.
\section{The Core Framework Functions}
The core framework forms the skeleton of the firmware and usually doesn't need any changes when new user-facing features are added. It provides:
\begin{itemize}
\item Hardware resource allocation
\item Settings storage and loading
\item Functional block initialization
\item Communication port with different back-ends (USB, UART, wireless)
\item Message sending and delivery
\item Interrupt management and routing to functional blocks
\item Virtual mass storage to allow editing of the configuration files
\end{itemize}
When the firmware needs to be ported to a different STM32 microcontroller, the core framework is relatively straightforward to adapt and the whole process can be accomplished in a few hours. The time consuming part is modifying the functional blocks to work correctly with the new device's hardware.
\subsection{Source Code Layout}
Looking at the source code repository, at the root we'll find device specific driver libraries and files provided by ST Microelectronics, the FreeRTOS middleware, and a folder \verb|User| containing the GEX firmware. This folder is a git submodule. The GEX core framework consists of everything in \verb|User|, excluding the \verb|units| folder. The USB Device library, which had to be modified to support a composite class, is stored inside the \verb|User| folder as well. Hardware configuration, such as the status LED position or clock settings, are defined using compile flags set in the top level Makefile.
\section{Functional Blocks} \label{sec:units-function}
GEX's functional blocks, internally called \textit{units}, have been mentioned a few times but until now haven't been properly explained. GEX's user-facing functions are implemented in \textit{unit drivers}. Those are stand-alone modules that the user can enable and configure using the configuration file. In principle, there can be multiple instances of each unit type. However, in practice, we have to work with hardware constraints: there is only one ADC peripheral, two SPI ports and so on. This limitation is handled using resource allocation, as explained below.
Each unit is defined by a section in the configuration file \verb|UNITS.INI|. It is given a name and a \textit{callsign}, a number which serves as an address for messages from the host PC, or, conversely, to indicate which unit sent an event report (such as a pin change interrupt). A unit is internally represented by an object that holds its configuration, internal state, and a link to the unit driver. The driver handles commands sent from the host PC, initializes and de-initializes the unit based on its settings and implements other aspects of a unit's function, such as periodic updates and interrupt handling.
\section{Resource Allocation}
The microcontroller provides a number of hardware resources that require exclusive access: GPIO pins, peripheral blocks (SPI, I2C, UART\textellipsis), and DMA channels. When two units tried to control the same pin, the results would be unpredictable; worse, with a multiple access to a serial port, the output would be a mix of the data streams and completely useless.
To prevent multiple access, the firmware includes a \textit{resource registry}. Each individual resource is represented by a field in a resource table together with its owner. Initially, all resources are free, except those not available on the particular platform (i.e. a GPIO port E may be disabled if not present on the microcontroller's package). On start-up, the resources used by the core framework are taken by a virtual unit \verb|SYSTEM| to prevent interference by user's units. This is the case of the status LED, the LOCK button, GPIO pins used for connecting USB, communication UART, the wireless module and the crystal oscillator, as well as the timer/counter which keeps the system timebase.
\todo[inline]{resources diagram}
\section{Settings Storage}
The system and unit settings are written, in a binary form, into designated pages of the microcontroller's Flash memory. The unit settings serialization and parsing is implemented by the respective unit drivers.
As the settings persist after a firmware update, it's important to maintain backwards compatibility. This is achieved by prefixing the unit's settings by a version number. When the settings are loaded by a new version of the firmware, it first checks the version and decides whether to use the old or new format. When the settings are next changed, the new format will be used.
The mentioned INI files that can be edited through the communication API or using a text editor with the virtual mass storage, are parsed and generated on demand and are never stored in the Flash or RAM, other than in short temporary buffers. The INI parser processes the byte stream on-the-fly as it is received, and a similar method is used to build a INI file from the configured units and system settings.
\todo[inline]{a diagram}
\section{Communication Ports}
The firmware supports three different communication ports: hardware UART, USB (virtual serial port), and a wireless connection. Each interface is configured and accessed in a different way, but for the rest of the firmware (and for the PC-side application) they all appear as a full duplex serial port. To use interfaces other than USB, the user must configure those in the system settings (a file \verb|SYSTEM.INI| on the configuration disk).
At start-up, the firmware enables the USB peripheral, configures the device library and waits for enumeration by the host PC. When not enumerated, it concludes the USB cable is not connected, and tries some other interface. The UART interface can't be tested as reliably, but it's possible to measure the voltage on the Rx pin. When idle, a UART Rx line should be high (here 3.3\,V). The wireless module, when connected using SPI, can be detected by reading a register with a known value and comparing those.
\subsection{USB Connection}
GEX uses vid:pid \verb|1209:4c60| and the wireless gateway \verb|1209:4c61|. The USB interface uses the CDC/ACM USB class (\ref{sec:cdc-acm}) and consists of two bulk endpoints with a payload size of up to 64 bytes.
\subsection{Communication UART}
The parameters of the communication UART (such as the baud rate) are defined in \verb|SYSTEM.INI|. It's mapped to pins PA2 and PA3; this is useful with STM32 Nucleo boards that don't include a User USB connector, but provide a USB-serial bridge using the on-board ST-Link programmer, connected to those pins.
This is identical to the USB connection from the PC application's side, except a physical UART is necessarily slower and does not natively support flow control. The use of the Xon and Xoff software flow control is not practical with binary messages that could include those bytes by accident, and the ST-Link USB-serial adapter does not implement hadware flow control.
\subsection{Wireless Connection}
The wireless connection uses an on-board communication module and a separate device, a wireless gateway, that connects to the PC. The wireless gateway is interfaced differently from the GEX board itself, but it also shows as a virtual serial port on the host PC. This is required to allow communicating with the gateway itself through the CDC/ACM interface in addition to addressing the end devices.
This interface will be explained in more detail in chapter XX\todo{LINK}.
\section{Message Passing}
One of the key functions of the core framework is to deliver messages from the host PC to the right units. This functionality resides above the framing protocol, which will be described in chapter XX \todo{Link to tinyframe description}.
A message that is not a response in a multi-part session (this is handled by the framing library) is identified by its Type field. Two main groups of messages exist: \textit{system messages} and \textit{unit messages}. System messages can access the INI files, query a list of the available units, restart the module etc. Unit messages are addressed to a particular unit by their callsign (see \ref{sec:units-function}), and their payload format is defined by the unit driver. The framework reads the message type, then the callsign byte, and tries to find a matching unit in the unit list. If no unit with the callsign is found, an error response is sent back, otherwise the unit driver is given the message to handle it as required.
The framework provides one more messaging service to the units: event reporting. An asynchronous event, such as an external interrupt, an ADC trigger or an UART data reception needs to be reported to the host. This message is annotated by the unit callsign so the user application knows it's origin.

@ -0,0 +1,39 @@
\chapter{Supported Hardware Buses}
\section{UART and USART}
The \textit{Universal Synchronous / Asynchronous Receiver Transmitter} has a long history and is still in widespread use today. It is the protocol used in RS-232, which can be considered a predecessor of USB in some aspects. RS-232 was once a common way of connecting modems, printers, mice and other devices to personal computers. UART framing is also used in the industrial bus RS-485.
UART, as implemented by microcontrollers, is a two-wire full duplex interface that uses 3.3\,V or 5\,V logic levels. The data lines are high when idle. A frame starts by a start-bit (low) followed by \textit{n} data bits (typically eight), an optional parity bit and 0.5 to 2 stop bits (high). Variants with fewer or more bits exist, especially in older hardware. The parity bit can be odd, even, or missing entirely. A stop bit is usually 1 clock cycle long; other lengths are used in protocols derived from UART, such as in the SmartCard interface. \todo{reference}
\todo[inline]{figure}
UART and USART are two variants of the same interface. USART includes a clock signal and should therefore support higher frequencies. UART timing relies on a well-known clock speed and is synchronized by start bits. In RS-232 the two data lines (Rx and Tx) are accompanied by RTS (Ready To Send), CTS (Clear To Send) and DTR (Data Terminal Ready) that facilitate handshaking and hardware flow control.
\todo[inline]{examples}
\section{SPI}
SPI (Serial Peripheral Interface) is a point-to-point or multi-drop master-slave interface based on shift registers. It uses at least 4 wires: SCK (Serial Clock), MOSI (Master Out Slave In), MISO (Master In Slave Out) and SS (Slave Select). SS is often marked CSB (Chip Select Bar) or NSS (Negated Slave Select) to indicate it's active low. Slave devices are addressed using their Slave Select input while the other wires are shared. A slave that's not addressed releases the MISO line to a high impedance state so it doesn't interfere in ongoing communication.
Transmission and reception on the SPI bus happen at the same time. A bus master asserts the SS pin of a slave it wishes to address and then sends data on the MOSI line while receiving a response on MISO. The slave doesn't know the command before the first byte is completed, so it usually responds with zeros or sends a status byte in this phase.
\todo[inline]{figure}
SPI devices often provide a number of control, configuration and status registers that can be read and written by the bus master. The first byte of a command usually contains one bit that determines if it's a read or write access, and an address field selecting the target register.
\todo[inline]{examples}
\section{I2C}
Last of the three common protocols covered here is be I2C. It's a two-wire, open-drain bus that supports multi-master operation. I2C is more complicated than either UART or SPI; it supports 3 speeds \todo{speeds}.
\todo[inline]{diagrams and more from the specification}
\section{1-Wire}
1-Wire uses a bi-directional data line that can also power the connected devices, giving the bus its name. TODO ,,,,,
\section{NeoPixel}
...m,,,

@ -1,16 +1,24 @@
\chapter{Introduction}
\chapter{Motivation}
Prototyping, design evaluation and the measurement of physical properties in experiments make a daily occurrence in the engineering praxis. This task typically involves the generation and capture of electrical signals coming to and from specialized sensors, actuators and other circuitry. As the technology advanced, mainly driven by the consumer electronics market and the automotive industry, a variety of affordable integrated sensors became available. Those devices can provide a sufficient accuracy and precision for the task at hand while keeping the circuit complexity down by integrating a large portion of the necessary circuitry together with the sensor on a single chip or in a compact module. Those modern components gives as a low cost alternative to expensive laboratory equipment and much larger instruments previously used.\todo{concrete examples}
Prototyping, design evaluation and the measurement of physical properties in experiments make a daily occurrence in the engineering praxis. Those tasks typically involve the generation and sampling of electrical signals coming to and from sensors, actuators, and other circuitry.
However, the drive for miniaturization and the advent of modern hardware buses, in particular USB (Universal Serial Bus), lead to the disappearance of low level computer ports, such as the once ubiquitous parallel port, that would provide an easy way of connecting those digital devices (and low level hardware in general) to personal computers.
In the recent years a wide range of intelligent sensors became available thanks to the drive for miniaturization in the consumer electronics industry. Those devices often provide a sufficient accuracy and precision while keeping the circuit complexity and cost low. In contrast to analog sensors, here the signal conditioning and processing circuits are built into the sensor itself and we interface it using a digital connection.
Today, when one wants to perform some measurements using a digital sensor, the usual route is to implement an embedded firmware for a microcontroller that can be connected to the PC through USB. This approach makes it possible to optimize the solution for a particular task and achieve high performance. However, building such a specialized tool, or even writing the firmware alone, is time-consuming and requires domain knowledge that is entirely removed from the measurements we want to perform with it.
It's natural that we'd want to communicate with those integrated sensors from our computers and laptops to perform experiments or even to just get familiar with the particular device before using it in a project. It's also convenient to have a direct access to hardware, be it analog signal sampling, generation, or even just logic level inputs and outputs. However, the drive for miniaturization and the advent of USB (Universal Serial Bus) lead to the disappearance of low level computer ports, such as the printer port (LPT), that would provide an easy way of doing so.
Clearly it would be advantageous to have a way to easily attach those integrated devices and low other level hardware to a PC without having to burden ourselves with technicalities of the connection, even at the cost of lower performance compared to a specialized device or a professional tool. The design and implementation of such a user-friendly, general purpose hardware interfacing system is the object of this work.
Today, when one wants to perform some measurements using a digital sensor, the usual route is to implement an embedded firmware for a microcontroller that connects to the PC through USB, or perhaps just shows the results on a display. This approach has some advantages, but is time-consuming and requires knowledge entirely unrelated to the measurements we wish to perform. It would be advantageous to have a way to interface hardware without having to burden ourselves with the technicalities of the connection, even at the cost of lower performance compared to a specialized device or a professional tool.
The design and implementation of such a universal instrument is the object of this work. For technical reasons, such as naming the source code repositories, we need a name for the project; it'll hereafter be referred to as \textit{GEX}, originating from GPIO Expander.
\section{Project's Expected Outcome}
The idea behind GEX has formed over many years, and it's the author's belief that many engineers have at some point wanted to build something similar, and often did so. Indeed, several projects approaching this problem from different angles can be found on the internet; those will be presented in chapter \ref{sec:prior-art}. The aim here is to build an extensible open source platform that others could re-use and adapt to their specific needs.
Building on the experience with earlier embedded projects, a STM32 microcontroller shall be used. Those are ARM Cortex M devices with a wide range of hardware peripherals that appear be a good fit for the project. Low-cost evaluation boards are widely available that could be used as a hardware platform instead of developing a custom PCB. In addition, those chips are relatively cheap and popular in the embedded hardware community; there's a good possibility of the project building a community around it and growing beyond what will be presented in this paper.
Besides the use of existing development boards, custom PCBs will be developed in different form factors. Those could use the Arduino connector or the Raspberry Pi Zero GPIO header (and board shape) to exploit the cases and boxes available for the minicomputer on the market, as well as add-on boards (\textit{shields} and \textit{HATs}).
The possibilities of wireless connection should be evaluated. This feature would make GEX more convenient to use when it's attached e.g. to a mobile robot or installed in poorly accessible locations.

@ -0,0 +1,84 @@
\chapter{Requirement Analysis}
We'll now investigate some situations where GEX could be used, to establish its requirements and desired features.
\subsection{\label{sec:uses-digital-ifaces}Interfacing Intelligent Modules}
When adding a new digital sensor or a module to a hardware project, we want to test it first, learn how to properly communicate with it and confirm its performance. Based on this evaluation we decide whether the module matches our expectations and learn how to properly connect it, which is needed for a successful PCB layout.
In experimental setups, this may be the only thing we need. Data can readily be collected after just connecting the module to a PC, same as commanding motor controllers or other intelligent devices.
A couple well known hardware buses have established themselves as the standard ways to interface digital sensors and modules: SPI, I2C and UART are the most used ones, often accompanied by a few extra GPIO lines such as Reset, Chip Enable, Interrupt. There are exceptions where silicon vendors have developed proprietary communication protocols that are still used, either for historical reasons or because of their specific advantages. An example is the 1-Wire protocol used by digital thermometers.
Moving to industrial and automotive environments, we can encounter various fieldbuses, Ethernet, CAN, current loop, HART, LIN, DALI, RS485 (e.g. Modbus), mbus, PLCBUS and others. Those typically use transceiver ICs and other circuitry, such as TVS, discrete filters, galvanic isolation etc. They could be supported using add-on boards and additional firmware modules handling the protocol. For simplicity and to meet time constraints, the development of those boards and modules will be left for future expansions of the project.
\subsection{Analog signal acquisition}
Sometimes it's necessary to use a traditional analog sensor, capture a transient waveform or to just measure a voltage. GEX was meant to focus on digital interfaces, however giving it this capability makes it much more versatile. Nearly all microcontrollers include an analog-digital converter which we can use to measure input voltages and, paired with a timer, to records signals varying in time.
Certain tasks, such as capturing transient effects on a thermocouple when inserted into a flame (an example from developing fire-proof materials) demand level triggering similar to that of oscilloscopes. The converter continuously measures the input voltage and a timed capture starts only after a set threshold is exceeded. This can be accompanied by a pre-trigger feature where the timed capture is continuously running and the last sample is always compared with the threshold, recording a portion of the historic records together with the following samples.
\subsection{Analog signal output}
An analog signal can not only be measured, but it's often necessary to also generate it. This could serve as an excitation signal for an experiment, for instance to measure the characteristic curves of a diode or a transistor. Conveniently, we can at the same time use GEX's analog input to record the output.
Generating an analog signal is possible using a pulse-width modulation (PWM) or by a dedicated digital-analog converter included in many microcontrollers. Higher frequencies or resolution can be achieved with a dedicated external IC.
\subsection{Logic level input and output}
We've covered some more advanced features, but skipped the simplest feature: a direct access to GPIO pins. Considering the latencies of USB and the PC's operating system, this can't be reliably used for "bit banging", however we can still accomplish a lot with just changing logic levels - e.g. to control character LCDs, or emulate some interfaces that include a clock line, like SPI. As mentioned in \ref{sec:uses-digital-ifaces}, many digital sensors and modules use plain GPIOs in addition to the communication bus for out-of-band signaling or features like chip selection or reset.
\subsection{Pulse generation and measurement}
Some sensors have a variable frequency or a pulse-width modulated (PWM) output. To capture those signals and convert them to a more useful digital value, we can use the external input functions of a timer/counter in the microcontroller. Those timers have many possible configurations and can also be used for pulse counting or a pulse train generation.
\section{Connection to the Host Computer}
\subsection{Messaging}
USB shall be the primary way of connecting the module to a host PC. Thanks to USB's flexibility, it can present itself as any kind of device or even multiple devices at once.
The most straightforward method of interfacing the board is by passing binary messages in a fashion similar to USART (and plain UART can be available as well). We'll need a two-way connection to enable command confirmations, query-type commands and asynchronous event reporting.
This is possible either using a "Virtual COM port" driver (the CDC/ACM USB class), or through a raw access to the corresponding USB endpoints. Using a raw access avoids potential problems with the operating system's driver interfering or not recognizing the device correctly; on the other hand, having GEX appear as a serial port makes it easier to integrate into existing platforms that have a good serial port support (such as National Instruments LabWindows CVI or MATLAB).
\subsection{Configuration Files}
The module must be easily reconfigurable. Given the settings are almost always going to be tied on the connected external hardware, it would be practical to have an option to store them permanently in the microcontroller's non-volatile memory.
We can load those settings into GEX using the serial interface, which also makes it possible to reconfigure it remotely when the wireless connection is used. With USB, we can also make the board appear as a mass storage device and expose the configuration as text files. This approach, inspired by ARM mbed's mechanism for flashing firmware images to development kits, avoids the need to create a configuration GUI, instead using the PC OS's built-in applications like File Explorer and Notepad. We can expose additional information, such as a README file with instructions or a pin-out reference, as separate files on the virtual disk.
\section{Planned Feature List}
Let's list the features we wish to initially support in the GEX firmware:
\begin{itemize}
\item \textbf{Hardware interfacing functions}
\begin{itemize}
\item I/O pin direct access (read, write), pin change interrupt
\item Analog input: voltage measurement, sampled capture
\item Analog output: static level, waveform generation
\item Frequency, duty cycle, pulse length measurement
\item Single pulse and PWM generation
\item SPI, I$^2$C, UART/USART
\item Dallas 1-Wire
\item NeoPixel (addressable LED strips)
\end{itemize}
\item \textbf{Communication with the host computer}
\begin{itemize}
\item USB connection as virtual serial port or direct endpoint access
\item Connection using plain UART
\item Wireless connection
\end{itemize}
\item Reconfiguration using INI files, accessed through the API or using a virtual mass storage
\end{itemize}
\section{Microcontroller selection}
The STM32F072 microcontroller was chosed for the built prototypes and the initial firmware, owning to it's low cost, advanced peripherals and the availability of development boards. GEX can be later ported to other MCUs, like the STM32L072, STM32F103 or STM32F303.
The STM32F072 is a Cortex M0 device with 128\,KiB of flash memory, 16\,KiB of RAM and running at 48\,MHz. It is equipped with a USB Full Speed peripheral block, a 12-bit ADC and DAC, a number of general purpose timers/counters, SPI, I$^2$C, and USART peripherals, among others. It supports crystal-less USB, using the USB SOF packet for synchronization of the internal 48\,MHz RC oscillator; naturally, a real crystal resonator will provide better timing accuracy.
To effectively utilize the time available for this work, only the STM32F072 firmware will be developed while making sure the planned expansion is as straightforward as possible.
\todo[inline]{info about form factor choices + some sketches}

@ -4,7 +4,7 @@ This chapter presents an overview of the \textit{Universal Serial Bus} (USB) \te
\section{Basic Principles and Terminology}
%TODO add a diagram of the hierarchical topology
\todo[inline]{add a diagram of the hierarchical topology}
USB is a hierarchical bus with a single master (\textit{host}) and multiple slave devices. A USB device that provides functionality to the host is called a \textit{function}. Communication between the host and a function is organized into virtual channels called \textit{pipes}. Each pipe is identified by an \textit{endpoint} number.
@ -22,11 +22,12 @@ There are four types of transfers: control, bulk, isochronous, and interrupt. Ea
The endpoint transfer type and other characteristics, together with other information about the device, such as the serial number, are defined in a \textit{descriptor table}. This is a tree-like binary structure defined in the function's memory. The descriptor table is loaded by the host to learn about the used endpoints and to attach the right driver to it.
The function's endpoints are grouped into \textit{interfaces}. An interface describes a logical connection of endpoints, such as the reception and transmission endpoint that belong together. An interface is assigned a \textit{class} defining how it should be used. Standard classes are defined by the USB specification to provide a uniform way of interfacing devices of the same type, such as human-interface devices (mice, keyboards, gamepads) or mass storage devices. The use of standard classes makes it possible to re-use the same driver software for devices from different manufacturers. The class used for the GEX's "virtual COM port" function was originally meant for telephone modems, a common way of connecting to the Internet at the time the first versions of USB were developed. A device using this class will show as \verb|/dev/ttyACM0| on Linux and as a COM port on Windows, provided the system supports it natively or the right driver is installed.
%TODO add reference to the document
%TODO fix: massive gap here
\todo[inline]{add reference to the document}
%function - https://technet.microsoft.com/en-us/library/cc939102.aspx
\todo[inline]{fix: massive gap here}
\todo[inline]{function - https://technet.microsoft.com/en-us/library/cc939102.aspx}
\newpage
\input{fig.gex-descriptors}
@ -52,8 +53,7 @@ The USB cable contains 4 conductors:
The data lines, D+ and D--, are also commonly labeled DP and DM. This differential pair should be routed in parallel and kept at approximately the same length.
USB revisions are, where possible, backwards compatible, often even keeping the same connector shape. The bus speed is negotiated by the device using a 1.5\,k$\Omega$ pull-up resistor (to 3.3\,V) on one of the data lines: for Full Speed, D+ is pulled high (fig. \label{fig:usb-pullup-fs}), for Low Speed the pull-up is on the D-- line. The polarity of the differential signals is inverted depending on the used speed. Some microcontrollers integrate the correct pull-up resistor inside the USB block, removing the need for an external resistor.
USB revisions are, where possible, backwards compatible, often even keeping the same connector shape. The bus speed is negotiated by the device using a 1.5\,k$\Omega$ pull-up resistor to 3.3\,V on one of the data lines: for Full Speed, D+ is pulled high (fig. \label{fig:usb-pullup-fs}), for Low Speed it's on D--. The polarity of the differential signals is inverted depending on the used speed. Some microcontrollers integrate the correct pull-up resistor inside the USB block (including out STM32F072), removing the need for an external resistor.
\begin{figure}
\centering
@ -61,27 +61,29 @@ USB revisions are, where possible, backwards compatible, often even keeping the
\caption{\label{fig:usb-pullup-fs}Pull-up and pull-down resistors of a Full Speed function, as prescribed by the USB specification rev. 2.0}
\end{figure}
When a function needs the host to re-enumerate it, that is, reload the descriptors and re-attach the correct drivers, it can momentarily remove the pull-up resistor, which the host will interpret as if the device was plugged out. In the case of an internal pull-up, this can be done by flipping a control bit. An external resistor could be connected through a transistor to facilitate re-enumeration, or it might be driven directly by a GPIO pin.
When a function wants to be re-enumerated by the host, which is needed to reload the descriptors and re-attach the correct drivers, it can momentarily remove the pull-up resistor, which the host will interpret as if the device was plugged out. With an internal pull-up this can be done by flipping a bit in a control register. An external resistor can be connected through a transistor controlled by a GPIO pin.
%https://www.eevblog.com/forum/projects/driving-the-1k5-usb-pull-up-resistor-on-d/
%http://www.beyondlogic.org/usbnutshell/usb2.shtml
\todo[inline]{https://www.eevblog.com/forum/projects/driving-the-1k5-usb-pull-up-resistor-on-d/}
\todo[inline]{http://www.beyondlogic.org/usbnutshell/usb2.shtml}
The V$_\mathrm{BUS}$ line supplies power to the function in the case of a \textit{bus-powered} device. \textit{Self-powered} devices can leave this pin unconnected and instead use an external power supply. The maximal current drawn from the V$_\mathrm{BUS}$ line is configured using a descriptor and should not be exceeded.
The V$_\mathrm{BUS}$ line supplies power to \textit{bus-powered} devices. \textit{Self-powered} devices can leave this pin unconnected and instead use an external power supply. The maximal current drawn from the V$_\mathrm{BUS}$ line is configured using a descriptor and should not be exceeded, but experiments suggest this is often not enforced.
\section{USB Classes}
This section explains the function of the Mass Storage class and the CDC/ACM class that find use in the GEX firmware. A list of all standard classes with a more detailed explanation can be found in \todo{link to the ref manual}.
This section explains the Mass Storage class and the CDC/ACM class that are used in the GEX firmware. A list of all standard classes with a more detailed explanation can be found in \todo{link to the ref manual}.
\subsection{Mass Storage Class}
The Mass Storage class (MSC) is natively supported by all modern operating systems (MS Windows, MacOS, GNU/Linux, FreeBSD etc.) and finds use in thumb drives, external disks, memory card readers and other storage devices.
The Mass Storage class (MSC) is supported by all modern operating systems (MS Windows, MacOS, GNU/Linux, FreeBSD etc.) to support thumb drives, external disks, memory card readers and other storage devices.
\todo[inline]{links}
%http://www.usb.org/developers/docs/devclass_docs/Mass_Storage_Specification_Overview_v1.4_2-19-2010.pdf
%http://www.usb.org/developers/docs/devclass_docs/usbmassbulk_10.pdf
The MSC specification defines multiple \textit{transport protocols} that can be selected using the descriptors. For it's simplicity, the \textit{Bulk Only Transport} (BOT) will be used. BOT uses two bulk endpoints for reading and writing blocks of data and for the exchange of control commands and status messages. For the device to be recognized by the operating system, it must also implement a \textit{command set}. Most mass storage devices use the \textit{SCSI Transparent command set}
\footnote{To confirm this assertion, the descriptors of five thumb drives and an external hard disk were analyzed using \verb|lsusb|. All but one device used the SCSI command set, one (incidentally the oldest) used \textit{SFF-8070i}. A list of possible different command sets can be found in TODO (usb spec overview)}.
The defined commands let the host read information about the attached storage, such as its capacity, and check for media presence and readiness to write or detach.
\footnote{To confirm this assertion, the descriptors of five thumb drives and an external hard disk were analyzed using \verb|lsusb|. All but one device used the SCSI command set, one (the oldest thumb drive) used \textit{SFF-8070i}. A list of possible command sets can be found in TODO (usb spec overview)}.
The command set's commands let the host read information about the attached storage, such as its capacity, and check for media presence and readiness to write or detach. This is used e.g. for the "Safely Remove" function which checks that all internal buffers have been written to Flash.
\todo[inline]{links}
% weird flash - SFF-8070i subclass
@ -91,25 +93,26 @@ The defined commands let the host read information about the attached storage, s
%http://janaxelson.com/mass_storage_faq.htm
The MSC class together with the SCSI command set are rather complicated, thankfully a driver library is provided by ST Microelectronics that can be used as given, or customized. The library also includes a CDC/ACM implementation.
The MSC class together with the SCSI command set are implemented in a USB Device library provided by ST Microelectronics. The library also includes a basic CDC/ACM implementation (see below).
In order to emulate a mass storage device without having a physical storage medium, we need to generate and parse the filesystem on-the-fly, as the host OS tries to access it. This will be discussed in chapter ??\todo{chapter num}.
In order to emulate a mass storage device without having a physical storage medium, we need to generate and parse the filesystem on-the-fly as the host OS tries to access it. This will be discussed in chapter ??\todo{chapter num}.
\subsection{CDC/ACM Class}
\subsection{CDC/ACM Class} \label{sec:cdc-acm}
%https://www.keil.com/pack/doc/mw/USB/html/group__usbd__cdc_functions__acm.html
Historically meant for modem communication, this class is now the de facto standard way of making USB devices appear as serial ports on the host OS. The CDC (\textit{Communication Device Class}) class uses three endpoints: bulk IN and OUT, and an interrupt endpoint.
Historically meant for modem communication, this class is now the de facto standard way of making USB devices appear as serial ports on the host OS. The CDC (\textit{Communication Device Class}) uses three endpoints: bulk IN and OUT, and an interrupt endpoint.
The interrupt endpoint is used for commands and notifications about the modem line, while the bulk endpoints are used for useful data. ACM stands for \textit{Abstract Control Model} and it's a CDC's subclass that defines the control messages format. Since we don't use any physical serial port in this implementation and the line is virtual both on the PC and in the end device, the interrupt endpoint can mostly be ignored.
\todo{verify this vvv}
The interrupt endpoint is used for control commands and notifications while the bulk endpoints are used for useful data. ACM stands for \textit{Abstract Control Model} and it's a CDC's subclass that defines the control messages format. Since we don't use a physical UART and the line is virtual both on the PC and in the end device, the control commands can be ignored.
An interesting property of this class is that the bulk endpoints transport raw data without any wrapping frames. By changing the device class in the descriptor table to 255 (\textit{Vendor Specific Class}), we can retain the messaging functionality of the designated endpoints and access the device directly using e.g. libUSB, whereas the OS will ignore the device and won't try to attach the serial port driver, which would otherwise interfere. The same trick can be used to hide the mass storage class, when not needed.
An interesting property of this class is that the bulk endpoints transport raw data without any wrapping frames. By changing the device class in the descriptor table to 255 (\textit{Vendor Specific Class}), we can retain the messaging functionality of the designated endpoints and access the device directly using e.g. libUSB, while the OS will ignore it and won't try to attach any driver that could interfere otherwise. The same trick can be used to hide the mass storage class when not needed.
\subsection{Interface Association: Composite Class}
Since it's creation, the USB specification expected that each function will have only one interface enabled at a time. After it became apparent that there is a need for having multiple unrelated interfaces work in parallel, a workaround called the \textit{Interface Association Descriptor} (IAD) was devised. IAD is an entry in the descriptor table that defines which interfaces belong together and should be handled by the same driver.
Since it's creation, the USB specification expected that each function will have only one interface enabled at a time. After it became apparent that there is a need for having multiple unrelated interfaces work in parallel, a workaround called the \textit{Interface Association Descriptor} (IAD) was introduced. IAD is an entry in the descriptor table that defines which interfaces belong together and should be handled by the same software driver.
To use the IAD, the function's class must be set to 239 (EFh), subclass 2, protocol 1 (in the top level descriptor), so the OS knows to look for the presence of IADs before binding drivers to any interfaces.
To use the IAD, the function's class must be set to 239 (EFh), subclass 2 and protocol 1, so the OS knows to look for the presence of IADs before binding drivers to any interfaces.
% TODO link to some references..
@ -117,7 +120,6 @@ In GEX, the IAD is used to tie together the CDC and ACM interfaces while leaving
%http://www.usb.org/developers/docs/whitepapers/iadclasscode_r10.pdf
\todo{examples of descriptors?}

@ -1,20 +1,19 @@
% Abstrakt
\begin{abstract-english}
\begin{otherlanguage}{english}
This work focuses on the design of an AC appliance degradation detector. The goal is to implement a~device in the form of a~power-plug adapter that could be used to monitor and study the characteristics of the AC current.
This thesis documents the development of a general purpose software and hardware platform for interfacing low level hardware from high level programming languages and applications run on a PC, using USB and also wirelessly.
A~prototype with a~STM32\,F3 processor and an ESP8266 programmable WiFi module has been realised, together with a~custom firmware for both processors, which allows easy access to the measurements and charts using a~web browser. The device also supports regular reporting to a~Xively or ThingSpeak monitoring server.
\end{otherlanguage}
The requirements of common engineering tasks and problems occurring in the university environment were evaluated to design an extensible, reconfigurable hardware module that would make a practical, versatile, and low cost tool that in some cases also eliminates the need for professional measurement and testing equipment.
Several hardware prototypes and control libraries in programming languages C and Python have been developed. The Python library additionally integrates with MATLAB scripts. The devices provide access to a range of hardware buses and low level features and can be reconfigured using configuration files stored inside its permanent memory.
\end{abstract-english}
\begin{abstract-czech}
Tato práce se zabývá implementací detektoru poruch a~degradací síťového spotřebiče pomocí analýzy časového průběhu odebíraného proudu. Cílem je navrhnout a~realizovat přístroj ve formě zásuvkového adaptéru, který by bylo možné použít k~monitorování připojeného zařízení.
\begin{otherlanguage}{czech}
Tato práce popisuje vývoj univerzální softwarové a~hardwarové platformy pro přístup k~hardwarovým sběrnicím a~elektrickým obvodům z~prostředí vysokoúrovňových programovacích jazyků a~aplikací běžících na PC, a~to za využití USB a~také bezdrátově.
V~rámci práce byl realizován prototyp přístroje s~procesorem řady STM32\,F3 a~programovatelným WiFi modulem ESP8266. Zařízení umožňuje pohodlné ovládání a~zobrazení grafů spektra a~průběhu proudu pomocí webového rozhraní. Dále je podporováno pravidelné hlášení stavu na servery Xively a~ThingSpeak.
Byly vyhodnoceny požadavky typických problémů, vyskytujících se v~praxi při práci s~vestavěnými systémy a~ve výuce, pro návrh snadno rozšiřitelného a~přenastavitleného hardwarového modulu který bude praktickým, pohodlným a~dostupným nástrojem který navíc v~některých případech může nahradit profesionální laboratorní přístroje.
Bylo navrženo několik prototypů hardwarových modulů, spolu s~obslužnými knihovnami v~jazycích C a~Python; k~modulu lze také přistupovat z~prostředí MATLAB. Přístroj umožňuje přístup k~většině běžných hardwarových sběrnic a~umožňuje také např. měřit frekvenci a~vzorkovat či generovat analogové signály.
\end{otherlanguage}
\end{abstract-czech}

Binary file not shown.

@ -16,15 +16,34 @@
\maketitle % titulní strana a automatické oddíly
% thanks
% abstract
% TOC
\part{Introduction}
\input{ch.introduction}
\input{ch.requirements}
\input{ch.requirement_analysis}
\input{ch.existing_solutions}
\part{Theoretical Background}
\input{ch.usb}
\input{ch.freertos}
\input{ch.fat16}
\input{ch.fat16} % TODO
\input{ch.hw_buses} % TODO
\part{Firmware Implementation}
\input{ch.fw_structure}
\input{ch.gex_units}
\part{Hardware Design}
\input{ch.prototype1_hw}
\appendix % začátek příloh
% seznam bibliografie

Loading…
Cancel
Save