This is the mail archive of the ecos-discuss@sources.redhat.com mailing list for the eCos project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

RE: how to run the program


Hopefully, these comments will help you get your
application running
without GDB.  I use Linux.  If you're using Windows
you'll have
to figure out the translation.

I routinely run applications on the ARM AEB-1 without
using GDB
and without even knowing how to use the flash rom. 
(Maybe someday
I'll learn that, too)

The following steps will detail how I get the
following program to run
on the AEB-1 without using GDB.


---------------------------------------------------------------
// Sample program: sample.c
//  AEB-1 specific code
// This program will blink LED1 as a heartbeat.
// Print hello 3 times.
// Ask the user to type a floating point number
// then tell the user what number was entered.
// The hello thread then endlessly reports the
// eCos system time.
// The heartbeat continues as the only active thread.

/* INCLUDES */
#include <stdio.h>                      /* printf
,etc.*/
#include <cyg/kernel/kapi.h>            /* All the
kernel specific stuff */

// GLOBAL VARIABLES
cyg_thread thread_s[2];         /* space for two
thread objects */
char stack[2][4096];            /* space for two 4K
stacks  - which is probably huge */
cyg_handle_t simple_threadA, simple_threadB;  // make
room for thread handles
cyg_thread_entry_t simple_program, blinker_led4; //
declare the thread functions
cyg_mutex_t cliblock;          // a mutex object for
our I/O calls

// MAIN PROGRAM
void cyg_user_start(void)
{
  cyg_mutex_init(&cliblock); // initialize the mutex
storage area
  // create the thread for the hello dialogue
  cyg_thread_create(4, simple_program,
(cyg_addrword_t) 0,
                    "Thread A", (void *) stack[0],
4096,
                    &simple_threadA, &thread_s[0]);
  // create the thread for the heartbeat
  cyg_thread_create(4, blinker_led4, (cyg_addrword_t)
0,
                    "Blinker4", (void *) stack[1],
256,
                    &simple_threadB, &thread_s[1]);
  // start both threads
  cyg_thread_resume(simple_threadA);
  cyg_thread_resume(simple_threadB);

}

// this is the LED heartbeat thread
void blinker_led4(cyg_addrword_t data)
{
  char *PC=(char*)0xFFFF1C00;   // The base address of
the PPI
                                // notice I'm using an
8 bit data size
                                // since that is the
size of the I/O port
  PC=PC+0x08;  // the offset to I/O PORT C whose high
nibble is the LED bank
  while (1)  // infinite loop
  {
    *PC=*PC|0x80; // activeate it:   | 0b1000000
    cyg_thread_delay(100); // wait a little bit
    *PC=*PC&0x70; // de-activeate it:  & 0b0111000
    cyg_thread_delay(100); // wait a little bit
  }
}

// this is the dialogue thread
void simple_program(cyg_addrword_t data)
{
  char *PC=(char*)0xFFFF1C00; // can use the PPI here
too
  int i; // a counter
  float test_float; // storage for a number
  cyg_tick_count_t time;

  PC=PC+0x08;  // the LED channel

  *PC=*PC|0x10; // turn on LED4 (green) all's fine
 

  // let's say hello three times 
  for(i=0;i<3;i++)
{
  cyg_mutex_lock(&cliblock);
    { // this block is mutexed  .... more to
understand about this, later
      printf("Hello, World! %d of 2\r\n",i);  // still
have to say \r\n for some reason
      cyg_mutex_unlock(&cliblock);
    }
  cyg_thread_delay(100);  // wait a little...
}
  *PC=*PC&0xE0; // turn off LED4 (green) signal hello
done
  *PC=*PC|0x20; // turn on LED3 (yellow) signal we
want some input
  cyg_mutex_lock(&cliblock);
    {
      printf("Type a number  ->"); // request
      scanf("%f",&test_float);    // wait for an
answer (note that heartbeat continues)
      printf("\n\rYou said ->%f<-\n\r",test_float); //
duh
      cyg_mutex_unlock(&cliblock);
    }
  *PC=*PC&0xD0; // turn off LED3 (yellow)
  *PC=*PC|0x40; // turn on LED2 (red)  dialogue thread
complete
// now print the time occasionally
  while(1)
  {
    time=cyg_current_time();
    cyg_mutex_lock(&cliblock);
      {
        printf("Time->%lld\n\r",time); // request
        cyg_mutex_unlock(&cliblock);
      }
    cyg_thread_delay(100); // wait a little bit
   
  }

}



---------------------------------------------------------------
Step 1: Configure an image of eCos that supports
regular serial
        I/O rather than GDB encoded I/O.

The following eCos image build should be done in a
separate
experimental directory.  I've done this in a directory
that
is called ecos-work.  Which I'll refer to in Step 2.

I've configured an image of eCos that turns off the
diagnostic I/O
garbly gook that encodes the I/O for GDB.  This was
necessary for
using a "terminal" program to talk to the AEB.
Hopefully, you're familiar with configuring and
building eCos for
the AEB-1.  I've included the following fine grained
configuration
changes to the default ecosconfig for the AEB-1

Fine grained alterations:
edit the ecos.ecc file with the following changes

   purpose: Set the TTY console to the device
/dev/tty1 (which we'll setup below)
        at:  CYGPKG_IO_SERIAL_TTY_CONSOLE
    change: # user_value "\"/dev/ttydiag\""
        to:  user_value "\"/dev/tty1\""

   purpose: Turn off the TTYDIAG junk - which I think
is to support gdb
        at:  CYGPKG_IO_SERIAL_TTY_TTYDIAG
    change: # user_value 1
        to:  user_value 0

   purpose: Turn on the AEB specific UART1 and call it
/dev/tty1
                can't say why I chose tty1
        at:  CYGPKG_IO_SERIAL_ARM_AEB
    change: # user_value 0
        to:  user_value 1

        at:  CYGPKG_IO_SERIAL_ARM_AEB_SERIAL1
    change: # user_value 0
        to:  user_value 1

        at:  CYGDAT_IO_SERIAL_ARM_AEB_SERIAL1_NAME
    change: # user_value "\"/dev/ser1\""
        to:  user_value "\"/dev/tty1\""

   Do this if you have the AEB-1C board 
   purpose: Change memory model to AEB-1C board (256K)
rather than AEB-1B board (128K)
        at: CYGHWR_HAL_ARM_AEB_REVISION
    change: # user_value B
        to:  user_value C

   purpose: This is still a mystery, but it made scanf
behave better.
            Without this, the buffer had to be filled
before scanf returned.
        at: CYGSEM_LIBC_STDIO_WANT_BUFFERED_IO
    change: # user_value 1
        to:  user_value 0
       also turned off _EXIT_FFLUSH to resolve
conflict

   purpose: Change the libc default console to our
device defined above
            (this is for printf, etc)
        at: CYGDAT_LIBC_STDIO_DEFAULT_CONSOLE
    change: # user_value "\"/dev/ttydiag\""
        to:  user_value "\"/dev/tty1\""

That does it for the fine grained configuration.....

Now, the actual library and header files must be made:
  ecosconfig check
     ensure no conflicts.  If there are, then you'll
have to track them from there.
  ecosconfig tree
     which builds the configuration tree
  make
     which actually builds the libraries based on the
configuration established in the ecos.ecc file
  make tests
     which builds the test programs  -  not really
necessary and not used in this example

That's it for Step 1.  The eCos configuration is ready
for running on the AEB-1 without GDB.



---------------------------------------------------------------
Step 2: Build your application


Rather than include a Makefile (which novices often
get hung up on) here's
a script that I'll call mybuild :

## beginning of script called mybuild
##  USAGE:  mybuild file
##      where file is prefix of source code file.c
##   example: mybuild sample
rm $1.o
rm $1
rm $1tmp
rm $1tmp2
rm $1arm
arm-elf-gcc -mcpu=arm7di -c -o $1.o  -Wall
-I$HOME/ecos-work/install/include -ffunction-sections
-fdata-sections $1.c
arm-elf-gcc -mcpu=arm7di 
-L$HOME/ecos-work/install/lib -Wl,--gc-sections -o $1
$1.o -Ttarget.ld -nostdlib
arm-elf-objcopy --strip-debug $1 $1tmp
arm-elf-objcopy -O binary $1tmp $1tmp2
uuencode $1tmp2 $1tmp2 | tr '`' ' ' > $1arm
## end of script

It's not elegant, but gets the point across.  Here's
what's going on.
The first 5 lines are cleanup.  (A Makefile would be
more elegant)
The first arm-elf-gcc compiles the source for your
application 
     -mcpu=arm7di   picks the cpu for the AEB-1
     -c             compile only, no linking
     -o $1.o        the object file name    (sample.o)
     -Wall          report all warnings
     -I$HOME/ecos-work/install/include
                    directory for the include files in
the application source code:
                #include <stdio.h>                    
 /* printf ,etc.*/
                #include <cyg/kernel/kapi.h>          
 /* All the kernel specific stuff */
     -ffunction-sections
                    removes unused functions from
object file.  Keeps size of executable down.
     -fdata-sections
                    removes unused data from object
file.  Keeps size of executable down.
     $1.c           the source file
The next arm-elf-gcc links the source to the eCos
library that was built in step1
     -mcpu=arm7di   picks the cpu for the AEB-1 (maybe
redundant, I don't know)
     -L$HOME/ecos-work/install/lib
                    where to go for the library
     -Wl,--gc-sections
                    tells the linker to actually do
the -ffunction-sections and -fdata-sections
                    stuff, above.  (I think.  Anyone
have any more info on how this works?)
     -o $1          the output file name  (sample)
     $1.o           the object file to be linked
     -Ttarget.ld    the linker script that the eCos
build creates  (full of lots of intricate stuff
                    that I haven't completely figured
out yet)
     -nostdlib      leave out the gcc libraries thus
only using the eCos library (which nicely
                    include a C-API, etc.)
The first arm-elf-objcopy strips the debug stuff (if
any) from the linked code.
     $1             the linked file (sample)
     $1tmp          the output of this first objcopy
The next arm-elf-objcopy "relocates" the code and
turns it into executable code for the AEB.
     $1tmp          the input
     $1tmp2         the output
The uuencode translates the AEB executable to an ASCII
form that the AEB downloader will
receive and translate back to binary and load into
ram.
     $1tmp2         the name of the file to read
     $1tmp2         the name to put into the ASCII
file
     tr '`' ' '     translates ` to blanks (which is
what the AEB loader wants)
     $1arm          the final ASCII file that the AEB
boot loader will receive

That's it for step 2..... You're ready to run the
samplearm file on the AEB
     


---------------------------------------------------------------
Step 3: Download and run the application

The "terminal" program that I use is minicom.  It
should be easy
to convert the following for your terminal program.

Start up minicom.  Use ALT-P to set to comm parameters
to 38400 8N1
Power up the AEB board and minicom will print out the
AEB greeting.
Hit return within two seconds to keep the AEB boot
program running.
You'll have a prompt Boot:
Now it's time to download the program to the board.
The AEB download command will put the AEB into a mode
for receiving
the uuencoded executable:
   download c000
            this means store the downloaded binary
starting at memory
            address c000
The AEB will reply with a note indicating that it is
ready to receive.
I haven't had luck (haven't tried to hard) using
minicom to actually
upload the file.  So, in another window I type
       cat samplearm >> /dev/modem
If you can figure out the minicom upload I'd be
interested.
Anyway, the red LED will flicker for each line that is
received
from the serial port.  The above command will include
the EOF
character so when it's done I get the Boot: prompt
back.
Now it's loaded and you're ready to run it.
The command
    go c040
will run the program.  At this time, I don't remember
the details
behind the address c000 in the download command and
the
execution at c040
I suspect it's in the target.ld file during linking. 
But not sure.

Any way the program should be running....

The sample program at one point will ask for the user
to type in
a number.  I haven't figured out the echo yet, though.
 

---------------------------------------------------------------
Final comments:
I discovered all of this by scrounging thru web pages
and
some trial and error.  Hopefully, the sample will work
and
then you can start learning from here.  I'd be
interested in
knowing if it did work for you.
And if you can answer any of my uncertainties about
some of the
details that I mention above, that would be
appreciated.

Have fun.
keith

__________________________________________________
Do You Yahoo!?
Yahoo! Mail - Free email you can access from anywhere!
http://mail.yahoo.com/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]