Please note as of Wednesday, August 15th, 2018 this wiki has been set to read only. If you are a TI Employee and require Edit ability please contact x0211426 from the company directory.

Soft-UART Implementation on AM335X PRU - Software Users Guide

From Texas Instruments Wiki
Jump to: navigation, search

This wiki is no longer updated, and the Soft-UART software developed for the 3.2.0 Linux kernel is not supported on e2e.


This article serves as the User's Guide for the Soft-UART implementation on the Programmable Real-Time Unit (PRU) of the AM335x devices from Texas Instruments. This user's guide will detail the features supported, location of source code, software configuration options and selection method, build procedure, and sample test procedure.

The Soft-UART software emulates a UART protocol on the PRU. The implementation uses the serializers of on-chip McASP for the UART TX and RX lines. The following high level components create the Soft-UART solution:

  1. PRU Firmware - This firmware is responsible for controlling the physical transmission/reception of data.
  2. Linux Driver - The driver is implemented using the serial subsystem of the Linux kernel as in interface to send and receive data.
  3. OpenEmbedded Recipes - The building of the entire system including bootloaders, kernel, and file system is accomplished using an overlay to the OpenEmbedded project. The OpenEmbedded project is a community effort for building custom embedded distributions. It solves the often complex cross-compilation and linking issues as well and handling generation of file system images. More details for using this overlay can be found in the Build Procedure section below.
   Note: The Linux Driver is implemented on the 3.2.0 kernel.  Currently there no plans to port this driver to other kernel versions.


The Soft-UART implementation supports the following features:

  • 6 - 8 bits per character (configurable)
  • LSB-first
  • 1 or 2 stop bits
  • Receiver oversampling of x8 and x16 (configurable)
  • Parity generation and error detection (even, odd, or no parity)
  • Configurable McASP serializer mapping for each TX & RX signal
  • Configurable half or full duplex
  • Independent baud rates supported for Soft-UART ports
    • Configurable maximum baud rate (up to 115200 baud)
    • Dependent baud rate for each Soft-UART based upon software-configurable maximum baud rate divided by 1, 2, 4, 6, 12, 16, 24, 48, 64, 96, 192, & 384
  • Two full duplex Soft-UARTS per PRU

Hardware Requirements

This code depends on additional hardware not found in the EVM box. A reference schematic for the soft-UART hardware can be found here.

The hardware to support the Soft-UART implementation requires the following signals and AM335x pins:

McASP Serializer (AXR<m>)
McASP Serializer (AXR<k>)

Location of the Source Code

Source code for all the Soft-UART software components are maintained in Gitorious. Following is the list of software components with their repositories and the branch details.

SUART Firmware
pru/am335x-pru-uart-fw git:// master
Linux Kernel and Driver Source pru/am335x-pru-linux-drivers git:// master
OpenEmbedded Recipes pru/am335x-pru-recipes git:// master

NOTE: the git clone URLs have changed as of 5/8/2018.
Linux Kernel and Driver Source:
SUART Firmware:
OpenEmbedded Recipes not currently available.

The source code from the git repository can be pulled into local host using the git commands below replacing the values in <> marks with the value from the table above. Note: Install git if not available on the local host

git clone <GIT CLONE URL>    # Command to pull the repository
git checkout <LATEST BRANCH>  # Command to checkout to the required branch, if needed

Following are the example commands to pull the Linux driver source code

git clone git://

It is also work noting that many of these repositories also have git tags corresponding to particular releases. These tags can be viewed online, or in the checked out repository by using the git tag command.

Soft-UART Configuration Options

The following parameters can be configured within the Soft-UART code. All configuration changes are made by editing the file drivers/serial/am335x_pru_suart/am335x_suart_board.h.

  1. Number of Soft-UARTs
  2. Enabling PRUs and McASPs
  3. PRU to McASP mapping
  4. gSuartInfo structure
    • McASP serializer to Soft-UART mapping
    • Soft-UART mode (Full Duplex or Half Duplex)
  5. Maximum baud rate
  6. Receiver over-sampling
  7. FIFO time-out

Number of Soft-UARTs

The number of SUARTs is configurable in am335x_suart_board.h header file in the SUART driver source code. Edit the macro NR_SUART in the drivers/serial/am335x_pru_suart/am335x_suart_board.h. Value of NR_SUART should be an integer ranging from 1 to 4. The table below shows the device files

UART# Device File
1 /dev/ttySU0
2 /dev/ttySU1
3 /dev/ttySU2
4 /dev/ttySU3

