Subversion Repositories svn.mios32

Compare Revisions

Ignore whitespace Rev 1538 → Rev 1539

/trunk/apps/benchmarks/midi_parser/benchmark.h
New file
0,0 → 1,45
// $Id: benchmark.h 534 2009-05-18 21:08:36Z tk $
/*
* Header file for benchmark routines
*
* ==========================================================================
*
* Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
* Licensed for personal non-commercial use only.
* All other rights reserved.
*
* ==========================================================================
*/
 
#ifndef _BENCHMARK_H
#define _BENCHMARK_H
 
/////////////////////////////////////////////////////////////////////////////
// Global definitions
/////////////////////////////////////////////////////////////////////////////
 
 
/////////////////////////////////////////////////////////////////////////////
// Global Types
/////////////////////////////////////////////////////////////////////////////
 
 
/////////////////////////////////////////////////////////////////////////////
// Prototypes
/////////////////////////////////////////////////////////////////////////////
 
extern s32 BENCHMARK_Init(u32 mode);
 
extern s32 BENCHMARK_Reset_LinearRAM(u32 par);
extern s32 BENCHMARK_Start_LinearRAM(u32 par);
 
extern s32 BENCHMARK_Reset_LinearRAM_KnownLen(u32 par);
extern s32 BENCHMARK_Start_LinearRAM_KnownLen(u32 par);
 
 
/////////////////////////////////////////////////////////////////////////////
// Export global variables
/////////////////////////////////////////////////////////////////////////////
 
 
#endif /* _BENCHMARK_H */
/trunk/apps/benchmarks/midi_parser/app.c
New file
0,0 → 1,224
// $Id: app.c 1118 2010-10-24 13:54:51Z tk $
/*
* Benchmark for MIDI parser
* See README.txt for details
*
* ==========================================================================
*
* Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
* Licensed for personal non-commercial use only.
* All other rights reserved.
*
* ==========================================================================
*/
 
/////////////////////////////////////////////////////////////////////////////
// Include files
/////////////////////////////////////////////////////////////////////////////
 
#include <mios32.h>
 
#include <FreeRTOS.h>
#include <portmacro.h>
 
#include "benchmark.h"
#include "app.h"
 
 
/////////////////////////////////////////////////////////////////////////////
// Global Variables
/////////////////////////////////////////////////////////////////////////////
 
 
/////////////////////////////////////////////////////////////////////////////
// Local variables
/////////////////////////////////////////////////////////////////////////////
 
