changeset 326:afd0ab675643

Reinstate accidentally deleted examples
author jlarmour
date Tue, 03 Sep 2002 16:03:16 +0000
parents e46ccba0c5f1
children 46ef6d9976db
files examples/Makefile examples/build_Makefile examples/hello.c examples/instrument-test.c examples/serial.c examples/simple-alarm.c examples/twothreads.c
diffstat 7 files changed, 451 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/examples/Makefile
@@ -0,0 +1,116 @@
+# Mostly written by Jonathan Larmour, Red Hat, Inc.
+# This file is in the public domain and may be used for any purpose
+
+# PKG_INSTALL_DIR might need to be edited.  Right now it is set
+# assuming that a user ran pkgconf.tcl in /cygdrive/c/ecos-work on Windows NT,
+# or used the Configuration Tool with C:\ecos-work as a build-tree.
+#
+# You can also override it on the make command-line, e.g.:
+#   make PKG_INSTALL_DIR=/myecc/install
+# or you can set it in your environment
+
+PKG_INSTALL_DIR = /cygdrive/c/ecos-work/install
+
+# You must also set XCC to the name of your cross-compiler, including any
+# options it needs.
+
+# Uncomment one of the below, or invoke make with the name of the compiler
+# you want, e.g.:
+#   make XCC="sparclite-elf-gcc -mcpu=sparclite -msoft-float"
+# You can also set XCC in your environment
+
+#XCC = mn10300-elf-gcc                                 # MN10300/AM31
+#XCC = mn10300-elf-gcc -mam33                          # AM33
+#XCC = mips-tx39-elf-gcc                               # MIPS TX39
+#XCC = mips-tx49-elf-gcc -mips2 -EL                    # MIPS TX49 LITTLE-ENDIAN
+#XCC = mips-tx49-elf-gcc -mips2 -EB                    # MIPS TX49 BIG-ENDIAN
+#XCC = mips64vr4300-elf-gcc -mgp32 -EB                 # MIPS VR4300
+#XCC = sh-elf-gcc -m3 -mb                              # SH3 BIG-ENDIAN
+#XCC = sh-elf-gcc -m3 -ml                              # SH3 LITTLE-ENDIAN
+#XCC = powerpc-eabi-gcc -msoft-float -mcpu=860         # POWERPC
+#XCC = arm-elf-gcc -mcpu=arm7di                        # AEB
+#XCC = arm-elf-gcc -mcpu=arm7tdmi                      # PID7
+#XCC = arm-elf-gcc -mcpu=arm7tdmi -mbig-endian         # PID7 BIG-ENDIAN
+#XCC = arm-elf-gcc -mcpu=arm9                          # PID9
+#XCC = thumb-elf-gcc -mthumb-interwork                 # PID7 THUMB
+#XCC = thumb-elf-gcc -mthumb-interwork -mbig-endian    # PID7 THUMB BIG-ENDIAN
+#XCC = arm-elf-gcc -mcpu=arm710c -D__CL7111            # CIRRUS LOGIC CL7111
+#XCC = arm-elf-gcc -mcpu=arm7tdmi -D__EDB7211          # CIRRUS LOGIC EDB7211
+#XCC = arm-elf-gcc -mcpu=arm7tdmi -D__EDB7209          # CIRRUS LOGIC EDB7209
+#XCC = arm-elf-gcc -mcpu=arm7tdmi -D__EDB7209 -D__EDB7212 # CIRRUS LOGIC EDB7212
+#XCC = arm-elf-gcc -mcpu=arm7tdmi                      # ARM COGENT CMA230
+#XCC = arm-elf-gcc -mcpu=arm7tdmi -D__CMA222           # ARM COGENT CMA222
+#XCC = thumb-elf-gcc                                   # ARM COGENT CMA230 THUMB
+#XCC = arm-elf-gcc -mcpu=strongarm                     # EBSA285
+#XCC = arm-elf-gcc -mcpu=strongarm1100                 # ASSABET/BRUTUS
+#XCC = sparclite-elf-gcc -msoft-float -mcpu=sparclite  # SPARCLITE
+#XCC = i686-pc-linux-gnu-gcc                           # SYNTHETIC LINUX
+#XCC = i386-elf-gcc                                    # i386 PC
+#XCC = v850-elf-gcc                                    # NEC v850
+
+###### VARIABLES
+# Any of these can be overriden on the command-line or in your environment
+
+ifeq ($(findstring sh-elf-gcc,$(XCC)),sh-elf-gcc)
+CFLAGS        = -ggdb
+else
+CFLAGS        = -g
+endif
+
+CXXFLAGS      = $(CFLAGS)
+
+EXTRACFLAGS   = -Wall -I$(PKG_INSTALL_DIR)/include -ffunction-sections -fdata-sections
+
+EXTRACXXFLAGS = $(EXTRACFLAGS) -fno-exceptions -fno-rtti -fvtable-gc -finit-priority
+
+LDFLAGS       = -nostartfiles -L$(PKG_INSTALL_DIR)/lib -Wl,--gc-sections
+LIBS          = -Ttarget.ld -nostdlib
+
+LD            = $(XCC)
+XCXX          = $(XCC)
+
+###### RULES
+
+.PHONY: all clean CCCHECK
+
+all: hello twothreads simple-alarm serial
+
+clean:
+	-rm -f hello hello.o twothreads twothreads.o
+	-rm -f simple-alarm simple-alarm.o serial serial.o
+	-rm -f instrument-test instrument-test.o
+
+CCCHECK:
+ifeq ($(XCC),)
+	@echo You must set XCC to the name of your cross-compiler
+	@false
+endif
+
+
+%.o: %.c
+	$(XCC) -c -o $*.o $(CFLAGS) $(EXTRACFLAGS) $<
+
+%.o: %.cxx
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(EXTRACXXFLAGS) $<
+
+%.o: %.C
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(EXTRACXXFLAGS) $<
+
+%.o: %.cc
+	$(XCXX) -c -o $*.o $(CXXFLAGS) $(EXTRACXXFLAGS) $<
+
+hello: CCCHECK hello.o
+	$(LD) $(LDFLAGS) -o $@ $@.o $(LIBS)
+
+twothreads: CCCHECK twothreads.o
+	$(LD) $(LDFLAGS) -o $@ $@.o $(LIBS)
+
+simple-alarm: CCCHECK simple-alarm.o
+	$(LD) $(LDFLAGS) -o $@ $@.o $(LIBS)
+
+serial: CCCHECK serial.o
+	$(LD) $(LDFLAGS) -o $@ $@.o $(LIBS)
+
+instrument-test: CCCHECK instrument-test.o
+	$(LD) $(LDFLAGS) -o $@ $@.o $(LIBS)
+
new file mode 100644
--- /dev/null
+++ b/examples/build_Makefile
@@ -0,0 +1,56 @@
+#! /bin/sh
+
+# This script will create a generic Makefile template
+# suitable for use with an installed eCos configuration.
+
+# usage: <eCos_repository>/build_Makefile [<eCos_install_dir>]
+# env:   ${SRCS} - the default list of source files
+#        ${DST}  - the default target
+
+HOME=${1-`pwd`}
+if [ ! -d ${HOME}/install ]; then
+  echo "Not an eCos install tree"
+  echo "usage: <eCos_repository>/build_Makefile [<eCos_install_dir>]"
+  echo "env:   \${SRCS} - the default list of source files"
+  echo "       \${DST}  - the default target"
+  exit
+fi
+
+cat <<EOF >Makefile
+#
+# Makefile for eCos tests
+#
+
+# Copied from 'makefile' the "install" tree
+
+EOF
+
+grep export ${HOME}/makefile >>Makefile
+
+cat <<EOF >>Makefile
+
+#
+# Target specific flags, etc.
+#
+
+EOF
+
+cat ${HOME}/install/include/pkgconf/ecos.mak >>Makefile
+
+cat <<EOF >>Makefile
+
+# Simple build rules
+
+.c.o:
+	\$(CC) -c \$(ECOS_GLOBAL_CFLAGS) -I\$(PREFIX)/include \$*.c
+
+.o:
+	\$(CC) \$(ECOS_GLOBAL_LDFLAGS) -L\$(PREFIX)/lib -Ttarget.ld \$*.o -o \$@
+
+SRCS=${SRCS-source_file.c}
+OBJS=\${SRCS:%.c=%.o}
+DST=${DST-result_prog}
+
+\${DST}: \${OBJS}
+
+EOF
new file mode 100644
--- /dev/null
+++ b/examples/hello.c
@@ -0,0 +1,8 @@
+/* this is a simple hello world program */
+#include <stdio.h>
+
+int main(void)
+{
+  printf("Hello, eCos world!\n");
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/examples/instrument-test.c
@@ -0,0 +1,50 @@
+/* this is a program which uses eCos instrumentation buffers; it needs
+   to be linked with a kernel which was compiled with support for
+   instrumentation */
+
+#include <stdio.h>
+#include <pkgconf/kernel.h>
+#include <cyg/kernel/instrmnt.h>
+#include <cyg/kernel/kapi.h>
+
+#ifndef CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
+# error You must configure eCos with CYGVAR_KERNEL_INSTRUMENT_EXTERNAL_BUFFER
+#endif
+
+struct Instrument_Record
+{
+    CYG_WORD16  type;                   // record type
+    CYG_WORD16  thread;                 // current thread id
+    CYG_WORD    timestamp;              // 32 bit timestamp
+    CYG_WORD    arg1;                   // first arg
+    CYG_WORD    arg2;                   // second arg
+};
+
+struct Instrument_Record instrument_buffer[20];
+cyg_uint32        instrument_buffer_size = 20;
+
+int main(void)
+{
+  int i;
+
+  cyg_instrument_enable(CYG_INSTRUMENT_CLASS_CLOCK, 0);
+  cyg_instrument_enable(CYG_INSTRUMENT_CLASS_THREAD, 0);
+  cyg_instrument_enable(CYG_INSTRUMENT_CLASS_ALARM, 0);
+
+  printf("Program to play with instrumentation buffer\n");
+
+  cyg_thread_delay(2);
+
+  cyg_instrument_disable(CYG_INSTRUMENT_CLASS_CLOCK, 0);
+  cyg_instrument_disable(CYG_INSTRUMENT_CLASS_THREAD, 0);
+  cyg_instrument_disable(CYG_INSTRUMENT_CLASS_ALARM, 0);
+
+  for (i = 0; i < instrument_buffer_size; ++i) {
+    printf("Record %02d: type 0x%04x, thread %d, ",
+	   i, instrument_buffer[i].type, instrument_buffer[i].thread);
+    printf("time %5d, arg1 0x%08x, arg2 0x%08x\n",
+	   instrument_buffer[i].timestamp, instrument_buffer[i].arg1,
+	   instrument_buffer[i].arg2);
+  }
+  return 0;
+}
new file mode 100644
--- /dev/null
+++ b/examples/serial.c
@@ -0,0 +1,83 @@
+/* 
+ * Written 1999-03-19 by Jonathan Larmour, Cygnus Solutions
+ * This file is in the public domain and may be used for any purpose
+ */
+
+/* CONFIGURATION CHECKS */
+
+#include <pkgconf/system.h>     /* which packages are enabled/disabled */
+#ifdef CYGPKG_KERNEL
+# include <pkgconf/kernel.h>
+#endif
+#ifdef CYGPKG_LIBC
+# include <pkgconf/libc.h>
+#endif
+#ifdef CYGPKG_IO_SERIAL
+# include <pkgconf/io_serial.h>
+#endif
+
+#ifndef CYGFUN_KERNEL_API_C
+# error Kernel API must be enabled to build this example
+#endif
+
+#ifndef CYGPKG_LIBC_STDIO
+# error C library standard I/O must be enabled to build this example
+#endif
+
+#ifndef CYGPKG_IO_SERIAL_HALDIAG
+# error I/O HALDIAG pseudo-device driver must be enabled to build this example
+#endif
+
+/* INCLUDES */
+
+#include <stdio.h>                      /* printf */
+#include <string.h>                     /* strlen */
+#include <cyg/kernel/kapi.h>            /* All the kernel specific stuff */
+#include <cyg/io/io.h>                  /* I/O functions */
+#include <cyg/hal/hal_arch.h>           /* CYGNUM_HAL_STACK_SIZE_TYPICAL */
+
+
+
+/* DEFINES */
+
+#define NTHREADS 1
+#define STACKSIZE ( CYGNUM_HAL_STACK_SIZE_TYPICAL + 4096 )
+
+/* STATICS */
+
+static cyg_handle_t thread[NTHREADS];
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+/* FUNCTIONS */
+
+static void simple_prog(CYG_ADDRESS data)
+{
+    cyg_io_handle_t handle;
+    Cyg_ErrNo err;
+    const char test_string[] = "serial example is working correctly!\n";
+    cyg_uint32 len = strlen(test_string);
+
+    printf("Starting serial example\n");
+
+    err = cyg_io_lookup( "/dev/haldiag", &handle );
+
+    if (ENOERR == err) {
+        printf("Found /dev/haldiag. Writing string....\n");
+        err = cyg_io_write( handle, test_string, &len );
+    }
+        
+    if (ENOERR == err) {
+        printf("I think I wrote the string. Did you see it?\n");
+    }
+    
+    printf("Serial example finished\n");
+
+}
+
+void cyg_user_start(void)
+{
+    cyg_thread_create(4, simple_prog, (cyg_addrword_t) 0, "serial",
+                      (void *)stack[0], STACKSIZE, &thread[0], &thread_obj[0]);
+    cyg_thread_resume(thread[0]);
+}
new file mode 100644
--- /dev/null
+++ b/examples/simple-alarm.c
@@ -0,0 +1,76 @@
+/* this is a very simple program meant to demonstrate
+   a basic use of time, alarms and alarm-handling functions
+   in eCos */
+
+#include <cyg/kernel/kapi.h>
+
+#include <stdio.h>
+
+#define NTHREADS 1
+#define STACKSIZE 4096
+
+static cyg_handle_t thread[NTHREADS];
+
+static cyg_thread thread_obj[NTHREADS];
+static char stack[NTHREADS][STACKSIZE];
+
+static void alarm_prog( cyg_addrword_t data );
+
+/* we install our own startup routine which sets up
+    threads and starts the scheduler */
+void cyg_user_start(void)
+{
+  cyg_thread_create(4, alarm_prog, (cyg_addrword_t) 0,
+		    "alarm_thread", (void *) stack[0],
+		    STACKSIZE, &thread[0], &thread_obj[0]);
+  cyg_thread_resume(thread[0]);
+}
+
+/* we need to declare the alarm handling function (which is
+   defined below), so that we can pass it to
+   cyg_alarm_initialize() */
+cyg_alarm_t test_alarm_func;
+
+/* alarm_prog() is a thread which sets up an alarm which is then
+   handled by test_alarm_func() */
+static void alarm_prog(cyg_addrword_t data)
+{
+  cyg_handle_t test_counterH, system_clockH, test_alarmH;
+  cyg_tick_count_t ticks;
+  cyg_alarm test_alarm;
+  unsigned how_many_alarms = 0, prev_alarms = 0, tmp_how_many;
+
+  system_clockH = cyg_real_time_clock();
+  cyg_clock_to_counter(system_clockH, &test_counterH);
+  cyg_alarm_create(test_counterH, test_alarm_func,
+		   (cyg_addrword_t) &how_many_alarms,
+		   &test_alarmH, &test_alarm);
+  cyg_alarm_initialize(test_alarmH, cyg_current_time()+200, 200);
+
+  /* get in a loop in which we read the current time and
+     print it out, just to have something scrolling by */
+  for (;;) {
+    ticks = cyg_current_time();
+    printf("Time is %llu\n", ticks);
+    /* note that we must lock access to how_many_alarms, since the
+       alarm handler might change it.  this involves using the
+       annoying temporary variable tmp_how_many so that I can keep the
+       critical region short */
+    cyg_scheduler_lock();
+    tmp_how_many = how_many_alarms;
+    cyg_scheduler_unlock();
+    if (prev_alarms != tmp_how_many) {
+      printf("  ---> alarm calls so far: %u\n", tmp_how_many);
+      prev_alarms = tmp_how_many;
+    }
+    cyg_thread_delay(30);
+  }
+}
+
+/* test_alarm_func() is invoked as an alarm handler, so
+   it should be quick and simple.  in this case it increments
+   the data that is passed to it. */
+void test_alarm_func(cyg_handle_t alarmH, cyg_addrword_t data)
+{
+  ++*((unsigned *) data);
+}
new file mode 100644
--- /dev/null
+++ b/examples/twothreads.c
@@ -0,0 +1,62 @@
+#include <cyg/kernel/kapi.h>
+
+#include <stdio.h>
+#include <math.h>
+#include <stdlib.h>
+
+/* now declare (and allocate space for) some kernel objects,
+   like the two threads we will use */
+cyg_thread thread_s[2];		/* space for two thread objects */
+
+char stack[2][4096];		/* space for two 4K stacks */
+
+/* now the handles for the threads */
+cyg_handle_t simple_threadA, simple_threadB;
+
+/* and now variables for the procedure which is the thread */
+cyg_thread_entry_t simple_program;
+
+/* and now a mutex to protect calls to the C library */
+cyg_mutex_t cliblock;
+
+/* we install our own startup routine which sets up threads */
+void cyg_user_start(void)
+{
+  printf("Entering twothreads' cyg_user_start() function\n");
+
+  cyg_mutex_init(&cliblock);
+
+  cyg_thread_create(4, simple_program, (cyg_addrword_t) 0,
+		    "Thread A", (void *) stack[0], 4096,
+		    &simple_threadA, &thread_s[0]);
+  cyg_thread_create(4, simple_program, (cyg_addrword_t) 1,
+		    "Thread B", (void *) stack[1], 4096,
+		    &simple_threadB, &thread_s[1]);
+
+  cyg_thread_resume(simple_threadA);
+  cyg_thread_resume(simple_threadB);
+}
+
+/* this is a simple program which runs in a thread */
+void simple_program(cyg_addrword_t data)
+{
+  int message = (int) data;
+  int delay;
+
+  printf("Beginning execution; thread data is %d\n", message);
+
+  cyg_thread_delay(200);
+
+  for (;;) {
+    delay = 200 + (rand() % 50);
+
+    /* note: printf() must be protected by a
+       call to cyg_mutex_lock() */
+    cyg_mutex_lock(&cliblock); {
+      printf("Thread %d: and now a delay of %d clock ticks\n",
+	     message, delay);
+    }
+    cyg_mutex_unlock(&cliblock);
+    cyg_thread_delay(delay);
+  }
+}