Enabling PRUs and McASPs

Once the number of SUARTS required is decided, now it is required to configure the SUART driver about the PRU and McASP on which the SUARTS need to RUN. PRU is configurable in the am335x_suart_board.h header file. Edit the macros PRU0_MODE, PRU1_MODE in drivers/serial/am335x_pru_suart/am335x_suart_board.h to enable/disable usage of a PRU. Value of these macros should be PRU_MODE_RX_TX_BOTH if the PRU need to be enabled, else it should be PRU_MODE_INVALID to disable the PRU. Each PRU supports 2 SUARTS.

PRU# MACRO Value to Enable Value to Disable

PRU to McASP mapping

By default in the driver McASP1 is mapped to PRU0 and McASP0 is mapped to PRU1. The mapping of McASP to PRU can be changed by modifying the PRU_INTC_CHANMAP8_FULL and PRU_INTC_CHANMAP13_FULL defines in include/linux/mfd/pruss.h

For McASP1 to PRU0, McASP0 to PRU1 mapping

#define PRU_INTC_CHANMAP8_FULL (0x00000000) // 35 34 33 32 - McASP1 to PRU0

//#define PRU_INTC_CHANMAP8_FULL (0x00010100) // 35 34 33 32 - McASP1 to PRU1

#define PRU_INTC_CHANMAP13_FULL (0x01010000) // 55 54 53 52 - McASP0 to PRU1

//#define PRU_INTC_CHANMAP13_FULL (0x00000000) // 55 54 53 52 - McASP0 to PRU0

For McASP1 to PRU0, McASP0 to PRU1 mapping

//#define PRU_INTC_CHANMAP8_FULL (0x00000000) // 35 34 33 32 - McASP1 to PRU0

#define PRU_INTC_CHANMAP8_FULL (0x00010100) // 35 34 33 32 - McASP1 to PRU1

//#define PRU_INTC_CHANMAP13_FULL (0x01010000) // 55 54 53 52 - McASP0 to PRU1

#define PRU_INTC_CHANMAP13_FULL (0x00000000) // 55 54 53 52 - McASP0 to PRU0

When McASP to PRU mapping is changed, make sure to change the gSuartInfo structure with proper McASP and PRU number for all the SUARTS.

gSuartInfo Structure

gSuartInfo structure is an important structure where the mapping of SUARTs to hardware resources are specified. For each SUART, it is required to specify the PRU number, McASP number and McASP serializer numbers in this structure. This structure is present in driver file drivers/serial/am335x_pru_suart/am335x_suart_board.h.

typedef struct suart_info {

    u32 suartNum;
    u32 pruNum;
    u32 txPruChn;
    u32 rxPruChn;
    u32 txSysEvent;
    u32 rxSysEvent;
    u32 ctxBase;
    u32 fmtDataBase;
    u32 mcaspNum;
    u32 txSerializer;
    u32 rxSerializer;

} tSurtInfo;

In this structure, the members pruNum, mcaspNum, txSerializer, and rxSerializer are configurable. In a given PRU, structure members txPruChn, rxPruChn, txSysEvent, rxSysEvent, ctxBase, and fmtDataBase should not be changed or mixed. The suartNum in the structure has no significance, but the order of entries matters. Data in the zeroth index of the structure array will be considered as data of /dev/ttySU0 and respectively for the other array elements.

Snapshot of this structure is specified at the end of this wiki.

McASP serializer to Soft-UART mapping

