Mercurial > ecos-v3_0-branch
changeset 168:ead06911cbae
Add up-to-date examples
| author | jlarmour |
|---|---|
| date | Wed, 04 Jul 2001 17:34:09 +0000 |
| parents | 59f91bb9f684 |
| children | 11b54a94cf58 |
| 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); + } +}
