Easy Programming Tutorial

From wikiPodLinux

Note: This tutorial is fairly old and contains dead links. You would probably be better off following Keripo's tutorial here (http://ipodlinux.org/forums/viewtopic.php?t=20822).

This is a tutorial for how to program for any iPod. You will need to have a fairly good knowledge of the C programming language. This is not too hard, and I learned it in less than 2 weeks (to a good enough level.) To follow this tutorial, you will need to know basic C, and be competant at using a computer. First, we are going to install Cygwin, which is how we are going to compile our programs.

Table of contents

Cygwin

We will be using Cygwin, because it enables programming from windows, and is just as easy to use for programming, as linux is. Before you can do anything, you will need to download it from the Cygwin Website. (http://www.cygwin.com) You will need to download setup.exe, which weighs in at around 300kB. Run the installer, (It is easiest if you install to C:\cygwin\) and select the ENTIRE devel package. When you click next, cygwin itself will be downloaded, as well as lots of dev tools which we will need. On a fast connection, this will take around 25 minutes.

Now for what cygwin actually does. It gives you a linux shell or command prompt, within windows, allowing linux apps to be easily PORTED (It won't run them out of the box) so that they will run within windows. We are going to use it because we need several linux tools available to us.

When Cygwin has finally finished downloading and installing, execute cygwin.bat (In C:\cygwin\.) It will print a few lines about setting up your profile, then give you a basic command prompt. If this works, cygwin has been installed correctly. If you go to C:\Cygwin\home\, you will find a folder with your windows logon name as a title. Enter this folder, it is the cygwin home directory, which means if a file is in there I can call it directly from the cygwin prompt, without changing directory for every file. From now on I will refer to it as your cygwin home folder.

Notepad2

Before you start programming, you will need to Download (http://www.flos-freeware.ch/notepad2.html) notepad2. This is very similar to windows notepad, but notepad2 has 2 features which we will be using extensively. Firstly, it can open text files with LF encoding, so it can open linux files. We will need this to modify a cygwin config file. Also, while this is not strictly necessary, notepad2 understands C, so it colour codes certain syntax, can check whether closing brackets line up etc. It is a file hardly any bigger than the official windows notepad, and as such can replace windows notepad. I have done this, and never looked back, but use it as a stand-alone executable for the moment, to see if you like the way it works.

The Toolchain

First we need to download the main toolchain, then add some additional files that are missing.
Download this file (http://www.josh.sys-techs.com/ipl/arm-uclinux-tools-cygwin-20060116.tar.bz2), rename it to arm.tar.bz2 and place it in your cygwin home folder. Open up cygwin, and type tar -C / -xvjf arm.tar.bz2. Loads of lines of text will flash past, and then it will return to the cygwin prompt.
However, the toolchain for cygwin misses several important files. Download these from here (http://filexoom.com/files/4931/C%20programs/toolchain%20files.zip) or here. (http://rapidsharing.com/download.php?id=2AAA71E0) Extract the .zip, and copy all of the files to C:\cygwin\usr\local\arm-uclinux-elf-tools\arm-uclinux-elf\include\
You are very nearly done, you just need to add the cross-compiler to your PATH. All this means (for those without unix experiance) is that if the program directory is in your path, you can just type in the program name and it will be executed. You will need to open C:\cygwin\etc\profile in notepad2.
Find the line

PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:$PATH

and replace it with

PATH=/usr/local/bin:/usr/bin:/bin:/usr/X11R6/bin:/usr/local/arm-uclinux-elf-tools/bin:$PATH

Installation of Cygwin and the toolchain is now complete. Test by typing arm-elf-gcc at the cygwin prompt. If it replies arm-elf-gcc: No Input Files then eveything worked, otherwise, make sure you did everything correctly.

Actual Programming

Now, we get to the iPod-specific part. You need to choose whether you want to make text-based apps, or the far more elegant graphical apps. I would suggest making a few text apps first, as they are very simple, and then moving on to graphical work. If you just want to make text-based apps, then everything is installed and ready.

Text-Based Apps

Put your .c file in C:/cygwin/home/(User)/, and type arm-elf-gcc program.c -o program -lm -elf2flt. Now look in your cygwin home folder, there should be 3 files; program.c, program.gdb, and program. Program.c is your source code, program.gdb is used by the gcc debugger and can be ignored, and program (no extension) is your compiled binary. You cannot execute this in older versions of pz2, but from more recent versions and from pz0. So, if you don't have a version of pz2 greater than 1400 or pz0, I would recommend launching it with loader2 and getloader2args. When you select your program in the loader2 menu, the normal orange lines of text will fly past, and then your program will begin. Note that if the program is a simple hello world, the iPod will probably reboot a few seconds after running it, so watch closely.
Here (http://rapidsharing.com/download.php?id=C0A6CB91) (zip containing source, custom header library and compiled binary) is a simple game I (Confused fishcake) wrote, although the gameplay is somewhat lacking, the most important feature is the input.h header file. It contains a function called buttonpress, which returns an integar value dependant on what key is pressed. Each iPod button is mapped to a standard keyboard letter, the mappings can be found here. The tricky bit to remember is that by pressing the button, you often jog the scroll wheel a little, sending the program an r or an l. To start with, you can press the button with a plastic object to negate this effect, but my function buttonpress scans for the first 15 letters typed in, so you would have to move the wheel an awful lot for it not to register you pressing the button.

Graphical Apps

Firstly, let me deal with setting up cygwin, and downloading the necessary files. You need 4 things to compile podzilla2 modules; Hotdog, TTK, Podfile, and Podzilla2. Open up cygwin, and type these commands:

svn co https://ipodlinux.svn.sourceforge.net/svnroot/ipodlinux/libs/hotdog/
svn co https://ipodlinux.svn.sourceforge.net/svnroot/ipodlinux/libs/ttk/
svn co https://ipodlinux.svn.sourceforge.net/svnroot/ipodlinux/legacy/podfile/
svn co https://ipodlinux.svn.sourceforge.net/svnroot/ipodlinux/apps/ipod/podzilla2/

This downloads the most recent source code. You can now begin to compile:

Hotdog

Hotdog is a fast graphic library for the iPod, which will be used from TTK in the nearer future. But to compile TTK successfully we have to compile Hotdog first.

  cd hotdog                   //This changes to the hotdog directory.
  make IPOD=1                 //This makes hotdog just for the the iPod.
  make                        //This makes hotdog just for the the desktop.

TTK

TTK is the GUI library for the iPod, which you will need to learn to program graphical apps. For now though, we just need to compile it:

  cd ttk                      //This changes to the ttk directory.
  make -s                     //This makes ttk for the iPod and the desktop.
  make -s NOMWIN=1 NOX11=1    //This makes ttk just for the iPod, not the desktop.
  make NOHDOG=1               //This makes ttk without hotdog 

When you compile Podzilla2 (along with the modules) it uses the compiled TTK components. However, it does not modify them, so it is easy to update TTK to use the latest source code:

  cd ttk        //This changes to the ttk directory.
  make clean    //This removes all compiled elements for a cleaner update.
  cd ..         //This goes back to your home directory.
  svn co http://svn.ipodlinux.org/tools/ttk    //This updates TTK.
  cd ttk        //This changes to the ttk directory.
  make -s       //This makes ttk just for the iPod, not the desktop.

Podfile

  cd podfile    //This changes to the podfile directory.
  make -s       //This makes podfile, which packages your modules into a *.mod.o file.

Although you can update Podfile in a similar way to TTK (see above), to the best of my knowledge podfile is unlikely to be updated. Nevertheless, here would be the steps required to update Podfile:

  cd podfile    //This changes to the podfile directory.
  make clean    //This removes all compiled elements for a cleaner update.
  cd ..         //This goes back to your home directory.
  svn up http://svn.ipodlinux.org/tools/podfile    //This updates podfile.
  cd podfile    //This changes to the podfile directory.
  make -s       //This makes podfile.

Podzilla 2

Before I begin, I need to go through the basic structure of podzilla2, as it will make everything a lot easier later. Firstly, you have your podzilla binary. This binary is created the same, regardless of what modules you compile, so I tend to stick with using the nightly binaries. Also, you have your appearance files - fonts/schemes. These hardly ever change, so its usually worth downloading the pzmodules file and extracting those. The only thing that you need to update on your iPod are the module files. I am going to talk quickly about the format of the modules:

You need a few different types of files to make and use modules:

  modulename.c - This is the main source code. It must be named the same as your module.
  Module - This gives a few details about the module. Its format is:
     Module: mymodule                   //Substitute your module name for mymodule.
     Display-name: Podzilla Test Module //This is what your module will be named as in podzilla.
     Author: Your Name                  //Put your name here.
  Makefile - This tells your compiler what actions to perform. It needs to look like this:
     obj-m := mymodule.o                //Your source code file, but .o instead of .c
     MODULE = mymodule                  //Name of your module.
     DATA = Image.png Text.txt          //Any files which your program will require.

Once you have compiled your modules, you will get 2 additional files; modulename.o, and modulename.mod.o. You can ignore modulename.o, you just need to place modulename.mod.o along with your Module file and any data files, in /usr/lib/modulename/.

Now that you understand the basic format of modules, you can compile:

  cd podzilla2
  make -s IPOD=1    //Use just 'make' to compile it for the desktop. 

Note: If you are using cygwin you can't compile podzilla for the desktop. This only works for Linux and MacSOX users!

Now look in /podzilla2/modules/, in each module folder there should be a compiled *.mod.o file. IGNORE the compiling errors:

  Unused variable x
  x defined but not used
  Assembler messages: ignoring changed attributes for text.

These are all harmless, and you can safely ignore them.

Making your first Module

Our first module will be called cow. It is very similar to the module called mymodule which is in svn, but when compiling podzilla2, it tends to delete mymodule. Firstly, you must save the source code as cow.c, in /podzilla2/modules/cow/. The source code is going to be:

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include "pz.h"

static PzModule *module;
static ttk_surface image;
static int imgw, imgh;
static char *text;

void draw_cow (PzWidget *wid, ttk_surface srf) 
{
    // Draw the message
    char *p = text;
    int y = wid->y + 5;
    while (*p) {
	char svch;
	if (strchr (p, '\n')) {
	    svch = *strchr (p, '\n');
	    *strchr (p, '\n') = 0;
	} else {
	    svch = 0;
	}
	ttk_text (srf, ttk_textfont, wid->x + 5, y, ttk_makecol (BLACK), p);
	p += strlen (p);
	y += ttk_text_height (ttk_textfont) + 1;
	*p = svch;
	if (*p) p++;
    }
    y += 3;
    // Dividing line
    ttk_line (srf, wid->x + 5, y, wid->x + wid->w - 5, y, ttk_makecol (DKGREY));
    
    y += 3;
    // The image
    ttk_blit_image (image, srf, wid->x + (wid->w - imgw) / 2, wid->y + (wid->h - imgh) / 2);
    y += imgh;
    
    // The message
#define MSG "When you are done, press any button."
    ttk_text (srf, ttk_menufont, wid->x + (wid->w - ttk_text_width (ttk_menufont, MSG)) / 2,
	      wid->y + wid->h - ttk_text_height (ttk_menufont) - 5, ttk_makecol (BLACK), MSG);
}

int event_cow (PzEvent *ev) 
{
    switch (ev->type) {
    case PZ_EVENT_BUTTON_UP:
	pz_close_window (ev->wid->win);
	break;
    case PZ_EVENT_DESTROY:
	ttk_free_surface (image);
	free (text);
	break;
    }
    return 0;
}

PzWindow *new_cow_window()
{
    static int calledyet = 0;
    PzWindow *ret;
    FILE *fp;
    
    if (!calledyet) {
	calledyet++;
	pz_message ("Select again to see a cow.");
	return TTK_MENU_DONOTHING;
    }

    image = ttk_load_image (pz_module_get_datapath (module, "image.png"));
    if (!image) {
	pz_error ("Could not load %s: %s", pz_module_get_datapath (module, "image.png"),
		  strerror (errno));
	return TTK_MENU_DONOTHING;
    }
    ttk_surface_get_dimen (image, &imgw, &imgh);

    fp = fopen (pz_module_get_datapath (module, "message.txt"), "r");
    if (!fp) {
	pz_warning ("Could not read from %s: %s.", pz_module_get_datapath (module, "message.txt"),
		    strerror (errno));
	text = (char *)strdup ("Hi! I forgot to name the cow!");
    } else {
	long len;
	fseek (fp, 0, SEEK_END);
	len = ftell (fp);
	fseek (fp, 0, SEEK_SET);
	text = malloc (len + 1);
	fread (text, 1, len, fp);
	text[len] = 0;
    }

    ret = pz_new_window ("cow", PZ_WINDOW_NORMAL);
    pz_add_widget (ret, draw_cow, event_cow);
    return pz_finish_window (ret);
}

void cleanup_cow() 
{
    printf ("Bye-bye now...\n");
}

void init_cow() 
{
    module = pz_register_module ("cow", cleanup_cow);
    pz_menu_add_action ("/Extras/Cool Stuff/Cow", new_cow_window);
    printf ("Hi! cow loaded, action set.\n");
}

PZ_MOD_INIT (init_cow)

A bit hefty, but this covers loading text files and image files, so it not all that bad. I have to refer you to the article on Modifying Podzilla for how this all works, but it is pretty self-explanatory. I will come back to how it works in a minute, but first I shall go through the steps of compiling and putting the program on your iPod:

First, make a makefile and a Module file. You should by now be able to do this. Then get a picture (preferably of a cow) and save it as image.png, roughly 40x40. You also need a short message.txt, just a line or 2 of writing. Here is a tgz archive of my files (http://filexoom.com/files/4931/C%20programs/cow.tgz), and here (http://filexoom.com/files/4931/C%20programs/cow.zip) is a zip.

Put the cow folder in /podzilla2/modules/ and then compile podzilla2. You will get a file cow.mod.o which you need to place along with your Module file, your text file, and your png file, in /usr/lib/cow/ on your iPod. Refer to the bottom of the page for instuction on how to do this.

REST OF ARTICLE STILL UNDER CONSTRUCTION

Useful Links

Here are some links which should prove useful:

Putting files on your linux partition from windows.

There are 4 main ways to transfer your program to the linux partition (You need to put the module folder in /usr/lib/):

  1. Use SLAX - A very easy to use linux live cd, the main problem is that it takes a while to boot, but excellent if you have access to 2 computers.
  2. Use LTools - Quite easy to use, but has a nasty habit of corrupting your linux partition when you write to it, I wouldn't recommend this.
  3. Start files - I have never really used them, basically you make a script which moves files across when the iPod boots.
  4. Use Loader2 and getloader2args - If you have loader2 and getloader2args installed (LOADS of tutorials flying around the forums), then it is very easy to transfer files. Add these 2 lines to the end of your loader.cfg file:
-Lin2Win @ (hd0,1)/kernel.bin rm -r /mnt/lib && cp -r /usr/lib /mnt/
-Win2Lin @ (hd0,1)/kernel.bin rm -r /usr/lib && cp -r /mnt/lib /usr/

When you select Lin2Win, all of the files in /usr/lib/ are copied to a folder called lib in your windows partition. When you select Win2Lin, all of the files in the folder lib in your windows partition are copied to /usr/lib/. First of all run Lin2Win, then you can modify whatever files you like from windows, when you are done, eject your ipod then run Win2Lin. I strongly recommend using this method, because it takes ~12 seconds to execute each script, which makes it the fastest method, and it also carries none of the risks of writing using LTools.

Navigation



  • Google Search (http://www.google.com/custom?sa=Google+Search&cof=S%3Ahttp%3A%2F%2Fwww.ipodlinux.org%3BVLC%3Apurple%3BAH%3Acenter%3BBGC%3Awhite%3BLH%3A141%3BLC%3Ablue%3BL%3Ahttp%3A%2F%2Fipodlinux.org%2Fstylesheets%2Fimages%2Fwiki.png%3BALC%3Ablue%3BLW%3A128%3BT%3Ablack%3BAWFID%3A70a74ab66f4d59ae%3B&domains=ipodlinux.org&sitesearch=ipodlinux.org)