Example DSPLIB/DSPLink Application on OMAP-L1x
- 1 Introduction
- 2 Prerequisites
- 3 Running the Application
- 4 Rebuilding the Application
- 5 Performance
- 6 Optional: Debugging the DSP Server
- 7 Optional: Adding DSPLIB Functions to the Application
The call_dsplib application demonstrates a simple way to call C674x DSPLIB functions from an ARM Linux application. This example application is included with the Media:example.zip installation in versions 1.1 or higher and is verified on OMAPL1 platform. Unzip the example in the C674x DSPLIB root folder.
The call_dsplib example consists of an ARM Linux application (call_dsplib) and a DSP "server" application (dsplib_server.out). The user runs the ARM application from a Linux shell, and the ARM app in turn loads and runs the DSP executable using DSPLINK. The two applications converse via the MSGQ API (also part of DSPLINK), with shared data buffers managed by the CMEM Linux module. Depending on command line arguments supplied by the user, the DSP application will call a single DSPLIB function and return appropriate output data and a cycle count for benchmarking purposes. The ARM application will then report the total processing time from its perspective (including DSP execution and MSGQ communication) and shut down the DSP before terminating.
This application is based in part on the helloDSP example application. That application can serve as an excellent introduction to DSPLINK.
- call_dsplib -- ARM Linux application file. Uses DSPLINK to load and execute DSP application.
- dsplib_server.out -- DSP application. Calls into DSPLIB to process requests from ARM application.
ARM Source Files
- arm_main.c -- Main ARM application source. This code sets up DSPLINK and CMEM, loads the DSP application, and manages communication with the DSP via MSGQ.
- arm_interface.c/h -- ARM application source that handles DSPLIB function-specific data. Manages importing data from input files, saving output to output file, and freeing CMEM buffers when processing is complete.
- arm_parse.c/h -- ARM application source that handles parsing input text files.
- common_interface.h -- Header file used by both ARM and DSP applications. Contains universal typdefs and enumerations.
- arm_makefile -- GNU make makefile for the ARM application.
DSP Source Files
- dsp_main.c -- Main DSP application source. Contains static setup structs for DSP/BIOS and dynamic TSK create code.
- dsp_interface.c/h -- DSP application source that contains DSPLINK/MSGQ code and translates ARM request to DSPLIB function call.
- common_interface.h -- Header file used by both ARM and DSP applications. Contains universal typdefs and enumerations.
- dsplib_server.cmd -- Contains manual additions to the TCF-generated linker command file
- dsplib_server.tcf -- DSP/BIOS textual configuration file (TCF). Defines configuration of DSP application (memory segments, etc.).
- dsp_makefile -- GNU make makefile for the DSP application.
Linux Module Files
- linux/cmemk.ko -- Pre-built CMEM Linux module for use with OMAP-L137 EVM.
- linux/dsplinkk.ko -- Pre-built DSPLINK Linux module for use with OMAP-L137 EVM.
- linux/loadmodules.sh -- Shell script to load above Linux modules.
Sample Input Files
- sample_inputs/README.txt -- Explains the format for text input files. The sample input files also demonstrate the form expected by the ARM application.
- sample_inputs/* subfolders -- Contain sample text input files for calling various DSPLIB functions.
This section lists software packages and hardware necessary to run and/or build the call_dsplib example application.
- OMAP-L137 EVM and host PC with SDK installation
- Check out the getting started guide for the EVM for help setting up the EVM and SDK
- The CMEM Linux module included with the SDK is incompatible with the Linux kernel image provided in the SDK. Since this application requires CMEM, you will need to either use the cmemk.ko file provided with this application or else rebuild the CMEM module in your SDK installation.
- C674x DSPLIB installation version 1.1 or later
- Available via TI.com
- Setup Linux on your OMAP-L137 EVM according to instructions included in Using the Linux PSP on OMAP-L1
- Using NFS (instead of ramdisk or flash FS) is strongly recommended
Where to Download call_dsplib
The call_dsplib example application is installed with the C674x DSPLIB (v1.1 or higher). To get it, download the DSPLIB installer from TI.com.
Running the Application
This section gives step by step instructions to run the call_dsplib example application using the pre-compiled binaries (call_dsplib and dsplib_server.out) in the Release or Debug folder. Rebuilding the application will overwrite these files.
- Create a working folder in your NFS and copy over the following files:
- call_dsplib (from Debug or Release folder)
- dsplib_server.out (from Debug or Release folder)
- Input text files (samples are provided for several DSPLIB functions in the sample_inputs folder; sample_inputs/README.txt explains the contents of these files)
- All input text files must be in the same folder as the call_dsplib application
- Use chmod to allow execution of loadmodules.sh and call_dsplib
- From EVM linux shell: run loadmodules.sh
- It's OK if DSPLINK gives the following warning message: dsplinkk: no version for "struct_module" found: kernel tainted.
- From EVM linux shell: run call_dsplib. The DSPLIB function and input data are specified using command line
- The ARM application will save results from the DSPLIB function to the file output.txt
The following usage examples demonstrate how to use call_dsplib using the sample input files provided with the application. Note that the input files (*.txt) must be present on the NFS in the same folder as the call_dsplib application.
$> ./call_dsplib DSPF_sp_fftSPxSP fft_input.txt Initializing DSPLINK... Calling DSPLIB function... Received response from DSP after 0.002827 seconds. DSP completed processing in 550956 cycles. Closing DSPLINK... call_dsplib completed successfully!
$> ./call_dsplib DSPF_sp_ifftSPxSP ifft_input.txt Initializing DSPLINK... Calling DSPLIB function... Received response from DSP after 0.002826 seconds. DSP completed processing in 544813 cycles. Closing DSPLINK... call_dsplib completed successfully!
$> ./call_dsplib DSPF_sp_fir_gen fir_gen_input.txt Initializing DSPLINK... Calling DSPLIB function... Received response from DSP after 0.001017 seconds. DSP completed processing in 128262 cycles. Closing DSPLINK... call_dsplib completed successfully!
$> ./call_dsplib DSPF_sp_mat_mul mat_mul_input.txt Initializing DSPLINK... Calling DSPLIB function... Received response from DSP after 0.001238 seconds. DSP completed processing in 212622 cycles. Closing DSPLINK... call_dsplib completed successfully!
Rebuilding the Application
This section gives step by step instructions to rebuild the call_dsplib example application on the host PC. This will overwrite the original pre-built binaries, so you may want to back up those files before proceeding.
- Open terminal on host PC and go to DSPLIB installation's example/call_dsplib folder. Pre-built binaries are available in the Debug and Release folders. (Debug pauses during execution, allowing breakpoints to be set in the DSP code.)
- Modify the make files, dsp_makefile and arm_makefile, to insert appropriate paths for the following:
- Toolchains and codegen tools
- DSPLINK and DSP/BIOS installations
- DSPLIB installation
- CMEM (C library, not Linux module)
- On Windows: you will need Linux cross compile tools to rebuild the ARM application. TI does not provide this, but free packages (such as CodeSourcery GPP Lite) are available online.
- Use the following command line instructions to build the apps:
- $> make -f dsp_makefile
- $> make -f arm_makefile
- On Windows: use gmake instead of make (found in the xdctools folder of your DSP/BIOS folder)
- On Windows: instead of using gmake clean, use gmake with the -B option to force rebuilding all files.
Extra Steps for OMAP-L138
When rebuilding the DSP application for use on OMAP-L138, you may encounter a linker error similar to this:
undefined first referenced symbol in file --------- ---------------- _DDR /.../dsplink.lib
This problem occurs because the application uses a generic TCI file instead of a device-specific file. For OMAP-L138, depending on your version of DSPLINK, the generic TCI file may not be sufficient. If you see this error, the following extra steps should resolve it:
- In dsplib_server.tcf, find the line:
and change it to:
- In dsplib_server.tcf, change all instances of SDRAM to DDR
With these changes, you should be able to build the DSP application.
Extra Step for Recent DSPLINK Releases
When rebuilding the DSP application with recent releases of DSPLINK, you may encounter a linker error similar to this:
undefined first referenced symbol in file --------- ---------------- _DSPLINKDATA_init /.../dsplink.lib
This problem occurs because the DSPLINK data library was not present in older versions of DSPLINK. You can correct this issue with a simple addition to the file dsp_makefile:
LIBS := -ldsplink.lib -ldsplinkpool.lib -ldsplinkmpcs.lib -ldsplinkmplist.lib -ldsplinkmsg.lib -ldsplinknotify.lib -ldsplinkringio.lib -ldsplib674x.lib -ldsplinkdata.lib
Appending the final item should allow you to build the DSP application successfully.
The call_dsplib application is designed to strike a balance between simplicity and optimized performance. All code (including the DSPLIB functions) is executed from SDRAM with L1 and L2 RAM dedicated strictly to cache. This arrangement will necessarily produce larger cycle counts than the demo applications yield when run on the C674x simulator due to the realities of EMIF access. Additionally, inter-processor communication (IPC) imposes its own latency on the application. While the overall performance of the application is pretty good, there is still potentially room for improvement:
- Hold DSP program data and/or buffers in L2RAM
- Pre-fetch data using EDMA
- Use alternative, light-weight IPC schemes
Also, keep in mind that the ARM is free to process other tasks while the DSP executes a DSPLIB function. That capability is not overtly demonstrated by this application.
The following table summarizes the performance of several DSPLIB functions in either scenario. The numbers for the demo application are measured using the C674x Cycle Accurate Simulator. Additionally, the overall delay from the ARM perspective (i.e. time between sending a message to the DSP and receiving a response after processing is complete) is listed for the call_dsplib application.
|DSPLIB Function||Test Parameters||DSP Cycles (call_dsplib)||DSP Cycles (demo)||ARM Completion Time (call_dsplib)|
|DSPF_sp_fftSPxSP||N = 8192||551,000||105,000||2.83 ms|
|DSPF_sp_ifftSPxSP||N = 8192||545,000||105,000||2.83 ms|
|DSPF_sp_fir_gen||ny = 8192, nh = 16||128,000||82,000||1.02 ms|
|DSPF_sp_fir_cplx||ny = 4096, nh = 16||194,000||131,000||1.24 ms|
|DSPF_sp_iir||n = 4096||108,000||24,600||0.967 ms|
|DSPF_sp_lms||ny = 2048, nh = 8||115,000||98,300||0.898 ms|
|DSPF_sp_mat_mul||nr1 = nc1 = nc2 = 64||213,000||156,000||1.24 ms|
|DSPF_sp_mat_mul_cplx||nr1 = nc1 = nc2 = 32||89,500||65,600||0.812 ms|
|DSPF_sp_mat_trans||rows = cols = 64||60,000||4,320||0.721 ms|
Optional: Debugging the DSP Server
This section lists the additional steps required to debug the DSP "server" application.
- Make sure you're using the Debug versions of call_dsplib and dsplib_server.out
- Run call_dsplib with the appropriate function name and input file. The console will display the following message: DSPLIB server loaded and running. Press Enter to continue.
- Connect to the DSP via CCS and JTAG. Go to File->Load Symbols->Load Symbols Only... and select the file dsplib_server.out in the Debug folder.
- In CCS, open the file dsp_interface.c and place any breakpoints that you wish. Select Debug->Run.
- On the linux console, press enter to run the algorithm. In CCS, you may now step through the code if the application reaches a breakpoint.
- After the DSPLIB function completes, the Linux terminal will display the following message: DSPLIB processing complete. Press Enter to continue.
- You may check the LOG (trace) on the DSP and view memory contents. When you're done, select Debug->Run Free and Debug->Disconnect.
- On the Linux terminal, press enter. The application will then terminate.
Optional: Adding DSPLIB Functions to the Application
The call_dsplib application includes several DSPLIB functions as-is, but does not make every function available. This section details the source code changes necessary to add another DSPLIB function.
Changes to File: common_interface.h
- Append a new typedef struct declaration to the end of the file. This struct should contain a member (with appropriate type) for each parameter in the DSPLIB function. You can omit all "const" or "restrict" modifiers from the parameters.
Changes to File: arm_interface.c
- Add new function: parse_<fxn name> Be sure to include a function prototype near the top of the file. The function should have identical return type and input parameters to the existing parse_<x> functions. The contents of the new function should be straightforward to infer from the existing parse_<x> functions.
- Add a new case to the parse_params function switch statement. This should call your new parse_<fxn_name> function.
- Add new function: save_<fxn name> Be sure to include a function prototype near the top of the file. The function should have identical return type and input parameters to the existing save_<x> functions. The contents of the new function should be straightforward to infer from the existing save_<x> functions.
- Add a new case to the save_params function switch statement. This should call your new save_<fxn_name> function.
- Add new function: free_<fxn name> Be sure to include a function prototype near the top of the file. The function should have identical return type and input parameters to the existing free_<x> functions. The contents of the new function should be straightforward to infer from the existing free_<x> functions.
- Add a new case to the free_params function switch statement. This should call your new free_<fxn_name> function.
Changes to File: dsp_interface.c
- Add a new case to the dsplibDelegate function switch statement. This should call the appropriate DSPLIB function.