Serializers for a specific SUART should be specified gSuartInfo structure fields txSerializer and rxSerializer. The serializer numbers specified should belong to the McASP instance assigned to the PRU core on which SUART is running. Value for the txSerializer or rxSerializer in a McASP will be PRU_SUART_SERIALIZER_x (where x can be any number from o to 3. If McASP serializer is not connected to a specific SUART in hardware, then the values of serializer should be set to PRU_SUART_SERIALIZER_NONE.

McASP Serializers

Soft-UART mode: Full duplex or Half duplex

If SUART need to operate in Full duplex then it is required to specify valid serializers for txSerializer and rxSerializer in the gSuartInfo structure. For Half duplex operation specify either txSerializer or rxSerializer as PRU_SUART_SERIALIZER_NONE.

Maximum baud rate

To modify the base baud rate, edit the macro SUART_DEFAULT_BAUD in the file pru/hal/uart/include/suart_api.h.

Possible value
This implies that any Soft-UART can have the maximum baud rate of 115200. The various baud rate supported with this configuration would be 115200, 57600, 38400, 19200, 9600, 4800, 2400, 1200.
This implies that any Soft-UART can have the maximum baud rate of 57600. The various baud rate supported with this configuration would be 57600, 19200, 9600, 4800, 2400, 1200, 300.
This implies that any Soft-UART can have the maximum baud rate of 38400. The various baud rate supported with this configuration would be 38400, 19200, 9600, 2400, 1200.
This implies that any Soft-UART can have the maximum baud rate of 19200. The various baud rate supported with this configuration would be 19200, 9600, 4800, 1200.

The table below provides the list of supported baud-rates for the given maximum baud rate and the baud rate divisor values.

Baud Rate divisor
Note: The shaded boxes are not supported by any standard terminal emulation programs like (mini-com, Tera-term; HyperTerminal etc).

Receiver over-sampling

To modify the over sampling, edit the macro SUART_DEFAULT_OVRSMPL in the driver header file drivers/serial/am335x_pru_suart/suart_api.h.

Possible value
SUART_8X_OVRSMPL The receive line is over-sampled 8x times. This is the default setting and is recommended for most of the requirements.
SUART_16X_OVRSMPL The receive line is over-sampled 16x times. Note that having this setting, the maximum baud rate supported would be 57600.

FIFO timeout

FIFO timeout is configurable at module init. See the "Running the Soft-UART Sample Application" section for details.

Build Procedure

This section will detail both how to build an entire distribution using OpenEmbedded and the overlay contained in the pru-recipes repository as well as building the Linux kernel and PRU firmware stand-alone.

Building using OpenEmbedded

This sections covers using OpenEmbedded and the pru-recipes overlay to build the entire distribution. This is required when building applications that will link with the pcsc-lite library to provide the proper cross-compilation environment and libraries. The pru-recipes overlay was based on the Arago project overlay from and so you will see the use of the arago name throughout.


Install Required Packages

For an Ubuntu 10.04 host you should install the following packages:

  • build-essential
  • subversion
  • ccache
  • sed
  • wget
  • cvs
  • git-core
  • coreutils
  • unzip
  • texinfo
  • docbook-utils
  • gawk
  • help2man
  • diffstat
  • file
  • g++
  • texi2html
  • bison
  • flex
  • htmldoc
  • chrpath
  • libxext-dev
  • xserver-xorg-dev
  • doxygen
  • corkscrew

You can use the following command to install all of these package:

sudo apt-get install build-essential subversion ccache sed wget cvs git-core coreutils unzip texinfo docbook-utils gawk help2man diffstat file g++ texi2html bison flex htmldoc chrpath libxext-dev xserver-xorg-dev doxygen corkscrew

Install the Toolchain

You will also need to install the codesourcery toolchain. The normal toolchain location to install to is in /opt/arm-2009q1. You can find information on installing the toolchain at this link

NOTE: you may need to install the toolchain using sudo or change permissions of /opt/arm-2009q1 to allow you to write to that directory.

Change Default Shell

OpenEmbedded contains packages that may have shell script that is not Dash shell compliant. To avoid possible issues it is best to change your /bin/sh shell to bash using the following command:

sudo dpkg-reconfigure dash

Select No when prompted

Disk Space Requirements

Building an entire distribution can require a sizeable amount of disk space (Minimum of 19GB).

Obtain the Sources

In order to build with OpenEmbedded you will need to clone three repositories that contain the metadata (recipes) used to build all the packages. NOTE: OpenEmbedded contains recipes for more packages than are required for SmartCard. These packages can be used to add additional functionality to your system but are not built by default.

git clone git:// arago
git clone git://
git clone git://

For the arago-oe-dev and arago-bitbake repositories the last validated revisions are:

  • arago-oe-dev: 1428ddd69c31eb7f9874c8e7941ea614b423904b
  • arago-bitbake: 789382350344a40a3d7c094b5a96bee2a69d01fa

To use these revisions you must do:

  1. cd <repo name>
  2. git checkout <revision>

For example to use the correct revision for arago-oe-dev you would do:

cd arago-oe-dev
git checkout 1428ddd69c31eb7f9874c8e7941ea614b423904b

Setup the Environment File

 cd arago
cp setenv.sample setenv

Edit setenv and set OEBASE to the location where you cloned the arago repositories above. For example if you made a directory in /home/user/build and cloned the repositories in this directory then OEBASE should be set to:

 export OEBASE=/home/user/build

Setup the Configuration File

 cd arago/conf
cp local.conf.sample local.conf

Change MACHINE ?= “arago” to MACHINE ?= “UPDATE

If you have more than 1 CPU Uncomment the PARALLEL_MAKE and BB_NUMBER_THREADS lines and set the value to the number of CPUs you have

NOTE: If you want to preserve disk space you can also uncomment the line INHERIT += "rm_work". However, if you do this then using the method described below to do custom one-off builds without updating recipes will no longer work since your work directories will be cleaned after each package is built.

Source Environment Script

In the terminal you are going to use for building you will need to source the environment script to set the required variables. This can be done using:

source arago/setenv

Build the Distribution

Using the following command will build the kernel, bootloader, and file system with all required packages for SUART support.


NOTE: It can take a long time to do the initial build of the file system depending on your system resources. During this time the build system is downloading the package sources and compiling the packages that make up the system. As long as you do not delete your arago-tmp and downloads directories which are created during the build process, subsequent builds will be done much faster because they will only have to build the delta changes.

Soft-UART Recipes

The following recipes (paths given from the OEBASE directory) were created to build the Soft-UART software components:

  1. arago/recipes/pru/ Stages the pasm executable required to build PRU firmware
  2. arago/recipes/pru/ Builds the Soft-UART firmware. This is required for the driver to load.
  3. arago/recipes/linux/linux-pru: Build the Linux kernel will support SUART Driver.

Building Firmware

In case you wish to modify the SUART firmware and rebuild outside of the OpenEmbedded flow you can use the following command to build the firmware.


  1. You will need to have cloned the firmware repositories listed above in order to have access to the SUART firmwares.
  2. You will need to have the pasm tool. You can download the tool from this link

Building SUART Firmware

  1. cd pru-uart-fw
  2. git checkout master
  3. mkdir -p bin
  4. pasm -b PRU_SUART_Emulation.p bin/PRU_SUART_Emulation

Building Linux Kernel and Device Driver

Pull the Linux kernel source from the pru-linux-drivers Gitorious repository specified above and go to the latest branch. Execute the following commands to get default config for AM335x

make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- mrproper
make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- am335x_evm_defconfig

Execute the following command to select the PRU multi-function driver, SUART driver and McASP(s).

make ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- menuconfig 

1. Enabling the PRU multi-function driver within menuconfig

Device Drivers  --->  Multifunction device drivers  --->  Texas Instruments MFD PRUSS support


2. Enabling AM335x PRU based SUART driver within menuconfig

Device Drivers  --->    Character devices  --->     Serial drivers  --->  PRU based SUART emulation

If only 1 or javascript:void(0)2 SUARTs are required by system then enable either McASP0 or McASP1. (McASP0 is enabled by default when the SUART driver is enabled )


If 3 or 4 SUARTs are required by system then enable both McASP0 and McASP1.


IMPORTANT NOTE: If McASP1 is also used for SUART, make sure that “ALSA for SoC Audio” is disabled as it uses McASP1.

Device Drivers ---> Sound card support ---> Advanced Linux Sound Architecture ---> ALSA for SoC audio support


Once the SUART driver options are enabled then compile the kernel and drivers by executing following commands.

make -j8 ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- uImage
make -j8 ARCH=arm CROSS_COMPILE=arm-arago-linux-gnueabi- modules

Any drivers built as modules need to be added to the target root file system.

Components on Target File System

All the software components of the Soft-UART have to be placed at specific directories in the target file sytem. Following table has the list of software components and their location on the target file system.

SUART Firmware Firmware to run on PRU cores /lib/firmware/PRU_SUART_Emulation.bin
Linux Driver SUART driver. Loads firmware and provides access to the SUART ports /lib/modules/<kernel version>/kernel/drivers/serial/omapl_pru/suart/suart_emu.ko

Running the Soft-UART Sample Application

This section describes the testing steps for a sample Soft-UART application:

  1. Boot the board and login using root
  2. Insert the suart_emu.ko module to load the firmware and provide access to the Soft-UARTs. The suart_timeout parameter can be set at this time (default of 5ms).
    root@am335x-evm:~# modprobe suart_emu suart_timeout=<timeout in ms>
    am33xx_pruss_uart am33xx_pruss_uart.1: fw size 3916. downloading...
    Configuring McASP0
    Configuring McASP1
    In pruss_enable
    Out pruss_enable
    In pruss_enable
    Out pruss_enable
    In pruss_enable_system_interrupts
    Out pruss_enable_system_interrupts
    In pruss_enable
    Out pruss_enable
    In pruss_enable
    Out pruss_enable
    In pruss_enable_system_interrupts
    Out pruss_enable_system_interrupts
    pru_set_ram_data_for, uart_num : 3 pru_num:0 mcasp_num:1 tx_ser:1 rx_ser:0
    pru_set_ram_data_for, uart_num : 1 pru_num:1 mcasp_num:0 tx_ser:2 rx_ser:0
    pru_set_ram_data_for, uart_num : 2 pru_num:1 mcasp_num:0 tx_ser:3 rx_ser:1
    In pruss_run
    pruss_run value=0x00000000,addr=0xc2922000
    pruss_run value=0x00000009,addr=0xc2922000
    pruss_run value=0x0000000b,addr=0xc2922000
    Out pruss_run
    RUN PRU0
    In pruss_run
    pruss_run value=0x00000000,addr=0xc2924000
    pruss_run value=0x00000009,addr=0xc2924000
    pruss_run value=0x0000000b,addr=0xc2924000
    Out pruss_run
    RUN PRU1
    am33xx_pruss_uart.1: ttySU0 at MMIO 0x4a310000 (irq = 24) is a suart_tty
    am33xx_pruss_uart.1: ttySU1 at MMIO 0x4a310000 (irq = 25) is a suart_tty
    am33xx_pruss_uart.1: ttySU2 at MMIO 0x4a310000 (irq = 20) is a suart_tty
    am33xx_pruss_uart.1: ttySU3 at MMIO 0x4a310000 (irq = 21) is a suart_tty
    am33xx_pruss_uart am33xx_pruss_uart.1: am33xx_pruss_uart device registered(pru_clk=192000000, asp_clk=100000000)
  3. Connect the SUART port to a PC with a serial cable. Open a terminal progrAam on the PC.
  4. For RX, run the following command on the L138/137 board. Type or transmit a file in the PC terminal program.
    root@am335x-evm:~# microcom -s <baud> /dev/ttySUn
  5. For TX, run the following command on the L138/L137 board.
    root@am335x-evm:~# cat SUART-README_For_Verification.txt > /dev/ttySUn

Refer to the Test Guide under Additional Documentation for other test methods.

Configurable Parameters in am335x_suart_board.h

Following are the configurable parameters in the AM335x SUART driver             
NR_SUART           -- Number of SUARTS, valid values are 1,2,3 and 4
PRU0_MODE       -- Is PRU0 used(PRU_MODE_RX_TX_BOTH) or not used(PRU_MODE_INVALID)
PRU1_MODE       -- Is PRU1 used(PRU_MODE_RX_TX_BOTH) or not used(PRU_MODE_INVALID)

Description of few configurable parameters in the gSuartInfo table    
UART#           -- This has no significance in the table, added for readability (order is important)   
PRU_NUM     -- PRU on which the UART has to RUN(Data from TX_CHN to DATA_BASE is depending on PRU_NUM)
MCASP#         -- McASP on which the SUART is connected (Make sure it is enabled in menuconfig)
TX_SER           -- Transmit serializer on the corresponding McASP  
RX_SER          -- Receiver serializer on the corresponding McASP               

To disable usage of PRU, change the PRUx_MODE and change TX_SER,                                 
RX_SER of the corresponding entries as PRU_SUART_SERIALIZER_NONE  
/* Number of SUARTS supported by the driver */                      
#define NR_SUART    4                                                     
#define PRU1_MODE    PRU_MODE_RX_TX_BOTH                                            
static tSuartInfo gSuartInfo[MAX_SUARTS_SUPPORTED] =              
/* UART#    PRU_NUM  TX_CHN RX_CHN TX_EVT RX_EVT CTX_BASE DATA_BASE MCASP#                    TX_SER                    RX_SER*/
{     1,  PRUCORE_1,      0,     1,    24,    25,    0xB0,     0x90,    0,    PRU_SUART_SERIALIZER_2,    PRU_SUART_SERIALIZER_0},
{     2,  PRUCORE_1,      2,     3,    26,    27,   0x100,     0xE0,    0,    PRU_SUART_SERIALIZER_3,    PRU_SUART_SERIALIZER_1},
{     3,  PRUCORE_0,      0,     1,    20,    21,    0xB0,     0x90,    1,    PRU_SUART_SERIALIZER_1,    PRU_SUART_SERIALIZER_0},
{     4,  PRUCORE_0,      2,     3,    22,    23,   0x100,     0xE0,    1,   PRU_SUART_SERIALIZER_NONE, PRU_SUART_SERIALIZER_NONE},

Additional Documentation