Upload
john-dunbar
View
10
Download
0
Embed Size (px)
Citation preview
Running head: Developing a Windows Driver for the PIC Microcontroller 1
Developing a Windows Uniform Serial Bus Driver for the PIC Microcontroller
John H. Dunbar
LIB-495 Liberal Arts Capstone
Section Number OL011
Thomas Edison State College
Mentor: Dr. Augustus Black
October 2016
Developing a Windows Driver for the PIC Microcontroller 2
Abstract
Computer users need methods to access the information stored on a computer and interact with
the computer in useful ways. A microcontroller is an integrated electronic circuit which can
convert user interaction into electronic signals. A driver can be written for an operating system to
convert the electronic signals from the microcontroller into instructions for the computer.
Keywords: driver, operating system, microcontroller
Developing a Windows Driver for the PIC Microcontroller 3
Developing a Windows Uniform Serial Bus Driver for the PIC Microcontroller
Chapter 1: Introduction
Introduction to the Chapter
Advanced integrated circuits exist which allow custom computer hardware interfaces to
be created. These interfaces require complex software known as drivers to be recognized by and
communicate with a computer. Hardware interfaces come in many varieties including Peripheral
Component Interconnect (PCI), Universal Serial Bus (USB), and serial. Similarly, there are a
variety of computer operating systems which communicate with hardware interfaces using
different programming languages. There are many combinations of microcontrollers, operating
systems, and interface types. This study aims to identify the basic requirements to develop a
Windows USB driver for a PIC18F45K50 microcontroller.
Background of the Topic
Advances in computer peripheral technology appear to be happening at a rapid rate.
Oculus just came out with a virtual reality headset. Microsoft will soon be selling the augmented
reality HoloLens. TrackIR has developed a sensor to capture head motion on translate it to in
game character’s head motion (NaturalPoint Inc., 2016). These are all devices that have come
about in the last few years that will shape the way that we interact with computers and they all
utilize USB connectivity.
Problem Statement
There are two microcontrollers in existence which are identified as USB devices by the
computer. One is the Arduino. The Arduino is a cheap easy to use board with a lot of online help
and documentation. However, this board isn’t designed to be programmed as a computer
Developing a Windows Driver for the PIC Microcontroller 4
peripheral. It is designed to act as a stand-alone device that can be used to run household projects
like an aquaponics system or Christmas lights. The second microcontroller is called the Teensy.
The Teensy can be programmed as a keyboard, a mouse, joystick, or game pad and it already has
drivers written for it. The problem with the Teensy is that the premade drivers are generic. For
example, the mouse driver is only programmed to have left click, right click, middle click,
mouse wheel, and x/y position. That does in fact describe a fully functional mouse. However,
what it doesn’t give you is the ability to add new features or take away unnecessary features.
This issue led me to find a microcontroller that would offer potential for customization
and to the major research question: How to write a Windows USB driver for the PIC
microcontroller?
To do that, I first must discover: What is a driver? What are the hardware requirements
for a USB device? How does a computer communicate with a USB device? Will the internal
clock on the PIC be fast enough for USB communication? Do I need an external clock? What is
the difference between a driver for Windows compared to other operating systems? How are
drivers for a USB device different from those of a PCI device?
Professional Significance of Work
Computers are powerful resources which people use daily to perform a variety of tasks
from ordering lunch to performing advanced scientific research. In the 1980’s when computers
were just becoming mainstream peripheral devices included mainly the key board and mouse.
Now there are printers, 3D printers, virtual reality, augmented reality, facial recognition, game
controllers, and more. The ability to develop custom peripheral computer hardware is a powerful
tool for an information technology professional to have.
Developing a Windows Driver for the PIC Microcontroller 5
Software developers have a challenging time creating products that are compatible with
the large variety of hardware and operating system combinations in existence. Hardware drivers
can be developed to function on multiple operating systems. From an economic standpoint, if
resources are limited, it is better to develop a driver for the Window’s operating system because
it has an over 80% market share among desktop computers ( Net Applications.com, 2006-2016).
Also, because it is such a common operating system, the amount of documentation and support
provided to developers is much greater.
In a similar way, because USB is such a commonly used hardware connection type, it
makes sense that it should be a priority when learning to write Window’s drivers. One could also
learn to write drivers for PCI or serial devices. However, they are less common, more complex,
and don’t have as much support and documentation as USB.
Overview of Methodology
To write a driver, first a device is needed. This is where the PIC microcontroller comes
into play. The microcontroller will act as the brain to which connects the other components of the
controller. The PIC18F45K50 is a good choice because it is USB compatible and has the
capability to connect up to 33 switches (Microchip Technology Inc., 2012-2014), giving potential
to create more in depth projects.
An entire test circuit will be set up on a breadboard to save on the time and cost of
purchasing and designing a custom circuit board. The PIC comes with blank memory. To write
code to the chip, a Cana Kit programmer was acquired. Microcontroller program code will be
written using the MPLAB Integrated Development Environment (IDE). The code will then be
translated to hexadecimal by MPLAB and subsequently written to the chip utilizing the Cana Kit
programmer and the PIC Kit 2 software.
Developing a Windows Driver for the PIC Microcontroller 6
To test the validity of the development environment, a simple LED blink program will be
written to the PIC microcontroller. The microcontroller will then be then inserted into the
breadboard and wired to the LED. Once power is applied to the microcontroller and the LED
blinks, the development environment will have been proven to work. The next step is to write a
simple driver that can write to the LED pin and toggle the LED on or off. The driver for
Windows will be written in C# utilizing the Microsoft Visual Studio IDE. Documentation on the
Microsoft website will be utilized to ensure that Microsoft standards for USB communication are
followed. Once the simple driver is created, the capability of the driver could potentially be
expanded for a large variety inputs and outputs.
Delimitations
It would be interesting to test the device to see if driver profiles could be set up to specify
different hardware configurations in the microcontroller. This would allow users to quickly
change the way the computer sees a device. A game controller could end up being used as a
mouse or a keyboard by using a separate profile. However, due to the time constraints of the
research, testing will be saved for a later time.
Definition of Terms
Driver- software designed by electronics manufacturers to allow peripheral
devices to communicate with an operating system
Microcontroller- a programmable electronic chip used for embedded electronics
Universal Serial Bus (USB)- a type of connection to a computer used commonly
today to connect to and share data with a computer from devices not directly
connected to the motherboard
Developing a Windows Driver for the PIC Microcontroller 7
Peripheral Component Interconnect (PCI)- the type of connections on a
computer motherboard commonly used for connecting peripherals such as
graphics cards or network cards
Integrated Programming Environment (IDE)- a computer program which
includes features and tools for writing other computer programs
Breadboard- a device made of a matrix of conductive material used for creating
prototype electronic circuits without the need for soldering
Summary
There are many ways for peripheral devices to communicate with a computer. The most flexible
method of communication is USB. There are existing microcontrollers to communicate with the
PC however, they only offer limited capabilities. It would be convenient and professionally
rewarding to create custom USB drivers.
Chapter 2: Literature Review
Introduction
There is a distinct path that data follows as it passes from the device to the host. A review
of the literature shows that starting from a USB device, a microcontroller is required to pass data
on to the host (Axelson, 2015, pg. 25). Once data is generated on a device, it travels across the
USB cable and through the connectors to the host. For proper communication to occur, the host
must know what type of data to expect (Axelson, 2015, pg. 95-96). This is accomplished through
enumeration and the creation of pipes using a devices endpoint descriptor (Axelson, 2015, pg.
95-96). At this point, the driver takes control and shuffles data between applications and the
device (Orwick & Smith, 2007, Chap. 5, para. 1).
Body Paragraphs
Developing a Windows Driver for the PIC Microcontroller 8
PIC Microcontroller
In his book, Designing Embedded Hardware, Catsoulis (2005) explains how in the 1970’s the
company General Instruments manufactured a 16-bit processor called the CP1600. The company
began to suffer because Intel and Motorola were building competing processors with greater I/O
capability. As a solution to the CP1600’s limited I/O capability, General Instruments developed a
Peripheral Interface Controller (PIC) to boost the I/O of the CP1600. In the end, General
Instruments lost to Intel and Motorola. However, the PIC processor continues to be manufactured
by the company Microchip Technology which was created from the microelectronics division of
General Instruments (Chap. 14 2nd paragraph). PIC microcontrollers are popular because they are
cheap, readily available, include many varieties of chips, and don’t consume very much power
(Axelson, 2015, p. 153). The PIC microcontroller is so common that it can be found in Sony
PlayStation hand controllers, children’s toys, consumer appliances, and industrial systems
(Catsoulis, 2005, Chap. 14 2nd paragraph). Another application of PIC microcontrollers is
controlling USB device communications. For a USB device to connect to a host it needs a USB
compatible chip with a CPU or other architecture for exchanging data with a host (Axelson,
2015, p. 25). All microcontrollers include a CPU, memory, and I/O connections on a chip
(Rafiquzzaman, 2014, Chap. 7 3rd paragraph). However, not all microcontrollers are built for
USB communication. The PIC is one brand of microcontroller with models capable of USB
device control. The PIC18F45K50 is a specific model of microcontroller that is capable of USB
communication. (28/40/44-Pin, 2014, p. 1).
USB Specifications
There are several versions of USB which can be used for passing data from a device to a
host. In a white paper written by Murphy (2016), he describes the various versions of USB,
Developing a Windows Driver for the PIC Microcontroller 9
saying, in 1996 USB 1.0 was introduced. It supported a low speed connection of 1.5Mb/s and a
full speed connection of 12Mb/s. High speed transmission can be a problem because it causes a
buildup of electromagnetic interference (EMI) which requires more expensive manufacturing
materials to mitigate. Having two speeds is beneficial because it allows manufacturers who don’t
require high speed data transmission to use cheaper parts. In 1998 USB 1.1 was developed to add
some minor improvements to the 1.0 specification (p. 2). In 2000, USB 2.0 was released with a
new high speed transfer rate of 480 Mb/s (USB-IF, 2000, p. 11). USB 3.0 was released in 2008
and brought the maximum transfer speed up to 5 Gb/s, more than 10 times the speed of USB 2.0
(USB-IF, 2011, p. 3-5). The latest version of USB is 3.1. It was released in 2013 and includes
new power saving features and a 10 Gb/s transfer rate (USB-IF, 2013, p. 1-1).
USB Physical Connection
Before data can be passed from device to host, a physical connection must be made
between the two. Axelson (2015) details the requirements of a USB 2.0 connection by stating
that connections are made with one wire for power, another for ground, and two signal wires
called D+ and D-. The predecessor to USB, called RS-232, used one signal wire for transmit and
the other for receive. USB uses both signal wires as either transmit or receive, restricting traffic
to one direction at a given time (p. 453). The USB 2.0 Specification (2008) describes the unique
USB connectors that can be used to terminate the two ends of the four-wire cable. The host end
(upstream) is terminated with a Series “A” connector. The device end (downstream) of the cable
utilizes Series “B” connector. However, manufacturers may opt to connect the cable directly to
the device without using a downstream connector (p. 86).
Developing a Windows Driver for the PIC Microcontroller 10
(USB-IF, 2000, p. 87)
According to Catsoulis (2005), the entire USB system consists of at least one USB device
(with a maximum of 127), at least one hub, and one host. Although peripheral USB hubs exist,
the host possesses a root hub which serves as the origin for attached devices. A peripheral USB
hub is only required when the host lacks the number USB ports required for the number of
devices desired. A hub is required to allow the host to initiate communication with a device. This
initial communication is called enumeration (Chap. 11 para. 6 & 7).
USB Logical Connection
Transfer Types
Axelson (2015) describes four transfer types supported by USB devices. When a device
is connected to a host, the host uses control transfers to get device descriptors containing
information about the device capabilities. Bulk transfers are the fastest type of transfer but
cannot guarantee the integrity of data at the receiving end. Interrupt transfers are a transfer type
with a set maximum time to transfer. Isochronous transfers strictly follow standards of timing but
cannot handle error correcting (p. 34).
End Points
According to McDowell & Seyer (1998) an endpoint is a place defined within the
firmware of a USB device to which data can flow to or from. An endpoint can be either an input
Developing a Windows Driver for the PIC Microcontroller 11
or an output but not both. For a USB device to receive both input and output, it needs at least two
endpoints (Chap. 2, What are Pipes and Endpoints, para. 2).
Axelson (2015) explains that an endpoint is a reserved block of memory in a device that is used
to hold a buffer that can store multiple incoming or outgoing bytes of information. Not including
endpoint zero, a high-speed device can have up to 30 endpoints (p. 36). Device firmware
declares the number of endpoints supported for a device and the details of how the device
expects to handle input and output on those endpoints. A review of the software library provided
by Microchip Technology shows that an endpoint descriptor transfer type is defined in the USB
endpoint descriptor (usb_descriptors.c, 2016).
Pipes
A logical connection between a host and a device is created with pipes that are matched
to endpoints. The Microsoft Developer Network website states that when the device is
configured, the driver assigns a pipe to the device endpoints defined in the descriptor. Depending
on the endpoint’s definition, the driver will pair it with a particular variety of pipe. A bulk
endpoint gets a bulk pipe, isochronous gets isochronous, interrupt gets interrupt, control gets
control (How to Enumerate USB Pipes, 2016, 3rd para.). McDowell & Seyer (1998) describe
two main categories of pipes which the four pipes discussed above fall under, stream pipes and
message pipes. Stream pipes have no predefined packet structure to abide by. Message pipes
have a structure dictated by the host and the data must be properly organized prior to
transmission. A control pipe (pipe zero) is used for device set up and transmission of data
describing device features. One control pipe exists for each device on a host (Chap. 2, What are
Pipes and Endpoints, para. 3). For data transfers to occur, Axelson (2015) states that a host is
Developing a Windows Driver for the PIC Microcontroller 12
required to open a pipe to a device. Pipes are created when a device is connected to the host and
enumeration takes place. When the device is detached, pipes are destroyed (p. 37).
Enumeration/PnP Manager
Axelson (2015) describes that when a device is plugged into a USB port on a host, it
registers with the host through the enumeration process. The host first recognizes a device has
been plugged in because the device will send a high signal on either the D+ or D- wire to the root
hub, which subsequently notifies the host. The host then sends a USB reset signal to the device
through the hub. During the reset, the device will notify the host if it supports high speed by
sending a high signal on D-. Once this step is complete, the device is ready to receive control
transfers from the host on endpoint zero (p. 94). In his book, Advanced PIC Microcontroller
Projects in C, Ibrahim (2011) explains that the next thing the host does is send a Get Descriptor
command to the device to determine the device’s maximum packet size. After learning of the
devices maximum packet size, the host gives the device a unique address and sends a Set
Address request to the device. Using the newly assigned address, the host sends the Get
Descriptor request again because the first time it stopped after it found the maximum packet size.
The second request allows the host to learn the device manufacturer, type of device, and
maximum control packet size (Chap. 8, Enumeration, para. 1). The next command the host sends
is to get the device’s configuration data which includes descriptors for interfaces or other vendor
defined descriptors as well as the endpoint details for the given interfaces. Axelson (2015)
describes the final steps of enumeration mentioning that once the device responds to the host
with configuration data, the host uses the data to find the best match for a driver to manage
further device communications and vendor defined commands (p. 95-96).
Windows Driver Foundation
Developing a Windows Driver for the PIC Microcontroller 13
The book Developing Drivers with Windows Driver Foundation written by Orwick and
Smith (2007) defines the Windows Driver Foundation (WDF) as a set of tools called frameworks
for developing Windows drivers. The two frameworks included in the WDF are the User Mode
Driver Framework (UMDF) and the Kernel Mode Driver Framework (KMDF) (Chap. 1 para. 4).
Belevsky and Pavlov (2008) explain that user mode drivers exist to increase system security,
stability, and fault tolerance by limiting the driver’s access to the core of the operating system. A
kernel mode driver allows direct access to user memory including the buffers used for passing
data (Chap. 6 para. 3,5).
The WDF frameworks consist of a library of objects used to interface with the operating
system for device input and output (Orwick & Smith, 2007, Kernel Objects and Data Structures
para. 1). In his book Windows 7 Device Driver, Reeves (2010) describes objects in the context of
computer programming by explaining that the objects are a digital representation of either a
physical entity or conceptual idea. The blueprint for the object is called a class and it defines the
storage of attributes and functions which represent the digital object. When a class is utilized in a
project, it behaves as a template for creating objects (Chap. 1 para. 2). Orwick and Smith (2007)
explain that objects are used in the WDF to represent common driver concepts like a devices, I/O
requests, or queues. Drivers communicate with devices through these WDF objects rather than
passing data to the operating system directly (Chap. 5, para. 1). The objects that make up the
Windows Driver Foundation are arranged in a hierarchy with the WDFDRIVER object as the
root (Reeves, 2010).
Conclusion
There is a distinct path that data follows as it passes from the device to the host. Details
regarding how data passes between a device and a host can be found in a variety of books,
Developing a Windows Driver for the PIC Microcontroller 14
websites, and other publications. There are multiple steps involved in passing data between a
device and a host. The detail of literature allows readers to gain a thorough comprehension of the
USB communications procedures.
Chapter 3: Methodology and Design
Introduction to the Chapter
The main question being answered by this research paper is: How to write a Windows
USB driver for the PIC microcontroller? To answer this question, the research covered will focus
on resolving the answers to several sub questions, such as: What is a driver? What are the
fundamental requirements of a driver? What is the development environment for writing a
driver? How do applications communicate with a driver? What are the fundamental
requirements of a USB device? By understanding the answers to these sub questions, readers
with a basic understanding of object oriented programming should be able to develop a simple
driver for a PIC microcontroller USB device and the Windows operating system. This paper
utilizes a qualitative approach and the action methodology.
Body Paragraphs
There are many books written on the topic of USB devices and Windows software
development. The literature describes in detail much of the communication between USB
devices and the Windows operating system. In regards to Windows defined software libraries and
functions, the Microsoft Software Developer Network website will be used to reference
unfamiliar functions. Where a lack of clear instructions exists, an analysis of open source
software will be conducted utilizing the Microsoft Visual Studio 2015 integrated development
environment. Because complex and unnecessary code can complicate learning and debugging
(Martin, 2008), an emphasis will be placed on obtaining clean, concise sample code and
Developing a Windows Driver for the PIC Microcontroller 15
removing any unused libraries, functions, and parameters. Data will be gathered by utilizing the
Visual Studio 2015 debugging tools, Windows event viewer, and registry editor. To ensure that a
working USB device has been created, testing will be documented using screen captures, photos
of the device, videos, and source code. The PIC18F45K50 microcontroller from Microchip
Technologies LLC. will be utilized as a test USB device using firmware included with the
MPLAB integrated development environment. A button will be connected to the microcontroller
on pin RB4 to test input to the Windows operation system and an LED will be connected to pin
RD3 to test output.
What is a driver? The book, “Developing drivers with the Microsoft Windows Driver
Foundation” will be the main resource in answering this question. The information derived from
the book will help clarify exactly where the data processing of a driver ends and where the
application takes control. This material will also cover the different varieties of drivers and under
what circumstances they should be used.
What are the fundamental requirements of a driver? The literature covers driver
requirements on an abstract basis. To get a deeper understanding of the specific functions and
code required by a driver, driver templates found in the Visual Studio library or online can be
utilized as a supplement to the books. Using the literature as a guide to the source code of a
driver, any code found to be irrelevant to the device hardware setup will be removed. This will
help to narrow down the driver to its most basic parts so that it can be better understood and to
mitigate the chance of software errors and reduce the time required for debugging.
What is the development environment for writing a driver? A major aspect of writing any
sort of code is the development environment. Reviewing the Microsoft Software Developer
Network will be essential to ensure that a proper Windows configuration is set up to write and
Developing a Windows Driver for the PIC Microcontroller 16
deploy a driver for testing. Besides ensuring correct environment and settings for writing the
driver, a specific setup will also be required for writing firmware to the microcontroller. This will
require a review of Microchip’s website to ensure all the software has been properly installed and
that code can be written to the device.
What is required to be defined in the firmware to allow device communication to occur with a
host? A combination of data sheets and the book titled “An Introduction to USB and USB
Programming on Microchip Devices” will help outline the locations in firmware code where a
definition of the device can be created for sharing with a host.
What are the fundamental requirements of a USB device? The book, “USB Complete” by
Jan Axelson will help identify the hardware and software requirements of a USB device. This
book covers USB device communication starting from the electronic signals passing through a
USB cable up to the methods available for applications to retrieve data from the device driver
(Axelson, 2015). To send data to the PC a physical connection needs to exist. Knowing which
wires of the USB cable pass data and which provide power is important to ensure that data is
being passed correctly and no parts are damaged. By reviewing manufacturer data sheets and
using a multimeter to check signals, the correct USB cable configuration can be connected to a
device.
How do applications communicate with a driver? Steps must be taken to ensure USB
device drivers are successfully communicating with their intended applications within the
operating system. If the device is meant to be used as a keyboard, then will it only work with an
application that is looking for keyboard devices to connect to? A device can be made to be
recognized by the Windows operating system but can that same device communicate with any
Developing a Windows Driver for the PIC Microcontroller 17
application? How does an application define the user input it is seeking? To find answers to these
questions, a review of additional books and online materials is required.
Conclusion
Once the results of the research have been accumulated the process for writing a driver
can still be obscured if it is not correctly presented. To ensure that it is organized in an
understandable way, the data will be presented starting with an explanation of the main question.
This will be followed by a summary of results of the research on the sub questions. A power
point presentation will be utilized to document the process of developing a driver. Source code,
images, and video will be displayed to show the process of writing firmware to a device, device
enumeration by the operating system, and finally, device interaction with a Windows application.
Chapter 4: Results of the Study
Introduction
Devices are a requirement for interfacing with a computer to send or receive data
(Reeves, 2010, Introduction para. 1). Devices are made by different manufacturers utilizing
various types of firmware code to control device functions (Ibrahim, 2011, Chap 8 Device
Descriptors). To make a device usable by a Windows operating system, software developers must
create a device driver. This paper aims to address the issue with the main question: How to write
a Windows USB driver for the PIC microcontroller? To answer this major question, five sub
questions were devised: What is a driver? What are the fundamental requirements of a driver?
What is the development environment for writing a driver? How do applications communicate
with a driver? What are the fundamental requirements of a USB device? By answering these
questions, it should become clear what the process is for writing a Windows driver.
Developing a Windows Driver for the PIC Microcontroller 18
What is a driver?
The MSDN website defines a driver as follows:
“In the most fundamental sense, a driver is a software component that lets the operating
system and a device communicate with each other. For example, suppose an application needs to
read some data from a device. The application calls a function implemented by the operating
system, and the operating system calls a function implemented by the driver. The driver, which
was written by the same company that designed and manufactured the device, knows how to
communicate with the device hardware to get the data. After the driver gets the data from the
device, it returns the data to the operating system, which returns it to the application.” (What is a
Driver?, 2016, para. 1)
There are different kinds of drivers. For Windows, Orwick and Smith (2007) describe
kernel mode drivers and user mode drivers. Kernel mode drivers are written for maximum
control. They give the driver full access to underlying system commands. This allows
programming of drivers with unrestricted access to operating system components. However, if
there are any errors in the driver code, a kernel mode driver could cause applications or the host
operating system itself to crash. User mode drivers are not as versatile as kernel mode drivers
because Windows set of functions available to a user mode driver is less than a kernel mode
driver. This makes user mode drivers safer for an operating system (Chap. 2, Core Windows
Architecture, para. 2).
Besides the different modes of drivers, Axelson (2015) tells readers that Windows also
maintains a set of generic drivers for devices. For example, if a device is programmed with
firmware that defines it as a human interface device, then when the device is connected to a host,
Developing a Windows Driver for the PIC Microcontroller 19
Windows will automatically give it a premade generic human interface driver. The firmware can
even define a device to belong to a specific type of HID class such as a game controller, joystick,
mouse, or keyboard. Windows has another generic driver called WinUSB. If a device is set to use
WinUSB, then Windows will assign it a WinUSB driver. Like HID drivers, Windows has
predefined functions which can be utilized by applications to access hardware (pg. 149).
What are the fundamental requirements of a driver?
According to Orwick and Smith (2007), Microsoft provides a software development
library called the Windows Driver Kit (WDK). As part of the development kit, template driver
projects are included as a foundation for building either user mode or kernel mode drivers (Chap.
1 Getting Started with Driver Development, para.1). The kernel mode driver template for USB
devices contains three main files called Device.c, Driver.c, and Queue.c. Each file has a
matching header file used to define functions and variables used by other parts of the driver as
well as the declarations of framework callback functions. The main template files contain the
basic functions required for a device driver. They include, DriverEntry, EvtDeviceAdd,
CreateDevice, EvtDevicePrepareHardware, and QueueInitialize. Also included in the template
are a Public.h header file which contains a GUID used by applications to interface with the
driver and an INF file. Axelson (2015) states that the INF file contains the information required
by a driver to detect its specific hardware device. Specifically, within the INF file a device PID
and VID must be defined (pg. 234). Once this is defined to match the PID and VID of the
firmware, the driver can be compiled and installed on a host. The device can now be paired with
a driver.
Though a device may be recognized by the system, the applications still cannot
communicate with the device. This is because the driver template provided by the WDK is not
Developing a Windows Driver for the PIC Microcontroller 20
yet handling the callback function for input or output. According to Orwick and Smith, the driver
framework receives requests form the applications and passes them to the driver. The driver must
tell the framework how it wants to handle the incoming request. This is done with a callback
function (Chap. 4, KMDF Overview, para. 6). For example, if a host application has input or a
command for a device, the framework looks for the “EVT_WDF_IO_QUEUE_IO_WRITE”
callback function within the driver code (EVT_WDF_IO_QUEUE_IO_WRITE callback
function, 2016). By declaring an EVT_WDF_IO_QUEUE_IO_WRITE callback function in the
Queue.h file, an EvtIOWrite function can be added to Queue.c to handle incoming requests to
write to the device.
Once the driver has retrieved the request from the application, it can send it to a device
using a pipe. According to the Microsoft Developer Network website, to create a pipe, in the
EvtDevicePrepareHardware function, two WDF functions must be added. They are
WdfUsbTargetDeviceGetInterface and WdfUsbInterfaceGetConfiguredPipe. The
WdfUsbTargetDeviceGetInterface function returns a device interface. The interface can be used
to retrieve pipes using the WdfUsbInterfaceGetConfiguredPipe function (Working with USB
Pipes, 2016) (Working with USB Interfaces, 2016). Once a pipe has been retrieved, it can be
used in the EvtIOWrite callback function to write data to the device by passing the pipe and data
passed by an application as parameters to the WdfUsbTargetPipeWriteSynchronously function
(WdfUsbTargetPipeWriteSynchronously, 2016).
What is the development environment for writing a driver?
Writing a Windows driver requires a set of software programs for development and
testing. Orwick and Smith (2007) explain that one of the first tools required to get started is the
Windows Driver Kit (WDK). The Windows Driver Kit has a set of essential tools, predefined
Developing a Windows Driver for the PIC Microcontroller 21
functions, and templates for creating Windows drivers (Getting Started with Driver
Development, para. 1). Besides a Windows operating system, one of the prerequisites for
installing the WDK is the Microsoft Visual Studio Integrated Development Environment (IDE)
(Windows Driver Kit, 2016).
Orwick and Smith (2007) warn that when testing a driver, it is a good practice to have the
development environment separated from the testing environment. Kernel mode drivers have
access to a part of the operating system that can cause errors and possibly irreversible damage to
the system if errors in the code exist. For this reason, it is recommended that a second computer
is used for driver testing and debugging (Getting Started with Driver Development, para. 4). To
mitigate that risk, one solution is to set up a virtual machine on the development computer. A
virtual machine is software that simulates an operating system. VMware, a developer of virtual
machines, wrote a white paper to describe some of the benefits of virtual machines. The white
paper explains that virtual machines are beneficial because they allow developers to quickly test
code without having to have a separate computer to test the code. Instead, the virtual machine
can be loaded right on the local machine while simultaneously using the developing operating
system to make quick changes to errors in code and redeploy (VMware, 2005). The VMware
virtual machine has a set of tools which allow the user to copy and paste items into the virtual
machine as well awareness of USB devices connected to the development operating system.
On the hardware side, the MPLABX IDE is required for programming a Microchip
device such as the PIC18F45K50. The IDE allows users to create edit, compile, test and debug
source code (Ibrahim, 2014, Chap. 3 para. 6). The website for MPLABX describes a useful set of
software available for the IDE called the Microchip Libraries for Applications (MLA). The MLA
Developing a Windows Driver for the PIC Microcontroller 22
has sample firmware for common Microchip devices as well as applications for testing the
firmware after it has been loaded onto a device (Microchip Libraries for Applications, 2016).
How do applications communicate with a driver?
After completing the code for a driver with the capability of writing data to device, the
driver must be tested. For an application to communicate with a driver, it must issue a read or
write command using a handle to a device connected to the host. Getting a handle to the device
requires a few steps. According to Axelson (2015),the process starts when a Globally Unique
Identifier (GUID) variable is created and assigned a value matching that of the device class to
connect to. Next, the application gets a list of all the connected devices with a matching GUID
by issuing the SetupDiGetClassDevs function. Subsequently, the SetupDiEnumDeviceInterfaces
function is used to get a device interface by specifying the index of the device from the list
returned by the SetupDiGetClassDevs function. Once retrieved, the interface can be checked for
a matching vendor ID and product ID. If it doesn’t match, the function is called again using the
next higher index until a desired device interface is found. The SetupDiGetDeviceInterfaceDetail
function is used to retrieve a path to the device. The path is then used to create a handle to the
device using the CreateFile function (pg. 249-256). Once the handle has been created, it can be
used as a means for reading or writing data to a device by passing it as a parameter in the
WriteFile or ReadFile function. The other parameter in the function is a buffer for the data that is
being read or written. To write data, the buffer must be filled with data prior to calling the write
function.
What are the fundamental requirements of a USB device?
Axelson (2015) explained several hardware requirements for USB devices in the book
USB Complete. One of the first requirements is a chip capable of controlling communications
Developing a Windows Driver for the PIC Microcontroller 23
with a host. The chip must have firmware loaded on it to allow communication to occur (pg. 25).
Some PIC microcontrollers like the PIC18F45K50 are capable of USB communication
(28/40/44-Pin, 2014, p. 1). The firmware for PIC devices is written using the MPLABX IDE
(Ibrahim, 2014, Chap. 3 para. 6). Ibrahim (2011) describes that a device requires several
descriptors be defined in the device firmware for the device to connect properly. The
configuration descriptor describes device power requirements and the number of interfaces on
the device. There is also an interface descriptor which defines the interface class and number of
endpoints. The last descriptor required is the endpoint descriptor which defines the address of an
endpoint and the maximum packet size that the endpoint can read (Ibrahim, 2011, Chap 8 Device
Descriptors). These descriptors are used by the driver to direct input and output to and from the
device.
Conclusion
It can now be seen that in order to write and test a driver there are several main
requirements. First, an environment must be set up to write and test the driver and the firmware.
Then the device must be loaded with firmware that properly defines the way the device is to
function. After that, a driver must be written for applications to be able to communicate with the
device. The driver should contain callback functions so that an application can communicate
with a driver. Finally, the driver must be tested using an application that has the required
functions to create a connection to the device.
Chapter 5: Summary and Discussion
Introduction
Developing a Windows Driver for the PIC Microcontroller 24
A computer can communicate with hardware devices using a driver. This paper addresses
the procedure of developing a device driver for the Windows operating system. There are
different types of Windows devices. This paper discusses the development of drivers for USB
devices. The major question asked by this paper is: How to write a Windows USB driver for the
PIC microcontroller? This main question can be answered by resolving five sub-questions: What
is a driver? What are the fundamental requirements of a driver? What is the development
environment for writing a driver? How do applications communicate with a driver? What are the
fundamental requirements of a USB device? The answers to all these questions will give readers
an understanding of the basic requirements of a simple device driver.
Statement of Problem
Computer operating system requires user input and output to be fulfil its purpose. For this
to happen, devices require a driver to pass communications to the applications in the operating
system. This issue led me to find a microcontroller that would offer potential for customization
and to the major research question: How to write a Windows USB driver for the PIC
microcontroller?
Review of Methodology
To understand how to write a driver for the Windows operating system, several methods
were used. Literature from books and online resources were used to gain a general understanding
of the requirements of a driver. The book USB Complete by Jan Axelson (2015) provided details
about how electronic devices communicate with the operating system (pg. 234). The Microsoft
Developer Network website included descriptions of various functions used in the driver code.
The descriptions included details about where the function should be located within the code and
what parameters were required for the functions. At the application level, there was a need to
Developing a Windows Driver for the PIC Microcontroller 25
identify the specific device for USB communication. The Microchip Technology firmware
source code provided the information required for the operating system to identify the device as
well as the size of the data block that it uses as input and output.
Summary of Results
The sub-questions were effective at describing the requirements of a Windows USB
device driver.
Sub Question One
To really understand the process of writing a driver for the Windows operating system, it
is important to know the answer to the question: “What is a driver?” There are drivers for many
computer peripherals including USB devices. Orwick and Smith (2007) describe two specific
types of drivers, kernel mode drivers and user mode drivers (Chap. 2, Core Windows
Architecture, para. 2). The operating system uses these drivers to handle data passed from
electronic devices to the operating system.
Sub Question Two
In order to understand the answer to the second sub-question, “What are the fundamental
requirements of a driver?” Windows Driver Template files were viewed to see the essential
elements of the driver. The template contained 3 main files, Device.c, Driver.c, and Queue.c.
Within these files, there were several required functions, DriverEntry, EvtDeviceAdd,
CreateDevice, EvtDevicePrepareHardware, and QueueInitialize. These functions contain several
lines of code each and give the driver the ability to pass data between the device and the
operating system applications. One additional file needs added to give the driver write capability.
That function is the “EVT_WDF_IO_QUEUE_IO_WRITE”
(EVT_WDF_IO_QUEUE_IO_WRITE callback function, 2016). The INF file is also included in
Developing a Windows Driver for the PIC Microcontroller 26
the template and helps the operating system match the driver to the device when the device is
plugged in (Axelson, 2015, pg. 234).
Sub Question Three
Writing any type of software requires special software. The second sub-question asks:
“What is the development environment for writing a driver?” Orwick and Smith (2007) describe
the Windows Driver Kit (WDK) as one tool that is required to write Windows drivers. In order to
use the development kit, the Microsoft Visual Studio program is required. This program is like a
word processor with special tools used for writing computer software. (Windows Driver Kit,
2016).
Sub Question Four
Even though a driver for a device may exist, applications must have access to the driver
in order to communicate with a device. The answer to the question “How do applications
communicate with a driver?” will resolve the issue by describing what functions an application
must have to pass data to a device driver. Axelson (2015) describes that applications get a list of
available devices for communication by using the “SetupDiGetClassDevs” function. The
function returns a list of devices which the application can sift through until it finds one with a
Vendor ID and Product ID matching the device it wants to connect with (pg. 249-256). Once a
device has been found, it can have data or commands written to it using the WriteFile function.
Or data can be read from it using the ReadFile function.
Sub Question Five
The final sub-question is: “What are the fundamental requirements of a USB device?”
Axelson (2015) explained that a USB device requires a microchip with firmware installed (pg.
25). The firmware holds the definition of the device so the host can determine which driver to
Developing a Windows Driver for the PIC Microcontroller 27
assign to it once it is connected. Ibrahim (2011) describes a type of data block called a descriptor
as an item included in the device firmware. The descriptors define the device type, GUID,
Vendor ID, Product ID, as well as the addresses for device input and output and maximum
message size for those addresses (Ibrahim, 2011, Chap 8 Device Descriptors).
Relationship of Research to the Field
The literature describes many aspects of USB development which were confirmed
through the project. Jan Axelson (2015) describes the requirement that a driver connect to a
device using a GUID and an application connect using a vendor ID and a product ID (pg. 249-
256). By creating an actual USB device using a PIC18 microcontroller, this became very clear as
the driver would not install correctly if the GUID was incorrect, and an application would not
connect to the device when the vendor ID and product ID were not properly defined.
Discussion of Results
A review of the literature regarding driver development shows that there are several steps
for communication to occur between a USB device and a Windows application. Often, the
literature focuses on a single step of USB communication, such as USB device firmware,
microcontroller programming, operating system structure, or driver frameworks. This paper adds
to the literature by showing how all the steps connect to allow USB communication. Rather than
focus on a single step, the paper shows how data originates at either the host or the device and is
passed from one place to the next until it arrives at its destination.
Conclusion
This paper addressed the question: “How to write a Windows USB driver for the PIC
microcontroller?” By answering the sub-questions, it can be seen that devices communicate to a
host through a few steps. First, the device must be loaded with firmware which holds the
Developing a Windows Driver for the PIC Microcontroller 28
definition of what type of device it is, and how it passes data to the computer. Then the device
must have a driver written for it, so that it can be detected when it is plugged into the computer.
The driver must have an INF file which defines the device it is matched to by a GUID, Vendor
ID, and Product ID. Once a device is successfully connected, a driver must contain the proper
functions so that applications can pass data to and from the device. The literature helped to
outline all the steps required for this USB communication to occur. This paper adds to the
literature by providing a detailed description of how the communication occurs from start to
finish.
References
Axelson, J. (2015). USB complete: The developer's guide. Madison, WI: Lakeview Research
LLC.
Belevsky, P. & Pavlov S. (2008). Windows® Embedded CE 6.0 Fundamentals. Available from
https://www.safaribooksonline.com/library/view/windows-embedded-ce/9780735626256/
Catsoulis, J. (2005). Designing Embedded Hardware, 2nd Edition. Available from
Developing a Windows Driver for the PIC Microcontroller 29
https://www.safaribooksonline.com/library/view/designing-embedded-hardware/
0596007558/ch11.html
Eliasz, A. (2016). An Introduction to USB and USB Programming on Microchip Devices. The
Internet Technical Bookshop.
EVT_WDF_IO_QUEUE_IO_WRITE callback function. (2016) Retrieved November 26, 2016
from
https://msdn.microsoft.com/en-us/library/windows/hardware/ff541813(v=vs.85).aspx
Ibrahim, D. (2014). PIC microcontroller projects in C: Basic to advanced. Available from
https://www.safaribooksonline.com/library/view/advanced-pic-microcontroller/
9780750686112/
Ibrahim, D. (2014). PIC microcontroller projects in C: Basic to advanced. Available from
https://www.safaribooksonline.com/library/view/pic-microcontroller-projects/
9780080999241/
McDowell, S. & Seyer, M. D. (1998) USB Explained. Available from
https://www.safaribooksonline.com/library/view/usb-explained/9780132442350/
Microchip Libraries for Applications. (2016). Retrieved on November 16, 2016 from
http://www.microchip.com/mplab/microchip-libraries-for-applications
Microchip Technology Inc. (2012-2014). 28/40/44-Pin, Low-Power, High-Performance
Microcontrollers with XLP Technology Retrieved from
http://ww1.microchip.com/downloads/en/DeviceDoc/30000684B.pdf
Murphy, R. (09/14/2016). USB 101: An Introduction to USB 2.0. Retrieved from
http://www.cypress.com/documentation/application-notes/an57294-usb-101-introduction-
universal-serial-bus-20
Developing a Windows Driver for the PIC Microcontroller 30
NaturalPoint Inc. (2016). https://naturalpoint.com/trackir/trackir5/. Retrieved from
https://naturalpoint.com/: https://naturalpoint.com/trackir/trackir5/
Net Applications.com. (2006-2016). operating-system-market-share. Retrieved from
netmarketshare: https://www.netmarketshare.com/operating-system-market-share.aspx?
qprid=10&qpcustomd=0
Orwick, P., & Smith, G. (2007). Developing Drivers with the Microsoft Windows Driver
Foundation. Available from https://www.safaribooksonline.com/library/view/developing-
drivers-with/9780735623743/
Rafiquzzaman, M. (2014). Fundamentals of Digital Logic and Microcontrollers, 6th Edition.
Available from https://www.safaribooksonline.com/library/view/fundamentals-of-
digital/9781118969304/
Reeves, R. D. (2010) Windows 7 Device Driver. Available from
https://www.safaribooksonline.com/library/view/windows-7-device/9780321670540/
Russinovich, M. E., Solomon, D. A., & Ionescu, A. (2012). Windows Internals (6th ed., Vol. 2).
Redmond, WA: Microsoft Press.
USB-IF (2000). Universal Serial Bus Specification. Retrieved from
http://www.usb.org/developers/docs/usb20_docs/
USB-IF (2011). Universal Serial Bus 3.0 Specification. Retrieved from
http://www.usb.org/developers/docs/documents_archive/
USB-IF (2013). Universal Serial Bus 3.1 Specification. Retrieved from
http://www.usb.org/developers/docs/documents_archive/
VMWare White Paper. (2005). Retrieved from http://www.vmware.com/pdf/dev_test.pdf
WDF Driver Development Guide. (2016, July 30). Retrieved November 14, 2016, from
Developing a Windows Driver for the PIC Microcontroller 31
https://msdn.microsoft.com/en-us/windows/hardware/drivers/wdf/index
WdfUsbTargetPipeWriteSynchronously method. (2016). Retrieved November 14, 2016, from
https://msdn.microsoft.com/library/windows/hardware/ff551163
What is a Driver? (2016) Retrieved November 26, 2016, from https://msdn.microsoft.com/en-
us/library/windows/hardware/ff554678(v=vs.85).aspx
Windows Driver Kit (WDK). (2016). Retrieved November 16, 2016 from
https://msdn.microsoft.com/en-us/library/windows/hardware/ff557573(v=vs.85).aspx
Working With USB Interfaces. (2016). Retrieved November 26,2016 from
https://msdn.microsoft.com/en-us/windows/hardware/drivers/wdf/working-with-usb-
interfaces
Working With USB Pipes. (2016). Retrieved November 26, 2016 from
https://msdn.microsoft.com/en-us/windows/hardware/drivers/wdf/working-with-usb-
pipes
How to Enumerate USB Pipes. (2016). Retrieved November 14, 2016, from
https://msdn.microsoft.com/en-us/library/windows/hardware/hh968306(v=vs.85).aspx