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
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 uwehttps://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/
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.
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
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.
Okay, Let see how it apply to work
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:
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.
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.
Saturday, January 8, 2011
Subscribe to:
Comments (Atom)