parent
08f498f952
commit
56be653f17
@ -0,0 +1,3 @@ |
|||||||
|
\chapter{The FAT16 Filesystem and Its Emulation} |
||||||
|
|
||||||
|
... |
@ -1,2 +1,42 @@ |
|||||||
\chapter{FreeRTOS} |
\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,,, |
@ -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} |
@ -1,20 +1,19 @@ |
|||||||
% Abstrakt |
% Abstrakt |
||||||
|
|
||||||
\begin{abstract-english} |
\begin{abstract-english} |
||||||
|
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. |
||||||
|
|
||||||
\begin{otherlanguage}{english} |
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. |
||||||
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. |
|
||||||
|
|
||||||
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} |
|
||||||
|
|
||||||
|
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} |
\end{abstract-english} |
||||||
|
|
||||||
|
|
||||||
\begin{abstract-czech} |
\begin{abstract-czech} |
||||||
|
\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ě. |
||||||
|
|
||||||
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í. |
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. |
||||||
|
|
||||||
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. |
|
||||||
|
|
||||||
|
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} |
\end{abstract-czech} |
||||||
|
Binary file not shown.
Loading…
Reference in new issue