Building the Sample Application
This section describes all the steps required to build a USB-based application. The instructions provided in this section are not intended for any particular toolchain, but instead are described in a generic way that can be adapted to any toolchain.
The best way to start building a USB-based project is to start from an existing project. If you are using µC/OS-II or µC/OS-III, Micrium provides example projects for multiple development boards and compilers. If your target board is not listed on Micrium’s web site, you can download an example project for a similar board or microcontroller.
The purpose of the sample project is to allow a host to enumerate your device. You will add a USB class instance to both, full-speed and high-speed configurations (if both are supported by your controller). Refer to the Class Instance Concept page for more details about the class instance concept. After you have successfully completed and run the sample project, you can use it as a starting point to run other USB class demos you may have purchased.
µC/USB-Device requires a Real-Time Operating System (RTOS). The following assumes that you have a working example project running on µC/OS-II or µC/OS-III.
Understanding Micrium Examples
A Micrium example project is usually placed in the following directory structure.
\Micrium \Software \EvalBoards \<manufacturer> \<board_name> \<compiler> \<project name> \*.*
Note that Micrium does not provide by default an example project with the µC/USB-Device distribution package. Micrium examples are provided to customers in specific situations. If it happens that you receive a Micrium example, the directory structure shown above is generally used by Micrium. You may use a different directory structure to store the application and toolchain projects files.
\Micrium
This is where Micrium places all software components and projects. This directory is generally located at the root directory.
\Software
This sub-directory contains all software components and projects.
\EvalBoards
This sub-directory contains all projects related to evaluation boards supported by Micrium.
\<manufacturer>
This is the name of the manufacturer of the evaluation board. In some cases this can also be the name of the microcontroller manufacturer.
\<board name>
This is the name of the evaluation board.
\<compiler>
This is the name of the compiler or compiler manufacturer used to build the code for the evaluation board.
\<project name>
The name of the project that will be demonstrated. For example a simple µC/USB-Device with µC/OS-III project might have the project name ‘uCOS-III-USBD’.
\*.*
These are the source files for the project. This directory contains configuration files app_cfg.h
, os_cfg.h
, os_cfg_app.h
, cpu_cfg.h
and other project-required sources files.
os_cfg.h
is a configuration file used to configure µC/OS-III (or µC/OS-II) parameters such as the maximum number of tasks, events, objects, which µC/OS-III services are enabled (semaphores, mailboxes, queues), and so on. os_cfg.h
is a required file for any µC/OS-III application. See the µC/OS-III documentation and books for further information.
app.c
contains the application code for the example project. As with most C programs, code execution starts at main()
. At a minimum, app.c
initializes µC/OS-III and creates a startup task that initializes other Micrium modules.
app_cfg.h
is a configuration file for your application. This file contains #defines
to configure the priorities and stack sizes of your application and the Micrium modules’ tasks.
app_<module>.c
and app_<module>.h
These optional files contain the Micrium modules’ (µC/TCP-IP, µC/FS, µC/USB-Host, etc) initialization code. They may or may not be present in the example projects.
Copying and Modifying Template Files
Copy the files from the application template and configuration folders into your application as illustrated in Building the Sample Application#Figure - Copying Template Files.
app_usbd.*
is the master template for USB application-specific initialization code. This file contains the function App_USBD_Init()
, which initializes the USB stack and class-specific demos.
app_usbd_<class>.c
contains a template to initialize and use a certain class. This file contains the class demo application. In general, the class application initializes the class, creates a class instance, and adds the instance to the full-speed and high-speed configurations. Refer to the chapter(s) of the USB class(es) you purchased for more details about the USB class demos.
usbd_cfg.h
is a configuration file used to setup µC/USB-Device stack parameters such as the maximum number of configurations, interfaces, or class-related parameters.
usbd_dev_cfg.c
and usbd_dev_cfg.h
are configuration files used to set device parameters such as vendor ID, product ID, and device release number. They are also necessary to configure the USB device controller driver parameters, such as base address, dedicated memory base address and size, controller’s speed, and endpoint capabilities.
Modify Device Configuration
Modify the device configuration file (usbd_cfg.c
) as needed for your application. See Building the Sample Application#Listing - Device Configuration Template below for details.
USBD_DEV_CFG USBD_DevCfg_Template = { (1) 0xFFFE, (2) 0x1234, 0x0100, "OEM MANUFACTURER", (3) "OEM PRODUCT", "1234567890ABCDEF", USBD_LANG_ID_ENGLISH_US (4) };
(1) Give your device configuration a meaningful name by replacing the word “Template
”.
(2) Assign the Vendor ID, Product ID and Device Release Number. For development purposes you can use the default values, but once you decide to release your product, you must contact the USB Implementers Forum (USB-IF) at www.usb.org in order to get valid IDs. USB-IF is a non-profit organization that among other activities, maintains all USB Vendor ID and Product ID numbers.
(3) Specify human readable Vendor ID, Product ID, and Device Release Number strings.
(4) A USB device can store strings in multiple languages. Specify the language used in your strings. The #defines for the other languages are defined in the file usbd_core.h
in the section “Language Identifiers”.
Modify Driver Configuration
Modify the driver configuration (usbd_dev_cfg.c
) as needed for your controller. See Building the Sample Application#Listing - Driver Configuration Template below for details.
USBD_DRV_CFG USBD_DrvCfg_Template = { (1) 0x00000000, (2) 0x00000000, (3) 0u, USBD_DEV_SPD_FULL, (4) USBD_DrvEP_InfoTbl_Template (5) };
(1) Give your driver configuration a meaningful name by replacing the word “Template
”.
(2) Specify the base address of your USB device controller.
(3) If your target has dedicated memory for the USB controller, you can specify its base address and size here. Depending on the USB controller, dedicated memory can be used to allocate driver buffers or DMA descriptors.
(4) Specify the USB device controller speed: USBD_DEV_SPD_HIGH
if your controller supports high-speed or USBD_DEV_SPD_FULL
if your controller supports only full-speed.
(5) Specify the endpoint information table. The endpoint information table should be defined in your USB device controller BSP files. Refer to Endpoint Information Table for more details on the endpoint information table.
Modify USB Application Initialization Code
Listing - App_USBD_Init() in app_usbd.c shows the code that you should modify based on your specific configuration done previously. You should modify the parts that are highlighted by the text in bold. The code snippet is extracted from the function App_USBD_Init()
defined in app_usbd.c
. The complete initialization sequence performed by App_USBD_Init()
is presented in Listing - App_USBD_Init() in app_usbd.c.
#include <usbd_bsp_template.h> (1) CPU_BOOLEAN App_USBD_Init (void) { CPU_INT08U dev_nbr; CPU_INT08U cfg_fs_nbr; USBD_ERR err; USBD_Init(&err); (2) dev_nbr = USBD_DevAdd(&USBD_DevCfg_Template, (3) &App_USBD_BusFncts, (4) &USBD_DrvAPI_Template, (5) &USBD_DrvCfg_Template, (6) &USBD_DrvBSP_Template, (7) &err); if (USBD_DrvCfg_Template.Spd == USBD_DEV_SPD_HIGH) { (8) cfg_hs_nbr = USBD_CfgAdd(dev_nbr, USBD_DEV_ATTRIB_SELF_POWERED, 100u, USBD_DEV_SPD_HIGH, "HS configuration", &err); } .... }
(1) Include the USB driver BSP header file that is specific to your board. This file can be found in the following folder: \Micrium\Software\uC-USB-Device\Drivers\<controller>\BSP\<board name>
(2) Initialize the USB device stack’s internal variables, structures and core RTOS port.
(3) Specify the address of the device configuration structure that you modified in the section "Modify Device Configuration".
(4) Specify the address of the Bus Event callbacks structure. See section Bus Event Callback Structure for more details on this structure.
(5) Specify the address of the driver’s API structure. The driver’s API structure is defined in the driver’s header file named usbd_drv_<controller>.h
.
(6) Specify the address of the driver configuration structure that you modified in the section "Modify Driver Configuration".
(7) Specify the address of the driver’s BSP API structure. The driver’s BSP API structure is defined in the driver’s BSP header file named usbd_bsp_<controller>.h
.
(8) If the device controller supports high-speed, create a high-speed configuration for the specified device.
Including USB Device Stack Source Code
First, include the following files in your project from the µC/USB-Device source code distribution, as indicated in Figure - µC/USB-Device Source Code.
Second, add the following include paths to your project’s C compiler settings:
\Micrium\Software\uC-USB-Device-V4\
If you are using the MSC class, add the following include path:
\Micrium\Software\uC-USB-Device-V4\Class\MSC\Storage\<storage name>
Modifying the Application Configuration File
The USB application initialization code templates assume the presence of app_cfg.h
. The following #defines
must be present in app_cfg.h
in order to build the sample application.
#define APP_CFG_USBD_EN DEF_ENABLED (1) #define USBD_OS_CFG_CORE_TASK_PRIO 6u (2) #define USBD_OS_CFG_TRACE_TASK_PRIO 7u #define USBD_OS_CFG_CORE_TASK_STK_SIZE 256u #define USBD_OS_CFG_TRACE_TASK_STK_SIZE 256u #define LIB_MEM_CFG_OPTIMIZE_ASM_EN DEF_DISABLED (3) #define LIB_MEM_CFG_ARG_CHK_EXT_EN DEF_ENABLED #define LIB_MEM_CFG_ALLOC_EN DEF_ENABLED #define LIB_MEM_CFG_HEAP_SIZE 1024u #define TRACE_LEVEL_OFF 0u (4) #define TRACE_LEVEL_INFO 1u #define TRACE_LEVEL_DBG 2u #define APP_CFG_TRACE_LEVEL TRACE_LEVEL_DBG (5) #define APP_CFG_TRACE printf (6) #define APP_TRACE_INFO(x) ((APP_CFG_TRACE_LEVEL >= TRACE_LEVEL_INFO) ? (void)(APP_CFG_TRACE x) : (void)0) #define APP_TRACE_DBG(x) ((APP_CFG_TRACE_LEVEL >= TRACE_LEVEL_DBG) ? (void)(APP_CFG_TRACE x) : (void)0)
(1) APP_CFG_USBD_EN
enables or disables the USB application initialization code.
(2) These #defines relate to the µC/USB-Device OS port. The µC/USB-Device core requires only one task to manage control requests and asynchronous transfers, and a second, optional task to output trace events (if trace capability is enabled). To properly set the priority of the core and debug tasks, refer to Task Priorities.
(3) Configure the desired size of the heap memory. Heap memory used for µC/USB-Device drivers that use internal buffers and DMA descriptors which are allocated at run-time and to allocate internal buffers that require memory alignment. Refer to the µC/LIB documentation for more details on the other µC/LIB constants.
(4) Most Micrium examples contain application trace macros to output human-readable debugging information. Two levels of tracing are enabled: INFO and DBG. INFO traces high-level operations, and DBG traces high-level operations and return errors. Application-level tracing is different from µC/USB-Device tracing (refer to Debug and Trace for more details).
(5) Define the application trace level.
(6) Specify which function should be used to redirect the output of human-readable application tracing. You can select the standard output via printf()
, or another output such as a text terminal using a serial interface.
Besides the file app_cfg.h
, another application file, app_usbd_cfg.h
, specific to class demos should be modified according to the class(es) you want to play with. For that, the following #defines
allows you to enable class demos.
#define APP_CFG_USBD_AUDIO_EN DEF_DISABLED (1) #define APP_CFG_USBD_CDC_EN DEF_ENABLED #define APP_CFG_USBD_CDC_EEM_EN DEF_ENABLED #define APP_CFG_USBD_HID_EN DEF_DISABLED #define APP_CFG_USBD_MSC_EN DEF_DISABLED #define APP_CFG_USBD_PHDC_EN DEF_DISABLED #define APP_CFG_USBD_VENDOR_EN DEF_DISABLED
(1) This #define
enables the USB class-specific demo. You can enable one or more USB class-specific demos. If you enable several USB class-specific demos, your device will be a composite device.
app_usbd_cfg.h
contains also other #defines
specific to each class. Refer to the proper class application configuration section presented in this table for more details.
µC/USB-Device Class | Application Configuration page |
---|---|
Audio Class | Using the Audio Class Demo Application |
Communications Device Class (CDC) Abstract Control Model (ACM) | Using the ACM Subclass Demo Application |
Communications Device Class (CDC) Ethernet Emulation Model (EEM) | CDC EEM Demo Application |
Human Interface Device Class (HID) | Using the HID Class Demo Application |
Mass Storage Class (MSC) | Using the MSC Demo Application |
Personal Healthcare Device Class (PHDC) | Using the PHDC Demo Application |
Vendor Class | Using the Vendor Class Demo Application |
Every USB class also needs to have certain constants defined to work correctly. Building the Sample Application#Table - USB Class Configuration References presents the section to refer to based on the USB class.
µC/USB-Device Class | Configuration page |
---|---|
Audio Class | Audio Class General Configuration |
Communications Device Class (CDC) | CDC General Configuration |
Communications Device Class (CDC) Ethernet Emulation Model (EEM) | CDC EEM Subclass Configuration |
Human Interface Device Class (HID) | HID Class General Configuration |
Mass Storage Class (MSC) | MSC General Configuration |
Personal Healthcare Device Class (PHDC) | PHDC General configuration |
Vendor Class | Vendor Class General Configuration |