MPLAB® Harmony v2 USB Audio Speaker (with RTOS) Tutorial


MPLAB® Harmony is a flexible firmware development platform for PIC32 microcontrollers. This integrated software framework provides driver libraries and APIs that make it easier for you to use PIC32 peripherals (Timers, GPIO, UART, I2C, SPI, etc.). It also includes middleware libraries for USB (Host and Device), TCP/IP (Ethernet and Wi-Fi®), Graphics, Bluetooth®, and others. It also provides the framework to build your application in the Real-Time Operating System (RTOS) environment or on the non-RTOS environment. If you wish to implement an RTOS-based solution, you need to choose one of the available RTOS ports under Harmony.

MPLAB Harmony comes with many demonstration applications. This tutorial shows you how to use the MPLAB Harmony Configurator (MHC) to add an RTOS to one of these applications, usb_speaker.

During the course of this tutorial, you will be using FreeRTOS v9.0. The source code for FreeRTOS is licensed under a modified GNU General Public License. Please refer the third party link on FreeRTOS

Two Ways to Use This Tutorial

  1. Use the following step-by-step instructions to add an RTOS to the existing Harmony usb_speaker Demo Application (found in the <Harmony install path>/apps/audio/usb_speaker folder).
  2. Use the solution project as an example.
    • Configure the solution project based on the hardware you are using.
    • Use MHC to generate Harmony code.
    • Build the project and program the device.
    • Note: refer to Step 1 in this lab if you need help performing these tasks.

Lab Objectives

  • Verify the existing usb_speaker demo application works well (plays a continuous audio stream).
    • The existing application uses a cooperative multitasking (non-RTOS) model.
  • Add a new time-consuming task to overload the CPU.
    • This will break the cooperative multitasking model.
  • Verify the modified usb_speaker demo has an audio quality problem.
  • Use MHC to add the FreeRTOS real-time operating system to the application.
    • Use the RTOS to ensure the audio task has enough time to do its job.
  • Verify the RTOS version of the usb_speaker application works well.


Hardware Tools

Tool About Purchase
In-Circuit Emulator
PIC32MZ Embedded Connectivity with FPU
Starter Kit
PIC32 Multimedia Expansion Board II (v5)
For PIC32 Starter Kits

It is not necessary to have an MPLAB Real ICE™ to program/debug the code. The PIC32MZ EF Starter Kit includes a PICkit™ on-board (PKOB)** debugger. The PKOB debugger can be connected to a host PC through the USB mini-B connector on the PIC32MZ EF Starter Kit for programming/debugging. See the red cable in the Hardware Setup figure.

Apart from the hardware tools listed above, the following items are required for the lab:

  • Wired stereo headset (speaker)
  • USB Type-A male to micro-B male cable for the device to act as a USB speaker
  • USB Type-A male to mini-B male cable for programming/debugging with PKOB.
Figure: Hardware Setup

Software Tools

This project has been verified to work with the following versions of software tools in Windows 7:
MPLAB® X IDE v4.01, MPLAB® XC32 Compiler v1.44, and MPLAB Harmony v2.04.

Because we regularly update our tools, occasionally you may discover an issue while using newer versions. If you suspect that to be the case, we recommend that you double-check using the same version that the project was tested with.

Archived versions of our tools can be found on the following Microchip websites:

Note that multiple versions of all these tools can co-exist on the same computer.

Tool About Installers
Windows Linux Mac OSX
Integrated Development Environment
C/C++ Compiler
MPLAB® Harmony 2.xx
Integrated Software Framework


The MPLAB Harmony framework utilizes cooperative multitasking, along with a state machine-based programming model. The state machine programming model used in this framework divides a task into smaller tasks that can be performed in an acceptable amount of time. It yields to other tasks upon completion of each small task. Cooperative multitasking is a type of multitasking in which the system never initiates a context switch from a running application task to another application task. Instead, the application task (which typically uses state machine-based programming model) should voluntarily yield control periodically or when idle to enable multiple application tasks to be run simultaneously. The disadvantages of this approach are that system-wide decisions as to how long each application task should run are not decided at the system level and are left for each application task to voluntarily yield control. This approach can result in the inefficient use of system resources and system performance.

Let us take an application example of a graphics-based USB speaker, which uses cooperative multitasking. This example has two application tasks:

  1. USB Speaker application task playing audio streamed by USB Host
  2. Display task for displaying graphic equalizer content on the LCD.

If the display task consumes more time than acceptable for the USB Speaker application task, the system performance is affected while playing audio data streamed by the USB host. When adding FreeRTOS to the USB Speaker solution, the FreeRTOS scheduler decides on the yield time at the system level for the two different application tasks. Thus, the system performance wouldn't be impacted, even if the display task doesn't voluntarily yield control to the other application task.