static u32 benchmark_cycles;
 
 
/////////////////////////////////////////////////////////////////////////////
// Local prototypes
/////////////////////////////////////////////////////////////////////////////
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called after startup to initialize the application
/////////////////////////////////////////////////////////////////////////////
void APP_Init(void)
{
// initialize all LEDs
MIOS32_BOARD_LED_Init(0xffffffff);
 
// initialize stopwatch for measuring delays
MIOS32_STOPWATCH_Init(100);
 
// initialize benchmark
BENCHMARK_Init(0);
 
// init benchmark result
benchmark_cycles = 0;
 
// print welcome message on MIOS terminal
MIOS32_MIDI_SendDebugMessage("\n");
MIOS32_MIDI_SendDebugMessage("====================\n");
MIOS32_MIDI_SendDebugMessage("%s\n", MIOS32_LCD_BOOT_MSG_LINE1);
MIOS32_MIDI_SendDebugMessage("====================\n");
MIOS32_MIDI_SendDebugMessage("\n");
MIOS32_MIDI_SendDebugMessage("Play MIDI notes to start different benchmarks\n");
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This task is running endless in background
/////////////////////////////////////////////////////////////////////////////
void APP_Background(void)
{
// clear LCD screen
MIOS32_LCD_Clear();
 
// print message
MIOS32_LCD_CursorSet(0, 0);
MIOS32_LCD_PrintString("see README.txt ");
MIOS32_LCD_CursorSet(0, 1);
MIOS32_LCD_PrintString("for details ");
 
// wait endless
while( 1 );
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a MIDI package has been received
/////////////////////////////////////////////////////////////////////////////
void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package)
{
static s32 (*benchmark_reset)(u32 par);
static s32 (*benchmark_start)(u32 par);
u32 benchmark_par = 0;
u32 num_loops = 100;
 
if( midi_package.type == NoteOn && midi_package.velocity > 0 ) {
 
// determine test number (use note number, remove octave)
u8 test_number = midi_package.note % 12;
 
// set the tested port and RS optimisation
switch( test_number ) {
case 0:
MIOS32_MIDI_SendDebugMessage("Testing linear search in RAM\n");
benchmark_reset = BENCHMARK_Reset_LinearRAM;
benchmark_start = BENCHMARK_Start_LinearRAM;
benchmark_par = 0;
num_loops = 100;
break;
 
case 1:
MIOS32_MIDI_SendDebugMessage("Testing linear search in AHB RAM\n");
benchmark_reset = BENCHMARK_Reset_LinearRAM;
benchmark_start = BENCHMARK_Start_LinearRAM;
benchmark_par = 1;
num_loops = 100;
break;
 
case 2:
MIOS32_MIDI_SendDebugMessage("Testing linear search with known length in RAM\n");
benchmark_reset = BENCHMARK_Reset_LinearRAM_KnownLen;
benchmark_start = BENCHMARK_Start_LinearRAM_KnownLen;
benchmark_par = 0;
num_loops = 100;
break;
 
case 3:
MIOS32_MIDI_SendDebugMessage("Testing linear search with known length in AHB RAM\n");
benchmark_reset = BENCHMARK_Reset_LinearRAM_KnownLen;
benchmark_start = BENCHMARK_Start_LinearRAM_KnownLen;
benchmark_par = 1;
num_loops = 100;
break;
 
default:
MIOS32_MIDI_SendDebugMessage("This note isn't mapped to a test function.\n");
return;
}
 
// add some delay to ensure that there a no USB background traffic caused by the debug message
MIOS32_DELAY_Wait_uS(50000);
 
// reset benchmark
benchmark_reset(benchmark_par);
 
portENTER_CRITICAL(); // port specific FreeRTOS function to disable tasks (nested)
 
// turn on LED (e.g. for measurements with a scope)
MIOS32_BOARD_LED_Set(0xffffffff, 1);
 
// reset stopwatch
MIOS32_STOPWATCH_Reset();
 
// start benchmark
{
int i;
 
for(i=0; i<num_loops; ++i)
benchmark_start(benchmark_par);
}
 
// capture counter value
benchmark_cycles = MIOS32_STOPWATCH_ValueGet();
 
// turn off LED
MIOS32_BOARD_LED_Set(0xffffffff, 0);
 
portEXIT_CRITICAL(); // port specific FreeRTOS function to enable tasks (nested)
 
// print result on MIOS terminal
if( benchmark_cycles == 0xffffffff )
MIOS32_MIDI_SendDebugMessage("Time: overrun!\n");
else
MIOS32_MIDI_SendDebugMessage("Time: %5d.%d mS\n", benchmark_cycles/(10*num_loops), benchmark_cycles%(10*num_loops));
}
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called before the shift register chain is scanned
/////////////////////////////////////////////////////////////////////////////
void APP_SRIO_ServicePrepare(void)
{
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called after the shift register chain has been scanned
/////////////////////////////////////////////////////////////////////////////
void APP_SRIO_ServiceFinish(void)
{
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a button has been toggled
// pin_value is 1 when button released, and 0 when button pressed
/////////////////////////////////////////////////////////////////////////////
void APP_DIN_NotifyToggle(u32 pin, u32 pin_value)
{
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when an encoder has been moved
// incrementer is positive when encoder has been turned clockwise, else
// it is negative
/////////////////////////////////////////////////////////////////////////////
void APP_ENC_NotifyChange(u32 encoder, s32 incrementer)
{
}
 
 
/////////////////////////////////////////////////////////////////////////////
// This hook is called when a pot has been moved
/////////////////////////////////////////////////////////////////////////////
void APP_AIN_NotifyChange(u32 pin, u32 pin_value)
{
}
Property changes:
Added: svn:executable
## -0,0 +1 ##
+*
\ No newline at end of property
Index: midi_parser/app.h
===================================================================
--- midi_parser/app.h (revision 0)
+++ midi_parser/app.h (revision 1539)
@@ -0,0 +1,47 @@
+// $Id: app.h 674 2009-07-29 19:54:48Z tk $
+/*
+ * Header file of application
+ *
+ * ==========================================================================
+ *
+ * Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
+ * Licensed for personal non-commercial use only.
+ * All other rights reserved.
+ *
+ * ==========================================================================
+ */
+
+#ifndef _APP_H
+#define _APP_H
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Global definitions
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Global Types
+/////////////////////////////////////////////////////////////////////////////
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Prototypes
+/////////////////////////////////////////////////////////////////////////////
+
+extern void APP_Init(void);
+extern void APP_Background(void);
+extern void APP_MIDI_NotifyPackage(mios32_midi_port_t port, mios32_midi_package_t midi_package);
+extern void APP_SRIO_ServicePrepare(void);
+extern void APP_SRIO_ServiceFinish(void);
+extern void APP_DIN_NotifyToggle(u32 pin, u32 pin_value);
+extern void APP_ENC_NotifyChange(u32 encoder, s32 incrementer);
+extern void APP_AIN_NotifyChange(u32 pin, u32 pin_value);
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Export global variables
+/////////////////////////////////////////////////////////////////////////////
+
+
+#endif /* _APP_H */
Index: midi_parser/mios32_config.h
===================================================================
--- midi_parser/mios32_config.h (revision 0)
+++ midi_parser/mios32_config.h (revision 1539)
@@ -0,0 +1,21 @@
+// $Id: mios32_config.h 1196 2011-04-30 20:18:46Z tk $
+/*
+ * Local MIOS32 configuration file
+ *
+ * this file allows to disable (or re-configure) default functions of MIOS32
+ * available switches are listed in $MIOS32_PATH/modules/mios32/MIOS32_CONFIG.txt
+ *
+ */
+
+#ifndef _MIOS32_CONFIG_H
+#define _MIOS32_CONFIG_H
+
+// The boot message which is print during startup and returned on a SysEx query
+#define MIOS32_LCD_BOOT_MSG_LINE1 "MIDI Parser Benchmark"
+#define MIOS32_LCD_BOOT_MSG_LINE2 "(c) 2012 T.Klose"
+
+
+// function used to output debug messages (must be printf compatible!)
+#define DEBUG_MSG MIOS32_MIDI_SendDebugMessage
+
+#endif /* _MIOS32_CONFIG_H */
Index: midi_parser/README.txt
===================================================================
--- midi_parser/README.txt (revision 0)
+++ midi_parser/README.txt (revision 1539)
@@ -0,0 +1,45 @@
+$Id: README.txt 1185 2011-04-22 18:32:15Z tk $
+
+Benchmark for MIDI Parser
+===============================================================================
+Copyright (C) 2012 Thorsten Klose (tk@midibox.org)
+Licensed for personal non-commercial use only.
+All other rights reserved.
+===============================================================================
+
+Required tools:
+ -> http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fdoc%2FMEMO
+
+===============================================================================
+
+Required hardware:
+ o MBHP_CORE_STM32 or STM32 Primer or MBHP_CORE_LPC17
+
+===============================================================================
+
+This benchmark searches a SysEx string with 9 bytes in a search storage of 256 entries.
+
+The storage is organized in a linear way, no binary search tree or similar is
+used to simplify the implementation.
+
+Two different methods are used: storage with fixed lenght entries, and with
+variable length entries (has the advantage that more entries could be stored if
+some only specify 2 bytes like for common MIDI events...)
+
+The benchmark demonstrates, that this implementation is sufficient, because the
+SysEx string is found in much less time than it's transmitted over MIDI (9 bytes == 2.9 mS)
+
+For LPC17 we also check if it makes a difference if the storage is located in CPU or AHB RAM.
+
+
+Results STM32F103RE @ 72 MHz:
+- Testing linear search in RAM 0.451 mS
+- Testing linear search with known length in RAM 0.535 mS (+16%)
+
+Results LPC1769 @ 120 MHz:
+- Testing linear search in RAM 0.176 mS
+- Testing linear search in AHB RAM 0.193 mS (+8%)
+- Testing linear search with known length in RAM 0.242 mS (+27%)
+- Testing linear search with known length in AHB RAM 0.242 mS (no change compared to CPU RAM - interesting...)
+
+===============================================================================
Index: midi_parser/benchmark.c
===================================================================
--- midi_parser/benchmark.c (revision 0)
+++ midi_parser/benchmark.c (revision 1539)
@@ -0,0 +1,188 @@
+// $Id: benchmark.c 534 2009-05-18 21:08:36Z tk $
+/*
+ * Benchmark for MIDI Parser
+ * See README.txt for details
+ *
+ * ==========================================================================
+ *
+ * Copyright (C) 2008 Thorsten Klose (tk@midibox.org)
+ * Licensed for personal non-commercial use only.
+ * All other rights reserved.
+ *
+ * ==========================================================================
+ */
+
+/////////////////////////////////////////////////////////////////////////////
+// Include files
+/////////////////////////////////////////////////////////////////////////////
+
+#include <mios32.h>
+#include "benchmark.h"
+
+
+// for LPC17: simplify allocation of large arrays
+#if defined(MIOS32_FAMILY_LPC17xx)
+# define AHB_SECTION __attribute__ ((section (".bss_ahb")))
+#else
+# define AHB_SECTION
+#endif
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Local Variables
+/////////////////////////////////////////////////////////////////////////////
+
+#define NUM_ENTRIES 256
+#define STORAGE_SIZE (NUM_ENTRIES*10)
+static u8 search_storage[STORAGE_SIZE];
+
+static u8 search_storage_ahb[STORAGE_SIZE] AHB_SECTION;
+
+static u8 search_string[10];
+
+
+/////////////////////////////////////////////////////////////////////////////
+// Initialisation
+/////////////////////////////////////////////////////////////////////////////
+s32 BENCHMARK_Init(u32 mode)
+{
+ return 0; // no error
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+s32 BENCHMARK_Reset_LinearRAM(u32 par)
+{
+ int i;
+
+ u8 *storage = par ? (u8 *)&search_storage_ahb[0] : (u8 *)&search_storage[0];
+
+ for(i=0; i<NUM_ENTRIES; ++i) {
+ u8 *entry = (u8 *)&storage[i*10];
+ entry[0] = 0xf0;
+ entry[1] = 0x01;
+ entry[2] = 0x02;
+ entry[3] = 0x03;
+ entry[4] = 0x04;
+ entry[5] = 0x05;
+ entry[6] = 0x06;
+ entry[7] = i & 0x7f;
+ entry[8] = i >> 7;
+ entry[9] = 0xff;
+ }
+
+ int n = NUM_ENTRIES-1;
+ search_string[0] = 0xf0;
+ search_string[1] = 0x01;
+ search_string[2] = 0x02;
+ search_string[3] = 0x03;
+ search_string[4] = 0x04;
+ search_string[5] = 0x05;
+ search_string[6] = 0x06;
+ search_string[7] = n & 0x7f;
+ search_string[8] = n >> 7;
+ search_string[9] = 0xff;
+
+ return 0; // no error
+}
+
+s32 BENCHMARK_Start_LinearRAM(u32 par)
+{
+ int i;
+
+ u8 *storage = par ? (u8 *)&search_storage_ahb[0] : (u8 *)&search_storage[0];
+
+ for(i=0; i<NUM_ENTRIES; ++i) {
+ u8 *s1 = (u8 *)&storage[i*10];
+ u8 *s2 = (u8 *)&search_string[0];
+
+ while( *s1 == *s2 && *s1 != 0xff && *s2 != 0xff ) {
+ ++s1;
+ ++s2;
+ }
+
+ if( *s1 == *s2 ) {
+#if 0
+ MIOS32_MIDI_SendDebugMessage("Found %d\n", i);
+#endif
+ return 0; // found (no error)
+ }
+ }
+
+ return -1; // search string not found (not intended)
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+s32 BENCHMARK_Reset_LinearRAM_KnownLen(u32 par)
+{
+ int i;
+
+ u8 *storage = par ? (u8 *)&search_storage_ahb[0] : (u8 *)&search_storage[0];
+
+ for(i=0; i<NUM_ENTRIES; ++i) {
+ u8 *entry = (u8 *)&storage[i*10];
+ entry[0] = 9;
+ entry[1] = 0xf0;
+ entry[2] = 0x01;
+ entry[3] = 0x02;
+ entry[4] = 0x03;
+ entry[5] = 0x04;
+ entry[6] = 0x05;
+ entry[7] = 0x06;
+ entry[8] = i & 0x7f;
+ entry[9] = i >> 7;
+ }
+
+ int n = NUM_ENTRIES-1;
+ search_string[0] = 9;
+ search_string[1] = 0xf0;
+ search_string[2] = 0x01;
+ search_string[3] = 0x02;
+ search_string[4] = 0x03;
+ search_string[5] = 0x04;
+ search_string[6] = 0x05;
+ search_string[7] = 0x06;
+ search_string[8] = n & 0x7f;
+ search_string[9] = n >> 7;
+
+ return 0; // no error
+}
+
+s32 BENCHMARK_Start_LinearRAM_KnownLen(u32 par)
+{
+ int i;
+
+ u8 *storage = par ? (u8 *)&search_storage_ahb[0] : (u8 *)&search_storage[0];
+
+ u8 *s1 = (u8 *)&storage[0];
+ u8 *s1_end = (u8 *)(s1 + STORAGE_SIZE - 1);
+ u8 len_s2 = search_string[0];
+
+ for(i=0; i<NUM_ENTRIES && s1 < s1_end; ++i) {
+ u8 len_s1 = *s1++;
+
+ if( len_s1 != len_s2 ) {
+ s1 += len_s1;
+ } else {
+ int j;
+ u8 *s2 = (u8 *)&search_string[1];
+ for(j=0; j<len_s2 && *s1++ == *s2++; ++j);
+
+ if( j == len_s2 ) {
+#if 0
+ MIOS32_MIDI_SendDebugMessage("Found %d\n", i);
+#endif
+ return 0; // found (no error)
+ } else {
+ s1 += len_s1 - j - 1;
+ }
+ }
+ }
+
+ return -1; // search string not found (not intended)
+}
Index: midi_parser/Makefile
===================================================================
--- midi_parser/Makefile (revision 0)
+++ midi_parser/Makefile (revision 1539)
@@ -0,0 +1,56 @@
+# $Id: Makefile 817 2010-01-09 22:57:32Z tk $
+
+################################################################################
+# following setup taken from environment variables
+################################################################################
+
+PROCESSOR = $(MIOS32_PROCESSOR)
+FAMILY = $(MIOS32_FAMILY)
+BOARD = $(MIOS32_BOARD)
+LCD = $(MIOS32_LCD)
+
+
+################################################################################
+# Source Files, include paths and libraries
+################################################################################
+
+THUMB_SOURCE = app.c \
+ benchmark.c
+
+
+# (following source stubs not relevant for Cortex M3 derivatives)
+THUMB_AS_SOURCE =
+ARM_SOURCE =
+ARM_AS_SOURCE =
+
+C_INCLUDE = -I .
+A_INCLUDE = -I .
+
+LIBS =
+
+
+################################################################################
+# Remaining variables
+################################################################################
+
+LD_FILE = $(MIOS32_PATH)/etc/ld/$(FAMILY)/$(PROCESSOR).ld
+PROJECT = project
+
+DEBUG = -g
+OPTIMIZE = -Os
+
+CFLAGS = $(DEBUG) $(OPTIMIZE)
+
+
+################################################################################
+# Include source modules via additional makefiles
+################################################################################
+
+# sources of programming model
+include $(MIOS32_PATH)/programming_models/traditional/programming_model.mk
+
+# application specific LCD driver (selected via makefile variable)
+include $(MIOS32_PATH)/modules/app_lcd/$(LCD)/app_lcd.mk
+
+# common make rules
+include $(MIOS32_PATH)/include/makefile/common.mk