Tuesday, January 18, 2011

cross compile for arm

toolchain build script below is posted in the following blog entry as a reply.

http://www.hermann-uwe.de/blog/building-an-arm-cross-toolchain-with-binutils-gcc-newlib-and-gdb-from-source

toolchain

Your cross-toolchain script is pretty stale. Try this one.

#!/bin/sh
# Builds a arm-eabi cross compiler for use on linux
# host systems. This target has no file system or kernel.
#
TARGET="arm-none-eabi"
SRC="/build-dir/packages" # package directory
PREFIX="/build-dir/arm/toolchain" # final toolchain directory
PARALLEL="-j 2"
BINUTILS=binutils-2.20
GCC=gcc-4.5.1
GMP=gmp-5.0.1
MPFR=mpfr-3.0.0
MPC=mpc-0.8.2
NEWLIB=newlib-1.18.0
# Note: the 7.x series of GDB seem to have issues with psim...
GDB=gdb-6.8
export PATH="$PATH:$PREFIX/bin"
# Before we do anything we need all the source files.
# We keep them in one place and we never need to
# download them twice if this build fails.
mkdir $SRC
cd $SRC
echo "Dounloading source packages. This may take a while."
echo
wget -c http://ftp.gnu.org/gnu/binutils/$BINUTILS.tar.bz2
wget -c ftp://ftp.gnu.org/gnu/gcc/$GCC/$GCC.tar.bz2
wget -c ftp://ftp.gmplib.org/pub/$GMP/$GMP.tar.bz2
wget -c http://www.mpfr.org/mpfr-current/$MPFR.tar.bz2
wget -c http://www.multiprecision.org/mpc/download/$MPC.tar.gz
wget -c ftp://sources.redhat.com/pub/newlib/$NEWLIB.tar.gz
wget -c ftp://ftp.gnu.org/gnu/gdb/$GDB.tar.bz2
cd ..
echo "Starting Build..."
echo
mkdir build
echo "Building binutils"
echo
tar xfj $SRC/$BINUTILS.tar.bz2
cd build
../$BINUTILS/configure --target=$TARGET --prefix=$PREFIX \
--enable-interwork --disable-multilib --with-gnu-as \
--with-gnu-ld --disable-nls --disable-werror
make $PARALLEL
make install
cd ..
rm -rf build/* $BINUTILS
echo "Building GCC pass 1"
tar xfj $SRC/$GCC.tar.bz2
# the compiler math prereqs
tar -jxf $SRC/$GMP.tar.bz2
tar -jxf $SRC/$MPFR.tar.bz2
tar -zxf $SRC/$MPC.tar.gz
cd $GCC
mv ../$GMP gmp
mv ../$MPFR mpfr
mv ../$MPC mpc
cd ../build
../$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-interwork \
--disable-multilib --enable-languages="c" --with-newlib \
--with-gmp-include=$(pwd)/gmp --with-gmp-lib=$(pwd)/gmp/.libs \
--without-headers --disable-shared --disable-nls --with-gnu-as --with-gnu-ld
make $PARALLEL all-gcc
make install-gcc
cd ..
rm -rf build/* # (We retain the GCC directory for pass 2)
echo "Building Newlib"
echo
tar xfz $SRC/$NEWLIB.tar.gz
cd build
../$NEWLIB/configure --target=$TARGET --prefix=$PREFIX --enable-interwork \
--disable-multilib --with-gnu-as --with-gnu-ld --disable-nls
make $PARALLEL
make install
cd ..
rm -rf build/* $NEWLIB
echo " Building GCC pass 2"
echo
cd build
../$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-interwork \
--disable-multilib --enable-languages="c,c++" --with-newlib \
--with-gmp-include=$(pwd)/gmp --with-gmp-lib=$(pwd)/gmp/.libs \
--without-headers --disable-shared --disable-libssp --disable-nls \
--disable-hardfloat --enable-threads=single --with-gnu-as --with-gnu-ld
make $PARALLEL
make install
cd ..
rm -rf build/* $GCC
echo "Building GDB"
echo
tar xfj $SRC/$GDB.tar.bz2
cd build
../$GDB/configure --target=$TARGET --prefix=$PREFIX \
--enable-interwork --disable-multilib
make all
make install
cd ..
rm -rf build $GDB
echo "Lets see if it compiles without errors..."
echo 'main(){}' > dummy.c
$PREFIX/bin/$TARGET-gcc-4.5.1 dummy.c -o dummy
ls -l dummy
rm dummy dummy.c a.out
echo "cool! that's a start"
echo "Compiler Finished for "$TARGET
# All that should be left now is this script, the new toolchain and the packages.
# Save the packages for other tuned toolchains.


*************************************************
another toolchain from uwe
https://github.com/esden/summon-arm-toolchain/raw/master/summon-arm-toolchain


#!/bin/bash
# Written by Uwe Hermann <uwe@hermann-uwe.de>, released as public domain.
# Modified by Piotr Esden-Tempski <piotr@esden.net>, released as public domain.

#
# Requirements (example is for Debian, replace package names as needed):
#
# apt-get install flex bison libgmp3-dev libmpfr-dev libncurses5-dev \
# libmpc-dev autoconf texinfo build-essential
#
# Or on Ubuntu Maverick give `apt-get build-dep gcc-4.5` a try.
#

# Stop if any command fails
set -e

##############################################################################
# Settings section
# You probably want to customize those
##############################################################################
TARGET=arm-none-eabi  # Or: TARGET=arm-elf
PREFIX=${HOME}/sat # Install location of your final toolchain
DARWIN_OPT_PATH=/opt/local # Path in which MacPorts or Fink is installed
# Set to 'sudo' if you need superuser privileges while installing
SUDO=
# Set to 1 to be quieter while running
QUIET=0
# Set to 1 to use linaro gcc instead of the FSF gcc
USE_LINARO=1
# Set to 1 to enable building of OpenOCD
OOCD_EN=1
# Set to 1 to build libstm32 provided by ST
LIBSTM32_EN=0
# Set to 1 to build libopenstm32 an open source library for stm32
LIBOPENSTM32_EN=1
# Make the gcc default to Cortex-M3
DEFAULT_TO_CORTEX_M3=0

##############################################################################
# Version and download url settings section
##############################################################################
if [ ${USE_LINARO} == 0 ] ; then
 # For FSF GCC:
 GCCVERSION=4.5.1
 GCC=gcc-${GCCVERSION}
 GCCURL=http://ftp.gnu.org/gnu/gcc/${GCC}/${GCC}.tar.gz
else
 # For the Linaro GCC:
 GCCRELEASE=4.5-2010.11-0
 GCCVERSION=4.5-2010.11-1
 GCC=gcc-linaro-${GCCVERSION}
 GCCURL=http://launchpad.net/gcc-linaro/4.5/${GCCRELEASE}/+download/${GCC}.tar.bz2
fi

BINUTILS=binutils-2.20
NEWLIB=newlib-1.18.0
GDB=gdb-7.2
OOCD=master
LIBCMSIS=v1.10-2
LIBSTM32=v3.0.0-1
LIBSTM32USB=v3.0.1-1
LIBOPENSTM32=master

##############################################################################
# Flags section
##############################################################################

if which getconf > /dev/null; then
 CPUS=$(getconf _NPROCESSORS_ONLN)
else
 CPUS=1
fi
PARALLEL=-j$((CPUS + 1))
echo "${CPUS} cpu's detected running make with '${PARALLEL}' flag"

GDBFLAGS=
BINUTILFLAGS=

if [ ${DEFAULT_TO_CORTEX_M3} == 0 ] ; then
 GCCFLAGS=
else
 # To default to the Cortex-M3:
 GCCFLAGS="--with-arch=armv7-m --with-mode=thumb --with-float=soft"
fi

# Pull in the local configuration, if any
if [ -f local.sh ]; then
    . ./local.sh
fi

MAKEFLAGS=${PARALLEL}
TARFLAGS=v

if [ ${QUIET} != 0 ]; then
    TARFLAGS=
    MAKEFLAGS="${MAKEFLAGS} -s"
fi

export PATH="${PREFIX}/bin:${PATH}"

SUMMON_DIR=$(pwd)
SOURCES=${SUMMON_DIR}/sources
STAMPS=${SUMMON_DIR}/stamps


##############################################################################
# Tool section
##############################################################################
TAR=tar

##############################################################################
# OS and Tooldetection section
# Detects which tools and flags to use
##############################################################################

case "$(uname)" in
 Linux)
 echo "Found Linux OS."
 ;;
 Darwin)
 echo "Found Darwin OS."
 GCCFLAGS="${GCCFLAGS} \
                  --with-gmp=${DARWIN_OPT_PATH} \
           --with-mpfr=${DARWIN_OPT_PATH} \
           --with-mpc=${DARWIN_OPT_PATH} \
    --with-libiconv-prefix=${DARWIN_OPT_PATH}"
 OOCD_CFLAGS="-m32 -I/opt/mine/include -I/opt/local/include"
 OOCD_LDFLAGS="-L/opt/mine/lib -L/opt/local/lib"
 ;;
 CYGWIN*)
 echo "Found CygWin that means Windows most likely."
 ;;
 *)
 echo "Found unknown OS. Aborting!"
 exit 1
 ;;
esac

##############################################################################
# Building section
# You probably don't have to touch anything after this
##############################################################################

# Fetch a versioned file from a URL
function fetch {
    if [ ! -e ${STAMPS}/$1.fetch ]; then
        log "Downloading $1 sources..."
        wget -c --no-passive-ftp $2
        touch ${STAMPS}/$1.fetch
    fi
}

# Log a message out to the console
function log {
    echo "******************************************************************"
    echo "* $*"
    echo "******************************************************************"
}

# Unpack an archive
function unpack {
    log Unpacking $*
    # Use 'auto' mode decompression.  Replace with a switch if tar doesn't support -a
    ARCHIVE=$(ls ${SOURCES}/$1.tar.*)
    case ${ARCHIVE} in
 *.bz2)
     echo "archive type bz2"
     TYPE=j
     ;;
 *.gz)
     echo "archive type gz"
     TYPE=z
     ;;
 *)
     echo "Unknown archive type of $1"
     echo ${ARCHIVE}
     exit 1
     ;;
    esac
    ${TAR} xf${TYPE}${TARFLAGS} ${SOURCES}/$1.tar.*
}

# Install a build
function install {
    log $1
    ${SUDO} make ${MAKEFLAGS} $2 $3 $4 $5 $6 $7 $8
}


mkdir -p ${STAMPS} ${SOURCES}

cd ${SOURCES}

fetch ${BINUTILS} http://ftp.gnu.org/gnu/binutils/${BINUTILS}.tar.bz2
fetch ${GCC} ${GCCURL}
fetch ${NEWLIB} ftp://sources.redhat.com/pub/newlib/${NEWLIB}.tar.gz
fetch ${GDB} http://ftp.gnu.org/gnu/gdb/${GDB}.tar.bz2

if [ ${OOCD_EN} != 0 ]; then
if [ ! -e openocd-${OOCD}.tar.bz2 ]; then
 log "Cloning OpenOCD sources..."
 git clone git://openocd.git.sourceforge.net/gitroot/openocd/openocd openocd-${OOCD}
        cd openocd-${OOCD}
 ./bootstrap
 cd ..
 tar cfvj openocd-${OOCD}.tar.bz2 openocd-${OOCD}
        #git archive --format=tar --prefix=openocd-${OOCD}/ ${OOCD} | \
        #    bzip2 --stdout > ../openocd-${OOCD}.tar.bz2
        rm -rf openocd-${OOCD}
fi
fi

if [ ${LIBSTM32_EN} != 0 ]; then
if [ ! -e libcmsis-${LIBCMSIS}.tar.bz2 ]; then
 log "Cloning libcmsis sources..."
 git clone git://git.open-bldc.org/libcmsis.git
        cd libcmsis
        git archive --format=tar --prefix=libcmsis-${LIBCMSIS}/ ${LIBCMSIS} | \
            bzip2 --stdout > ../libcmsis-${LIBCMSIS}.tar.bz2
        cd ..
        rm -rf libcmsis
fi

if [ ! -e libstm32-${LIBSTM32}.tar.bz2 ]; then
 log "Cloning libstm32 sources..."
 git clone git://git.open-bldc.org/libstm32.git
        cd libstm32
        git archive --format=tar --prefix=libstm32-${LIBSTM32}/ ${LIBSTM32} | \
            bzip2 --stdout > ../libstm32-${LIBSTM32}.tar.bz2
        cd ..
        rm -rf libstm32
fi

if [ ! -e libstm32usb-${LIBSTM32USB}.tar.bz2 ]; then
 log "Cloning libstm32usb sources..."
 git clone git://git.open-bldc.org/libstm32usb.git
        cd libstm32usb
        git archive --format=tar --prefix=libstm32usb-${LIBSTM32USB}/ ${LIBSTM32USB} | \
            bzip2 --stdout > ../libstm32usb-${LIBSTM32USB}.tar.bz2
        cd ..
        rm -rf libstm32usb
fi
fi

if [ ${LIBOPENSTM32_EN} != 0 ]; then
if [ ! -e libopenstm32-${LIBOPENSTM32}.tar.bz2 ]; then
 log "Cloning libopenstm32 sources..."
 git clone git://libopenstm32.git.sourceforge.net/gitroot/libopenstm32/libopenstm32
        cd libopenstm32
        git archive --format=tar --prefix=libopenstm32-${LIBOPENSTM32}/ ${LIBOPENSTM32} | \
            bzip2 --stdout > ../libopenstm32-${LIBOPENSTM32}.tar.bz2
        cd ..
        rm -rf libopenstm32
fi
fi

cd ${SUMMON_DIR}

if [ ! -e build ]; then
    mkdir build
fi

if [ ! -e ${STAMPS}/${BINUTILS}.build ]; then
    unpack ${BINUTILS}
    cd build
    log "Configuring ${BINUTILS}"
    ../${BINUTILS}/configure --target=${TARGET} \
                           --prefix=${PREFIX} \
                           --enable-interwork \
                           --enable-multilib \
                           --with-gnu-as \
                           --with-gnu-ld \
                           --disable-nls \
                           --disable-werror \
      ${BINUTILFLAGS}
    log "Building ${BINUTILS}"
    make ${MAKEFLAGS}
    install ${BINUTILS} install
    cd ..
    log "Cleaning up ${BINUTILS}"
    touch ${STAMPS}/${BINUTILS}.build
    rm -rf build/* ${BINUTILS}
fi

if [ ! -e ${STAMPS}/${GCC}-boot.build ]; then
    unpack ${GCC} boot
    cd build
    log "Configuring ${GCC}-boot"
    ../${GCC}/configure --target=${TARGET} \
                      --prefix=${PREFIX} \
                      --enable-interwork \
                      --enable-multilib \
                      --enable-languages="c" \
                      --with-newlib \
                      --without-headers \
                      --disable-shared \
                      --with-gnu-as \
                      --with-gnu-ld \
                      --disable-nls \
                      --disable-werror \
        --with-system-zlib \
        ${GCCFLAGS}
    log "Building ${GCC}-boot"
    make ${MAKEFLAGS} all-gcc
    install ${GCC}-boot install-gcc
    cd ..
    log "Cleaning up ${GCC}-boot"
    touch ${STAMPS}/${GCC}-boot.build
    rm -rf build/* ${GCC}
fi

if [ ! -e ${STAMPS}/${NEWLIB}.build ]; then
    unpack ${NEWLIB}
    cd build
    log "Configuring ${NEWLIB}"
    ../${NEWLIB}/configure --target=${TARGET} \
                         --prefix=${PREFIX} \
                         --enable-interwork \
                         --enable-multilib \
                         --with-gnu-as \
                         --with-gnu-ld \
                         --disable-nls \
                         --disable-werror \
                         --disable-newlib-supplied-syscalls \
    --with-float=soft
    log "Building ${NEWLIB}"
    make ${MAKEFLAGS} CFLAGS_FOR_TARGET="-msoft-float" CCASFLAGS="-msoft-float"
    install ${NEWLIB} install
    cd ..
    log "Cleaning up ${NEWLIB}"
    touch ${STAMPS}/${NEWLIB}.build
    rm -rf build/* ${NEWLIB}
fi

# Yes, you need to build gcc again!
if [ ! -e ${STAMPS}/${GCC}.build ]; then
    unpack ${GCC}
    cd build
    log "Configuring ${GCC}"
    ../${GCC}/configure --target=${TARGET} \
                      --prefix=${PREFIX} \
                      --enable-interwork \
                      --enable-multilib \
                      --enable-languages="c,c++" \
                      --with-newlib \
                      --disable-shared \
                      --with-gnu-as \
                      --with-gnu-ld \
        --disable-nls \
                      --disable-werror \
                      --with-system-zlib \
        ${GCCFLAGS}
    log "Building ${GCC}"
    make ${MAKEFLAGS}
    install ${GCC} install
    cd ..
    log "Cleaning up ${GCC}"
    touch ${STAMPS}/${GCC}.build
    rm -rf build/* ${GCC}
fi

if [ ! -e ${STAMPS}/${GDB}.build ]; then
    unpack ${GDB}
    cd build
    log "Configuring ${GDB}"
    ../${GDB}/configure --target=${TARGET} \
                      --prefix=${PREFIX} \
                      --enable-interwork \
                      --enable-multilib \
                      --disable-werror \
        ${GDBFLAGS}
    log "Building ${GDB}"
    make ${MAKEFLAGS}
    install ${GDB} install
    cd ..
    log "Cleaning up ${GDB}"
    touch ${STAMPS}/${GDB}.build
    rm -rf build/* ${GDB}
fi

if [ ${OOCD_EN} != 0 ]; then
if [ ! -e ${STAMPS}/openocd-${OOCD}.build ]; then
    unpack openocd-${OOCD}
    cd build
    log "Configuring openocd-${OOCD}"
    CFLAGS="${CFLAGS} ${OOCD_CFLAGS}" \
    LDFLAGS="${LDFLAGS} ${OOCD_LDFLAGS}" \
    ../openocd-${OOCD}/configure --enable-maintainer-mode \
                      --prefix=${PREFIX} \
                      --enable-dummy \
        --enable-parport \
        --enable-ft2232_libftdi \
        --enable-usb_blaster_libftdi \
        --enable-amtjtagaccel \
        --enable-zy1000 \
        --enable-ep93xx \
        --enable-at91rm9200 \
        --enable-gw16012 \
        --enable-presto_libftdi \
        --enable-usbprog \
        --enable-jlink \
        --enable-vsllink \
        --enable-rlink \
        --enable-arm-jtag-ew \
        --enable-buspirate
    log "Building openocd-${OOCD}"
    make ${MAKEFLAGS}
    install openocd-${OOCD} install
    cd ..
    log "Cleaning up openocd-${OOCD}"
    touch ${STAMPS}/openocd-${OOCD}.build
    rm -rf build/* ${OOCD}
fi
fi

if [ ${LIBSTM32_EN} != 0 ]; then
if [ ! -e ${STAMPS}/libcmsis-${LIBCMSIS}.build ]; then
    unpack libcmsis-${LIBCMSIS}
    cd libcmsis-${LIBCMSIS}
    log "Building libcmsis-${LIBCMSIS}"
    make arch_prefix=${TARGET} prefix=${PREFIX}
    install libcmsis-${LIBCMSIS} arch_prefix=${TARGET} prefix=${PREFIX} install
    cd ..
    log "Cleaning up libcmsis-${LIBCMSIS}"
    touch ${STAMPS}/libcmsis-${LIBCMSIS}.build
    rm -rf libcmsis-${LIBCMSIS}
fi

if [ ! -e ${STAMPS}/libstm32-${LIBSTM32}.build ]; then
    unpack libstm32-${LIBSTM32}
    cd libstm32-${LIBSTM32}
    log "Building libstm32-${LIBSTM32}"
    make arch_prefix=${TARGET} prefix=${PREFIX}
    install libstm32-${LIBSTM32} arch_prefix=${TARGET} prefix=${PREFIX} install
    cd ..
    log "Cleaning up libstm32-${LIBSTM32}"
    touch ${STAMPS}/libstm32-${LIBSTM32}.build
    rm -rf libstm32-${LIBSTM32}
fi

if [ ! -e ${STAMPS}/libstm32usb-${LIBSTM32USB}.build ]; then
    unpack libstm32usb-${LIBSTM32USB}
    cd libstm32usb-${LIBSTM32USB}
    log "Building libstm32usb-${LIBSTM32USB}"
    make arch_prefix=${TARGET} prefix=${PREFIX}
    install libstm32usb-${LIBSTM32USB} arch_prefix=${TARGET} prefix=${PREFIX} install
    cd ..
    log "Cleaning up libstm32usb-${LIBSTM32USB}"
    touch ${STAMPS}/libstm32usb-${LIBSTM32USB}.build
    rm -rf libstm32usb-${LIBSTM32USB}
fi
fi

if [ $LIBOPENSTM32_EN != 0 ]; then
if [ ! -e ${STAMPS}/libopenstm32-${LIBOPENSTM32}.build ]; then
    unpack libopenstm32-${LIBOPENSTM32}
    cd libopenstm32-${LIBOPENSTM32}
    log "Building libopenstm32-${LIBOPENSTM32}"
    make PREFIX=${TARGET} DESTDIR=${PREFIX}
    install libopenstm32-${LIBOPENSTM32} PREFIX=${TARGET} DESTDIR=${PREFIX} install
    cd ..
    log "Cleaning up libopenstm32-${LIBOPENSTM32}"
    touch ${STAMPS}/libopenstm32-${LIBOPENSTM32}.build
    rm -rf libopenstm32-${LIBOPENSTM32}
fi
fi

non blocking input

archived from:

http://cc.byexamples.com/2007/04/08/non-blocking-user-input-in-loop-without-ncurses/

we share the c/c++ coding by examples

Non-blocking user input in loop without ncurses.

The title sounds a bit awkward, let my briefly explain what is it all about.
In my program, I want to wait for user input, but at the same time, I want my other operations keep continue processing. That I define it as non-blocking user input. I want my program to wait for user input in the loop, if receives user input process it and continue wait for next user input, else continue processing other circular operations.
Usually, people will think about using ncurses library. By using ncurses, you can easily perform non-blocking user input using timeout(0) and getch(). Refers to the ncurses matrix for references.
What if I don’t want to uses ncurses? Its there any alternatives? Sometimes I just wanna add a function which need non-blocking in a large program, I don’t want to use ncurses because it makes my print line acts differently, or some other reason.
I have figure out a way, thanks to programmers at ##c@irc.freenode.net. It might look messy and complected, but it works the way I wanted. I uses functions of termios and select, lets look at the functions one by one.

int kbhit()
{
    struct timeval tv;
    fd_set fds;
    tv.tv_sec = 0;
    tv.tv_usec = 0;
    FD_ZERO(&fds);
    FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
    select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
    return FD_ISSET(STDIN_FILENO, &fds);

}
This function perform non-blocking checking on the standard input  (stdin) without timeout 0, tv.tv_sec and tv.tv_usec both set to zero.  select usually uses in the case where there have multiple I/O need to  process, or check at the same time. But in this case, I only interested  in standard input, therefore only one FD_SET(STDIN_FILENO, &fds) is  trigger. For select parameters details, please check out the manual.  Seems we are only interested in input, so we place out fd set at second  parameter of select(), the 3rd is for output and 4th is for exception.
Important part, after select if user input is trigger, FD_ISSET will return non zero value, else return 0. So, we now can use it like this

 while(!kbhit())
     {
       //do certain operation..
     }
 //user hits enter.

Due to the canonical mode of your terminal, you need to hit enter to confirm your user input. Canonical mode means it always wait for enter to confirms the user input. If that is not your case, bellow is another function to cater that.


void nonblock(int state)
{
    struct termios ttystate;
 
    //get the terminal state
    tcgetattr(STDIN_FILENO, &ttystate);
 
    if (state==NB_ENABLE)
    {
        //turn off canonical mode
        ttystate.c_lflag &= ~ICANON;
        //minimum of number input read.
        ttystate.c_cc[VMIN] = 1;
    }
    else if (state==NB_DISABLE)
    {
        //turn on canonical mode
        ttystate.c_lflag |= ICANON;
    }
    //set the terminal attributes.
    tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
 
}
The function name might be misleading, what the function actually does is turn off the canonical mode for stdin. First, get the states of stdin of term. Next turn off the canonical by set 0 to the bits. The line of ttystate.c_cc[VMIN] is set the minimum number of user input to accept. If you set it as 2, the select will wait until 2 character is given, then it will capture as input. At last set the term state. The function actually does allow you to turn on and off the canonical mode.
Okay, Let see how it apply to work

int main()
{
    char c;
    int i=0;
 
    nonblock(NB_ENABLE);
    while(!i)
    {
        usleep(1);
        i=kbhit();
        if (i!=0)
        {
            c=fgetc(stdin);
            if (c=='q')
                i=1;
            else
                i=0;
        }
 
        fprintf(stderr,"%d ",i);
    }
    printf("\n you hit %c. \n",c);
    nonblock(NB_DISABLE);
 
    return 0;
}

Press ‘q’ will lead the program to quit, else you will see the print of ‘0′ overwhelming the screen. Observed that I am using usleep(1) inside the loop, without putting usleep, the programs is more responsive, but it uses high CPU resources. On the other hand, putting usleep(1) reduces the CPU resources and also decreases responsiveness of the program. Depend on your needs, you may choose to put it in or not.
I have make the comparison between this application and a simple ncurses program, this program seems to use lesser memory. Couldn’t measure for CPU resources, as both ps and top shows 0.0 %.
Curses sample shows as bellow:

#include<stdio.h>
#include<curses.h>
#include<unistd.h>
 
int main ()
{
    int i=0;
 
    initscr();     //in ncurses
    timeout(0);
    while(!i)
    {
        usleep(1);
        i=getch();
        printw("%d ",i);
        if(i>0)
            i=1;
        else
            i=0;
    }
    endwin();
    printf("\nhitkb end\n");
    return 0;
}

Sunday, January 16, 2011

Notes from avr notes

Examples of reading binary and writing binary from shell command line.  It needs
the hexdump command on the target.

The echo shell command can also write binary values. Check the man pages for the
detailed description. With the echo command, we can set the previously configured
output pins “high” by writing 0x0000000F to the device file. The following command
does the trick:


echo –ne “\x00\x00\x00\x0F” > /dev/gpio0


To read out the pin state, the use of the commands less or cat is not adequate
because these applications expect an ASCII string, so the output is neither readable
nor interpretable. For this purpose the dd and hexdump tools are more suitable. To
read out the four bytes, use these commands in following constellation:


dd bs=4 count=1 if=/dev/gpio0 2> /dev/zero | hexdump


The dd program reads out the four bytes (bs=number of bytes, count=how many
times to read out bs bytes) from /dev/gpio0, dumps any error messages to /dev/zero
and pipes the data to hexdump. The hexdump program will print out the four bytes as
a nice hexadecimal value.