This lab enables the MEB II to act as a USB speaker by playing audio data (sampling rate: 48 kHz, 16-bit data) streamed by the USB host (typically a PC) in a FreeRTOS environment when co-operative multitasking is not suitable. The implementation is demonstrated by connecting the development board to the PC and then playing an audio file from the PC with the development board acting as a (USB) speaker. The lab demonstrates the system performance of the USB speaker when an additional task is added to the existing USB Speaker application. It demonstrates how a FreeRTOS based solution can perform an additional task without affecting system performance. The additional task used in this lab would be a simple delay task.

Figure 1.1 State Machine model of extended USB Speaker application
Figure 1.1 is the RTOS-based USB Speaker application's state machine model. The first application task is the USB speaker application task. The second, the delay task.

Figure 1.2 Architecture of Cooperative Multitasking based USB Speaker
Figure 1.2 is the architecture diagram for cooperative multitasking-based application with three tasks: a system task and two application tasks. The first application task is the USB Speaker application task. The second, the delay task.

Figure 1.3 Architecture of FreeRTOS based USB Speaker

Figure 1.3 is the architecture diagram for FreeRTOS application. The FreeRTOS scheduler would context-switch to different tasks based on scheduler configuration.

The APP_Tasks() function is the application task for the USB Speaker, the state APP1_Tasks() is the additional task, which just performs a blocking delay (to simplify the application). The internal state model implementation for the application tasks doesn't change, whether the application uses a cooperative multitasking or an RTOS-based solution. The below explains the state model implementation for the two application tasks.

Figure 1.4 APP_Tasks()

The application state machine (as shown in Figure 1.4) first opens the USB device driver and registers a device event handler to receive device layer USB events. The state machine then opens the audio codec and registers a buffer event handler. It then waits for the USB host to configure the device. Once the device is configured, the state machine enters into the idle loop waiting for an event from the USB host.

When the user opens an audio player application on the PC (USB host), the device receives (alternate) interface settings through the USB audio driver event handler. If the device is capable of servicing the new settings, the state machine then requests the host to send a stream of audio data. Once the device receives the audio stream, it enters the process data state where it submits the received audio data to the codec driver for playing and requests more data from the USB host. The cycle then repeats.

Click image to enlarge.
Click image to enlarge.

Figure 1.5 APP1_Tasks()

The state APP1_Tasks just provides a blocking delay when it is read to write data to the codec, and toggles an LED at the completion of the delay routine. This visually indicates parallel processing of APP1_Tasks (Delay application) with APP_Tasks (USB Speaker application).

Click image to enlarge.
Click image to enlarge.

Lab Solution:

This ZIP file contains the completed solution project for this lab.

Extracting the ZIP file will create the following folders:

  • usb_speaker_rtos contains the lab solution (in the firmware folder). It can be directly built and downloaded on the hardware to observe expected behavior.

Unlike its previous version, Harmony v2.x allows you to place the project in any folder.


Lab Index

Step 1: Verify the MPLAB Harmony "usb_speaker" Demo Application Works Without Noise Artifacts

  • Step 1.1 - Create a new project based on the existing usb_speaker demo application
  • Step 1.2 - Build the project and program the device
  • Step 1.3 - Detect and set up the “USB Audio Speaker” on your PC
  • Step 1.4 - Verify the performance

Step 2: Overload the State Machine by Adding a Time-Consuming Application to the Project

  • Step 2.1 - Configure MHC to add new application task
  • Step 2.2 - Generate Harmony code
  • Step 2.3 - Review generated source files
  • Step 2.4 - Add time-consuming application code to the project
  • Step 2.5 - Build and program the modified “USB Audio Speaker” application
  • Step 2.6 - Detect and Set up the “USB Audio Speaker” on your PC
  • Step 2.7 - Verify the performance

Step 3: Use MHC to Integrate FreeRTOS into the Application

  • Step 3.1 - Reconfigure Timer driver
  • Step 3.2 - Add FreeRTOS
  • Step 3.3 - Reconfigure codec driver
  • Step 3.4 - Reconfigure USB library
  • Step 3.5 - Reconfigure Timer System Service
  • Step 3.6 - Reconfigure RTOS system tasks
  • Step 3.7 - Reconfigure RTOS application tasks

Step 4: Generate Harmony Code

Step 5: Verify Application Performance

© 2024 Microchip Technology, Inc.
Notice: ARM and Cortex are the registered trademarks of ARM Limited in the EU and other countries.
Information contained on this site regarding device applications and the like is provided only for your convenience and may be superseded by updates. It is your responsibility to ensure that your application meets with your specifications. MICROCHIP MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND WHETHER EXPRESS OR IMPLIED, WRITTEN OR ORAL, STATUTORY OR OTHERWISE, RELATED TO THE INFORMATION, INCLUDING BUT NOT LIMITED TO ITS CONDITION, QUALITY, PERFORMANCE, MERCHANTABILITY OR FITNESS FOR PURPOSE. Microchip disclaims all liability arising from this information and its use. Use of Microchip devices in life support and/or safety applications is entirely at the buyer's risk, and the buyer agrees to defend, indemnify and hold harmless Microchip from any and all damages, claims, suits, or expenses resulting from such use. No licenses are conveyed, implicitly or otherwise, under any Microchip intellectual property rights.