C and assembly development introduction: Difference between revisions

From Hackspire
Jump to navigation Jump to search
(Use the SDK's toolchain building script and clean outdated info)
Line 2: Line 2:


'''If you are looking for a <u>Windows</u> tutorial, get one in the development resources of [http://ndlessly.wordpress.com/native-development-intro/ ndlessly]'''.
'''If you are looking for a <u>Windows</u> tutorial, get one in the development resources of [http://ndlessly.wordpress.com/native-development-intro/ ndlessly]'''.
This article is written for the Ndless SDK v3.6 and higher.


==Setting up a development environment==
==Setting up a development environment==
*Get the [http://www.unsads.com/projects/nsptools/downloader/download/release/5 Ndless SDK] with resources for C and assembly development on TI-Nspire. This article is written for the Ndless SDK v3.1 beta r695 and higher.
===Building and installing the toolchain and the SDK===
*Add the <tt>ndless/bin/</tt> directory of the SDK to your <tt>PATH</tt> environment variable (see [http://www.troubleshooters.com/linux/prepostpath.htm this tutorial]). If you don't like messing with PATH stuff, it's easy to just link the files inside. As root in the sdk/bin directory, run "link ./nspire-* /bin/nspire-*" where * is replaced with gcc, as and ld.
*'''Get the latest [http://www.unsads.com/projects/nsptools/downloader/download/release/5 Ndless SDK build]''' for C, C++ and assembly development on TI-Nspire.
*Use the nspire_emu emulator (nspire_emu/nspire_emu.exe). It runs in Wine.
:You may also prefer to use the freshest in-development version of the Ndless SDK from [https://github.com/OlivierA/Ndless GitHub]. Just git-clone it:
*Install a GNU ARM toolchain. You can use the following script. Just copy it into a file, make it executable, and run it.
git clone git://github.com/OlivierA/Ndless.git
**No need to be root
* '''Make sure you system have the following dependencies''': GMP (libgmp-dev), MPFR (libmpfr-dev), MPC (libmpc-dev) and wget. Install them with your system's packet manager if not.
**Add $PREFIX/bin to $PATH (by default $PREFIX is $HOME, but you can change the value in the script)
* '''Run the SDK's ''build_toolchain.sh'' '''script that will download and build a complete ARM toolchain compatible with Ndless, and install it to ~/ndless_toolchain (edit the <tt>PREFIX</tt> variable at the beginning of the script to change this). You don't need to be root for this.
**If you want, change the value of $PARALLEL to specify the number of make jobs to run. For example, use "-j4" if you want 4 jobs. This can speed things up.
  cd Ndless-SDK/toolchain/
**You need the GMP, MPFR, MPC and CURSES development libraries. It is easiest to install these with your package manager. You also need Wget and CVS.
  ./build_toolchain.sh
 
  Running again the script will continue from the last successful step (not redownloading everything for instance).
  #!/bin/sh
* Now either:
  # Written by Uwe Hermann <uwe@hermann-uwe.de>, released as public domain.
** '''Add the following folders to your PATH environment variable''': <tt>/home/[you]/ndless_toolchain/bin</tt> and the SDK's <tt>Ndless-SDK/ndless/bin</tt>. <tt>~/.bash_profile</tt> should be a good place for this, just add something like this to it:
  # Edited by Travis Wiens ( http://blog.nutaksas.com/2009/05/installing-gnuarm-arm-toolchain-on.html )
  export PATH="/home/[you]/ndless-toolchain/bin:/<path_to_SDK>/Ndless-SDK/ndless/bin:${PATH}"
# Edited by Lionel Debroux for newer gcc/binutils/newlib/gdb versions and nspire-gcc.
** If you don't like messing with PATH stuff, it's easy to just link the files inside. As root in the SDK's ndless/bin directory, run "link ./nspire-* /bin/nspire-*" where * is replaced with gcc, as and ld.
# Edited by Legimet for elf2flt and newer gcc/binutils/newlib/gdb versions.
*'''Build the SDK''', only if you are using the GitHub's clone version of the SDK:
# Edited by Levak to update elf2flt url
  cd Ndless
 
  make
TARGET=arm-none-eabi
PREFIX=$HOME
PARALLEL="" # or "-j<number of build jobs>"
 
BINUTILS=binutils-2.24 # http://www.gnu.org/software/binutils/
  GCC=gcc-4.8.2 # http://gcc.gnu.org/
NEWLIB=newlib-2.0.0 # http://sourceware.org/newlib/
GDB=gdb-7.7 # http://www.gnu.org/software/gdb/
 
mkdir build-binutils
mkdir build
 
# IMPORTANT NOTE: in order to compile GCC 4.8, you need the GMP, MPFR and MPC development libraries.
# For example, if you have installed them yourself in $PREFIX, you'll have to add --with-gmp=$PREFIX --with-mpfr=$PREFIX --with-mpc=$PREFIX.
 
# NOTE: the second rm -rf is commented, because it's not strictly necessary.
 
# Section 1: GNU Binutils.
(wget -c http://ftp.gnu.org/gnu/binutils/$BINUTILS.tar.bz2 && tar xvjf $BINUTILS.tar.bz2 && cd build-binutils && ../$BINUTILS/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --with-system-zlib --with-gnu-as --with-gnu-ld --disable-nls --with-float=soft --disable-werror && make $PARALLEL all && make install && cd ..) || exit 1;
##rm -rf $BINUTILS $BINUTILS.tar.bz2
 
# Section 2: GCC, step 1.
(wget -c ftp://ftp.gnu.org/gnu/gcc/$GCC/$GCC.tar.bz2 && tar xvjf $GCC.tar.bz2 && cd build && ../$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --enable-languages="c,c++" --with-system-zlib --with-newlib --without-headers --disable-shared --with-gnu-as --with-gnu-ld --with-float=soft --disable-werror && make $PARALLEL all-gcc && make install-gcc && cd .. && rm -rf build/*) || exit 1;
##rm -rf $GCC.tar.bz2
 
# Section 3: Newlib.
(wget -c ftp://sourceware.org/pub/newlib/$NEWLIB.tar.gz && tar xvzf $NEWLIB.tar.gz && cd build && ../$NEWLIB/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --with-gnu-as --with-gnu-ld --disable-nls --with-float=soft --disable-werror && make $PARALLEL && make install && cd .. && rm -rf build/*) || exit 1;
##rm -rf $NEWLIB $NEWLIB.tar.gz
 
# Section 4: GCC, step 2. Yes, this is necessary.
(cd build && ../$GCC/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --enable-languages="c,c++" --with-system-zlib --with-newlib --disable-shared --with-gnu-as --with-gnu-ld --with-float=soft --disable-werror && make $PARALLEL && make install && cd .. && rm -rf build/*) || exit 1
##rm -rf $GCC
 
# Section 5: GDB.
  (wget -c ftp://ftp.gnu.org/gnu/gdb/$GDB.tar.bz2 && tar xvjf $GDB.tar.bz2 && cd build && ../$GDB/configure --target=$TARGET --prefix=$PREFIX --enable-interwork --enable-multilib --disable-werror && make $PARALLEL && make install && cd .. && rm -rf build/*) || exit 1;
##rm -rf $GDB $GDB.tar.bz2
 
# Section 6: elf2flt.
cat > Ndless-elf2flt.patch << EOF
91a92,97
> #define R_ARM_CALL    28
> #define R_ARM_JUMP24  29
> #define R_ARM_TARGET1 38
> #define R_ARM_V4BX    40
> #define R_ARM_TARGET2 41
> #define R_ARM_PREL31  42
647a654,660
>                              case R_ARM_NONE:
>                              case R_ARM_PREL31:
>                              case R_ARM_TARGET1:
>                              case R_ARM_TARGET2:
>                              case R_ARM_CALL:
>                              case R_ARM_V4BX:
>                              case R_ARM_JUMP24:
  EOF
 
(git clone https://github.com/m-labs/elf2flt-lm32.git elf2flt && patch elf2flt/elf2flt.c Ndless-elf2flt.patch && cd build && ../elf2flt/configure --target=$TARGET --prefix=$PREFIX -with-libbfd=../build-binutils/bfd/libbfd.a --with-libiberty=../build-binutils/libiberty/libiberty.a --with-bfd-include-dir=../build-binutils/bfd --with-binutils-include-dir=../$BINUTILS/include && make $PARALLEL && make install && cd .. && rm -rf build/*) || exit 1;
 
*Create symbolic links to <tt>arm-linux-gnueabi-*</tt> for the different GCC tools (ld, gcc, objcopy, ...) if your installation use custom file names.


===Verifying the installation===
===Verifying the installation===
Line 86: Line 29:
  arm-none-eabi-gcc: no input files
  arm-none-eabi-gcc: no input files


As a convention for the next chapters, lines starting with <tt>$</tt> are commands you should type in a console. Other lines are commands output. You may [http://info.ee.surrey.ac.uk/Teaching/Unix/ pick up a tutorial] to learn the basic Unix commands before we continue.
You can use the Windows nspire_emu emulator (''nspire_emu/nspire_emu.exe'') for computer-side testing. It runs in Wine.
 
As a convention for the next chapters, lines starting with <tt>$</tt> are commands you should type in a console. Other lines are commands output.


==5-minute tutorial==
==5-minute tutorial==
Line 98: Line 43:
A ''Makefile'' is a script which describes how to build the program. It is interpreted by ''GNU Make'', which is run with the command <tt>make</tt>. So let's ''make'' the program:
A ''Makefile'' is a script which describes how to build the program. It is interpreted by ''GNU Make'', which is run with the command <tt>make</tt>. So let's ''make'' the program:
  $ make
  $ make
  nspire-gcc -Os -Wall -W -c hello.c
  nspire-gcc -Wall -W -marm -Os -c hello.c
  nspire-ld -nostdlib hello.o -o hello.elf
mkdir -p .
mkdir -p ../../calcbin/samples
  nspire-ld-bflt  hello.o -o ./helloworld.tns
''make'' tells us the different commands used during the building process.
''make'' tells us the different commands used during the building process.


arm-none-eabi-objcopy -O binary hello.elf ../../calcbin/samples/hello.tns
<tt>nspire-gcc</tt> is Ndless's wrapper for the GNU C Compiler ''GCC'', which compiles C and assembly source files to object files (here ''hello.o'').
<tt>nspire-gcc</tt> is Ndless's wrapper for the GNU C Compiler ''GCC'', which compiles C and assembly source files to object files (here ''hello.o'').


<tt>nspire-ld</tt> is the wrapper for the GNU linker ''ld'', which combines object files to produce an executable in the [http://en.wikipedia.org/wiki/Executable_and_Linkable_Format ELF] format (here ''hello.elf'').
<tt>nspire-ld-bflt</tt> is the wrapper for the GNU linker ''ld'', which combines object files to produce an executable in the bFLT binary format supported by Ndless.
 
<tt>arm-none-eabi-objcopy</tt> is a GNU utility used to convert the ELF file to an Ndless-compatible executable directly runnable on a TI-Nspire. The file ''hello.tns'' can be found in ''src/calcbin/samples''.


===A C program===
===A C program===

Revision as of 19:38, 30 March 2014

This tutorial describes how to set up an environment and use the Ndless SDK to write native Ndless-compatible programs for the TI-Nspire on Linux.

If you are looking for a Windows tutorial, get one in the development resources of ndlessly.

This article is written for the Ndless SDK v3.6 and higher.

Setting up a development environment

Building and installing the toolchain and the SDK

  • Get the latest Ndless SDK build for C, C++ and assembly development on TI-Nspire.
You may also prefer to use the freshest in-development version of the Ndless SDK from GitHub. Just git-clone it:
git clone git://github.com/OlivierA/Ndless.git
  • Make sure you system have the following dependencies: GMP (libgmp-dev), MPFR (libmpfr-dev), MPC (libmpc-dev) and wget. Install them with your system's packet manager if not.
  • Run the SDK's build_toolchain.sh script that will download and build a complete ARM toolchain compatible with Ndless, and install it to ~/ndless_toolchain (edit the PREFIX variable at the beginning of the script to change this). You don't need to be root for this.
cd Ndless-SDK/toolchain/
./build_toolchain.sh
Running again the script will continue from the last successful step (not redownloading everything for instance).
  • Now either:
    • Add the following folders to your PATH environment variable: /home/[you]/ndless_toolchain/bin and the SDK's Ndless-SDK/ndless/bin. ~/.bash_profile should be a good place for this, just add something like this to it:
export PATH="/home/[you]/ndless-toolchain/bin:/<path_to_SDK>/Ndless-SDK/ndless/bin:${PATH}"
    • If you don't like messing with PATH stuff, it's easy to just link the files inside. As root in the SDK's ndless/bin directory, run "link ./nspire-* /bin/nspire-*" where * is replaced with gcc, as and ld.
  • Build the SDK, only if you are using the GitHub's clone version of the SDK:
cd Ndless
make

Verifying the installation

  • Open a console, and run:
$ nspire-gcc

If everything has been correctly set up you should see something similar to:

arm-none-eabi-gcc: no input files

You can use the Windows nspire_emu emulator (nspire_emu/nspire_emu.exe) for computer-side testing. It runs in Wine.

As a convention for the next chapters, lines starting with $ are commands you should type in a console. Other lines are commands output.

5-minute tutorial

Your first build

Ndless comes with sample programs in the _samples/ directory of the Ndless SDK. We will try to build the C Hello World. Change the current directory of the console:

$ cd "<my_ndless_sdk_copy>/_samples/helloworld"

Check the content of the directory:

$ ls
Makefile  hello.c

A Makefile is a script which describes how to build the program. It is interpreted by GNU Make, which is run with the command make. So let's make the program:

$ make
nspire-gcc -Wall -W -marm -Os -c hello.c
mkdir -p .
nspire-ld-bflt  hello.o -o ./helloworld.tns

make tells us the different commands used during the building process.

nspire-gcc is Ndless's wrapper for the GNU C Compiler GCC, which compiles C and assembly source files to object files (here hello.o).

nspire-ld-bflt is the wrapper for the GNU linker ld, which combines object files to produce an executable in the bFLT binary format supported by Ndless.

A C program

Let's have a look at the Hello World source code hello.c. It follows the C conventions.

It has an entry point:

int main(void) {

and a return code (required but currently ignored by Ndless and the OS):

  return 0;
}

All Ndless programs requires the standard include file, os.h:

#include <os.h>

This allows programs to call syscalls provided by the TI-Nspire Operating System. Some syscalls are functions from the C standard library, others are part of the C POSIX library. There are also functions of Nucleus RTOS on which is based the TI-Nspire OS.

We are also using the nspireio2 library provided with the SDK:

#include <nspireio2.h>

Let's now say hello with nspireio2:

	nio_console csl;
	lcd_ingray(); // because nspireio2 doesn't support colors
	clrscr(); // clear the screen
	// 53 columns, 29 rows. 0px offset for x/y.
	// Background color 0 (black), foreground color 15 (white)
	nio_InitConsole(&csl, 53, 29, 0, 0, 0, 15);
	nio_DrawConsole(&csl);
	nio_printf(&csl, "hello world!");
	wait_key_pressed();
	nio_CleanUp(&csl);

Your first program

You can copy the helloworld directory and start to adapt the source code.

If you want to create a program from scratch:

  • Create a new directory for the program
  • Type in a console:
cd "<your directory path>"
nspire-tools new <program>
where <program> is your program name. This will create a Makefile to build <program>.tns
  • Create a new .c file and edit your program
  • Run the make command to build it

Going further

  • Pick up a good C tutorial before writing your own programs
  • Learn the syntax of GNU Make's Makefiles to adapt them to your own build requirements
  • Learn to use GNU GCC features and extensions