[Home] All Posts

Post Titles:

All Posts:

booting the Overo Tide(View Stand-alone)

u-boot.bin and MLO

The Overo Tide is brand new and you can't boot it with an older x-loader. You must have a recent version of u-boot.bin and MLO.

cd ~/overo-oe
bitbake -c clean u-boot-omap3 x-load
bitbake u-boot-omap3 x-load
ls tmp/deploy/glibc/images/overo/
# note MLO-overo and u-boot-overo.bin

saveenv

The Tide has no NAND so saveenv just won't work. If you feel the need to roll your own u-boot, be my guest.

However, you can also create a myubootenv.cmd script and turn it into a boot.scr.

myubootenv.cmd:

setenv ethaddr 00:00:00:FF:FF:FF
setenv mpurate 720
setenv vram 4M
setenv linuxmem 176M
setenv mmcargs 'setenv bootargs console=${console} mpurate=${mpurate} vram=${vram} mem=${linuxmem} omapfb.mode=dvi:${dvimode} omapfb.debug=y omapdss.def_disp=${defaultdisplay} root=${mmcroot} rootfstype=${mmcrootfstype}'
setenv bootcmd 'mmc init; run loaduimage; run mmcboot'
boot

And add the binary headers:

mkimage -A arm -O linux -T script -C none -a 0 -e 0 -n "myubootenv" -d myubootenv.cmd boot.scr

common u-boot / kernel parameters

  • bootcmd is what u-boot will execute when the boot command is issued
  • mpurate directly sets the ARM clock rate and also indirectly sets the DSP clock rate.
  • vram is the amount of shared video memory to be taken from the system memory
  • mem limits the amount of memory - useful if you are using the DSP - cmemk, dsplink, etc
  • ethaddr overrides the network card's firmware MAC address, primarily for PXE / tftp / network booting.
    • useful when your vendor doesn't set a MAC for you and you don't care to flash your NICs firmware.
    • using ifconfig eth0 hw ether in Linux will override this setting.
    • WARNING duplicate MAC addresses on your network will lead to frustrating and seemingly mysterious network bugs

node-waf on gumstix(View Stand-alone)

Goal

Install a node module natively using node-waf.

Specifically, I'm looking at node-inotify

Procedure

For reasons that I don't understand, the packaged build of nodejs in OpenEmbedded doesn't include node's waf tools. I just copied them over from a system that does have them installed:

Prereqs

GUMSTIX=192.168.1.110
scp -r /usr/local/lib/node/waf* ${GUMSTIX}:/usr/lib/node/
scp ~/overo-oe/tmp/deploy/glibc/ipk/armv7a/nodejs-dev_*.ipk ${GUMSTIX}:~/
ssh ${GUMSTIX}
sudo opkg install nodejs-dev_*.ipk
sudo opkg install git task-native-sdk python python-modules python-distutils python-misc python-subprocess

Installing node-inotify

git clone git://github.com/c4milo/node-inotify.git
cd node-inotify
node-waf configure build
node-waf install # installs locally

npm install inotify has the (dis)advantage of installing to the same location as node, which is in /usr in the case of opkg install nodejs

NOTE: The python modules may not all need to be installed. I'm unsure.

Test

test-inotify.js

Appendix

Errors you get when /var/volatile is full:

And actually, you get a lot of other miscellaneous errors too.

sudo opkg install ./python-subprocess_2.6.5-ml12.1.6_armv7a.ipk 
Collected errors:
 * pkg_init_from_file: Malformed package file ../python-subprocess_2.6.5-ml12.1.6_armv7a.ipk.

Errors you get without the wafadmin tools:

node-waf configure build
Traceback (most recent call last):
  File "/usr/bin/node-waf", line 14, in <module>
    import Scripting
ImportError: No module named Scripting

Errors you get without the python-subprocess module:

node-waf configure build
Traceback (most recent call last):
  File "/usr/bin/node-waf", line 14, in <module>
    import Scripting
  File "/usr/bin/../lib/node/wafadmin/Scripting.py", line 9, in <module>
    import Utils, Configure, Build, Logs, Options, Environment, Task
  File "/usr/bin/../lib/node/wafadmin/Utils.py", line 43, in <module>
    import subprocess as pproc
ImportError: No module named subprocess

Errors you get when nodejs-dev is not installed:

node-waf configure build
Checking for program g++ or c++          : /usr/bin/g++ 
Checking for program cpp                 : /usr/bin/cpp 
Checking for program ar                  : /usr/bin/ar 
Checking for program ranlib              : /usr/bin/ranlib 
Checking for g++                         : ok  
Checking for node path                   : not found 
Checking for node prefix                 : ok /usr 
Checking for program node                : /usr/bin/node 
Checking for function inotify_init       : yes 
'configure' finished successfully (2.605s)
Waf: Entering directory `/home/user/node-inotify/build'
[1/3] cxx: src/node_inotify.cc -> build/default/src/node_inotify_1.o
In file included from ../src/bindings.h:4,
                 from ../src/node_inotify.cc:2:
../src/node_inotify.h:5:18: error: node.h: No such file or directory
../src/node_inotify.h:6:25: error: node_events.h: No such file or directory
In file included from ../src/bindings.h:4,
                 from ../src/node_inotify.cc:2:
../src/node_inotify.h:15: error: 'v8' is not a namespace-name
../src/node_inotify.h:15: error: expected namespace-name before ';' token
../src/node_inotify.h:16: error: 'node' is not a namespace-name
../src/node_inotify.h:16: error: expected namespace-name before ';' token
In file included from ../src/node_inotify.cc:2:
../src/bindings.h:8: error: expected class-name before '{' token
../src/bindings.h:10: error: 'Handle' has not been declared
../src/bindings.h:10: error: expected ',' or '...' before '<' token
../src/bindings.h:16: error: ISO C++ forbids declaration of 'Handle' with no type
../src/bindings.h:16: error: expected ';' before '<' token
../src/bindings.h:17: error: ISO C++ forbids declaration of 'Handle' with no type
../src/bindings.h:17: error: expected ';' before '<' token
../src/bindings.h:18: error: ISO C++ forbids declaration of 'Handle' with no type
../src/bindings.h:18: error: expected ';' before '<' token
../src/bindings.h:19: error: ISO C++ forbids declaration of 'Handle' with no type
../src/bindings.h:19: error: expected ';' before '<' token
../src/bindings.h:20: error: ISO C++ forbids declaration of 'Handle' with no type
../src/bindings.h:20: error: expected ';' before '<' token
../src/bindings.h:25: error: 'ev_io' does not name a type
../src/bindings.h:27: error: 'EV_P_' has not been declared
../src/bindings.h:27: error: expected ',' or '...' before '*' token
../src/node_inotify.cc:5: error: variable or field 'InitializeInotify' declared void
../src/node_inotify.cc:5: error: 'Handle' was not declared in this scope
../src/node_inotify.cc:5: error: 'Object' was not declared in this scope
../src/node_inotify.cc:5: error: 'target' was not declared in this scope
../src/node_inotify.cc:20: warning: 'init' initialized and declared 'extern'
../src/node_inotify.cc:20: error: variable or field 'init' declared void
../src/node_inotify.cc:20: error: 'Handle' was not declared in this scope
../src/node_inotify.cc:20: error: 'Object' was not declared in this scope
../src/node_inotify.cc:20: error: 'target' was not declared in this scope
Waf: Leaving directory `/home/user/node-inotify/build'
Build failed:  -> task failed (err #1): 
  {task: cxx node_inotify.cc -> node_inotify_1.o}

npm-on-gumstix(View Stand-alone)

Goal

Use npm to install spark, express, connect on a gumstix overo (like beagleboard).

Install nodejs

nodejs is already available in OpenEmbedded

bitbake nodejs
TARGET=192.168.1.110
scp tmp/deplay/glibc/ipk/armv7a/nodejs_*.ipk ${TARGET}:~/
opkg install nodejs_*.ipk

and should soon be available in Angstrom (if the commit messages on bitbucket indicate anything)

opkg install nodejs

Making a user

USER=fastr
GROUP=wheel
visudo # uncomment %wheel
addgroup ${GROUP}
adduser ${USER} ${GROUP}

Create a sandbox

su ${USER}
cd
echo 'export PATH=~/local/bin:${PATH}' >> ~/.bash_profile
. ~/.bash_profile

mkdir ~/local/bin ~/local/share/man -p

cat >>~/.npmrc <<NPMRC
root = $HOME/.node_libraries
binroot = $HOME/bin
manroot = $HOME/share/man
NPMRC

TODO: use list of files to copy node locally also

Installing npm

ntpdate ntp.ubuntu.com sudo opkg install curl make curl http://npmjs.org/install.sh | sh

Installing a few modules

npm install connect express spark futures couchdb

test

mkdir ~/webapps

webapps/app.js:

var connect = require('connect');

module.exports = connect.createServer(function (req, res) {
  console.dir(req.headers);
  res.writeHead(200);
  res.end("check the console to see the browser headers logged");
});

webapps/config.js:

module.exports = {
  port: 3000,
  //user: "nobody", // set this when running as root in production
  env: "development"
}

cd ~/webapps
spark

Tada!

Backup / Clone via ssh (root login disabled)(View Stand-alone)

Goal

I want to use rsync to clone/backup a server such that if the main server goes down (or I accidentally rm -rf /usr instead of ./usr again) the recovery time should be in the order of minutes.

ssh key-only login for root

This doesn't allow root to login with a password, only with a key.

sudo su -
ssh-keygen -f .ssh/id_rsa -P ''
cat .ssh/id_rsa.pub >> .ssh/authorized_keys

/etc/ssh/sshd_config

PermitRootLogin without-password
PermitEmptyPasswords no

rysnc backups

Both servers have the exact same hard drive partitioning scheme and files - minus the UUIDs, network configuration, and backups folder.

Of course, I don't want to backup

  • devcie specific configuration: grub UUIDs, network interfaces, /boot
  • virtual filesystems: sys, dev, proc, .gvfs
  • temporary filesystems: /tmp, /var/run, /media
  • SCM repositories: .git, .svn

/etc/cron.daily/backup:

#!/bin/sh

CLONE='clone.example.tld'
/usr/bin/rsync -avh / ${CLONE}:/ \
      --exclude=/dev \
      --exclude=/proc \
      --exclude=/sys \
      --exclude=/media \
      --exclude=/tmp \
      --exclude=cache \
      --exclude=/etc/fstab \
      --exclude=/boot/grub \
      --exclude=/var/run \
      --exclude=/etc/hostname \
      --exclude=/etc/cron.daily/backup \
      --exclude=/etc/network/interfaces \
      --exclude='.git' \
      --exclude='.svn' \
      --exclude='.gvfs' \
      --exclude=/mnt/local/backup/ \
      --backup \
      --backup-dir=/mnt/local/backup/`date '+%F_%H-%M-%S'` \
      --delete

Appendix

Resources:

  • http://serverfault.com/questions/111187/disable-local-root-login-permit-root-login-over-ssh

man sshd_config

 PermitRootLogin
         Specifies whether root can log in using ssh(1).  The argument
         must be ``yes'', ``without-password'', ``forced-commands-only'',
         or ``no''.  The default is ``yes''.

         If this option is set to ``without-password'', password authenti-
         cation is disabled for root.

         If this option is set to ``forced-commands-only'', root login
         with public key authentication will be allowed, but only if the
         command option has been specified (which may be useful for taking
         remote backups even if root login is normally not allowed).  All
         other authentication methods are disabled for root.

         If this option is set to ``no'', root is not allowed to log in.

gumstix with upstart(View Stand-alone)

Goal

Use upstart rather than the default sysvinit.

Status: incomplete

Procedure

cd ~/overo-oe
bitbake omap3-console-image
bitbake time upstart
  # time - tmp/deploy/glibc/ipk/armv7a/time_1.7-r1.6_armv7a.ipk
  # libupstart0 - tmp/deploy/glibc/ipk/armv7a/libupstart0_0.3.11-r1.6_armv7a.ipk
  # upstart-sysvcompat - scp tmp/deploy/glibc/ipk/armv7a/upstart-sysvcompat_0.3.11-r1.6_armv7a.ipk
  # upstart - tmp/deploy/glibc/ipk/armv7a/upstart_0.3.11-r1.6_armv7a.ipk

Error (hack) fixing:

rm /usr/sbin/readprofile

configure bitbake kernel (remotely)(View Stand-alone)

Goal

Custom configure a kernel for gumstix overo.

In particular, I wanted to add support for ext4 and gpt (as opposed to mbr)

Procedure

Begin to configure the kernel

cd ~/overo-oe
REV=34 # CHANGE THIS to be the current kernel revision
bitbake linux-omap3-2.6.${REV} -c clean
bitbake linux-omap3-2.6.${REV} -c configure

Get into the bitbake environment.

cd tmp/work/overo-angstrom-linux-gnueabi/linux-omap3-2.6.${REV}-r*/git
cp ../temp/run.do_configure.* ./
vim run.do_configure.*
# replace the last line `do_configure' with `bash --norc`
# :%s/^do_configure$/bash --norc/g
./run.do_configure.*

Now at the bash-4.0$ prompt (which has all of the cross-compile variables pre-set)

make menuconfig

Once you've made the changes you need you may want to save the .config

Now run bitbake again

bitbake bitbake linux-omap3-2.6.${REV}

or

bitbake linux-omap3-2.6.34 -f -c compile
bitbake linux-omap3-2.6.34 -f -c deploy

And install onto the gumstix's microSDHC:

IP=192.168.1.20 # CHANGE THIS to the gumstix' ip address
scp tmp/deploy/glibc/images/overo/uImage-overo.bin root@${IP}:/media/mmcblk0p1/uImage

Note: /media/mmcblk0p1 will mount by default with the sync option, which makes transfer terribly slow.

Appendix

For me, bitbake linux-omap3-2.6.34 -c menuconfig results in:

NOTE: Running task 368 of 368 (ID: 5, /home/harry/overo-oe/org.openembedded.dev/recipes/linux/linux-omap3_2.6.34.bb, do_menuconfig)
ERROR: function do_menuconfig failed
ERROR: log data follows (/home/harry/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/linux-omap3-2.6.34-r89/temp/log.do_menuconfig.16568)
| Xlib:  extension "Generic Event Extension" missing on display "localhost:11.0".
| Xlib:  extension "RANDR" missing on display "localhost:11.0".
| Xlib:  extension "Generic Event Extension" missing on display "localhost:11.0".
| )
| GConf Error: Failed to contact configuration server; some possible causes are that you need to enable TCP/IP networking for ORBit, or you have stale NFS locks due to a system crash. See http://projects.gnome.org/gconf/ for information. (Details -  1: Failed to get connection to session: /bin/dbus-launch terminated abnormally with the following error: Autolaunch requested, but X11 support not compiled in.
| Cannot continue.
| )
| **
| ERROR:terminal-app.c:1444:terminal_app_init: assertion failed: (app->default_profile_id != NULL)
| /home/harry/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/linux-omap3-2.6.34-r89/temp/run.do_menuconfig.16568: line 1223: 16570 Aborted                 gnome-terminal --disable-factory -t "$TERMWINDOWTITLE" -x $SHELLCMDS
NOTE: Task failed: /home/harry/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/linux-omap3-2.6.34-r89/temp/log.do_menuconfig.16568

create file system image with tar(View Stand-alone)

Goal

A script for backing up an sdhc rootfs as a tarball.

Script

create-rootfs-image-from-sdhc.sh:

#!/bin/bash

set -e

SDHC=$1
MOUNT=/mnt/new_rootfs
PACKAGE=/home/shared/sdhc-rootfs-`date +%F`.tar
PACKAGE_LINK=/home/shared/sdhc-rootfs.tar

if [ ! -n "${SDHC}" ] || [ ! "0" == "`id -u`" ]
then
  echo 'Usage: `sudo '$0' /dev/MICRO_SDHC_PARTITION`'
  echo 'Example: `sudo '$0' /dev/sdc1`'
  echo 'most likely one of the below:'
  ls /dev/sd[b-z]* | grep [0-9]
  exit 1;
fi

# Create the environment for this script

umount ${SDHC} ${MOUNT} 2> /dev/null || true
mkdir -p ${MOUNT}
mount ${SDHC} ${MOUNT}
cd ${MOUNT}

echo "Creating backup of ${SDHC}"
tar cf ${PACKAGE} ./
ln -sf ${PACKAGE} ${PACKAGE_LINK}

sync
cd /tmp
umount ${MOUNT}
rm ${MOUNT} -rf

building an xdc application(View Stand-alone)

Scratchpad

testing file write speeds(View Stand-alone)

Goal

Get a good comparison between various SD Cards of various sizes, brands, and classes.

Determine if write bottlenecks are due to the Overo's data bus, or the microSDHC.

Results

Write and Read speeds are with booting from NAND.

TODO try jfs and ext4

Manufacturer      Size      Class     Write Speed     Read Speed    Filesystem
------------      ----      -----     -----------     ----------    ----------

KingMax           8GB       10        4.7 MB/s        14.1 MB/s     ext3,defaults

Kingston          16GB      10        4.9 MB/s        13.2 MB/s     ext3,defaults

Kingston          16GB      10        2.8 MB/s        13.5 MB/s     **ext2**,defaults

Kingston          16GB      4         4.9 MB/s        12.6 MB/s     ext3,defaults

SanDisk           16GB      2         3.1 MB/s        13.1 MB/s     ext3,defaults

? (Gumstix)       2GB       ?         3.2 MB/s        9.7 MB/s      ext3,defaults

Comparison: regular desktop with Kingston Multi-reader USB 2.0

Kingston          16GB      10        5.3 MB/s        137.0 MB/s    **ext4**,defaults

Kingston          16GB      10        3.3 MB/s        36.0 MB/s     ext3,defaults

Kingston          16GB      10        5.5 MB/s        91.2 MB/s     **ext2**,defaults

Procedure

I would like to try both configurations of booting from the NAND and booting from the microSDHC.

NOTE: The results above are only from booting the NAND.

Booting from the NAND

  1. Connect via Serial:
    1. ls /dev/tty*[uU][sS][bB]* # Should list usb-serial devices equally well on Mac and Linux
    2. sudo minicom -s # Configure to use the port listed above
  2. Power on and enter u-boot by pressing the any key
  3. run nandboot

If the card wasn't already formatted, it's formatted as ext3

mount | grep mmcblk0 | grep -v ext3
umount /media/mmcblk0p1/
mkfs.ext3 /dev/mmcblk0p1
mount /dev/mmcblk0p1 /media/mmcblk0p1

TODO: should have formatted all cards with filesystem before testing

Booting from the microSDHC

There are two other posts (possibly in the related posts section) about partitioning and formatting the microSDHC. Once that's done, they'll boot.

Benchmark Procedure

What we need to know is if the card can stream the MB it boasts or not.

NOTE: bitbake bonnie++ provides a good benchmarking tool for more realistic testing.

# Get some random bytes from memory - say 40MB or so
sync
dd if=/dev/urandom of=/dev/shm/rand.dd bs=1M count=40

# Emulate a continuous stream of data
sync
MMC=/media/mmcblk0p1
#NOTE: This fills the cache buffers with data 
cat /dev/shm/rand.dd /dev/shm/rand.dd | dd of=${MMC}/rand.dd

# The overhead of the un`sync`d data above will make this more accurate
cat /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd \
  /dev/shm/rand.dd /dev/shm/rand.dd /dev/shm/rand.dd | dd of=${MMC}/rand.dd

# Test read speed just for fun
sync
dd if=${MMC}/rand.dd of=/dev/shm/rand.dd

NOTE: By default these devices are mounted with the sync option. You'll get a whopping 6.4KB/s unless you remount them.

NOTE: Due to caching, the speeds appear slightly faster than they really are. If you just test with a small amount of data - 40MB, for example - you'll see that quite profoundly.

Appendix

Generating Random Bits

sync
dd if=/dev/urandom of=/dev/shm/rand.dd bs=1M count=40
41943040 bytes (42 MB) copied, 42.311 s, 991 kB/s

Writing to the NAND (which only had 45 MB free)

45474304 bytes (45 MB) copied, 414.42 s, 110 kB/s

Setting up Wifi on Gumstix Overo Fire(View Stand-alone)

Goal

Create a Gumstix experience that I can live with.

This is going to live in my living room accessible via wireless

Setup with the Out-of-Box system

First Things First

# secure my gumstix from netbots (it will have a public IP)
passwd

# make vim usable
echo ":set nocompatible" >> /etc/vimrc

# make the filesystem searchable with locate
updatedb

Wireless Networking

Disable Bluetooth

# (disable) bluetooth 
/etc/init.d/bluetooth stop
echo 0 > /sys/class/gpio/gpio164/value # reset
echo 0 > /sys/class/gpio/gpio15/value  # disable
update-rc.d -f bluetooth remove
update-rc.d -f blueprobe remove

Errors You may Encounter

Error:

Configuring network interfaces... ADDRCONF(NETDEV_UP): wlan0: link is not ready
udhcpc (v1.13.2) started
run-parts: /etc/udhcpc.d/00avahi-autoipd exited with code 1
Sending discover...
Sending discover...
Sending discover...
run-parts: /etc/udhcpc.d/99avahi-autoipd exited with code 1
No lease, failing

Fix:

# This helps... kinda... I think, but it may be solely the manual config below that gets it working
/etc/init.d/NetworkManager stop
update-rc.d -f NetworkManager remove
opkg remove networkmanager network-manager-applet

Error:

can't create /var/lib/dhcp/dhclient.leases: No such file or directory

Fix:

ln -s /var/lib/dhcp3 /var/lib/dhcp

Enable WiFi

Manually

ESSID='Apt Rm 04 & 05' # CHANGE THIS to suite your situation
ifdown -a
ifconfig wlan0 down
iwconfig wlan0 bit 18M fixed
iwconfig wlan0 essid "${ESSID}"
iwconfig wlan0 mode managed
iwconfig wlan0 key off
dhclient wlan0

/etc/networking/interfaces:

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
        pre-up iwconfig wlan0 mode managed
        pre-up iwconfig wlan0 essid "Apt Rm 04 & 05"
        pre-up iwconfig wlan0 key off

This also works, note that there are no quotes:

allow-hotplug wlan0
auto wlan0
iface wlan0 inet dhcp
    wireless_mode managed
    wireless_essid Apt Rm 04 & 05
    wileless_key off

Better(?) Marvel Firmware

wget http://old.nabble.com/file/p29272793/Marvell_firmware_9.70.7.zip
unzip Marvell_firmware_9.70.7.zip
locate sd8686
mv 9.70.7.p0/sd8686-9.70.7.p0.bin /lib/firmware/sd8686.bin

DMZ

I have a dd-wrt router on which I added my Gumstix to have a static IP and be the DMZ.

  1. Log in to dd-wrt
  2. Click services
  3. Click add under DHCP Server
  4. Enter the gumstix hwaddr, and desired hostname and desired ipaddr
  5. 'save' first (do NOT apply first)
  6. okay, now 'apply'
  7. Click NAT/QoS
  8. Click DMZ
  9. Add gumstix

dummy isp ccdc driver(View Stand-alone)

Goal

Create a simple dummy driver (called fsr172x) for the OMAP3530 that bypasses almost all extra functionality just to get the RAW data from the 12 data lines to a v4l2buf.

Overview

  • fsr172x is a platform-independent v4l2-slave device
    • controls the sensor device
    • interfaces with v4l2
    • is unaware of isp
  • omap34xxcam is the platform-dependent v4l2-master
    • controls the isp
    • interfaces with v4l2
  • v4l2 provides a common framework which the application may use
  • isp image support package?
  • ispccdc
    • controls the ccdc
  • fidcap is a dummy capture application which utilizes v4l2
    • fidcap is designed specifically for use with the fsr172x and therefore is a bad example
  • the master and slave have no knowledge of each other's implementations
  • a platform "driver" such as board-overo-camera (Gumstix Overo) or board-omap3beagle-camera.c (BeagleBoard) connects the two together..

Note: The file contents shown are not complete but rather snippets that give content to the changes. Note: The FSR172X is a stripped down version of the MT9T111. I recommend viewing the V4L2 Example Capture application as well.

Pre-reqs

Hacking V4L2

Our dummy driver will use a special formats for

  • standard: FSRX - as opposed to NTSC, PAL, etc
  • colorspace: FSR - as opposed to SRGB

These are created from enums and #defines that are completely arbitrary. The caveat is that any application or driver that depends on these settings must include this special modified version of the of videodev2.h.

drivers/media/video/isp/isp.c

This is a patch showing changes I've made for the fsr172x. Once I have this figured out I'll refactor it down into understandable chunks

diff --git a/drivers/media/video/isp/isp.c b/drivers/media/video/isp/isp.c
index 29dd005..2369f54 100644
--- a/drivers/media/video/isp/isp.c
+++ b/drivers/media/video/isp/isp.c
@@ -930,7 +930,7 @@ static irqreturn_t omap34xx_isp_isr(int irq, void *_pdev)
    return IRQ_HANDLED;

  spin_lock_irqsave(&bufs->lock, flags);
- wait_hs_vs = bufs->wait_hs_vs;
+ wait_hs_vs = 0; //bufs->wait_hs_vs; For FSR
  if (irqstatus & HS_VS) {
    if (bufs->wait_hs_vs) {
      bufs->wait_hs_vs--;
@@ -978,12 +978,23 @@ static irqreturn_t omap34xx_isp_isr(int irq, void *_pdev)
  }

  if (irqstatus & CCDC_VD0) {
+   DPRINTK_ISPCTRL("VD0 interupt\n");    
    if (isp->pipeline.pix.field == V4L2_FIELD_INTERLACED) {
      /* Skip even fields, and process only odd fields */
      if (isp->current_field != 0)
        if (RAW_CAPTURE(isp))
          isp_buf_process(dev, bufs);
    }
+   else // For FSR - progressive scan, process every field
+   {
+     //DPRINTK_ISPCTRL("Not interlaced\n");
+     if (RAW_CAPTURE(isp))
+     {
+       DPRINTK_ISPCTRL("Processing buff\n");
+       isp_buf_process(dev, bufs);
+     }
+   }
+   
    if (!ispccdc_busy(&isp->isp_ccdc))
      ispccdc_config_shadow_registers(&isp->isp_ccdc);
  }
@@ -1363,7 +1374,10 @@ static void isp_set_buf(struct device *dev, struct isp_buf *buf)
      && is_ispresizer_enabled())
    ispresizer_set_outaddr(&isp->isp_res, buf->isp_addr);
  else if (isp->pipeline.modules & OMAP_ISP_CCDC)
+ {
+   printk("SDR Address set to 0x%08X\n",buf->isp_addr);
    ispccdc_set_outaddr(&isp->isp_ccdc, buf->isp_addr);
+ }

 }

@@ -1412,7 +1426,10 @@ static int isp_try_pipeline(struct device *dev,
    pipe->prv_out = PREVIEW_MEM;
    pipe->rsz_in = RSZ_MEM_YUV;
  } else {
+    printk("ARRIVED IN: ISP_CCDC\n");
    pipe->modules = OMAP_ISP_CCDC;
+   // TODO if this is set in fsr172x, we shouldn't need this here
+   //pix_input->pixelformat = V4L2_PIX_FMT_FSR172X; // Added for FSR 
    if (pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10 ||
        pix_input->pixelformat == V4L2_PIX_FMT_SGRBG10DPCM8 ||
        pix_input->pixelformat == V4L2_PIX_FMT_SRGGB10 ||
@@ -1431,12 +1448,17 @@ static int isp_try_pipeline(struct device *dev,
    } else if (pix_input->pixelformat == V4L2_PIX_FMT_YUYV ||
         pix_input->pixelformat == V4L2_PIX_FMT_UYVY) {
      if (isp->bt656ifen)
-       pipe->ccdc_in = CCDC_YUV_BT;
+       pipe->ccdc_in = CCDC_YUV_BT;
      else
-       pipe->ccdc_in = CCDC_YUV_SYNC;
+       pipe->ccdc_in = CCDC_YUV_SYNC;
      pipe->ccdc_out = CCDC_OTHERS_MEM;
-   } else
+   } else if (pix_input->pixelformat == V4L2_PIX_FMT_FSR172X) { // Added for FSR
+      printk("ARRIVED IN: PIPELINE FSR\n");
+     pipe->ccdc_in = CCDC_RAW_FSR;
+     pipe->ccdc_out = CCDC_FSR_MEM;
+    } else {
      return -EINVAL;
+    }
  }

  if (pipe->modules & OMAP_ISP_CCDC) {
@@ -1652,7 +1674,8 @@ static int isp_buf_process(struct device *dev, struct isp_bufs *bufs)
  if (ISP_BUFS_IS_EMPTY(bufs))
    goto out;

- if (RAW_CAPTURE(isp) && ispccdc_sbl_wait_idle(&isp->isp_ccdc, 1000)) {
+  // We keep getting wait errors... this seems to fix the problem (originally 1000)
+ if (RAW_CAPTURE(isp) && ispccdc_sbl_wait_idle(&isp->isp_ccdc, 2e6)) {
    dev_err(dev, "ccdc %d won't become idle!\n",
           RAW_CAPTURE(isp));
    goto out;

drivers/media/video/isp/ispccdc.c

diff --git a/drivers/media/video/isp/ispccdc.c b/drivers/media/video/isp/ispccdc.c
index 137a5e6..df7c15d 100644
--- a/drivers/media/video/isp/ispccdc.c
+++ b/drivers/media/video/isp/ispccdc.c
@@ -631,6 +631,23 @@ static int ispccdc_config_datapath(struct isp_ccdc_device *isp_ccdc,
    ispccdc_config_vp(isp_ccdc, vpcfg);
    ispccdc_enable_vp(isp_ccdc, 1);
    break;
+
+  case CCDC_FSR_MEM:
+    printk("ARRIVED IN: CCDC_FSR_MEM\n");
+   syn_mode &= ~ISPCCDC_SYN_MODE_VP2SDR;
+   syn_mode &= ~ISPCCDC_SYN_MODE_SDR2RSZ;
+   syn_mode |= ISPCCDC_SYN_MODE_WEN;
+   syn_mode &= ~ISPCCDC_SYN_MODE_EXWEN;
+    isp_reg_and(isp_ccdc->dev, OMAP3_ISP_IOMEM_CCDC,
+        ISPCCDC_CFG, ~ISPCCDC_CFG_WENLOG);
+
+    // TODO aren't these 0 by default?
+   vpcfg.bitshift_sel = 0;
+   vpcfg.freq_sel = 0;
+   ispccdc_config_vp(isp_ccdc, vpcfg);
+   ispccdc_enable_vp(isp_ccdc, 0);
+    break;
+
  default:
    DPRINTK_ISPCCDC("ISP_ERR: Wrong CCDC Output\n");
    return -EINVAL;
@@ -700,6 +717,33 @@ static int ispccdc_config_datapath(struct isp_ccdc_device *isp_ccdc,
    blkcfg.dcsubval = 0;
    ispccdc_config_black_clamp(isp_ccdc, blkcfg);
    break;
+  case CCDC_RAW_FSR: // what values do we need here?
+    printk("ARRIVED IN: CCDC_RAW_FSR\n");
+    syncif.ccdc_mastermode = 1; // p1461 1 ==hs/vs output
+    syncif.datapol = 0; // 0 == normal, not one's complement
+    syncif.datsz = DAT12; // 12 lines
+    syncif.fldmode = 0; // 0 == progressive scan, not interlaced
+    syncif.fldout = 0; // (cam_fld) not used when 0 == fldmode
+    syncif.fldpol = 0; // not used when 0 == fldmode
+    syncif.fldstat = 0; // not used when 0 == fldmode, otherwise marks current frame as odd/even
+    syncif.hdpol = 0; // cam_hs polarity 0 == positive
+    syncif.ipmod = RAW; // aka inpmod p1553 should be 0 for raw
+    syncif.vdpol = 0; // cam_vs polarity 0 == positive
+    syncif.bt_r656_en = 0; // 1 == ITU enabled
+
+    // These should next four should always be set when mastermode is enabled
+    syncif.hs_width = 0; // aka hd_vd_wid p1554
+    syncif.vs_width = 0; // aka hd_vd_wid
+    syncif.ppln = (u8) 0x7D01; // 32001 Maybe should be 16001(?) p1555 pixels per line
+    syncif.hlprf = 128; // half line per field or frame
+
+    // isp modules
+    ispccdc_config_imgattr(isp_ccdc, 0); // mosiac filter??, probably should be all 0's
+    ispccdc_config_sync_if(isp_ccdc, syncif); // commit these values to the registers
+
+    // black clamp
+    blkcfg.dcsubval = 0; // black clamp substraction value, probably should be 0
+    ispccdc_config_black_clamp(isp_ccdc, blkcfg);
  case CCDC_OTHERS:
    break;
  default:
@@ -1202,6 +1246,8 @@ int ispccdc_try_pipeline(struct isp_ccdc_device *isp_ccdc,
  pipe->ccdc_in_v_st = 0;
  pipe->ccdc_out_w = pipe->ccdc_in_w;
  pipe->ccdc_out_h = pipe->ccdc_in_h;
+ 
+ printk("Out pixel height %d\n",pipe->ccdc_out_h);

  if (!isp_ccdc->refmt_en
      && pipe->ccdc_out != CCDC_OTHERS_MEM
@@ -1348,6 +1394,7 @@ int ispccdc_s_pipeline(struct isp_ccdc_device *isp_ccdc,
          OMAP3_ISP_IOMEM_CCDC,
          ISPCCDC_VDINT);
    } else {
+       printk("Arrived in vp out mem\n");
      ispccdc_config_outlineoffset(isp_ccdc,
          pipe->ccdc_out_w * 2, EVENEVEN, 1);
      ispccdc_config_outlineoffset(isp_ccdc,
@@ -1367,6 +1414,7 @@ int ispccdc_s_pipeline(struct isp_ccdc_device *isp_ccdc,
    }

  } else if (pipe->ccdc_out == CCDC_OTHERS_VP_MEM) {
+   printk("Arrived in vp out mem\n");
    isp_reg_writel(isp_ccdc->dev,
             (pipe->ccdc_in_h_st << ISPCCDC_FMT_HORZ_FMTSPH_SHIFT) |
             ((pipe->ccdc_in_w - pipe->ccdc_in_h_st) <<

drivers/media/video/isp/ispccdc.h

The FSR uses a type of RAW capture and has particular memory requirements not currently supported by the ISP. These new enums allow us to cleanly create new conditional branches in the ISP/CCDC code.

/* Enumeration constants for CCDC input output format */
enum ccdc_input {
  CCDC_RAW_GRBG,
  CCDC_RAW_RGGB,
  CCDC_RAW_BGGR,
  CCDC_RAW_GBRG,
  CCDC_RAW_FSR, // FSR
  CCDC_YUV_SYNC,
  CCDC_YUV_BT,
  CCDC_OTHERS
};

enum ccdc_output {
  CCDC_YUV_RSZ,
  CCDC_YUV_MEM_RSZ,
  CCDC_FSR_MEM, // FSR
  CCDC_OTHERS_VP,
  CCDC_OTHERS_MEM,
  CCDC_OTHERS_VP_MEM
};

arch/arm/mach-omap2/board-overo-camera.c

#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/mm.h>
#include <linux/videodev2.h>
#include <linux/delay.h>
#include <linux/platform_device.h>

#include <plat/mux.h>
#include <plat/board.h>
#include <plat/control.h>

#include <media/v4l2-int-device.h>
#include <media/fsr172x.h>

/* Include V4L2 ISP-Camera driver related header file */
#include <../drivers/media/video/omap34xxcam.h>
#include <../drivers/media/video/isp/ispreg.h>

#include "mux.h"
#include "board-overo-camera.h"

#define MODULE_NAME     "omap3beaglelmb"

#define CAM_USE_XCLKA       0

#define ISP_FSR172X_MCLK    216000000

#define LEOPARD_RESET_GPIO    98

#if defined(CONFIG_VIDEO_FSR172X) || defined(CONFIG_VIDEO_FSR172X_MODULE)

/* Arbitrary memory handling limit */
#define FSR172X_BIGGEST_FRAME_BYTE_SIZE PAGE_ALIGN(2048 * 1536 * 4)

// TODO can this be moved to fsr driver?
static struct isp_interface_config fsr172x_if_config = {
  .ccdc_par_ser   = ISP_PARLL,
  .dataline_shift   = 0x0,
  .hsvs_syncdetect  = ISPCTRL_SYNC_DETECT_VSRISE,
  .strobe     = 0x0,
  .prestrobe    = 0x0,
  .shutter    = 0x0,
  .cam_mclk   = ISP_FSR172X_MCLK, // 216MHz
  .wenlog     = ISPCCDC_CFG_WENLOG_AND, // (0 << 8)
  .wait_hs_vs   = 2,
  .u.par.par_bridge = 0x0, // no bridge
  .u.par.par_clk_pol  = 0x0,
};

static struct v4l2_ifparm fsr172x_ifparm_s = {
  .if_type = V4L2_IF_TYPE_RAW,
  .u   = {
    .raw = {
      .frame_start_on_rising_vs = 1,
      .bt_sync_correct  = 0,
      .swap     = 0,
      .latch_clk_inv    = 0,
      .nobt_hs_inv    = 0,  /* active high */
      .nobt_vs_inv    = 0,  /* active high */
      .clock_min    = FSR172X_CLK_MIN, // 2.048MHz
      .clock_max    = FSR172X_CLK_MAX, // 2.048MHz
    },
  },
};

/**
 * @brief fsr172x_ifparm - Returns the fsr172x interface parameters
 *
 * @param p - pointer to v4l2_ifparm structure
 *
 * @return result of operation - 0 is success
 */
static int fsr172x_ifparm(struct v4l2_ifparm *p)
{
  if (p == NULL)
    return -EINVAL;

  *p = fsr172x_ifparm_s;
  return 0;
}

#if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
static struct omap34xxcam_hw_config fsr172x_hwc = {
  .dev_index    = 0,
  .dev_minor    = 0,
  .dev_type   = OMAP34XXCAM_SLAVE_SENSOR,
  .u.sensor.sensor_isp  = 1,
  .u.sensor.capture_mem = FSR172X_BIGGEST_FRAME_BYTE_SIZE * 2,
  .u.sensor.ival_default  = { 1, 10 },
};
#endif

/**
 * @brief fsr172x_set_prv_data - Returns fsr172x omap34xx driver private data
 *
 * @param priv - pointer to omap34xxcam_hw_config structure
 *
 * @return result of operation - 0 is success
 */
static int fsr172x_set_prv_data(void *priv)
{
#if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
  struct omap34xxcam_hw_config *hwc = priv;

  if (priv == NULL)
    return -EINVAL;

  hwc->u.sensor = fsr172x_hwc.u.sensor;
  hwc->dev_index = fsr172x_hwc.dev_index;
  hwc->dev_minor = fsr172x_hwc.dev_minor;
  hwc->dev_type = fsr172x_hwc.dev_type;
  return 0;
#else
  return -EINVAL;
#endif
}

/**
 * @brief fsr172x_power_set - Power-on or power-off TVP5146 device
 *
 * @param power - enum, Power on/off, resume/standby
 *
 * @return result of operation - 0 is success
 */
static int fsr172x_power_set(struct v4l2_int_device *s, enum v4l2_power power)
{
  struct omap34xxcam_videodev *vdev = s->u.slave->master->priv;

  switch (power) {
  case V4L2_POWER_OFF:
  case V4L2_POWER_STANDBY:
    isp_set_xclk(vdev->cam->isp, 0, CAM_USE_XCLKA);
    break;

  case V4L2_POWER_ON:
#if defined(CONFIG_VIDEO_OMAP3) || defined(CONFIG_VIDEO_OMAP3_MODULE)
    isp_configure_interface(vdev->cam->isp, &fsr172x_if_config);
#endif
    break;

  default:
    return -ENODEV;
    break;
  }
  return 0;
}

struct fsr172x_platform_data fsr172x_pdata = {
  .master   = "omap34xxcam",
  .power_set  = fsr172x_power_set,
  .priv_data_set  = fsr172x_set_prv_data,
  .ifparm   = fsr172x_ifparm,
  /* Some interface dependent params */
  .clk_polarity = 0, /* data clocked out on falling edge */
  .hs_polarity  = 1, /* 0 - Active low, 1- Active high */
  .vs_polarity  = 1, /* 0 - Active low, 1- Active high */
};

#endif        /* #ifdef CONFIG_VIDEO_FSR172X */


static int beagle_cam_probe(struct platform_device *pdev)
{
  printk(KERN_INFO MODULE_NAME ": Driver registration complete \n");
  return 0;
}

static int beagle_cam_remove(struct platform_device *pdev)
{
  // FSR_COMMENT -  mux init on remove, but not on insert?
  /* MUX init */
  omap_ctrl_writew(OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
       0x10C); /* CAM_HS */
  omap_ctrl_writew(OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
       0x10E); /* CAM_VS */
  omap_ctrl_writew(OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
       0x110); /* CAM_XCLKA */
  omap_ctrl_writew(OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
       0x112); /* CAM_PCLK */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x116); /* CAM_D0 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x118); /* CAM_D1 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x11A); /* CAM_D2 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x11C); /* CAM_D3 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x11E); /* CAM_D4 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x120); /* CAM_D5 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x122); /* CAM_D6 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x124); /* CAM_D7 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x126); /* CAM_D8 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x128); /* CAM_D9 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x12A); /* CAM_D10 */
  omap_ctrl_writew(OMAP_PIN_INPUT | OMAP_MUX_MODE0,
       0x12C); /* CAM_D11 */

  return 0;
}

static int beagle_cam_suspend(struct device *dev)
{
  return 0;
}

static int beagle_cam_resume(struct device *dev)
{
  return 0;
}

static struct dev_pm_ops beagle_cam_pm_ops = {
  .suspend = beagle_cam_suspend,
  .resume  = beagle_cam_resume,
};

static struct platform_driver beagle_cam_driver = {
  .probe    = beagle_cam_probe,
  .remove   = beagle_cam_remove,
  .driver   = {
    .name = "beagle_cam",
    .pm = &beagle_cam_pm_ops,
  },
};

/**
 * @brief omap3beaglelmb_init - module init function. Should be called before any
 *                          client driver init call
 *
 * @return result of operation - 0 is success
 */
int __init omap3beaglelmb_init(void)
{
  platform_driver_register(&beagle_cam_driver);
  return 0;
}

late_initcall(omap3beaglelmb_init);

include/linux/videodev2.h

Note: Although these #defines are arbitrary, they must match between the file included with the driver and the file included in the application.

// Our own special colorspace goes in a section like this
enum v4l2_colorspace {
  /* ITU-R 601 -- broadcast NTSC/PAL */
  V4L2_COLORSPACE_SMPTE170M     = 1,

  /* 1125-Line (US) HDTV */
  V4L2_COLORSPACE_SMPTE240M     = 2,

  //
  // SEVERAL LINES SKIPPED FOR BREVITY IN THIS EXAMPLE
  //

  /* For RGB colourspaces, this is probably a good start. */
  V4L2_COLORSPACE_SRGB          = 8,

  /* For colourspaces not in the normal range (FSR172X). */
  V4L2_COLORSPACE_FSR172X       = 9,
};


// Our own special pixel format goes in a section like this
/*
 *  V I D E O   I M A G E   F O R M A T
 */

//
// SEVERAL LINES SKIPPED FOR BREVITY IN THIS EXAMPLE
//

/*  Vendor-specific formats   */
#define V4L2_PIX_FMT_WNVA     v4l2_fourcc('W', 'N', 'V', 'A') /* Winnov hw compress */
#define V4L2_PIX_FMT_SN9C10X  v4l2_fourcc('S', '9', '1', '0') /* SN9C10x compression */

//
// SEVERAL LINES SKIPPED FOR BREVITY IN THIS EXAMPLE
//

#define V4L2_PIX_FMT_STV0680  v4l2_fourcc('S', '6', '8', '0') /* stv0680 bayer */
#define V4L2_PIX_FMT_FSR172X  v4l2_fourcc('F', 'S', 'R', '0') /* 12bit raw fsr172x */

include/linux/v4l2-int-device.h

Nothing is changed here, but it's worth noting that we'll be using the predefined RAW mode...

/* Slave interface type. */
enum v4l2_if_type {
  /*
   * Parallel 8-, 10- or 12-bit interface, used by for example
   * on certain image sensors.
   */
  V4L2_IF_TYPE_BT656,
  V4L2_IF_TYPE_YCbCr,
  V4L2_IF_TYPE_RAW,
};

... and its associated struct

struct v4l2_if_type_raw {
  /*
   * 0: Frame begins when vsync is high.
   * 1: Frame begins when vsync changes from low to high.
   */
  unsigned frame_start_on_rising_vs:1;
  /* Use Bt synchronisation codes for sync correction. */
  unsigned bt_sync_correct:1;
  /* Swap every two adjacent image data elements. */
  unsigned swap:1;
  /* Inverted latch clock polarity from slave. */
  unsigned latch_clk_inv:1;
  /* Hs polarity. 0 is active high, 1 active low. */
  unsigned nobt_hs_inv:1;
  /* Vs polarity. 0 is active high, 1 active low. */
  unsigned nobt_vs_inv:1;
  /* Minimum accepted bus clock for slave (in Hz). */
  u32 clock_min;
  /* Maximum accepted bus clock for slave. */
  u32 clock_max;
  /*
   * Current wish of the slave. May only change in response to
   * ioctls that affect image capture.
   */
  u32 clock_curr;
};

If we were to create our own, we would need to modify this v4l2 struct:

struct v4l2_ifparm {
  enum v4l2_if_type if_type;
  union {
    struct v4l2_if_type_bt656 bt656;
    struct v4l2_if_type_ycbcr ycbcr;
    struct v4l2_if_type_raw raw;
  } u;
};

In our driver code we will access these settings as v4l2_ifparm.

arch/arm/mach-omap2/board-overo-camera.c

This board file and its header are the exact same as board-omap3beagle-camera with the exception that every occurrance of beagle has been replaced with overo and every occurance of mt9t111 has been replaced with fsr172x.

Again, we'll just use RAW, but if we had created our own FSR standard, we would need to add to this list:

static struct v4l2_ifparm fsr172x_ifparm_s = {
#if 1
  .if_type = V4L2_IF_TYPE_RAW,
  .u   = {
    .raw = {
      .frame_start_on_rising_vs = 1,
      .bt_sync_correct  = 0,
      .swap     = 0,
      .latch_clk_inv    = 0,
      .nobt_hs_inv    = 0,  /* active high */
      .nobt_vs_inv    = 0,  /* active high */
      .clock_min    = FSR172X_CLK_MIN,
      .clock_max    = FSR172X_CLK_MAX,
    },
  },
#else
  .if_type = V4L2_IF_TYPE_YCbCr,
  // REMOVED FOR BREVITY
  },
#endif
};

scratchspace

Linux Kernel vs TRM

  • omap34xxcam_hw_config.u.sensor.sensor_isp -> ???
  • omap34xxcam_hw_config.wait_hs_vs -> ???
  • isp_interface_config.u.par.par_bridge -> ???
  • omap34xxcam_videodev.cam.isp -> ???
    • v4l2_int_device->u.slave->master->priv -> ???

where stuff is

  • v4l2_ifparm: v4l2-int-device

    • fsr172x.c
    • board-overo-camera.c
  • omap34xxcam_hw_config: omap34xxcam

    • board-overo-camera.c

which v4l2 calls must we implement?

  • ???

what is this mess?

  • regulator_put - part of include/linux/regulator/consumer.h - for future compatibility. Does nothing as of right now. Just a stubbed out API.
  • dev_pm_ops - power management for suspending, resuming, etc
  • omap34xxcam is a master
  • fsr172x is a slave

drivers/media/video/fsr172x.c

// Creating a map between VIDIOC_X_YZ and our internal functions
static struct v4l2_int_ioctl_desc fsr172x_ioctl_desc[] = {
  { .num = vidioc_int_enum_framesizes_num,
    .func = (v4l2_int_ioctl_func *)ioctl_enum_framesizes },
  { .num = vidioc_int_enum_frameintervals_num,
    .func = (v4l2_int_ioctl_func *)ioctl_enum_frameintervals },
  { .num = vidioc_int_dev_init_num,
    .func = (v4l2_int_ioctl_func *)ioctl_dev_init },
  { .num = vidioc_int_dev_exit_num,
    .func = (v4l2_int_ioctl_func *)ioctl_dev_exit },
  { .num = vidioc_int_s_power_num,
    .func = (v4l2_int_ioctl_func *)ioctl_s_power },
  { .num = vidioc_int_g_priv_num,
    .func = (v4l2_int_ioctl_func *)ioctl_g_priv },
  { .num = vidioc_int_g_ifparm_num,
    .func = (v4l2_int_ioctl_func *)ioctl_g_ifparm },
  { .num = vidioc_int_init_num,
    .func = (v4l2_int_ioctl_func *)ioctl_init },
  { .num = vidioc_int_enum_fmt_cap_num,
    .func = (v4l2_int_ioctl_func *)ioctl_enum_fmt_cap },
  { .num = vidioc_int_try_fmt_cap_num,
    .func = (v4l2_int_ioctl_func *)ioctl_try_fmt_cap },
  { .num = vidioc_int_g_fmt_cap_num,
    .func = (v4l2_int_ioctl_func *)ioctl_g_fmt_cap },
  { .num = vidioc_int_s_fmt_cap_num,
    .func = (v4l2_int_ioctl_func *)ioctl_s_fmt_cap },
  { .num = vidioc_int_g_parm_num,
    .func = (v4l2_int_ioctl_func *)ioctl_g_parm },
  { .num = vidioc_int_s_parm_num,
    .func = (v4l2_int_ioctl_func *)ioctl_s_parm },
  { .num = vidioc_int_queryctrl_num,
    .func = (v4l2_int_ioctl_func *)ioctl_queryctrl },
  { .num = vidioc_int_g_ctrl_num,
    .func = (v4l2_int_ioctl_func *)ioctl_g_ctrl },
  { .num = vidioc_int_s_ctrl_num,
    .func = (v4l2_int_ioctl_func *)ioctl_s_ctrl },
  { .num = vidioc_int_s_video_routing_num,
    .func = (v4l2_int_ioctl_func *)ioctl_s_routing },
};


static struct v4l2_int_slave fsr172x_slave = {
  .ioctls = fsr172x_ioctl_desc,
  .num_ioctls = ARRAY_SIZE(fsr172x_ioctl_desc),
};

static struct v4l2_int_device fsr172x_int_device = {
  .module = THIS_MODULE,
  .name = "fsr172x",
  .priv = &fsr172x,
  .type = v4l2_int_type_slave,
  .u = {
    .slave = &fsr172x_slave,
  },
};

Note: Most of the ioctl_x_yz functions refer to V4L2s VIDIOC_X_YZ #defines.

Appendix

  • V4L2_FRMSIZE_TYPE_DISCRETE vs V4L2_FRMSIZE_TYPE_STEPWISE vs V4L2_FRMSIZE_TYPE_CONTINUOUS
    • discrete: finite values that don't change
    • step-wise: ??
    • continuous: ranges from a min to a max by a value of step

omap davinci linux cmem ddralg ddr2 dsplink(View Stand-alone)

Goal

Explain the physical allocation of DSP / ARM memory on the OMAP / DaVinci

Overview

In order to get DSP applications to work, you have to allocate actual physical memory for use by

  • The Operating System (such as the Linux Kernel)
  • CMEM (shared contiguous memory between DSP and ARM)
  • DDRALGHEAP / DDR2 / DSPLink

Pre-req:

You should know the base address of the RAM device. For the OMAP3530, for example, the RAM starts at 0x80000000, which is 2048MB, or 2GB.

The address space for a 32-bit system is up to 0xFFFFFFFF, which is 4096MB, or 4GB.

On a 32-bit desktop system (or a 64-bit system with a 32-bit memory bus) the theoretical limit for memory is 4GB, but in practice 3GB is the limitation, maybe 3.5 if you're lucky. This is due to the fact that RAM isn't the only device on the system. There are many other devices.

In the case of the OMAP3530, it would not be theoretically possible to have more than 1GB of memory since the first 2GB and last 1GB of address space are reserved for other devices. The most RAM on an OMAP3530 kit right now is 512MB. I'm guessing that RAM + NAND is probably the 1GB.

OS Memory

Linux (the ARM OS)

With the default system I believe that 120MB of memory is allocated to linux.

You can find out how much OS memory is currently allocated like so:

free -m
# or
cat /dev/meminfo

Since the kernel takes some memory unto itself, you're likely to see less than what should be physically available.

If you would like to modify this to be another amount, say 160MB you should add the parameter MEM=120M to the u-boot bootargs.

TI's BIOS (the DSP OS)

BIOS refers to TI's B? I? Operating System - similar to Linux or Windows, but without a user interface. It schedules, manages memory, runs applications, and even can use device drivers.

CMEM Memory

TI wiki CMEM Overview

Just like disk fragmentation occurs on a filesystem, memory fragmentation occurs in virtual memory in the heap.

For example, if you allocate 40MB of memory dynamically, the virtual address space will always be contiguous, but the physical address space could potentially be split up into blocks of 20MB, 10MB, and 10MB. As the OS runs for longer periods of time and more apps request and release various memory sizes, the risk of fragmentation becomes greater.

This is introduces latency, as the processor has to spend extra clock cycles switching back and forth between physical memory may be hundreds of megs in address space apart.

CMEM allocates memory which is guaranteed to be contiguous, not fragmented. If you allocate 8MB, you get 8MB of physical memory. Period.

This memory is shared between the DSP and the ARM.

DDRALGOHEAP

TI wiki DDRALGHEAP

This is codec memory, as allocated by BIOS. This should be the size

DDR2

This is BIOS memory.

Setting memory sizes

TODO

These are set in .tcf and .tci files. The TI wiki suggests that you don't need to know the base address - that XDC will calculate that based on the desired size - but I've only made changes by calculating everything myself.

Resources

Pixhawk Memory Map Tutorial TI wiki DDRALGHEAP TI wiki CMEM Overview UUG Phsyical vs Virtual Memory allocation and fragmentation LWN Avoiding - and fixing - memory fragmentation

appendix - mailing list discussion

On the OMAP3530 each core runs it's own OS.

The ARM runs Linux.

The DSP runs a special TI OS with the horrible name BIOS (also called DSPBIOS). I think TIOS would have been about 1000x better, to avoid confusion for people skimming the documentation for the first (or second, or third) time.

There is a special boot loader, u-boot, which tells Linux how much physical memory it is allowed to use. The rest of the memory is split between CMEM and BIOS (and or unallocated).

The kernel module cmem.ko accesses physical memory, past the size that Linux is aware of, by its physical address with a given size at module load time.

To allocate the memory in the CMEM area, I include TI's cmem C library and use their own alloc_contig function, which then gives direct access to physical memory which is guaranteed to be physically contiguous.

Another kernel module, dsplink.ko allows communication between the two OSes. For example, I contig_alloc() on the Linux side, but then pass that address to the DSP side so that BIOS knows that both the dsp algorithm and the arm application have shared access to this memory.

Otherwise, BIOS would only know about the memory that it has been allocated with (which is setup in special TI makefile-thing for DSP executables).

BIOS also uses malloc(), but it has the caveat that in their flavor of C, any memory allocation must be done before any executable statement.

refactor with bash(View Stand-alone)

Goal

Recursively replaces all occurances of <old-string> with <new-string> in <file-or-dir>.

The real magic

find ./ -type f | grep -v '.svn' | xargs sed -i "s/\<${OLD}\>/${NEW}/g"

Note that only whole strings are replaced thanks to \< and \>:

A nice text file which isn't tex.

refactor.sh tex md myfile

A nice text file which isn't md.

refactor.sh

!/bin/bash

OLD=${1}
NEW=${2}
TARGET=${3}

if [ ! -n "${TARGET}" ]
then
    echo "USAGE: ${0} <old-string> <new-string> <file-or-directory>"
    exit 1
fi

OLD=`echo "${OLD}" | sed 's/\\./\\\\./g'`
NEW=`echo "${NEW}" | sed 's/\\./\\\\./g'`

if [ ! -f "${TARGET}" ]
then
    cd "${TARGET}"
    find ./ -type f | grep -v '.svn' | xargs sed -i "s/\<${OLD}\>/${NEW}/g"
else
    sed -i "s/\<${OLD}\>/${NEW}/gi" "${TARGET}"
fi

pruning the dvsdk examples(View Stand-alone)

Goal

Get down to a bite-size chunk of TI examples from the myriad of examples present.

Procedure

Compiling the TI examples outside of ~/dvsdk

See the my prior post "OMAP DVSDK on OpenEmbedded" in the dvsdk category for getting working the EVM examples working on the Gumstix Overo.

cp -a ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/ ~/ti-examples
cd ~/ti-examples
vim xdcpaths.mak

Here's an example using the changes I made:

diff --git examples/xdcpaths.mak examples-pruned/xdcpaths.mak
index 38b5fac..9eb3a8c 100644
--- examples/xdcpaths.mak
+++ examples-pruned/xdcpaths.mak
@@ -1,4 +1,4 @@
-#
+
 #  Copyright (c) 2010, Texas Instruments Incorporated
 #  All rights reserved.
 #
@@ -58,7 +58,7 @@
 # indicating an "ARM-only codec" application.  The CE example Servers cannot be
 # built for DM357, and since setting PROGRAMS to APP_CLIENT introduces a
 # dependency on the Server, we can't support APP_CLIENT on DM357.
-DEVICES  := DM6446 DM6467 DM6437 DM355 DM365 OMAP2530 OMAP3530 OMAPL137 OMAPL138 X86
+DEVICES  := OMAP3530 X86

 # (Optional) remove from this list the GPP OS's you're not interested in
 # building.  In most cases, you'll likely only leave one, as WinCE users don't
@@ -66,7 +66,7 @@ DEVICES  := DM6446 DM6467 DM6437 DM355 DM365 OMAP2530 OMAP3530 OMAPL137 OMAPL138
 # GCC or uClibc, but not both)
 #
 # Note, this is a space-delimited list.
-GPPOS := LINUX_GCC LINUX_UCLIBC WINCE
+GPPOS := LINUX_GCC

 # (Optional) Remove from the list the types of programs you're not
 # interested in building:
@@ -76,7 +76,7 @@ GPPOS := LINUX_GCC LINUX_UCLIBC WINCE
 # APP_LOCAL  -- Client+codecs in a single program, whether ARM only or DSP only
 #
 # Note, this is a space-delimited list.
-PROGRAMS := APP_CLIENT DSP_SERVER APP_LOCAL
+PROGRAMS := APP_CLIENT DSP_SERVER

 # (Mandatory) Specify where various components are installed.
 # What you need depends on what device(s) you're building for, what type(s) of
@@ -97,10 +97,12 @@ PROGRAMS := APP_CLIENT DSP_SERVER APP_LOCAL
 # need (will be warned if you do, based on your DEVICES + PROGRAMS selection
 # above).
- 
-CE_INSTALL_DIR        := _your_CE_installation_directory_/codec_engine_2_25_02_11
-XDC_INSTALL_DIR       := _your_XDCTOOLS_installation_directory/xdctools_3_16_00_18
-BIOS_INSTALL_DIR      := _your_SABIOS_installation_directory/bios_5_41_00_06
-DSPLINK_INSTALL_DIR   := _your_DSPLink_installation_directory/dsplink-1_61_03-prebuilt
+
+DVSDK_INSTALL_DIR     := $(HOME)/dvsdk/dvsdk_3_01_00_10
+
+CE_INSTALL_DIR        := $(DVSDK_INSTALL_DIR)/codec_engine_2_25_02_11
+XDC_INSTALL_DIR       := $(DVSDK_INSTALL_DIR)/xdctools_3_16_00_18
+BIOS_INSTALL_DIR      := $(DVSDK_INSTALL_DIR)/bios_5_41_00_06
+DSPLINK_INSTALL_DIR   := $(DVSDK_INSTALL_DIR)/dsplink_linux_1_65_00_02/packages

 # no need to specify the installation directories below if your CE installation
 # has cetools/ directory on top
@@ -108,13 +110,13 @@ DSPLINK_INSTALL_DIR   := _your_DSPLink_installation_directory/dsplink-1_61_03-pr
 # Note, CMEM_INSTALL_DIR is a misnomer - it should be LINUXUTILS_INSTALL_DIR
 # but we've got an existing user base.  Need to fix this later.
 USE_CETOOLS_IF_EXISTS := 1
-XDAIS_INSTALL_DIR     := _your_xDAIS_installation_directory/xdais_6_25_02_11
-FC_INSTALL_DIR        := _your_FC_installation_directory/framework_components_2_25_01_05
-CMEM_INSTALL_DIR      := _your_CMEM_installation_directory/linuxutils_2_25_02_08
-WINCEUTILS_INSTALL_DIR:= _your_WINCEUTILS_installation_directory/winceutils_1_00_03_13
-BIOSUTILS_INSTALL_DIR := _your_BIOSUTILS_installation_directory/biosutils_1_02_02
-EDMA3_LLD_INSTALL_DIR := _your_EDMA3_LLD_installation_directory/edma3_lld_01_11_00_02
-LPM_INSTALL_DIR       := _your_LPM_installation_directory/local_power_manager_1_24_02_09
+XDAIS_INSTALL_DIR     := $(DVSDK_INSTALL_DIR)/xdais_6_25_02_11
+FC_INSTALL_DIR        := $(DVSDK_INSTALL_DIR)/framework_components_2_25_01_05
+CMEM_INSTALL_DIR      := $(DVSDK_INSTALL_DIR)/linuxutils_2_25_02_08
+WINCEUTILS_INSTALL_DIR:= $(DVSDK_INSTALL_DIR)/winceutils_1_00_03_13
+BIOSUTILS_INSTALL_DIR := $(DVSDK_INSTALL_DIR)/biosutils_1_02_02
+EDMA3_LLD_INSTALL_DIR := $(DVSDK_INSTALL_DIR)/edma3_lld_01_11_00_02
+LPM_INSTALL_DIR       := $(DVSDK_INSTALL_DIR)/local_power_manager_1_24_02_09


 # (Mandatory) specify correct compiler paths and names for the architectures
@@ -122,9 +124,10 @@ LPM_INSTALL_DIR       := _your_LPM_installation_directory/local_power_manager_1_

 # compiler path and name for Montavista Arm 9 toolchain. NOTE: make sure the
 # directory you specify has a "bin" subdirectory
-CGTOOLS_V5T := /db/toolsrc/library/tools/vendors/cs/arm/arm-2007q3
-CC_V5T := bin/arm-none-linux-gnueabi-gcc
-CGTARGET := gnu.targets.arm.GCArmv5T
+CGTOOLS_V5T := $(HOME)/overo-oe/tmp/cross/armv7a
+CC_V5T := bin/arm-angstrom-linux-gnueabi-gcc
+CGTARGET := gnu.targets.arm.GCArmv5T
+# TODO can we use GCArmv7A?

 # compiler path and name for uClibc toolchain. NOTE: make sure the
 # directory you specify has a "bin" subdirectory
@@ -137,17 +140,17 @@ WINCE_PROJECTROOT := $(WINCE_ROOTDIR)/_your_ProjectRoot_/Wince600/TI_EVM_3530_AR

 # compiler path and name for TI C64x toolchain. NOTE: make sure the
 # directory you specify has a "bin" subdirectory
-CGTOOLS_C64P := /db/toolsrc/library/tools/vendors/ti/c6x/6.0.16/Linux
+CGTOOLS_C64P := /opt/TI/C6000CGT6.1.12
 #CC_C64P      := bin/cl6x

 # compiler path and name for TI C674 toolchain. NOTE: make sure the
 # directory you specify has a "bin" subdirectory
-CGTOOLS_C674 := /db/toolsrc/library/tools/vendors/ti/c6x/6.1.5/Linux
+CGTOOLS_C674 := /opt/TI/C6000CGT6.1.12
 #CC_C674      := bin/cl6x

 # compiler path and name for Linux 86 toolchain. NOTE: make sure the
 # directory you specify has a "bin" subdirectory
-CGTOOLS_LINUX86 := _your_Linux86_installation_directory
+CGTOOLS_LINUX86 := /usr
 #CC_LINUX86   := bin/gcc

 # -----------------------------------------------------------------------------

I tested that I could make clean && make and it worked. Amazaing!

Compiling fewer of the TI examples

cp -a ~/ti-examples ~/ti-examples-pruned
vim ~/ti-examples-pruned/makefile

The interesting parts of the top-level examples folder are buried 4 levels deep.

  • ./ti/sdo/ce/examples
    • apps
    • codecs
    • servers

I decided (rather arbitrarily) that I'm just interested in video_copy and all_codecs_new_config, so I deleted everything not related and kept making adjustments to makefiles, package.xdcs, and all_codecs_new_config/all.cfg until it compiled.

I also got rid of

  • all of the platforms in ./apps/video_copy/configuro/ and .tcis excepting the evm3530, which is closest to the gumstix.
  • all of the package folders

I may go back and try to get audio_copy and server_api_example as well.

Creating my own package

After trimming the fat from the file system I decided to lighten the directory structure as well and work towards getting my own project built.

mkdir -p ./faster-examples
cp -a ti-examples-pruned/ti/sdo/ce/examples/ ./fastr-examples/fastr_ce
cp ti-examples-pruned/makefile ./fastr-examples/
cp ti-examples-pruned/xdcpaths.mak ./fastr-examples/
cp ti-examples-pruned/config.bld ./fastr-examples/
cp ti-examples-pruned/buildutils/xdcrules.mak ./fastr-examples-extracted/buildutils/
OLD='ti.sdo.ce.examples'
NEW='fastr_ce'
find ./ -type f | grep -v '.svn' | xargs sed -i "s/${OLD}/${NEW}/gi"

And I made a makefile for the top-level:

./faster-examples/makefile

all:
%::
  $(MAKE) -C fastr_ce $@

./faster-examples/makefile

all:
%::
  $(MAKE) -C codecs $@
  $(MAKE) -C servers $@
  $(MAKE) -C apps $@

Again, I had to muck around a bit with the makefiles - particularly having the right number of parent paths ../../...

Creating my own Codec Engine app

cd ~/fastr-examples
OLD='all_codecs_new_config'
NEW='fsr_codecs'
find ./ -type f | grep -v '.svn' | xargs sed -i "s/${OLD}/${NEW}/gi"
mv fastr_ce/all_codecs_new_config fastr_ce/fsr_codecs

cd ~/fastr-examples
OLD='all_codecs_new_config'
NEW='fastr_codecs'
find ./ -type f | grep -v '.svn' | xargs sed -i "s/${OLD}/${NEW}/gi"
cd ~/fastr-examples/fastr_ce/apps
mv videnc_copy fodec

vim makefile # add `fodec` - the fastr codec

cross compiling node.js for arm(View Stand-alone)

Goal

Quickly build nodejs for an ARM target system using a pre-built toolchain. The first part of these instructions should apply to most cross-compiling situations.

Cross-compiling

You'll need a prebuilt toolchain. I'm going to suggest CodeSourcery because TI uses them. The caveat is that their versions of libc and such may not fit well with your linux-arm distribution.

CodeSourcery arm-none-linux-gnueabi- Toolchain

After downloading:

mkdir /opt/code-sourcery/
tar xf arm-2009q1-203-arm-none-linux-gnueabi-i686-pc-linux-gnu.tar.bz2 -C /opt/code-sourcery/

Set Environment

Copied from OpenEmbedded and modified for CodeSourcery. This can probably still be pruned a little bit, but it's good enough for now for me.

Sometimes this exits right away. I don't know why. Running it again seems to solve the problem.

cross-compiler-shell.sh

#!/bin/sh -e
export CSTOOLS=/opt/code-sourcery/arm-2009q1
export CSTOOLS_INC=${CSTOOLS}/arm-none-linux-gnueabi/libc/usr/include
export CSTOOLS_LIB=${CSTOOLS}/arm-none-linux-gnueabi/libc/usr/lib
export TARGET_ARCH="-march=armv7-a" # must be at least armv5te
export TARGET_TUNE="-mtune=cortex-a8 -mfpu=neon -mfloat-abi=softfp -mthumb-interwork -mno-thumb" # optional

export CPP="arm-none-linux-gnueabi-gcc -E"
export STRIP="arm-none-linux-gnueabi-strip"
export OBJCOPY="arm-none-linux-gnueabi-objcopy"
export AR="arm-none-linux-gnueabi-ar"
export F77="arm-none-linux-gnueabi-g77 ${TARGET_ARCH} ${TARGET_TUNE}"
unset LIBC
export RANLIB="arm-none-linux-gnueabi-ranlib"
export LD="arm-none-linux-gnueabi-ld"
export LDFLAGS="-L${CSTOOLS_LIB} -Wl,-rpath-link,${CSTOOLS_LIB} -Wl,-O1 -Wl,--hash-style=gnu"
export MAKE="make"
export CXXFLAGS="-isystem${CSTOOLS_INC} -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3 -fpermissive -fvisibility-inlines-hidden"
export LANG="en_US.UTF-8"
export HOME="/home/peru"
export CCLD="arm-none-linux-gnueabi-gcc ${TARGET_ARCH} ${TARGET_TUNE}"
export PATH="${CSTOOLS}/bin:/opt/code-sourcery/arm-2009q1/bin/:${HOME}/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"
export CFLAGS="-isystem${CSTOOLS_INC} -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3"
export OBJDUMP="arm-none-linux-gnueabi-objdump"
export CPPFLAGS="-isystem${CSTOOLS_INC}"
export CC="arm-none-linux-gnueabi-gcc ${TARGET_ARCH} ${TARGET_TUNE}"
export TITOOLSDIR="/mnt/data/overo-oe/ti"
export TERM="screen"
export SHELL="/bin/bash"
export CXX="arm-none-linux-gnueabi-g++ ${TARGET_ARCH} ${TARGET_TUNE}"
export NM="arm-none-linux-gnueabi-nm"
export AS="arm-none-linux-gnueabi-as"

bash --norc

Patch node.js for cross-compilation

mkdir ~/src
cd ~/src
wget http://nodejs.org/dist/node-v0.1.104.tar.gz
tar xf node*
cd node*
cp deps/libev/wscript deps/libev/wscript.orig
cp wscript wscript.orig

Patch libev/wscript

--- a/deps/libev/wscript
+++ b/deps/libev/wscript
@@ -41,6 +41,7 @@ def configure(conf):
     conf.check_cc(header_name="sys/eventfd.h", function_name="eventfd")


+  ''' Can't run cross-binary code
   code = """
       #include <syscall.h>
       #include <time.h>
@@ -54,6 +55,8 @@ def configure(conf):
   """
   conf.check_cc(fragment=code, define_name="HAVE_CLOCK_SYSCALL", execute=True,
                 msg="Checking for SYS_clock_gettime")
+  '''
+  conf.define('HAVE_CLOCK_SYSCALL', 1)

   have_librt = conf.check(lib='rt', uselib_store='RT')
   if have_librt:


vim wscript

--- a/wscript
+++ b/wscript
@@ -319,11 +319,15 @@ def v8_cmd(bld, variant):
   if bld.env['DEST_CPU'] == 'x86_64':
     arch = "arch=x64"

+ cross_arch = False
+ # TODO would use -1 != str.find('linux-gnueabi'), but this is sometimes a string and other times an array
+ # if bld.env['AR'] == 'arm-angstrom-linux-gnueabi-ar':
+ #   arch = "arch=arm"
+ #   cross_arch = True
+ # 
+ arch = "arch=arm"
+ cross_arch = True

   if variant == "default":
     mode = "release"
   else:
     mode = "debug"

+  snapshot = 'snapshot=on'
+  if cross_arch:
+    snapshot = ''
-  cmd_R = 'python "%s" -j %d -C "%s" -Y "%s" visibility=default mode=%s %s library=static snapshot=on'
+  cmd_R = 'python "%s" -j %d -C "%s" -Y "%s" visibility=default mode=%s %s library=static ' + snapshot

Cross-compile nodejs

cd ~/src/node*
~/cross-compiler-shell.sh
# prompt changes to a boring one without color
./configure --without-ssl # the codesourcery toolchain doesn't include openssl, but node mistakenly detected it
# Note you should see `arm-none-linux-gnueabi-gcc` instead of `gcc`
make

Installing OMAP DVSDK on Gumstix Overo(View Stand-alone)

Goal

Get the TI demos running on the gumstix.

OMAP & DaVinci Software for Dummies might be worth reading...

TI's DVSDK & EVM packages

According to TI's Getting Started Guide: OMAP35x DVEVM Software Setup, you'll need the following packages:

For the sake of getting started things, I recommend trying the TI way first. From those packages, we won't actually use codesourcery_tools since gumstix provides gcc-cross, which fulfills the same function.

You'll may also want dsplib64plus, dsplib64plus.h, dsplib64plus.lib

  • C64x+ DSP Library (DSPLIB) (direct link) local
    • C64x+DSPLIB-2.1-Linux-Install.bin is packaged incorrectly as sprc834.gz when it should be sprc834.tgz or sprc834.tar.gz... or C64x+DSPLIB-2.1-Linux-Install.tar.gz would have been best.
    • I don't know how you can actually include this library in a project. I posted to the TI forum about it... awaiting reply.

Installing

Unpacking

You'll need to unpackage the downloads in specific locations and also unpackage some of the sub-packages. Assuming that you've downloaded all of the above into ~/Downloads:

cd ~/Downloads

./dvsdk_3_01_00_10_Setup.bin # installs to ~/dvsdk

./cs1omap3530_setupLinux_1_01_00-prebuilt-dvsdk3.01.00.10.bin # Installs to ~/cs1omap3530
ln -s ~/cs1omap3530/cs1omap3530_1_01_00 ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00
sudo ./ti_cgt_c6000_6.1.12_setup_linux_x86.bin # Installs to /opt/TI/C6000CGT6.1.12
export C6X_C_DIR=/opt/TI/C6000CGT6.1.12/include:/opt/TI/C6000CGT6.1.12/lib
echo "export C6X_C_DIR=/opt/TI/C6000CGT6.1.12/include:/opt/TI/C6000CGT6.1.12/lib" >> ~/.bashrc

tar xf data_dvsdk_3_01_00_10.tar.gz -C ~/dvsdk/dvsdk_3_01_00_10/clips/

tar xf AM35x-OMAP35x-PSP-SDK-03.00.01.06.tar.gz -C ~/
cd ~/AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/kernel/
tar xf linux-03.00.01.06.tar.gz
cd ~/AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/u-boot/
tar xf u-boot-03.00.01.06.tar.gz
cd ~/AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/examples
tar xf examples.tar.gz

mv sprc834.gz sprc834.tar.gz
tar xf sprc834.tar.gz
./C64x+DSPLIB-2.1-Linux-Install.bin # Installs to ~/C64x+DSPLIB
sed -i 's,\\,/,g' ~/C64x+DSPLIB/dsplib_v210/dsplib64plus.h # convert from windows `\` to normal `/`
cp ~/C64x+DSPLIB/dsplib_v210/dsplib64plus.h /opt/TI/C6000CGT6.1.12/include/
cp -a ~/C64x+DSPLIB/dsplib_v210/src /opt/TI/C6000CGT6.1.12/include/
cp ~/C64x+DSPLIB/dsplib_v210/dsplib64plus.lib /opt/TI/C6000CGT6.1.12/lib/

Now that everything is installed you must configure ~/dvsdk/dvsdk_3_01_00_10/Rules.make. Here's an example of what the values that should probably be chaged:

* `DVSDK_INSTALL_DIR=$(HOME)/dvsdk/dvsdk_3_01_00_10`
* `CODEGEN_INSTALL_DIR=/opt/TI/C6000CGT6.1.12`
* `OMAP3503_SDK_INSTALL_DIR=$(HOME)/AM35x-OMAP35x-PSP-SDK-03.00.01.06`
* `CSTOOL_DIR=${OVEROTOP}/tmp/sysroots/i686-linux/usr/armv7a`
* `CSTOOL_PREFIX=$(CSTOOL_DIR)/bin/arm-angstrom-linux-gnueabi-`

Because some of the packages don't respect CSTOOL_PREFIX as they ought, also link the OpenEmbedded toolchain to arm-none-linux-gnueabi-

cd ${OVEROTOP}/tmp/sysroots/i686-linux/usr/armv7a/bin
ls | cut -d'-' -f5-99 | while read COMP
do
  ln -s arm-angstrom-linux-gnueabi-${COMP} arm-none-linux-gnueabi-${COMP} 
done

To test that everything is installed correctly, try to compile all of the TI packages (probably takes 30 min+).

cd ~/dvsdk/dvsdk_3_01_00_10
make help
make clobber # super clean
make everything
make

Using the overo-patched TI PSP Kernel

Now that everything is installed correctly enough to compile the vanilla TI demos, let's get the overo psp kernel

Get linux-omap-psp (or any omap-psp based-branch of the kernel) downloaded and patched for the overo.

cd ${OVEROTOP}
bitbake -c configure linux-omap-psp # Downloads and patches `git_arago-project.org.git.people.sriram.ti-psp-omap.git_a6bad4464f985fdd3bed72e1b82dcbfc004d7869.tar.gz`
ls ${OVEROTOP}/tmp/work/overo-angstrom-linux-gnueabi/linux-omap-psp-2.6.32-r81+gitra6bad4464f985fdd3bed72e1b82dcbfc004d7869/git

Right now /AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/kernel/linux-03.00.01.06 is being used as the kernel dir in Rules.make. Change that to the desired kernel.

echo ${OVEROTOP}/tmp/work/overo-angstrom-linux-gnueabi/linux-omap-psp-2.6.32-r81+gitra6bad4464f985fdd3bed72e1b82dcbfc004d7869/git
cd ~/dvsdk/dvsdk_3_01_00_10/
vim Rules.make
#LINUXKERNEL_INSTALL_DIR=$(HOME)/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/linux-omap-psp-2.6.32-r81+gitra6bad4464f985fdd3bed72e1b82dcbfc004d7869/git

Also, the Makefile is configured to build with the omap3_evm_defconfig, but we want the overo_defconfig

cd ~/dvsdk/dvsdk_3_01_00_10/
vim Makefile
# edit near "ifeq ($(PLATFORM),omap3530)"
# LINUXKERNEL_CONFIG=overo_defconfig

And try to compile the kernel now

make linux_clean
make linux

And now everything

make clobber
make everything

And lastly, copy some of the demo files out to ~/workdir/filesystem

make install

Running the demos

TI's Build/Run Instructions for Codec Engine Examples

Configure u-boot

The example loadscript for OMAP3530 assumes 80mb of OS memory, so that's what we'll set.

  1. reboot the overo
  2. press the 'any' key to enter u-boot
  3. set it to boot with only 80mb allocated for the OS
    • setenv mmcargs ${mmcargs} MEM=80M mem=80M
    • saveenv
    • run mmcboot

Copy the dvsdk examples to the overo

  • scp -r ~/workdir/filesys/opt GUMSTIX_IP:/
  • Create a hybrid loadmodules.sh that will load all of the modules
    • ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/apps/system_files/OMAP3530/loadmodules.sh
    • ~/workdir/filesys/opt/dvsdk/omap3530/loadmodules.sh
  • ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/ti/sdo/ce/examples/

    • servers/all_codecs/bin/ti_platforms_evm3530/all.x64P
    • apps/video_copy/bin/ti_platforms_evm3530/app_remote.xv5T
    • apps/video_copy/bin/ti_platforms_evm3530/app_local.xv5T
    • apps/video_copy/in.dat
  • run cd /opt/dvsdk/omap3530

  • Create a new file loadmodules.works.sh
  • Copy the insmod cmemk.ko and settings from the one in ce examples
  • Copy the other insmod MODULE.ko settings from the one in workdir
  • run app_local.xv5T - works, but may not use ARM
  • run app_remote.xv5T - doesn't work yet for me

Modifying the examples

  • ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/xdcpaths.mak

Appendix: Examining the TI Packages

dvsdk v3 (dvsdk_3_01_00_10_Setup.bin & data_dvsdk_3_01_00_10.tar.gz)

Unpacking:

  1. run ./dvsdk_3_01_00_10_Setup.bin and unpack as ~/dvsdk
  2. run tar xf data_dvsdk_3_01_00_10.tar.gz -C ~/dvsdk/dvsdk_3_01_00_10/clips
  3. run ls ~/dvsdk/dvsdk_3_01_00_10 to see that the results are as expected

This package contains these other packages:

  • bios_5_41_00_06
  • biosutils_1_02_02
  • ceutils_1_06
  • cg_xml_v2_12_00
  • codec_engine_2_25_02_11
  • dmai_2_05_00_12
  • dsplink_linux_1_65_00_02
  • dvsdk_demos_3_01_00_13
  • dvtb_4_20_05
  • edma3_lld_01_11_00_03
  • framework_components_2_25_01_05
  • linuxlibs_3_01
  • linuxutils_2_25_02_08
  • local_power_manager_linux_1_24_02_09
  • xdais_6_25_02_11
  • xdctools_3_16_01_27

It also contains these directories:

  • bin - check.sh info.sh
  • clips - the data files are in the package data_dvsdk_3_01_00_10.tar.gz
  • docs - lies, all lies (there aren't any docs there)
  • examples - has an example loadmodules.sh
  • kernel_binaries - pre-built binaries for the provided kernel
  • targetfs - for building with rootfs

And these files:

  • dvsdk_3_01_00_10_releasenotes.pdf
  • Makefile - make help to find out
  • Rules.make - edit this file to match your configuration. Example:
    • DVSDK_INSTALL_DIR=$(HOME)/dvsdk/dvsdk_3_01_00_10
    • CODEGEN_INSTALL_DIR=/opt/TI/C6000CGT6.1.12
    • OMAP3503_SDK_INSTALL_DIR=$(HOME)/AM35x-OMAP35x-PSP-SDK-03.00.01.06
    • CSTOOL_DIR=${OVEROTOP}/tmp/sysroots/i686-linux/usr/armv7a
    • CSTOOL_PREFIX=$(CSTOOL_DIR)/bin/arm-angstrom-linux-gnueabi-
  • uninstall

cs1omap3530 v1 (cs1omap3530_setupLinux_1_01_00-prebuilt-dvsdk3.01.00.10.bin)

Unpacking:

  1. run ./cs1omap3530_setupLinux_1_01_00-prebuilt-dvsdk3.01.00.10.bin and unpack to ~/cs1omap3530/
  2. run mv ~/cs1omap3530/cs1omap3530_1_01_00 ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00
  3. run ls ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00 to see that the results are as expected

This package contains an example codec server

  • ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00/
    • config.bld
    • cs1omap3530_release_notes.htm
    • csRules.mak
    • Makefile
  • ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00/packages/ti/sdo/codecs/
    • aachedec
    • deinterlacer
    • g711dec
    • g711enc
    • h264dec
    • h264enc
    • jpegdec
    • jpegenc
    • mpeg2dec
    • mpeg4dec
    • mpeg4enc
  • ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00/packages/ti/sdo/server/cs/
    • bin
    • codec.cfg
    • docs
    • link.cmd
    • main.c
    • package
    • package.bld
    • package.mak
    • package.xdc
    • package.xs
    • server.cfg
    • server.tcf

TI-C6x-CGT v6

Unpacking:

  1. run ./TI-C6x-CGT-v6.1.12.bin and unpack as /opt/TI/C6000CGT6.1.12
  2. run ls /opt/TI/C6000CGT6.1.12 to see that the results are as expected

This package contains the DSP Toolchain: C6000 CodeGen Tools

  • bin - abs6x, ap6x, asm6x, ci6x, clist6x, dem6x, embed6x, ilk6x, lnk6x, load6xexe, nm6x, opt6x, pprof6x, strip6x, acp6x, ar6x, cg6x, cl6x, cmp6x, dis6x, hex6x, libinfo6x, load6x, mk6x, ofd6x, pdd6x, spkc6x.dll, xref6x
  • DefectHistory.txt
  • include - access.h, cctype, cpp_inline_math.h, cstring, fastmath67x.h, hash_map, iostream.h, linkage.h, mathl.h, rope, stddef.h, string, valarray, xiosbase, xmemory algorithm, cerrno, cpy_tbl.h, ctime, file.h, hash_set, isfuncdcl.h, list, memory, set, stdexcept, string.h, vector, xlocale, xstddef assert.h, cfloat, csetjmp, ctype.h, float.h, inttypes.h, isfuncdef.h, locale, new, setjmp.h, stdint.h, strstream, wchar.h, xlocinfo, xstring bitset, ciso646, csignal, cwchar, fmt_specifier.h, iomanip, iso646.h, locale.h, new.h, signal.h, stdio.h, strstream.h, wchar.hx, xlocinfo.h, xtree c60asm.i, climits, cstdarg, cwctype, fstream, iomanip.h, istream, lock.h, numeric, slist, stdiostream.h, time.h, wctype.h, xlocmes, xutility c6x.h, clocale, cstddef, deque, fstream.h, ios, iterator, map, ostream, sstream, stdlib.h, typeinfo, xcomplex, xlocmon, xwcc.h cargs.h, cmath, cstdio, errno.h, functional, iosfwd, limits, mathf.h, pprof.h, stack, stl.h, unaccess.h, xdebug, xlocnum, ymath.h cassert, complex, cstdlib, exception, gsm.h, iostream, limits.h, math.h, queue, stdarg.h, streambuf, utility, xhash, xloctime, yvals.h
  • lib - fastmath67xe.lib, libc.a, rts6200_eh.lib, rts6400e_eh.lib, rts6400.lib, rts64pluse.lib, rts6700_eh.lib, rts6740e_eh.lib, rts6740.lib, rts67pluse.lib, fastmath67x.lib, lnk.cmd, rts6200e.lib, rts6400_eh.lib, rts64pluse_eh.lib, rts64plus.lib, rts6700e.lib, rts6740_eh.lib, rts67pluse_eh.lib, rts67plus.lib, fastmath67x.src, rts6200e_eh.lib, rts6200.lib, rts6400e.lib, rts64plus_eh.lib, rts6700e_eh.lib, rts6700.lib, rts6740e.lib, rts67plus_eh.lib, rtssrc.zip
  • LINKER_README.txt
  • man
  • README.txt
  • uninstall_cgt_c6000.bin

Scratchpad (unorganized, unfinished)

bitbake -c clean linux-omap-psp
bitbake -c clean ti-dsplink
bitbake -c clean ti-linuxutils
bitbake -c clean ti-dvsdk-demos

bitbake linux-omap-psp # Downloads `git_arago-project.org.git.people.sriram.ti-psp-omap.git_a6bad4464f985fdd3bed72e1b82dcbfc004d7869.tar.gz`
bitbake ti-dsplink # Downloads `dsplink_linux_1_65_00_02.tar.gz`
bitbake ti-linuxutils # Downloads `linuxutils_2_25_01_06.tar.gz`
bitbake ti-dvsdk-demos

You should be able to build the kernel just fine, but you'll need extra files from TI. I'm not sure which all of these are needed, but here are some links to files that will prove useful.

Building DVSDK

What we don't need

  • MLO, boot_lcd.scr, boot_dvi.scr, sdimage_dvsdk_3_01_00_10.tar.gz - These are specific for the DVEVM board.

linux-omap-psp

This should build without issue.

If you get confused as to which of the lovely files in ~/overo-oe/tmp/deploy/glibc/images/ is the kerenl you're looking for, try ls -t which will list the most recenly built kernels first.

without bitbake

http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=46&Itemid=54

bitbake -c configure linux-omap-psp
cd todo some directory
make menuconfig

no, really without bitbake

Grab the kernel source straight from the TI guy:

git clone git://arago-project.org/git/people/sriram/ti-psp-omap.git;protocol=git;branch=master

Set up a minimal set of env build variables

kernel.env:

CROSS_DIR=~/overo-oe/tmp/sysroots/i686-linux/usr/armv7a/bin
CROSS_PREFIX=arm-angstrom-linux-gnueabi-
export ARCH=arm
export CROSS_COMPILE=${CROSS_DIR}/${CROSS_PREFIX}

Configure the kernel

source kernel.env
make overo_defconfig
make menuconfig

kernel-dev.env:

if [[ -z "${KERNEL_CROSS_BUILD_ENVIRONMENT_SOURCED}" ]]; then

  # should work for MACHINE=beagleboard also, you will have to set OETMP correctly
  MACHINE=overo

  # Set OETMP to be your OE config TMPDIR. This is a configurable param for OE. 

  # For gumstix setups, look in ${OVEROTOP}/build/conf/site.conf
  # This is the gumstix default.
  OETMP=${OVEROTOP}/tmp

  # For beagleboard setups, look in ${OETREE}/build/conf/local.conf
  # This is the beagleboard default.
  # OETMP=${OETREE}/tmp

  SYSROOTSDIR=${OETMP}/sysroots
  STAGEDIR=${SYSROOTSDIR}/`uname -m`-linux
  CROSSBINDIR=${OETMP}/sysroots/i686-linux/usr/armv7a/bin

  export KERNELDIR=${SYSROOTSDIR}/${MACHINE}-angstrom-linux-gnueabi/kernel

  PATH=${STAGEDIR}/bin:${PATH}
  PATH=${STAGEDIR}/sbin:${PATH}
  PATH=${CROSSBINDIR}:${PATH}
  PATH=${STAGEDIR}/usr/bin:${PATH}
  PATH=${STAGEDIR}/usr/sbin:${PATH}
  PATH=${STAGEDIR}/usr/bin/armv7a-angstrom-linux-gnueabi:${PATH}

  unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE

  export ARCH="arm"
  export CROSS_COMPILE="arm-angstrom-linux-gnueabi-"
  export CC="arm-angstrom-linux-gnueabi-gcc"
  export LD="arm-angstrom-linux-gnueabi-ld"
  export KERNEL_CROSS_BUILD_ENVIRONMENT_SOURCED="true"

  echo "Altered environment for cross building kernel/u-boot with OE tools."
else
  echo "Cross build environment already configured."
fi

To include that in the environment:

source kernel-dev.env
make overo_defconfig
make menuconfig

ti-linuxutils

cmemk.ko

insmod /lib/modules/2.6.32/kernel/drivers/dsp/cmemk.ko 
CMEMK module: built on Jul 26 2010 at 17:53:26
  Reference Linux version 2.6.32
  File /home/user/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
no physical memory specified, continuing with no memory allocation capability...
cmemk initialized
rmmod cmemk.ko

Child Packages

A helpful FYI: Those two packages (ti-linuxutils, ti-dsplink) contain all of these:

./tmp/deploy/glibc/ipk/overo/
  kernel-firmware-ti-3410_2.6.33-r80.5_overo.ipk
  kernel-firmware-ti-5052_2.6.33-r80.5_overo.ipk
  kernel-module-ti-usb-3410-5052_2.6.33-r80.5_overo.ipk
  ti-biosutils-dbg_1_02_02-r1.5_overo.ipk
  ti-biosutils-dev_1_02_02-r1.5_overo.ipk
  ti-biosutils-sourcetree_1_02_02-r1.5_overo.ipk
  ti-biosutils_1_02_02-r1.5_overo.ipk
  ti-cgt6x-dbg_6_1_9-r4.5_overo.ipk
  ti-cgt6x-dev_6_1_9-r4.5_overo.ipk
  ti-cgt6x-sourcetree_6_1_9-r4.5_overo.ipk
  ti-cgt6x_6_1_9-r4.5_overo.ipk
  ti-codec-engine-dbg_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine-dev_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine-examples_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine-sourcetree_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine_2_25_01_06-r5.5_overo.ipk
  ti-dspbios-dbg_5_41_02_14-r1.5_overo.ipk
  ti-dspbios-dev_5_41_02_14-r1.5_overo.ipk
  ti-dspbios-sourcetree_5_41_02_14-r1.5_overo.ipk
  ti-dspbios_5_41_02_14-r1.5_overo.ipk
  ti-dsplink-dbg_1_64-r80f.5_overo.ipk
  ti-dsplink-dev_1_64-r80f.5_overo.ipk
  ti-dsplink-examples_1_64-r80f.5_overo.ipk
  ti-dsplink-module_1_64-r80f.5_overo.ipk
  ti-dsplink-sourcetree_1_64-r80f.5_overo.ipk
  ti-dsplink_1_64-r80f.5_overo.ipk
  ti-edma3lld-dbg_01_11_00_03-r0.5_overo.ipk
  ti-edma3lld-dev_01_11_00_03-r0.5_overo.ipk
  ti-edma3lld-sourcetree_01_11_00_03-r0.5_overo.ipk
  ti-edma3lld_01_11_00_03-r0.5_overo.ipk
  ti-framework-components-dbg_2_25_01_05-r1.5_overo.ipk
  ti-framework-components-dev_2_25_01_05-r1.5_overo.ipk
  ti-framework-components-sourcetree_2_25_01_05-r1.5_overo.ipk
  ti-framework-components_2_25_01_05-r1.5_overo.ipk
  ti-local-power-manager-dbg_1_24_01-r80d.5_overo.ipk
  ti-local-power-manager-dev_1_24_01-r80d.5_overo.ipk
  ti-local-power-manager-sourcetree_1_24_01-r80d.5_overo.ipk
  ti-local-power-manager_1_24_01-r80d.5_overo.ipk
  ti-lpm-module_1_24_01-r80d.5_overo.ipk
  ti-lpm-utils_1_24_01-r80d.5_overo.ipk
  ti-xdais-dbg_6_25_01_08-r1.5_overo.ipk
  ti-xdais-dev_6_25_01_08-r1.5_overo.ipk
  ti-xdais-sourcetree_6_25_01_08-r1.5_overo.ipk
  ti-xdais_6_25_01_08-r1.5_overo.ipk
  ti-xdctools-dbg_3_16_01_27-r2.5_overo.ipk
  ti-xdctools-dev_3_16_01_27-r2.5_overo.ipk
  ti-xdctools-sourcetree_3_16_01_27-r2.5_overo.ipk
  ti-xdctools_3_16_01_27-r2.5_overo.ipk

The individual bitbake files are these:

find ${OVEROTOP}/org.openembedded.dev/recipes/ | grep '\<ti\>' | grep bb | cut -d'/' -f3-99 | cut -d'_' -f1 | sort -u
org.openembedded.dev/recipes/
  firmwares/firmware-ti-wl1251.bb
  images/ti-codec-engine-test-image.bb
  images/ti-demo-x11-image.bb
  julius/ti-julius-demo
  tasks/task-gstreamer-ti.bb
  ti/am-benchmarks
  ti/am-sysinfo
  ti/bitblit
  ti/gstreamer-ti
  ti/matrix-gui
  ti/matrix-gui-common
  ti/matrix-gui-e
  ti/matrix-tui
  ti/ti-audio-soc-example
  ti/ti-biospsp
  ti/ti-biosutils
  ti/ti-cgt6x
  ti/ti-codec-engine
  ti/ti-codecs-dm355
  ti/ti-codecs-dm365
  ti/ti-codecs-dm6446
  ti/ti-codecs-dm6467
  ti/ti-codecs-omap3530
  ti/ti-codecs-omapl137
  ti/ti-codecs-omapl138
  ti/ti-devshell.bb
  ti/ti-dm355mm-module
  ti/ti-dm365mm-module
  ti/ti-dmai
  ti/ti-dspbios
  ti/ti-dsplib
  ti/ti-dsplink
  ti/ti-dvsdk-demos
  ti/ti-edma3lld
  ti/ti-framework-components
  ti/ti-linuxutils
  ti/ti-local-power-manager
  ti/ti-msp430-chronos
  ti/ti-sysbios
  ti/ti-xdais
  ti/ti-xdctools

Errors

If you try to compile from the default overo kernel (or your haven't cleaned your previous attempt of ti-xzy) you're likely to run into these errors:

bitbake ti-linuxutils
  |   CC [M]  /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.o
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c:65:2: warning: #warning *** not a warning *** Note: LINUX_VERSION_CODE >= 2.6.26
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c: In function 'ioctl':
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c:1530: error: implicit declaration of function 'dmac_clean_range'
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c:1541: error: implicit declaration of function 'dmac_inv_range'
  | make[4]: *** [/home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.o] Error 1

According to the e2e forum it's possible to patch the kernel (essentially adding a http:// entry to the linux-omap3_2.6.33.bb (which has been removed, btw). The question remains: what replaces dmac_clean_range? and wouldn't it be better to patch cmemk with the update?, but judging by linux-ti-omap4 I'm guessing that the revert patch is pretty popular and perhaps the removal was premature.

Using an ssh public key with git team members(View Stand-alone)

Goal

A copy-paste tutorial for getting team-members to use their own ssh keys for a project

Note

The following are examples. You should change them.

  • git.example.com:22 Your real domain might be something more like acmecorp.com or 74.125.224.16:8022.
  • 74.125.224.16:8022 Your real ip and port will be different.
  • tom Your real user name will be different - perhaps jerry.
  • foobar.git Your real project might be something like omap-kernel.git

The following are not examples.

  • gitosis is the user name you must use for cloning a private (internal) git repository.

gitosis users

Create your own ssh key rather than continuing to share a single key with multiple people.

ssh-keygen -f ~/.ssh/id_rsa -N ''
# confirm and continue

Move that new key to a temporary shared location

KEY=~/.ssh/id_rsa.pub
KEYNAME=`cat ${KEY} | cut -d'=' -f3 | cut -d' ' -f2`
echo "This new key '${KEYNAME}' should be in your own user name"
mkdir -p /tmp/keydir/
cp ${KEY} /tmp/keydir/${KEYNAME}.pub

If you are asked for your password when checking out a git project, you have not been added correctly and will not have access. Be sure to use gitosis as the repository user and not your normal user name.

# Good Example - using `gitosis`
git clone gitosis@git.example.com:22/foobar.git

# Bad Example - using your user name
git clone tom@git.example.com:22/foobar.git

Note that after generating the new key you will be prompted for passwords in other places that you may not have been prompted before.

ssh -p 22 tom@74.125.224.16
tom@74.125.224.16's password:

You should use ssh-copy-id so that you are not asked for your password. This is more secure than using a password.

ssh-copy-id tom@74.125.224.16

If the server is on a special port (not 22) you should edit your ~/.ssh/config

vim ~/.ssh/config

~/.ssh/config

Host 74.125.224.16
User tom
Port 8022

Host development-unit6
User root

git admin

The git admin will add your key to gitosis

cd ~/gitosis-admin
mv /tmp/keydir/* ./keydir/
ls ./keydir/ | while read NAME; do echo ${NAME}; done

And give you access to the projects you need

cd ~/gitosis-admin
vim gitosis.conf

More detailed information on setting up gitosis projects is in the previous git article.

CCDC hs vs as output via u-boot(View Stand-alone)

Goal

Configure the cam_hs and cam_vs as outputs.

Linux Kernel

I had tried this before and documented the experience somewhat as Export-gpio-pins-on-gumstix

Later I found that although the cam_d lines were outputting data, the values were coming out as 0s. There is a suspision that setting CONFIG_OMAP3_MUX in the kernel enables a number of other changes that may not be desired. The next step is to try via node-devreg and then u-boot.

/* Camera - HS/VS signals */
OMAP3_MUX(CAM_HS, OMAP_MUX_MODE0 | OMAP_PIN_INPUT),

gpio94 / cam_hs

u-boot

Make the changes you need:

cd ${OVEROTOP}
bitbake -c clean u-boot-omap3; bitbake -c configure u-boot-omap3
VERSION=`bitbake --show-versions | grep 'u-boot-omap3\>' | cut -d':' -f2`
UBOOTDIR=${OVEROTOP}/tmp/work/overo-angstrom-linux-gnueabi/u-boot-omap3-${VERSION}
cd ${UBOOTDIR}
cd ./git/board/overo
cp overo.h overo.h.orig
vim overo.h # find `CAM_HS` and `CAM_VS` and change IEN (input enable) to IDIS (input disable)

Make your own copy of u-boot (as not to wipe it out if you clean org.openembedded.dev):

cd ${OVEROTOP}/
mkdir -p ./user.collection/recipes/
cp -a ./org.openembedded.dev/recipes/u-boot ./user.collection/recipes/u-boot

Create a patchfile that bitbake can understand:

cd ${UBOOTDIR}
git diff --no-prefix git/board/overo/overo.h.orig git/board/overo/overo.h > pin-mux.patch
mv pin-mux.patch ${OVEROTOP}/user.collection/recipes/u-boot/u-boot-omap3-git/

Edit the bitbake file:

vim ${OVEROTOP}/user.collection/recipes/u-boot/u-boot-omap3_git.bb

So that it has pin-mux.patch;patch=yes \, something like this:

SRC_URI = "git://www.sakoman.com/git/u-boot.git;branch=omap3;protocol=git \
           file://fw_env.config \
           file://pin-mux.patch;apply==yes \
          "

And bitbake it:

cd ${OVEROTOP}
bitbake -c clean u-boot-omap3; bitbake u-boot-omap3

And copy it to your gumstix:

WARNING: Be wise. Test your u-boot on an SDHC before corrupting your NAND.

GUMSTIX=192.168.1.20 # change this to your gumstix's address
scp ${OVEROTOP}/tmp/deploy/glibc/images/overo/u-boot-overo.bin ${GUMSTIX}:/media/mmcblk0p1/u-boot.bin

node-devreg

with node-devreg you can change the registry settings in user-space

./doc/omap3530/control.js

// control registers
var padconf = {
  base_address: "0x48002030",
  description: "Pad Multiplexing Register Fields - Core Control Module Pad Configuration Register Fields - pin muxing, etc",
  pages: [764],
  registers: {
    cam_hs: {
      description: "Configuring hsync/vsync or gpio94/gpio95",
      address: "0x4800210C",
      offset: "0x000000DC",
      fields: {
        cam_hs: [15:0],
        cam_vs: [31:16]
      }
    }
  }
}
exports.padconf = padconf;

control_settings.js

var padconf = {
  "cam_hs": {
    "cam_hs": "0",
    "cam_vs": "0"
  }
}

Resources

  • How to build U-Boot patches for use with OE
  • Gumstix U-Boot development without bitbake
  • OMAP 3530 Technical Reference Manual spruf98h
    • p762 - Mode Selection - 0b000 Mode0, [...], 0b111 Mode7
    • p767 - CONTROL_PADCONF_CAM_HS[15:0] - physical address 0x4800 210C, mode0 cam_hs, mode4 gpio94, mode5 hw_dbg0, mode7 safe_mode
    • p767 - CONTROL_PADCONF_CAM_HS[31:16] - physical address 0x4800 210C, mode0 cam_vs, mode4 gpio95, mode5 hw_dbg1, mode7 safe_mode
    • p846 - CONTROL_PADCONF_CAM_HS, RW, 32-bit, offset 0x0000 00DC, physical address 0x4800 210C
    • p858
      • REGISTER NAME, Pad Name, Physical Address, WakeUpx, OffMode, Input Enable, Reserved, PU/PD, MuxMode
      • CONTROL_PADCONF_CAM_HS[15:0], cam_hs, 0x4800 210C, 0b00, 0b00000, 0b1, 0b000, 0b01, 0b111
      • CONTROL_PADCONF_CAM_HS[31:16], cam_vs, 0x4800 210C, 0b00, 0b00000, 0b1, 0b000, 0b01, 0b111
    • p1301 - Figure 12-1. Camera ISP Highlight
    • p1305 - 12.2.2 Camera ISP Signal Descriptions - (explains that this is only available in sync mode)
    • p1307 - Figure 12-2. Parallel Interface in Generic Configuration
    • p1308 - Figure 12-3. Parallel Interface in ITU-R BT.656 Configuration
    • p1309 - Figure 12-4. CSI2, CSI1 Serial Interface Configuration
    • pp1310-1312 - 12.2.4.1 Parallel Generic Configuration Protocol and Data Format (8, 10, 11, 12 Bits)
    • p1363 - Figure 12-53. Camera ISP Block Diagram
    • p1385 - SYNC mode: In this mode, the cam_hs and cam_vs signals use dedicated wires. Synchronization signals are provided by either the sensor or the camera ISP. This mode works with 8-, 10-, 11-, and 12-bit data. It supports both progressive and interlaced image-sensor modules.
    • p1459 - 12.5.5.6.1.2 Timing Generator and Frame Settings The polarities of the cam_hs, cam_vs, and cam_fld signals are controlled by the CCDC_SYN_MODE[3] HDPOL, CCDC_SYN_MODE[2] VDPOL, and CCDC_SYN_MODE[4] FLDPOL bit fields. The polarities can be positive or negative. [...] Furthermore, the directions of the cam_fld and cam_hs/cam_vs signals are controlled by the CCDC_SYN_MODE[1] FLDOUT and CCDC_SYN_MODE[0] VDHDOUT bits. If CCDC_SYN_MODE[0] VDHDOUT is set as an output, the CCDC_PIX_LINES register controls the length of the cam_hs and cam_vs signals.
    • p1548 - Table 12-193. CCDC_SYN_MODE.
      • EXWEN The cam_wen signal can be used as an external memory write-enable signal. The data is stored to memory only if cam_hs, cam_vs and cam_wen signals are asserted.
      • HDPOL Sets the cam_hs signal polarity.
      • VDPOL cam_vs signal polarity
      • VDHDOUT cam_hs and cam_vs signal directions.

Check isp and ccdc registers with json(View Stand-alone)

Goal

Reduce typing and thinking, increase getting'r'done-itude.

Feed in an array of registers to read, get a printout on the screen.

Feed in an array of registers with values, get a printout of success / error.

TODO: best way to deal with multiple "reserved" bits?

Script

ccdc-reg.js

#!/usr/bin/env node
var devreg = require('./devreg').devreg,
  devices = require('./ispccdc'),
  flattenDocs = require('./flattendocs').flattenDocs,
  settings = require('./settings').settings,
  Futures = require('./futures');

//devreg(device, device.base_addr.omap3530);
Objects.keys(devices).each(function (deviceName, i, arr) {
  device = flattenDocs(devices[deviceName]);
  devreg(device, device.base_addr, settings)
    .when(function (register_values) {
      // do nothing right now
    });
});

devreg.js

var physical_registers = {},
    sys = require('sys'),
    parseNumber = require('parse_number').parseNumber,
    exec = require('child_process').exec,
    device,
    settings,
    base_addr,
    global_msb = 32 - 1,
    Futures = require('./futures');
    // wget http://github.com/coolaj86/futures/raw/v0.9.0/lib/futures.js
    // or
    // npm install futures

// TODO: put in the 'Zen' enumerate functions, not magic parameters
function leadWith(string, len, char) {
  char = ('undefined' !== typeof char) ? char : ' ';
  string = string || '';
  string = '' + string;
  while (string.length < len) {
    string = char + string;
  }
  return string;
}

function trailWith(string, len, char) {
  char = ('undefined' !== typeof char) ? char : ' ';
  string = string || '';
  string = '' + string;
  while (string.length < len) {
    string += char;
  }
  return string;
}

// TODO
// print '0x    0f1 ' instead of '0x000000f1'
function format_field(value, shift, len, size) {
  var i = 0, string = ''+value;
  string = leadWith(string, shift+len);
  string = trailWith(string, size);
}

function print_nibbles(reg_name, value) {
  var bits = device.fields[reg_name],
    field_name,
    bit,
    slice,
    shift,
    len,
    bin;

  //sys.print(bits + ' ' + reg_name + ' ' + value);
  sys.print("\n");
  sys.print(leadWith('', 22, ' ') + leadWith('-', 12+8+8, '-') + "\n");
  for (field_name in bits) {
    if (!bits.hasOwnProperty(field_name)) return;

    len = 0;
    slice = bits[field_name];
    // interpret correctly no matter the order [0:2] or [3:1] or [4]
    if ('undefined' !== typeof slice[1]) {
      if (slice[1] > slice[0]) {
        shift = slice[1];
        len = slice[1] - slice[0];
      } else {
        shift = slice[0];
        len = slice[0] - slice[1];
      }
    } else {
      shift = slice[0];
    }
    len += 1;

    // TODO allow other byte orders?
    // Because most systems are LSB, if we want to
    // read bit 31:29, from a 32-bit register
    //  we must substr char 0:2
    if (true /* == lsb */) {
      shift = global_msb - shift;
    }

    field_name = trailWith(field_name + ' [' + slice.join(':') + '] ', 20);

    bin = leadWith(value.toString(2), 32, '0');
    nibble = bin.substr(shift, len);

    //sys.print('  ' + field_name + ' bin' + bin + 'slice:' + slice.join(',') + ' ' + len + ' nib:' + nibble + "\n");

    hex = leadWith(parseInt(nibble, 2).toString(16), 8, '0');
    dec = parseInt(nibble, 2).toString(10);

    sys.print('  ' + field_name + " 0x" + hex + " == " + dec + "\n");
  }
  sys.print(leadWith('', 22, ' ') + leadWith('-', 12+8+8, '-') + "\n");
  sys.print("\n\n");
}

function print_registers() {
  var reg_name,
    value,
    dec, // decimal
    hex,
    bin;

  for (reg_name in physical_registers) {
    if (!physical_registers.hasOwnProperty(reg_name)) return;

    value = physical_registers[reg_name];
    dec = leadWith(value.toString(10), 12, '0');
    hex = leadWith(value.toString(16), 8, '0');
    bin = leadWith(value.toString(2), 32, '0');

    key = trailWith(reg_name + ':', 20);
    sys.print(key.toUpperCase() + '   0x' + hex + ' == ' + dec + ' | 0b' + bin + "\n");
    print_nibbles(reg_name, value);
  }
}

// slice example: [3:1]
function getBinaryFieldData(slice, register_size, field_value) {
  var len = 0,
    mask = 1,
    last_bit = register_size - 1,
    shift,
    i;

  field_value = field_value || 0;

  // interpret correctly no matter the order [0:2] or [3:1] or [4]
  if ('undefined' !== typeof slice[1]) {
    // shift should be the lowest number
    if (slice[1] > slice[0]) {
      shift = slice[0];
      len = slice[1] - slice[0];
    } else {
      shift = slice[1];
      len = slice[0] - slice[1];
    }
  } else {
    shift = slice[0];
  }
  // The length must be at least 1
  len += 1;

  // create a bit mask of all 1s
  // Note: mask is already 1 to start with
  for (i = 1; i < len; i += 1) {
    mask <<= i;
    mask &= 1;
  }

  if (field_value > mask) {
    // TODO would this work for negative numbers? Wolud you use a negative number in a register?
    throw new Error('cowardly refusing to set ' + field_name + ' to "' + field_value + '" when the max value is "' + mask + '"');
  }

  // move the mask and the value into the right place
  for (i = 0; i <= shift; i += 1) {
    field_value <<= i;
    mask <<= i;
  }

  if (mask != (mask & field_value)) {
    throw new Error('Logic error "mask != (mask & field_value"');
  }

  return {
    // consider an 8-bit register
    and_mask: ~mask, // 11110011 resets the 2nd and 3rd bit
    or_value: field_value, // 00001100 ready to be ORed with the full register
    shift: shift, // 2 bits in (right to left), the 2nd and 3rd bit
    length: len, // 2 bits long
    substr_start: last_bit - (shift + (len - 1)) // 4 bits in (left to right) 0000 1100
  };
}

function andOrBinaryRegisterValue(reg_name, register) {
  var register_value = physical_registers[reg_name] || 0, 
    field_vals, 
    documentation = device.fields[reg_name];

  if ('undefined' === typeof documentation) {
    throw new Error('"' + reg_name + '"' undefined. Please check spelling and/or update the documentation file');
  }

  // The user was only interested it the value as a whole
  if ('number' === typeof register) {
    register_value = register;
    return register_value;
  }
  if ('string' === typeof register) {
    register_value = parseNumber(register);
    return register_value;
  }

  // The user wants to and & or the new value with the old value on a field-by-field basis
  if ('object' === typeof register) {
    Object.keys(register).forEach(function (field_name, i, arr) {
      var field;
      if ('undefined' === typeof documentation[field_name]) {
        throw new Error('"' + reg_name + ':' + field_name + '"' undefined. Please check spelling and/or update the documentation file');
      }
      field = getBinaryFieldData(documentation[field_name], global_msb + 1, register[field_name]);
      register_value &= field.and_mask; // set the field to 0
      register_value |= field.or_value; // set the field to the value
    });
    return register_value;
  }

  throw new Error('value in "settings:' + reg_name + '" should be in the form "0x00000000", "0b00000000", decimal, or key/value pairs of bits');
  //throw new Error('unexpected type ' + typeof register + ' for "' + JSON.stringify(register) + '"');
}

function write_settings() {
  var reg_name,
    register_value;

  //sys.print( ' ' + JSON.stringify(settings) + "\n");

  for (reg_name in settings) {
    if (!settings.hasOwnProperty(reg_name)) return;
    if (!physical_registers.hasOwnProperty(reg_name)) throw new Error("'" + reg_name + "' isn't a known register");

    register_value = andOrBinaryRegisterValue(reg_name, settings[reg_name]);

    devmem(reg_name, '0x' + register_value.toString(16), 'u32').when(function () {
      if (register_value !== physical_registers[reg_name]) {
        sys.puts('ERR: "' + reg_name + '" was written as "' + register_value + '" but read as "' + physical_registers[reg_name]  + '"');
      }
    });
  }
}

function assert_settings() {
  var reg_name,
    register_value;

  //sys.print( ' ' + JSON.stringify(settings) + "\n");

  for (reg_name in settings) {
    if (!settings.hasOwnProperty(reg_name)) return;
    if (!physical_registers.hasOwnProperty(reg_name)) throw new Error("'" + k + "' isn't a known register");

    register_value = andOrBinaryRegisterValue(reg_name, settings[reg_name]);
    if (register_value !== (register_value & physical_registers[reg_name])) {
      // TODO compare fields
      sys.puts('ERR: "' + reg_name + '" was expected to be "' + register_value + '" but is actualy "' + physical_registers[reg_name]  + '"');
    }
  }
}

// TODO platform abstract and move to devmem.js
function devmem(reg_name, hex_value, size) {
  var promise = Futures.promise(),
    k, // key
    v, // value
    hexaddr = (parseNumber(base_addr) | parseNumber(device.registers[reg_name]));
    hex,
    bin,
    dec;

  hex_value = ('undefined' !== typeof hex_value) ? hex_value : '';
  exec('devmem2 ' + hexaddr + ' w ' + hex_value + ' | grep : | cut -d":" -f2', function (error, stdout, stderr) {
    //sys.print('devmem2 ' + hexaddr + ' w ' + hex_value + ' | grep : | cut -d":" -f2' + "\n");

    if (stderr) {
      sys.print('stderr: ' + stderr);
      throw new Error("Couldn't access register: " + stderr);
    }

    if (error !== null) {
      console.log('exec error: ' + error);
    }

    // TODO handle other formats?
    stdout = stdout.substr(3); // removing leading ' 0x'
    dec = parseInt(stdout, 16);
    physical_registers[reg_name] = dec;
    promise.fulfill({reg_name : dec});
  });
  return promise;
}

function devreg(_device, _base_addr, _settings) {
  var promise = Futures.promise(),
    promises = [],
    join,
    key,
    value,
    hexaddr;

  device = _device;
  base_addr = _base_addr || device.base_addr;
  settings = _settings || {};

  //sys.puts(JSON.stringify(device) + "\n");
  for (key in device.registers) {
    if (!device.registers.hasOwnProperty(key)) return;
    //value = device.registers[key];
    //sys.print(key + ": " + value.substr(2) + "\n");
    promises.push(devmem(key));
  }
  join = Futures.join(promises);
  // TODO validate writes
  join
    .when(write_settings)
    .when(print_registers)
    .when(function () {
      promise.fulfill(physical_registers);
    });

  return promise;
}

exports.devreg = devreg;

flattendocs.js

// Work in Progress

settings.js

// TODO allow setting of user values
// will be checked
// registers can be set with decimal, hex, or binary value
var settings = {
  "registers" : {
    "pid": 0, // these types are implemented
    "pcr": 0x0,
    "syn_mode": 0b0, 
    "hd_vd_wid": { // Not implemented
      "reserved-0": 0,
      "hdw": 0x0,
      "reserved-1": 0b0,
      "vdw": 0
    },
    "pix_lines": 1,
    "horz_info": 1,
    "vert_start": 1,
    "vert_lines": 1,
    "culling": 1,
    "hsize_off": 1,
    "sdofst": 1,
    "sdr_addr": 1,
    "clamp": 1,
    "dcsub": 1,
    "colptn": 1,
    "blkcmp": 1,
    "fpc": 1,
    "fpc_addr": 1,
    "vdint": 1,
    "alaw": 1,
    "rec656if": 1,
    "cfg": 1,
    "fmtcfg": 1,
    "fmt_horz": 1,
    "fmt_vert": 1,
    "fmt_addr_i": 1,
    "prgeven0": 1,
    "prgeven1": 1,
    "prgodd0": 1,
    "prgodd1": 1,
    "vp_out": 1,
    "lsc_config": 1,
    "lsc_initial": 1,
    "lsc_table_base": 1,
    "lsc_table_offset": 1
  }
}
exports.settings = settings;

ispccdc.js

// TODO add reset values as to be able 
// to check for hardware bugs as well
var ccdc = {
  "base_addr" : "0x480BC600",
  "registers" : {
    "pid": "0x00",
    "pcr": "0x04",
    "syn_mode": "0x08", 
    "hd_vd_wid": "0x0c",
    "pix_lines": "0x10",
    "horz_info": "0x14",
    "vert_start": "0x18",
    "vert_lines": "0x1c",
    "culling": "0x20",
    "hsize_off": "0x24",
    "sdofst": "0x28",
    "sdr_addr": "0x2c",
    "clamp": "0x30",
    "dcsub": "0x34",
    "colptn": "0x38",
    "blkcmp": "0x3c",
    "fpc": "0x40",
    "fpc_addr": "0x44",
    "vdint": "0x48",
    "alaw": "0x4c",
    "rec656if": "0x50",
    "cfg": "0x54",
    "fmtcfg": "0x58",
    "fmt_horz": "0x5c",
    "fmt_vert": "0x60",
    "fmt_addr_i": "0x64",
    "prgeven0": "0x84",
    "prgeven1": "0x88",
    "prgodd0": "0x8c",
    "prgodd1": "0x90",
    "vp_out": "0x94",
    "lsc_config": "0x98",
    "lsc_initial": "0x9c",
    "lsc_table_base": "0xa0",
    "lsc_table_offset": "0xa4"
  },
  "fields": {
    "pid": {
      "reserved": [31,24],
      "tid": [23,16],
      "cid": [15,8],
      "prev": [7,0],
    },
    "pcr": {
      "reserved": [31,2],
      "busy": [1],
      "enable": [0],
    },
    "syn_mode": {
      "reserved": [31,20],
      "sdr2rsz": [19],
      "vp2sdr": [18],
      "wen" : [17],
      "vdhden": [16],
      "fldstat": [15],
      "lpf": [14],
      "inpmod": [13,12],
      "pack8": [11],
      "datsiz": [10,8],
      "fldmode": [7],
      "datapol": [6],
      "exwen": [5],
      "fldpol": [4],
      "hdpol": [3],
      "vdpol": [2],
      "fldout": [1],
      "vdhdout": [0]
    }, 
    "hd_vd_wid": {
      "reserved-0": [31,28],
      "hdw": [27,16],
      "reserved-1": [15,12],
      "vdw": [11,0]
    }, 
    "pix_lines": {
      "ppln": [31,16],
      "hlprf": [15,0]
    }, 
    "horz_info": {
      "reserved-0": [31],
      "sph": [30,16],
      "reserved-1": [15],
      "nph": [14,0]
    }, 
    "vert_start": {
      "reserved-0": [31],
      "slv0": [30,16],
      "reserved-1": [15],
      "slv1": [14,0]
    }, 
    "vert_lines": {
      "reserved": [31,15],
      "nlv": [14,0],
    },
    "culling": {
      "culhevn": [31,24],
      "culhodd": [23,16],
      "reserved": [15,8],
      "culv": [7,0]
    }, 
    "hsize_off": {
      "reserved": [31,16],
      "lnofst": [15,0]
    }, 
    "sdofst": {
      "reserved": [31,15],
      "fiinv": [14],
      "fofst": [13,12],
      "lofst0": [11,9],
      "lofst1": [8,6],
      "lofst2": [5,3],
      "lofst3": [2,0]
    }, 
    "sdr_addr": {
      "addr": [31,0]
    }, 
    "clamp": {
      "clampen": [31],
      "obslen": [30,28],
      "obsln": [27,25],
      "obst": [24,10],
      "reserved": [9,5],
      "obgain": [4,0]
    }, 
    "dcsub": {
      "reserved": [31,14],
      "dcsub": [13,0]
    }, 
    "colptn": {
      "cp3lpc3": [31,30],
      "cp3lpc2": [29,28],
      "cp3lpc1": [27,26],
      "cp3lpc0": [25,24],
      "cp2plc3": [23,22],
      "cp2plc2": [21,20],
      "cp2plc1": [19,18],
      "cp2plc0": [17,16],
      "cp1plc3": [15,14],
      "cp1plc2": [13,12],
      "cp1plc1": [11,10],
      "cp1plc0": [9,8],
      "cp0plc3": [7,6],
      "cp0plc2": [5,4],
      "cp0plc1": [3,2],
      "cp0plc0": [1,0]
    }, 
    "blkcmp": {
      "r_ye": [31,24],
      "gr_cy": [23,16],
      "gb_g": [15,8],
      "b_mg": [7,0]
    }, 
    "fpc": {
      "reserved": [31,17],
      "fperr": [16],
      "gb_g": [15],
      "b_mg": [14,0]
    }, 
    "fpc_addr": {
      "addr": [31,0]
    }, 
    "vdint": {
      "reserved-0": [31],
      "vdint0": [30,16],
      "reserved-1": [15],
      "vdint1": [14,0]
    }, 
    "alaw": {
      "reserved": [31,4],
      "ccdtbl": [3],
      "gwdi": [2,0]
    }, 
    "rec656if": {
      "reserved": [31,2],
      "eccfvh": [1],
      "r656on": [0]
    }, 
    "cfg": {
      "reserved-0": [31,16],
      "vdlc": [15], 
      "reserved-1": [14],
      "msbinvi": [13],
      "bswd": [12],
      "y8pos": [11],
      "reserved-2": [10,9],
      "wenlog": [8],
      "fidmd": [7,6],
      "bw656": [5],
      "reserved-3": [4],
      "reserved-4": [3],
      "reserved-5": [2],
      "reserved-6": [1,0]
    }, 
    "fmtcfg": {
      "reserved": [31,19],
      "vpif_frq": [18,16],
      "vpen": [15],
      "vpin": [14,12],
      "plen_even": [11,8],
      "plen_odd": [7,4],
      "lnum": [3,2],
      "lnalt": [1],
      "fmten": [0]
    }, 
    "fmt_horz": {
      "reserved-0": [31,29],
      "fmtsph": [28,16],
      "reserved-1": [15,13],
      "fmtlnh": [12,0]
    }, 
    "fmt_vert": {
      "reserved-0": [31,29],
      "fmtslv": [28,16],
      "reserved-1": [15,13],
      "fmtlnv": [12,0]
    }, 
    "fmt_addr_i": {
      "reserved-0": [31,26],
      "line": [25,24],
      "reserved-1": [23,13],
      "init": [12,0]
    }, 
    "prgeven0": {
      "even7": [31,28],
      "even6": [27,24],
      "even5": [23,20],
      "even4": [19,16],
      "even3": [15,12],
      "even2": [11,8],
      "even1": [7,4],
      "even0": [3,0]
    }, 
    "prgeven1": {
      "even15": [31,28],
      "even14": [27,24],
      "even13": [23,20],
      "even12": [19,16],
      "even11": [15,12],
      "even10": [11,8],
      "even9": [7,4],
      "even8": [3,0]
    }, 
    "prgodd0": {
      "odd7": [31,28],
      "odd6": [27,24],
      "odd5": [23,20],
      "odd4": [19,16],
      "odd3": [15,12],
      "odd2": [11,8],
      "odd1": [7,4],
      "odd0": [3,0]
    }, 
    "prgodd1": {
      "odd15": [31,28],
      "odd14": [27,24],
      "odd13": [23,20],
      "odd12": [19,16],
      "odd11": [15,12],
      "odd10": [11,8],
      "odd09": [7,4],
      "odd08": [3,0]
    }, 
    "vp_out": {
      "reserved": [31],
      "vert_num": [30,17],
      "horz_num": [16,4],
      "horz_st": [3,0]
    }, 
    "lsc_config": {
      "reserved-0": [31,15],
      "gain_mode_m": [14,12],
      "reserved-1": [11],
      "gain_mode_n": [10,8],
      "busy": [7],
      "after_reform": [6],
      "reserved-2": [5,4],
      "gain_format": [3,1],
      "enable": [0]
    }, 
    "lsc_initial": {
      "reserved-0": [31,22],
      "y": [21,16],
      "reserved-1": [15,6],
      "x": [5,0]
    }, 
    "lsc_table_base": {
      "base": [31,0]
    }, 
    "lsc_table_offset": {
      "reserved": [31,16],
      "offset": [15,0]
    }
  }
};
var isp = {
};
exports.ccdc = ccdc;
exports.isp = isp;

Shifting registers (the double carrot operator)(View Stand-alone)

Goal

Explain the use of << and | in C and the linux kernel. Intended for those with basic knowledge of computer science and computer engineering.

Status

Someone with more experience should look this over. There are goof-O's and misexplanations still.

TODO use an actual example examining just the first 8 bits

Multiplexing

Let's consider TI's OMAP3530 Application Processor. There are a lot of GPIO (general-purpose i/o) pins (which can be used as just about anything by bit-banging). Many of them are multiplexed meaning that it can be used as a gpio pin or part of the camera data line interface, but not both at the same time.

For example: The gumstix has an optionl LCD screen. Their driver for that screen uses lines that could otherwise be used as SPI (serial peripheral interface - a poor man's USB).

Instead of giving enough lines to do every possible thing under the sun at all times, there are a limited number of lines drawn out from the processor. If you want to use one feature, you may not be able to use another.

There has to be a setting that tells the processor which line is being used for what.

What's a Register?

A register holds a series of bits that the processor (or device) uses to store information or configuration.

The ISP / CCDC interface for the OMAP35x has numerous settings. It can be configured to capture raw data, jpeg data, or other specially formatted data from a camera device. It can be configured to interpret the vsync and hsync signals needed for a motion camera to separate data into frames or to produce those signals.

Many of these settings are simply on or off. A few of them are enumerable (raw or rgb or jpeg or yuv mode).

If each setting took one byte of storage, that would be a lot of wasted bits.

Many registers are 32-bits and so they can store lots of this settings information.

Let's consider a simple 8-bit register:

00000000

If this were the settings register for a device with 2 binary settings and 2 enumerable settings, one with 5 options, another with 3, then the default settings would be 0x0 by default.

Let's say the bits have this mapping:

* [0] VSYNO vsync out - 0 on, 1 off
* [1] HSYNO hsync out - 0 on, 1 off
* [2-4] capture mode - (3 bits mean a max of 8 options, we'll use just 5)
  * 000 RAW
  * 001 JPEG
  * 010 YUV
  * 011 RGB
  * ... so on
* [5-6] mask a color (r, g, or b)
  * 00 MNONE
  * 01 MRED
  * 10 MGREEN
  * 11 MBLUE
* [7] reserved for future use / wasted

This is how we might represent that vsync and hsync are outputs, the mode is raw, and we want to mask the color green (I don't know why, but just for example's sake):

01000011

No problem right? Any time you want to set that setting you could quickly come up with the decimal representation inside of your head and assign that to the address location, right?

Setting Registers in C

To simplify setting the register above you might create a header like this:

camera_reg.h

// a long list of registers (just 2 for our example)
#define CAMERA_REG_BASE 0x0034 C600 // Where all of the CAMERA device registers might begin
#define CAMERA_CAP_CFG_OFFSET 0x00  // How far away from the BASE the CAP_CFG register is. This would be the very first
#define CAMERA_OUT_CFG_OFFSET 0x08  // The next register, 8 bits away

// Which bit of the 8 sets which setting
#define CCAPCFG_HSYNC_SHIFT 1        // 0000 0001
#define CCAPCFG_VSYNC_SHIFT (1 << 1) // 0000 0010
#define CCAPCFG_MODE_SHIFT  (1 << 2) // 0000 0100
#define CCAPCFG_MASK_SHIFT  (1 << 5) // 0001 0000
#define CCAPCFG_RSV_SHIFT   (1 << 7) // 0100 0000


#define CCAPCFG_HSYNC_EN 1
#define CCAPCFG_VSYNC_EN 2
#define CCAPCFG_MODE_JPEG 4
#define CCAPCFG_MODE_YUV 8
#define CCAPCFG_MODE_RGB 12
// ...
#define CCAPCFG_MASK_RED 32
#define CCAPCFG_MASK_GREEN 64
#define CCAPCFG_MASK_BLUE 96

And then address the register in this fashion:

*(void*)(CAMERA_REG_BASE | CAMERA_CAP_CFG_OFFSET) = (CCAPCFG_HSYNC_EN|CCAPCFG_VSYNC_EN|CAPCFG_MASK_GREEN);

Exploring ISP and CCDC(View Stand-alone)

Goal

Trace from a hardware CCDC register setting through the ISP / CCDC module, through the driver, through V4L2, right to the application interface.

This example traces from the hardware bit for interlace mode in the CCDC regisetrs.

Warning: this is just thought-jotting. Not well organized yet.

Register Names

The #defines in the kernel are very nearly 1:1 mapped with the documentation in the TRM (spruf98g).

For example: CCDC_SYN_MODE[7] FLDMODE in the TRM is ISPCCDC_SYN_MODE_FLDMODE in the kernel. Almost exactly the same.

My general rule is to grep the most unique part of the name in question from the root of the kernel directory.

For example: grep FLDMODE -R ./

Interlaced Mode

The device is running in interlace mode even with CCDC_SYN_MODE[7] FLDMODE set to 0. Tracing...

Where is interlace mode set?

grep FLDMODE -R ./ shows

it is defined in ./drivers/media/video/isp/ispreg.h

#define ISPCCDC_SYN_MODE_FLDMODE (1 << 7)

and used in ./drivers/media/video/isp/ispccdc.c

if (syncif.fldmode)
  syn_mode |= ISPCCDC_SYN_MODE_FLDMODE;
else
  syn_mode &= ~ISPCCDC_SYN_MODE_FLDMODE;

What is syn_mode?

It appears to be the value as read from the 32-bit isp register

u32 syn_mode = isp_reg_readl(isp_ccdc->dev, OMAP3_ISP_IOMEM_CCDC,
           ISPCCDC_SYN_MODE);

What values it is set to depend heavily upon syncif (of type ispccdc_syncif) and then it is written back to the register.

What is syncif?

A struct defined in ./drivers/media/video/isp/ispccdc.h

It is set according to pipe->ccdc_in, which is an enum used to describe a format such as CCDC_RAW_GBRG (in the same file).

If the value is CCDC_OTHERS, syncif is not set, which means that the values already in the register stay in the register?

Not necessarily; since the ISP only knows about certain CCDC_XXX_XXXX formats it will unset certain registers for all CCDC_OTHERS formats.

However, it appears that CCDC_OTHERS and DAT12 are reserved for future use. CCDC_OTHERS isn't handled in isp_try_pipeline.

Where does pipe->ccdc_in come from?

It is of type isp_pipeline and the ccdc_in comes from ./drivers/media/video/isp/isp.c

It is determined by pix_input->pixelformat

What's the deal with pix_input->pixelformat?

It's a V4L format, such as V4L2_PIX_FMT_UYVY, as set in ./drivers/media/video/your_driver_here.c

The formats supported by the OMAP ISP are defined in ./drivers/media/video/isp/isp.c.

Where would I define it in ./drivers/media/video/your_driver_here.c

hmm... various places... I don't understand this stack well enough to say yet...

Where would I find these V4L2_PIX_FMT_XXX?

./include/linux/videodev2.h

And, fancy this - Documentation: ./Documentation/DocBook/v4l/videodev2.h.xml

How would I create my own V4L2_PIX_FMT_XXX?

In ./include/linux/videodev2.h there's a special place for that

/*  Vendor-specific formats   */
#define V4L2_PIX_FMT_CUSTOM v4l2_fourcc('C','F','M','T') // Arbitrary 4-characters which must be unique among V4L defines

For quick reference: V4L2_PIX_FMT_XXX is a u32

/*  Four-character-code (FOURCC) */
#define v4l2_fourcc(a, b, c, d)\
  ((__u32)(a) | ((__u32)(b) << 8) | ((__u32)(c) << 16) | ((__u32)(d) << 24))

How is pipe->modules determined?

modules is an |d register including things like resizer and preview. In fact, I believe those are the only two modules to date.

Peeking at the Davinci(View Stand-alone)

Goal

Find the linux kernel source for the old TMS320DM6446 (DM64x) Davinci.

There is a similar driver, the mt9t001, which may provide some insight into creating a custom raw capture driver.

Finding the Kernel

It looks like public access is not possible and or that the extranet site on which it was hosted no longer exists.

If you can find it elsewhere, the file is likely called something like DaVinciLSP-REL_mvl401c.tar.gz or DaVinciLSP-REL_mvl401i.tar.gz

Resources

Appendix

While trying to find the kernel, I first ended up finding the davinci_dvsdk instead:

  1. Visit ti.com
  2. Search 'davinci' or 'dm64x'
  3. Navigate to TMS320DM6446
  4. Find LINUXDVSDK-DV

The old way to get to the files was something like:

  1. visit ti.com
  2. click my.TI Login
  3. enter credentials
  4. click Extranets
  5. Search DaVinci
  6. DM644x
  7. Version 1.30 / 2.0

Export gpio pins on gumstix(View Stand-alone)

Goal

Be able to twiddle a gpio line by hand.

Resources

SPRS507F (OMAP3530/25 Applications Processor)

  • Table 2-1. Ball Characteristics (CBB Pkg.) - Page 28-69 - GPIO pins, mux modes, etc

Caution

If the gpio is already in use by another device in a different mode the results are undefind - and in some cases could cause physical damage to the board (creating a short, for example).

In the kernel via board-overo.c

You might take a glance at Table 2-2. Ball Characteristics (CBC Pkg.) to see which gpio pins are available for use.

If the GPIO you would like to export is pin-muxed, you must enable CONFIG_OMAP_MUX by running menuconfig or editing overo_defconfig

Create a function to export the gpios you need in KERNDIR/arch/arm/mach-omap2/board-overo.c check my other post about custom board files to learn where KERNDIR might be.

#define OVERO_GPIO_CAM_HS 94

static void __init test_custom_gpio_init(void)
{
  printk("... initing test_custom_gpio\n");
  if ((gpio_request(OVERO_GPIO_CAM_HS, "OVERO_GPIO_CAM_HS") == 0) &&
      (gpio_direction_output(OVERO_GPIO_CAM_HS, 1) == 0)) {
    if (0 == gpio_export(OVERO_GPIO_CAM_HS, 0)) {
      printk("exported test_custom_gpio 94");
    } else {
      printk("didn't export test_custom 94");
    }
  } else {
    printk(KERN_ERR "could not obtain test_custom gpio for "
                        "OVERO_GPIO_CAM_HS\n");
  }
}

Then add that function to the list in overo_init

static void __init overo_init(void)
{
  omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
  overo_i2c_init();
  platform_add_devices(overo_devices, ARRAY_SIZE(overo_devices));
  omap_serial_init();
  overo_flash_init();
  usb_musb_init();
  usb_ehci_init(&ehci_pdata);
  overo_spi_init();
  overo_init_smsc911x();
  overo_display_init();
  test_custom_gpio_init(); // our gpio function

// ... lots more stuff
}

In user-space via /sys/class/gpio/export

Note that this cannot be mixed with the in-kernel method method

echo 94 > /sys/class/gpio/export
echo 94 > /sys/class/gpio/unexport

In user-space via /dev/mem

TODO

Via uboot

TODO

Checking ISP registers(View Stand-alone)

Goal

Read, set, and check ISP registers

Use a raw capture from the CCDC to put the data into memory, bypassing the preview, resizer, and other ISP auxilaries.

Status

This document is just a note-taking place right now. Don't expect useful information below.

Resources

Glossary

  • CCD - charge-coupled device - image sensor
  • CCDC - CCD Camera
  • ISP - Image Signal Processor
  • SBL - Shared Logic Buffer
  • PRCM - ?

Outline of ISP documentation in SPRUF98G

Since TI didn't have the decency to create HTML documentation, nor to sort the documentation by topic, here's a bite-size breakdown of ISP-related information in spruf98g.pdf:

Contents:

  • 00.0 Camera ISP Index .................................................................................................... 21
  • 12.1 Camera ISP Overview ................................................................................................. 1308
  • 12.2 Camera ISP Environment ............................................................................................. 1313
  • 12.3 Camera ISP Integration ................................................................................................ 1359
  • 12.4 Camera ISP Functional Description .................................................................................. 1370
  • 12.5 Camera ISP Basic Programming Model ............................................................................. 1443
  • 12.6 Camera ISP Register Manual ......................................................................................... 1494

Figures:

  • 12-53. Camera ISP Block Diagram........................................................................................... 1371
  • 12-54. Camera ISP/Data Path/RAW RGB Images ......................................................................... 1373
  • 12-55. Camera ISP/Data Path/YUV4:2:2 Images .......................................................................... 1374
  • 12-56. Camera ISP/Data Path/JPEG Images ............................................................................... 1374

Tables:

  • 12-1. Camera ISP Functions................................................................................................. 1313
  • 12-17. Camera ISP Interrupts ................................................................................................. 1364
  • 12-68. Camera ISP Instance Summary...................................................................................... 1494
  • 12-69. ISP Register Summary ................................................................................................ 1494
  • 12-70. ISP_REVISION ......................................................................................................... 1495
  • 12-71. Register Call Summary for Register ISP_REVISION.............................................................. 1495
  • 12-72. ISP_SYSCONFIG ...................................................................................................... 1495
  • 12-73. Register Call Summary for Register ISP_SYSCONFIG........................................................... 1496
  • 12-74. ISP_SYSSTATUS ...................................................................................................... 1496
  • 12-75. Register Call Summary for Register ISP_SYSSTATUS........................................................... 1496
  • 12-76. ISP_IRQ0ENABLE ..................................................................................................... 1497
  • 12-77. Register Call Summary for Register ISP_IRQ0ENABLE.......................................................... 1499
  • 12-78. ISP_IRQ0STATUS ..................................................................................................... 1500
  • 12-79. Register Call Summary for Register ISP_IRQ0STATUS.......................................................... 1503
  • 12-80. ISP_IRQ1ENABLE ..................................................................................................... 1503
  • 12-81. Register Call Summary for Register ISP_IRQ1ENABLE.......................................................... 1506
  • 12-82. ISP_IRQ1STATUS ..................................................................................................... 1506
  • 12-83. Register Call Summary for Register ISP_IRQ1STATUS.......................................................... 1509
  • 12-88. ISP_CTRL ............................................................................................................... 1511
  • 12-89. Register Call Summary for Register ISP_CTRL.................................................................... 1514
  • 12-106. ISP_CBUFF Register Summary..................................................................................... 1521
  • 12-129. ISP_CSI1B Register Summary...................................................................................... 1529
  • 12-188. ISP_CCDC Register Summary...................................................................................... 1549
  • 12-259. ISP_HIST Register Summary ....................................................................................... 1581
  • 12-282. ISP_H3A Register Summary ........................................................................................ 1588
  • 12-331. ISP_PREVIEW Register Summary ................................................................................. 1603
  • 12-402. ISP_RESIZER Register Summary.................................................................................. 1628
  • 12-489. ISP_SBL Register Summary ........................................................................................ 1653
  • 12-616. ISP_CSI2A Register Summary...................................................................................... 1699

Outline of SPRS507F - OMAP3530/25 Applications Processor

  • 2.5.2 Video Interfaces - page 98-100

Relating to the Linux Kernel

  • 12.6 Camera ISP Register Manual ......................................................................................... 1494

  • disable CSI1 with CSI1_CTRL [0] IF_EN = 0x0

  • disable CSI2 with CM_FCLKEN_CAM[1] EN_CSI2 = 0

12.5.3 Programming the Timing CTRL Module

12.5.4 Programming the CCDC

Table 12-50. CCDC Required Configuration Parameters

  • ISP_CTRL[3:2] PAR_BRIDGE
  • ISP_CTRL[7:6] SHIFT
  • ISP_CTRL[4] PAR_CLK_POL

12.5.4.6.1.1 Input-Mode Selection

SYNC mode:

  • In this mode, the input data can be either raw data or YCbCr data. Setting CCDC_SYN_MODE.INPMODE = 0 selects raw data, and CCDC_SYN_MODE[13:12] INPMODE = 1 or 2 selects YCbCr data on 16 or 8 bits. If CCDC_SYN_MODE[13:12] INPMODE = 0, the cam_d signal width is selected through CCDC_SYN_MODE[10:8] DATSIZ: the possible values are 8, 10, 11, and 12 bits.
  • If CCDC_SYN_MODE[13:12] INPMODE = 1, the cam_d signal width is 8 bits, but the internal CCDC module data path is configured to 16 bits. It is mandatory to enable the 8- to 16-bit bridge by setting ISP_CTRL[3:2] PAR_BRIDGE = 2 or 3. The ISP_CTRL [3:2] PAR_BRIDGE bit also controls how the 8-bit data is mapped onto the 16-bit data.
  • The value set in CCDC_SYN_MODE[10:8] DATSIZ does not matter. The position of the Y component can be set with the CCDC_CFG[11] Y8POS bit.
  • If CCDC_SYN_MODE[13:12] INPMODE = 2, the cam_d signal width is 8 bits. The value set in CCDC_SYN_MODE[10:8] DATSIZ does not matter. The position of the Y component can be set with the CCDC_CFG[11] Y8POS bit.
  • The internal timing generator must be enabled with CCDC_SYN_MODE[16] VDHDEN = 1.

NOTE:

  • CCDC_REC656IF[0] R656ON = 0 to disable ITU mode

12.5.4.6.1.2 Timing Generator and Frame Settings

The polarities of the cam_hs, cam_vs, and cam_fld signals are controlled by the CCDC_SYN_MODE[3] HDPOL, CCDC_SYN_MODE[2] VDPOL, and CCDC_SYN_MODE[4] FLDPOL bit fields. The polarities can be positive or negative.

The pixel data is presented on cam_d one pixel for every cam_pclk rising edge or falling edge. It is controlled with the ISP_CTRL[4] PAR_CLK_POL bit.

The CCDC_SYN_MODE[7] FLDMODE bit fields set the image-sensor type to progressive or interlaced mode. When the sensor is interlaced, the CCDC_SYN_MODE[15] FLDSTAT status bit indicates whether the current frame is odd or even.

The polarity of the cam_d signal can also be controlled with the CCDC_SYN_MODE[6] DATAPOL bit field.

The polarity can be normal mode or ones complement mode.

Furthermore, the directions of the cam_fld and cam_hs/cam_vs signals are controlled by the CCDC_SYN_MODE[1] FLDOUT and CCDC_SYN_MODE[0] VDHDOUT bits. If CCDC_SYN_MODE[0] VDHDOUT is set as an output, the CCDC_PIX_LINES register controls the length of the cam_hs and cam_vs signals.

If CCDC_SYN_MODE[0] VDHDOUT = 1:

  • The HS sync pulse width is given by CCDC_HD_VD_WID[27:16] HDW. The VS sync pulse width is given by CCDC_HD_VD [11:0] VDW.
  • The HS period is given by CCDC_PIX_LINES[31:16] PPLN. The VS period is given by CCDC_PIX_LINES[15:0] HLPRF x 2.

Figure 12-107 shows the HS/VS sync pulse output timings.

12.5.4.6.2 Image-Signal Processing

  • CCDC_CLAMP[31] CLAMPEN = 0
  • CCDC_DCSUB = 0

12.5.9 Programming the Central-Resource SBL

???

Table 12-88. ISP_CTRL

  • CCDC_RAM_EN
  • CCDC_CLK_EN

12.6.5 Camera ISP_CCDC Registers

  • CCDC_SYN_MODE.VDHDOUT = 1 - cam_hs and cam_vs are output
  • VDHDEN = 1 - enable timing generator
  • INPMOD = 0 - Raw data
  • HDW = 0 - how many pulses to leave hs sync (always at least 1)
  • VDW = 0 - how many pulses to leave vs sync (always at least 1)

Table 12-193. CCDC_SYN_MODE

other

cam_pclk must start before sending cam_d and start cam_vs and cam_hs

RAW can be processed via IVA2.2 in software

SYNC mode: In this mode, the cam_hs and cam_vs signals use dedicated wires. Synchronization signals are provided by either the sensor or the camera ISP. This mode works with 8-, 10-, 11-, and 12-bit data. It supports both progressive and interlaced image-sensor modules.

12.4.6.1.3.1 SYNC CTRL Module

The SYNC CTRL module receives the pixel-clock signal from the image sensor (PCLK). The module can be slave or master of the horizontal and vertical synchronization signals (HS and VS) and of the field-identification signal (FIELD).

The HS, VS, and FLD signals can be set as inputs or outputs. The polarity of the HS, VS, and FLD signals can be set as positive or negative. If the HS, VS, and FLD signals are output, the signal length can be set.

For RAW data:

  • Data is clipped to the number of LSBs specified in the CCDC_SYN_MODE [10:8] DATSIZ field. This also sets the maximum data size allowed in subsequent clipping/limiting operations and is the output data alignment if data is written to memory.

Conversion Area Select Parameters

When the data formatter is enabled, HS/VS signals are still generated as output (CCDC_SYN_MODE [16] VDHDEN = 0x1). The settings for these output signals are in the following fields:

  • CCDC_HD_VD_WID[27:16] HDW
  • CCDC_HD_VD_WID[11:0] VDW
  • CCDC_PIX_LINES[31:16] PPLN
  • CCDC_PIX_LINES[15:0] HLPRF

NOTE: These four registers are not used when HS/VS signals are input signals (CCDC_SYN_MODE [16] VDHDEN = 0x0).

NOTE: The settings reflect those for the sensor readout frame, not the resultant reformatted frame. Registers CCDC_FMT_HORZ and CCDC_FMT_VERT control the interpretation of the input data frame when the data formatter is enabled.

Registers CCDC_HORZ_INFO, CCDC_VERT_START, and CCDC_VERT_LINES control the interpretation of the input data frame in normal mode (when the data formatter is not enabled).

  • CSI 0x480B C400 - 0x480B C5EC
  • CCDC 0x480B C600 - 0x480B C6A7

Resizer Physical Address 0x480B D000

spruf98g.pdf - page 1636 -

Table 12-423. RSZ_HFILT10

Description HORIZONTAL FILTER COEFFICIENTS 0 AND 1 REGISTER RW Type RW

Address Offset 0x0000 0028 Physical Address 0x480B D028

Instance ISP_RESIZER

On page 1458 there is a complete table with all the registers and values for those registers that need to be initialized for the CCDC to function.

Via the kernel

It seems that isp_interface_config is the struct which is used to set the isp registers in the kernel

A Note to TI

Next time your Table of Contents is 163 pages, consider putting it up in o googleable format, maybe? Or, better yet, don't do silly things - like create 34-hundred page manuals! Perhaps better to break it down by use-case or topic? Each major section in another manual unto itself?

Documenting with Jekyll(View Stand-alone)

Goal

Install Jekyll to use for writing documentation in Markdown syntax with code highlighting.

Create a site which has a list of article categories. See example

Known Issues

This document doesn't describe how to address the issue of relative paths of stylesheets, javascripts, etc in _layouts/default.html.

Putting Jekyll to Good Use

Installing Jekyll

As per the documentation

sudo gem install jekyll
sudo gem install rdiscount
#sudo apt-get install python-pygments

Because pygments requires extra syntax, I prefer to use highlight.js instead. For my needs, highlighting for Bash, C++, CSS, HTML, and JavaScript suffices. I make the assumption that highlight.zip is downloaded to ~/Downloads/highlight.zip.

I also recommend showdown.js rather than rdiscount, but rdiscount works well enough and has the (dis)advantage of rendering server-side.

Configuring Jekyll

The most important information can be found here at the Jekyll wiki

Creating a home for our site:

cd ~/
mkdir blog

Create a site style:

cd ~/blog
mkdir images/
wget http://fastr.github.com/images/ribbedbg.png \
  -O images/ribbedbg.png
mkdir stylesheets/

./stylesheets/fastr.css

body &#123;
  background-color: #789;
  background-image:url('/images/ribbedbg.png');
}
a &#123;
  color: inherit;
  text-decoration: none;
  border-bottom:1px dotted;
  padding-left: 2px;
  padding-right: 2px;
  text-shadow: 1px 1px 1px #888;
  -webkit-text-shadow: 1px 1px 1px #888;
  -moz-text-shadow: 1px 1px 1px #888;
}
a:hover &#123;
  border-bottom: 1px solid;
}
#article, #header &#123;
  width: 950px;
  background-color: #FFF;
  padding: 10px;
  padding-left: 15px;
  margin: 15px;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}
pre &#123;
  width: 900px;
  padding: 5px;
  padding-right: 10px;
  padding-left: 10px;
  margin: 5px;
  margin-top: 20px;
  margin-bottom: 30px;
  box-shadow: 5px 5px 5px #888;
  -webkit-box-shadow: 5px 5px 5px #888;
  -moz-box-shadow: 5px 5px 5px #888;
  border-radius: 5px;
  -moz-border-radius: 5px;
  -webkit-border-radius: 5px;
}

Using highlight.js rather than pygments:

cd ~/blog
mkdir vendor/
# highlight.js as mentioned above
mv ~/Downloads/highlight.zip vendor/ 
cd vendor/
unzip highlight.zip
rm highlight.zip

Create a site template:

cd ~/blog
mkdir _layouts

./_layouts/default.html

<!DOCTYPE html>
<html>
<head>
<title>&#123;&#123; page.title }}</title>
<link rel="stylesheet" type="text/css" href="/stylesheets/fastr.css.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/vendor/highlight/styles/sunburst.css" media="screen" />
<script src="/vendor/highlight/highlight.pack.js"></script>
<script>
  hljs.initHighlightingOnLoad();
</script>
</head>

<body>
  <h1 id="header">&#123;&#123; page.title }}</h1>

  <div id="article">
    &#123;&#123; content }}
  </div>
</body>
</html>

./_layouts/article.html

---
layout: default
---
<div>
  &#123;&#123; content }}
</div>
<em>Updated at &#123;&#123; page.updated_at }} </em>

This next part is a bit of a hack, but it will list all of the categories and also each article by category.

./index.html

Note: In the ruby "underneath the hood" (TM) categories is an iterator which returns two elements. The first is the category name. The second is an array of posts. Since liquid (part of Jekyll) doesn't consider the string an iterator, it skips over it in the posts loop. Hence for posts in category only loops over the second argument. The same affect can be acheived with rake, but that won't run on github. If you care to dig into liquid, there are alternate ways to solve this problem.

---
layout: default
title: Fastr Blog
---
<h2>Categories:</h2>
<ul>
&#123;% for category in site.categories %}
  <li><a href="#&#123;&#123; category | first }}">&#123;&#123; category | first }}</a></li>
&#123;% endfor %}
</ul>

<h2>Articles by Category:</h2>
<ul>
&#123;% for category in site.categories %}
  <li><a name="&#123;&#123; category | first }}">&#123;&#123; category | first }}</a>
    <ul>
    &#123;% for posts in category %}
      &#123;% for post in posts %}
        <li><a href="&#123;&#123; post.url }}">&#123;&#123; post.title }}</a></li>
      &#123;% endfor %}
    &#123;% endfor %}
    </ul>
    <br/>
  </li>
&#123;% endfor %}
</ul>

&#123;% for post in site.categories.quickstart %}
<!-- h2><a href=".&#123;&#123; post.url }}">&#123;&#123; post.title }}</a></h2 -->
<!-- &#123;&#123; post.content }} -->
&#123;% endfor %}

Page generated: &#123;&#123; site.time | date_to_string }}

Script to create articles:

Articles must be in the format YYYY-MM-DD-Title-of-Article.markup such as 2010-08-05-Installing-Jekyll.markdown. This script puts the date and format for you, that way you just write the title.

./mkdocument

#!/bin/bash
TITLE=$&#123;1}
POSTDIR=./_posts

if [ ! -n "$&#123;TITLE}" ]; then
  echo "USAGE: mkpost title-of-post"
  exit 1
fi

if [ ! -n "$&#123;EDITOR}" ]; then
  if [ -n "`which vim`" ]; then
    EDITOR=vim
  elif [ -n "`which nano`" ]; then
    EDITOR=nano
  elif [ -n "`which emacs`" ]; then
    EDITOR=emacs
  else
    echo "Couldn't find an editor. Tried vim, nano, & emacs. Try \`export EDITOR=your-favorite-editor\` "
  fi
fi

FILE=`date "+%Y-%m-%d"`-$&#123;TITLE}.markdown

if [ ! -e "$&#123;POSTDIR}/$&#123;FILE}" ]
then
  mkdir -p $&#123;POSTDIR}
  cat - > $&#123;POSTDIR}/$&#123;FILE} << EOF
---
layout: article
title: `echo $&#123;TITLE} | sed 's/-/ /g'`
categories: !!UPDATED ME!!
updated_at: `date +'%Y-%m-%d'`
rendered: site.time
---


You just created " $&#123;POSTDIR}/$&#123;FILE} "! 

Notice the UPDATED ME in the categories above.
Please change that to be a category.

Your article starts after the last -- above.


Remember

    Code blocks are indented by 4 spaces

Paragraphs have two spaces between lines.
Sentances have one.

  * lists can be bullet
  * like this

or

  1. can be numbered
  2. like this

Large Header
====

Small Header
----

>  block quotes have
>  a carret and two spaces
>
>    and can contain code
>
>  * bullets
>
>  1. etc

EOF
fi

$EDITOR $&#123;POSTDIR}/$&#123;FILE}

Creating an article:

cd ~/blog
./mkpost Name-of-Article
# new file is created in ~/blog/_posts/

Formating an article:

---
layout: default
title: Awesome Post
categories: foo, bar, baz
---

This will be the best blog ever.

Configure our site:

  • pygments provides code highlighting
  • rdiscount parses markdown formatting more similarly to showdown

./blog/_config.yml

destination: /var/www/your_folder_goes_here
pygments: true
markdown: rdiscount
lsi: true
exclude: mkarticle
permalink: /articles/:title.html

Hosting the site on Github

Create an account

Jekyll sites can be hosted via Github Pages

  1. visit github.com
  2. click Signup
  3. create account (we assume the user fastr for this demo)

Add an ssh key

  1. visit your Account Page
  2. click Add another public key
  3. the Title may be any name you wish
  4. cat ~/.ssh/id_rsaa.pub 2>/dev/null || ( ssh-keygen && cat ~/.ssh/id_rsa.pub )
  5. past the output from the line above into the Key

Setup Git

sudo apt-get install git-core
git config --global user.name "Your Name Goes Here"
git config --global user.email your_email_goes_here@email.com

Add the site repository

  1. visit github.com
  2. click New repository
  3. Project Details
    • Name would be fastr.github.com

Create the repository

cd ~/blog # do this instead of `mkdir fastr.github.com`; cd fastr.github.com
git init
touch README.md
git add .
git commit -m 'first commit'
git remote add origin git@github.com:fastr/fastr.github.com.git
git push origin master

Appendix

Tags

http://gist.github.com/143571

generate_tags.rb:

namespace :tags do
  task :generate do
    puts 'Generating tags...'
    require 'rubygems'
    require 'jekyll'
    include Jekyll::Filters

    options = Jekyll.configuration(&#123;})
    site = Jekyll::Site.new(options)
    site.read_posts('')

    html =<<-HTML
---
layout: default
title: Tags
---

<h2>Tags</h2>

    HTML

    site.categories.sort.each do |category, posts|
      html << <<-HTML
      <h3 id="#&#123;category}">#&#123;category}</h3>
      HTML

      html << '<ul class="posts">'
      posts.each do |post|
        post_data = post.to_liquid
        html << <<-HTML
          <li>
            <div>#&#123;date_to_string post.date}</div>
            <a href="#&#123;post.url}">#&#123;post_data['title']}</a>
          </li>
        HTML
      end
      html << '</ul>'
    end

    File.open('tags.html', 'w+') do |file|
      file.puts html
    end

    puts 'Done.'
  end
end

Official Ruby

To keep things simple, it's probably best to use the official version of ruby and rubygems rather than the pre-packaged ubuntu version.

If you have Ubuntu 10.10, using the prepackaged version should be fine, but there are several issues with earlier versions and ruby1.8 vs ruby1.9 yuckiness.

I would always recommend the official version of rubygems over the pre-packaged version.

Installing GCC (to build ruby)

sudo apt-get install build-essential

Installing Ruby

Just grabbing the latest release which passes the test cases should be fine.

Just google 'ruby download' or follow my instructions blindly.

cd ~/
wget ftp://ftp.ruby-lang.org//pub/ruby/ruby-1.9-stable.tar.gz
tar xf ruby*
cd ruby-*
./configure && make && make test
sudo make install

Installing RubyGems

Easy enough to install. Just google 'rubygems download' or follow my instructions blindly.

cd ~/
wget http://production.cf.rubygems.org/rubygems/rubygems-1.3.7.tgz
tar xf rubygems-*
cd rubygems-*
sudo ruby setup.rb

Partition MicroSDHC for Gumstix Overo(View Stand-alone)

Goal

UPDATE: fixed a bug with the number of cylinders. Now cards larger than 2gb will register their full size.

A script that can be run by a someone not familiar with the instrinsics of the Gumstix Overo to create a boot-image-ready microSDHC card of any size.

In the case that the script runs on the overo:

sudo partition-overo-sdhc.sh /dev/mmcblk0

In the case that the script runs on another Linux box:

sudo partition-overo-sdhc.sh /dev/sdf

Script

The following script automates the process described by Gumstix Overo: Creating a bootable microSD card

It may be run on the Gumstix Overo or on a system with an appropriate microSDHC reader.

/usr/local/bin/partition-overo-sdhc.sh:

#!/bin/bash
#http://www.gumstix.net/Setup-and-Programming/view/Overo-Setup-and-Programming/Creating-a-bootable-microSD-card/111.html

# set this script to exit at any point an operation returns failure
set -e

# Create the environment for this script
DEV=$1
DEFAULT_DEV=/dev/mmcblk0
IS_OVERO=`cat /proc/cpuinfo | grep Overo || true`
IS_MMCBLK=`echo ${DEV} | grep /dev/mmcblk || true`

if [ ! -n "${DEV}" ]
then
  if [ -n "${IS_OVERO}" ]
  then
    echo "About to partition (DESTROY data) ${DEFAULT_DEV}"
    DEV=${DEFAULT_DEV}
    echo "CTRL+C now if that's not what you wanted..."
    sleep 3
    echo "continuing..."
  else
    echo -n 'Usage: `'$0' /dev/MICRO_SDHC_BLOCK_DEVICE`'
    exit 1;
  fi
fi

# Attempt to ensure that the disk is not in use
umount ${DEV} 2>/dev/null || true
umount ${DEV} 2>/dev/null || true

# Backup the MBR - in case the working hard drive is specified by mistake, rather than the sd card
dd if=$DEV of=./mbr.bak bs=512 count=1 2> /dev/null
echo "Created backup of MBR... just to be safe"
echo 'use `dd of='${DEV}' if=./mbr.bak bs=512 count=1` to restore or `rm mbr.bak` to remove'

# Calculate what the number of cylinders should be according to the overo uboot specs
let BYTES=`fdisk $DEV -l | grep Disk | grep bytes | cut -d',' -f2 | cut -d' ' -f2`
CYL=$(($BYTES/255/63/512))

# This scripts fdisk to run in expert mode
# it changes the head, sector, and cylinder, to match those required for the overo uboot
# it then creates a 32mb FAT boot partition and uses the rest of the card for the rootfs
#
# Comments may not be placed between the EOF blocks below
fdisk $DEV << EOF >/dev/null 2>/dev/null || true
o
x
h
255
s
63
c
$CYL
r
n
p
1
1
+32M
t
c
a
1
n
p
2
6

w
EOF
# The return of this process is almost always false due to that the kernel cannot resync the
# partition table.
# A reboot (on the overo) or unplugging and replugging the sdhc (on a Linux box)
# is required before continuing on to copy over the SD image.

# Overo Note:
# if the `reboot` command doesn't work use
# echo b > /proc/sysrq-trigger
# which is similar to a hard power cycle

echo -n "Probably prepared SD card successfully..."
if [ -n "${IS_OVERO}" ] && [ -n "${IS_MMCBLK}"  ]
then
  echo "The overo should be rebooted (to resync the partition table with the kernel) because you can't hot-swap/reinsert the microSDHC."
  echo 'Try `reboot` (soft, but sometimes hangs) or `cd /; umount -a; sync; echo b > /proc/sysrq-trigger` (power cycle)'
else
  echo "The microSDHC must be removed from and reinserted into the card reader to continue"
fi

IP Address Basics(View Stand-alone)

Goal

Explain the basics of networking to a person familiar with a Western-US-style grid system such that he can properly set the ip address of a gumstix overo manually when dhcp is not available.

It's important to understand not just how to set up one gumstix, but other network devices that are laying around might need to be set up too, hence the explanation.

WARNING: This needs major revision before it meets that goal.

An IP Address is like a Street Address

If you've lived in the west you may be familiar with the grid system. There's Center St, Main St, and perhaps State St or University Ave in every city. From Center St and north all streets are called Nth North. Likewise south of center are all Nth South. East and West of main all streets are called Nth East and Nth West.

Likewise, ip addresses tell one computer where it can find another.

Common IP addresses

  • 10.x.x.yyy - large private network
  • 192.168.x.yyy - small private network
  • 169.254.yyy.yyy - automatic network (no internet access)
  • 127.0.0.1 - "localhost" - the non-functional loopback network address for testing and compatibility
  • yyy.yyy.yyy.yyy - internet address

A Gateway is like State St (in the west anyway)

In the west you can get (almost) anywhere in the city without needing a map. You may need directions to get from one city to the next (or to the interstate), but often you can count on State St to take you there.

The gateway is somewhat like State St, it helps you get to the next network over - such as the large internet.

Common Gateway address

* 10.x.x.1 - large private network
* 192.168.x.1 - small private network
* yyy.yyy.yyy.yyy - public network
* automatic networks have no gateway

A computer which does not connect to the internet does not have a gateway

Netmask is like city limits

Let's say you're 2 miles into your 30 mile trip to get to a certain 2900 N (along State St rather than the interstate - for example's sake). You just passed a 2500 N and all of the sudden you're at 1700 S. What!? Weren't you trying to get to 2900 N?

You've crossed the city limit! But that's okay, right? The 2900 N you're looking for is in a city another 28 miles away.

A netmask is like a city limit. It tells the computer how far it can expect to be able to search before going to the gateway.

Literally, the netmask is the value that gets bitwise ANDed with the ip of the computer to determine the network size.

Common Netmasks

* 255.255.255.0 - small private network
* 255.255.0.0 - large private network, automatic network
* 255.255.255.240 - 16 leased public (internet) addresses in a multi-office complex

255.255.0.0 is almost always a safe value if you're not sure what to put. There are plenty of Online Network Calculators to help with advanced settings.

DNS is like a GPS

For those of you from the east, you might find it difficult to tell Tom that Dick lives on 200 E, 300 N... or was it 300 E, 200 N... (people from the west are all too familiar with that problem) anyway, you'd remember Jefferson Ave and 15 Sidney Lane a lot easier if Dick lived at that address. Harry's GPS would allow you to put in easy-to-remember coordinates and give back exact grid-system coordinates.

www.google.com is like Jefferson Ave. 74.125.19.100 is like 200 E, 300N.

DNS is like GPS that translates web names to addresses.

Lucky for us, the only two DNS we need are both gri-system and easy-to-remember (too bad they aren't the pre-loaded defaults)

  • 8.8.8.8
  • 8.8.4.4

Example 1

Let's say that we have a small public network in a multi-office complex. For this senario we'll pretend that we're the cool kids at the googleplex.

  • We know that we have 16 addresses on our network
  • The whiteboard shows that 74.125.19.75 is not in use so we want to use that to put a test system public and live.
  • The netmask would be something like 255.255.0.0 by default, but we know that really it's 255.255.255.240 (because we only have 16 addresses)
  • The gateway would probably be 74.125.19.65 - the first available address on the network (just like 192.168.1.1, but in a higher subnet)
  • We want our DNS to be 8.8.8.8 (always)

In an ad-hoc (transient) configuration that it lost on reboot or when the network cable is unplugged:

# We have a working network card
ping -c 1 127.0.0.1 >/dev/null

# We're on a network with this gateway
ifconfig eth0 74.125.19.75 netmask 255.255.255.240 up
ping -c 1 74.125.19.65 >/dev/null

# Our gateway takes us to the internet
route add default gw 74.125.19.65
ping -c 1 8.8.8.8 >/dev/null

# We can resolve human-readable addresses
sh -c 'echo "nameserver 8.8.8.8" >> /etc/resolv.conf'
sh -c 'echo "nameserver 8.8.4.4" >> /etc/resolv.conf'
ping -c 1 www.google.com >/dev/null

In a more permanent configuration:

/etc/network/interfaces

auto eth0 eth0:0 eth0:3
# no DHCP, no static IP. Great OOBE
iface eth0 inet static
  address 169.254.0.10
  netmask 255.255.0.0

# what customers are already familiar with
iface eth0:0 inet static
  address 192.168.1.10
  netmask 255.255.255.0

# an address to use for testing on the internet
iface eth0:3 inet static
  address 74.125.19.77
  netmask 255.255.255.240
  network 74.125.19.64
  broadcast 74.125.19.79
  gateway 74.125.19.65

Example 2

A computer with the address of 192.168.254.53 and a netmask of 255.255.0.0 knows that it can only find computers within the 192.168.yyy.yyy network. If the netmask were 255.255.255.0 it would only look within 192.168.254.yyy. If the netmask were 255.255.255.240 it would assume that it needed to go to the gateway to reach any computer not between 192.168.254.49 and 192.168.254.62. The network would be literally 192.168.254.64 and the broadcast would be 192.168.254.80. In each subnet you lose 2 addresses.

Your gateway would most likely be 192.168.254.65 - the first available address on the subnet.

Format MicroSDHC for Gumstix Overo(View Stand-alone)

Goal

A script to run after the microSDHC has been partitioned properly for the gumstix overo to install the over-image of choice from a host system.

In the case that the script runs on the overo:

sudo install-overo-image-to-sdhc.sh /dev/mmcblk0

In the case that the script runs on another Linux box:

sudo install-overo-image-to-sdhc.sh /dev/sdf

Pre-Requisists

  • The host (server) system should have already run bitbake omap3-console-image
  • The microSDHC should have been partitioned appropriately

Script

install-overo-image-to-sdhc.env

There are quite a few variables here - more than just the card to install to.

/usr/local/bin/install-overo-image-to-sdhc.env:

# About the host system
USER=harry
HOST=192.168.1.20
PORT=22
export SCP_HOST="-P ${PORT} ${USER}@${HOST}"
export NET_CONF=/home/${USER}/Code/development/main/overo/etc/network/interfaces


# Where ~/overo-oe can be found
OE_PATH=/home/${USER}
export OVERO_PATH=${OE_PATH}/overo-oe/tmp/deploy/glibc/images/overo


# Boot options
KERNEL=''
FORMAT=tar.bz2
export MLO=${OVERO_PATH}/MLO-overo
export UBOOT=${OVERO_PATH}/u-boot-overo.bin
export UIMAGE=${OVERO_PATH}/uImage-${KERNEL}overo.bin
export ROOTFS=omap3-console-image-overo.${FORMAT}


# Create the environment for this script
export MNT=/mnt/overo_tmp


# NOTE /dev/shm is way faster but may not be available once the filesystem size is large
# TODO TMDIR should not be allowed to be MNT
# TODO this script should not run from MNT
export TMPDIR=/dev/shm

/usr/local/bin/install-overo-image-to-sdhc.sh:

#!/bin/bash
#http://www.gumstix.net/Setup-and-Programming/view/Overo-Setup-and-Programming/Creating-a-bootable-microSD-card/111.html

# set this script to exit at any point an operation returns failure
set -e

# Create the environment for this script
source install-overo-image-to-sdhc.env

DEV=$1
DEFAULT_DEV=/dev/mmcblk0
IS_OVERO=`cat /proc/cpuinfo | grep Overo || true`
IS_MMCBLK=`echo ${DEV} | grep /dev/mmcblk || true`

if [ ! -n "${DEV}" ]
then
  if [ -n "${IS_OVERO}" ]
  then
    echo "About to format (DESTROY data) ${DEFAULT_DEV}"
    DEV=${DEFAULT_DEV}
    echo "CTRL+C now if that's not what you wanted..."
    sleep 3
    echo "continuing..."
  else
    echo -n 'Usage: `'$0' /dev/MICRO_SDHC_BLOCK_DEVICE`'
    exit 1;
  fi
fi

# About the target system
# Matches mmcblk0p1 disk0s1 sdf1 - OpenEmbedded, Ubuntu, BSD
BOOT=${DEV}'*1'
ROOT=${DEV}'*2'


# Attempt to ensure that the disk is not in use
umount $DEV* 2>/dev/null || true
umount $DEV* 2>/dev/null || true

# Ready the mount point
umount $MNT || true
rm -rf $MNT
mkdir -p $MNT


# TODO this will fail due to -P
# TODO give overo units a sandboxed ssh key 
# or use curl to initiate a reverse connection
# ssh-copy-id $SCP_HOST

# Prepare FAT boot partition
# MLO *must* be installed first
mkfs.vfat -F 32 $BOOT -n FAT
mount $BOOT $MNT
scp $SCP_HOST:$MLO $MNT/MLO
scp $SCP_HOST:$UBOOT $MNT/u-boot.bin
scp $SCP_HOST:$UIMAGE $MNT/uImage
echo "sync-ing... this may take several seconds"
umount $MNT
umount $BOOT 2>/dev/null || true # overo auto-mounts in /media sometimes


# Prepare rootfs
mkfs.ext3 ${ROOT}
mount ${ROOT} /${MNT}
scp ${SCP_HOST}:${OVERO_PATH}/${ROOTFS} ${TMPDIR}/${ROOTFS}
tar xvjf ${TMPDIR}/${ROOTFS} -C $MNT #BAH! Takes forever!
rm ${TMPDIR}/${ROOTFS}


# Configure rootfs with any special sauce we might need
scp ${SCP_HOST}:${NET_CONF} ${MNT}/etc/network/
ln -s "/sbin/dhclient" ${MNT}/sbin/dhclient3 2>/dev/null || true
ln -s "/var/lib/dhcp" ${MNT}/var/lib/dhcp3 2>/dev/null || true


# sync and umount
echo "sync-ing... this may take several minutes"
umount $MNT
umount $ROOT 2>/dev/null || true


# Cleanup any mess we madermdir $MNT || true
#rm -rf $MNT

# sync and reboot!
sync
sync
#echo 1 > /proc/sys/kernel/sysrq

echo "copied sd card successfully"


# if the process fails, enter uboot and `run nandboot` to boot the nand rather than the sd card
# Kernel from NAND, RootFS from MMC
# setenv bootargs console=${console} mpurate=${mpurate} vram=${vram} omapfb.mode=dvi:${dvimode} omapfb.debug=y omapdss.def_disp=${defaultdisplay} root=${mmcroot} rootfstype=${mmcrootfstype}
# setenv bootargs console=${console} mpurate=${mpurate} vram=${vram} omapfb.mode=dvi:${dvimode} omapfb.debug=y omapdss.def_disp=${defaultdisplay} root=${mmcroot} rootfstype=${mmcrootfstype}
# nand read ${loadaddr} 280000 400000; bootm ${loadaddr}
# the first boot takes forever to load
# mixedboot=echo Kernel on nand, RootFS on mmc...; run mmcargs; nand read ${loadaddr} 280000 400000; bootm ${loadaddr}

bitbake libv8 - v8 on OpenEmbedded(View Stand-alone)

Goal

I would like to be able to cross-compile v8 using bitbake.

If you're interested in building it natively on a Gumstix Overo, that's done. Google my first post about node.JS on OpenEmbedded.

bitbake libv8
opkg install libv8

Current Status

scons doesn't use environment variables, so trying to get it working "the scons way" TM seems a lost cause, but I'll check on the scons, v8, and bitbake mailing list with my proposed method to be sure.

However, with a little Makefile magic I can get it to compile well enough it seems.

${OVEROTOP}/user.collection/recipes/libv8/libv8_r5266.bb

DESCRIPTION = "V8 JavaScript Engine"
PR = "r0"
DEPENDS = ""
SRC_URI = " \
svn://v8.googlecode.com/svn;module=trunk;proto=http;rev=5266 \
file://overo-opts.patch \
file://Makefile \
"
S = "${WORKDIR}/trunk"
FILES_${PN} = "${bindir}/libv8"
do_install() {
# install the lib somewhere?
}

#inherit scons # doesn't currently provide meaningful setup

${OVEROTOP}/user.collection/recipes/libv8/files/Makefile

all:
  CC=`which ${CC}` CXX=`which ${CXX}` AR=`which ${AR}` RANLIB=`which ${RANLIB}` scons arch=arm

.PHONY: all

${OVEROTOP}/user.collection/recipes/libv8/files/overo-opts.patch

diff --git trunk/SConstruct.orig trunk/SConstruct
index 0abaeed..b85262a 100644
--- trunk/SConstruct.orig
+++ trunk/SConstruct
@@ -42,6 +42,13 @@ ANDROID_TOP = os.environ.get('TOP')
 if ANDROID_TOP is None:
   ANDROID_TOP=""

+# OVERO_TOP is the top of the Overo checkout, fetched from the environment
+# variable 'OVERO_TOP'.   You will also need to set the CXX, CC, AR and RANLIB
+# environment variables to the cross-compiling tools.
+OVERO_TOP = os.environ.get('OVEROTOP')
+if OVERO_TOP is None:
+  OVERO_TOP=""
+
 # ARM_TARGET_LIB is the path to the dynamic library to use on the target
 # machine if cross-compiling to an arm machine. You will also need to set
 # the additional cross-compiling environment variables to the cross compiler.
@@ -108,6 +115,9 @@ ANDROID_LINKFLAGS = ['-nostdlib',
                      ANDROID_TOP + '/prebuilt/linux-x86/toolchain/arm-eabi-4.4.0/lib/gcc/arm-eabi/4.4.0/interwork/libgcc.a',
                      ANDROID_TOP + '/out/target/product/generic/obj/lib/crtend_android.o'];

+OVERO_FLAGS = ANDROID_FLAGS # Verizon Droids are armv7-a cortex-a8, I suppose that should be similar enough
+OVERO_INCLUDES = "" # TODO
+
 LIBRARY_FLAGS = {
   'all': {
     'CPPPATH': [join(root_dir, 'src')],
@@ -197,6 +207,14 @@ LIBRARY_FLAGS = {
                        '-Wstrict-aliasing=2'],
       'CPPPATH':      ANDROID_INCLUDES,
     },
+    'os:overo': {
+      'CPPDEFINES':   ['V8_TARGET_ARCH_ARM', '__ARM_ARCH_5__', '__ARM_ARCH_5T__',
+                       '__ARM_ARCH_5E__', '__ARM_ARCH_5TE__'],
+      'CCFLAGS':      OVERO_FLAGS,
+      'WARNINGFLAGS': ['-Wall', '-Wno-unused', '-Werror=return-type',
+                       '-Wstrict-aliasing=2'],
+      'CPPPATH':      OVERO_INCLUDES,
+    },
     'arch:ia32': {
       'CPPDEFINES':   ['V8_TARGET_ARCH_IA32'],
       'CCFLAGS':      ['-m32'],
@@ -204,6 +222,8 @@ LIBRARY_FLAGS = {
     },
     'arch:arm': {
       'CPPDEFINES':   ['V8_TARGET_ARCH_ARM'],
+      'CCFLAGS':      OVERO_FLAGS,
+      'CPPPATH':      OVERO_INCLUDES,
       'unalignedaccesses:on' : {
         'CPPDEFINES' : ['CAN_USE_UNALIGNED_ACCESSES=1']
       },
@@ -673,7 +693,7 @@ SIMPLE_OPTIONS = {
     'help': 'the toolchain to use (' + TOOLCHAIN_GUESS + ')'
   },
   'os': {
-    'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd', 'solaris'],
+    'values': ['freebsd', 'linux', 'macos', 'win32', 'android', 'openbsd', 'overo', 'solaris'],
     'default': OS_GUESS,
     'help': 'the os to build for (' + OS_GUESS + ')'
   },

Manual Cross-Compile

Here's a way to cross-compile without any patches or fully using bitbake:

bitbake v8
# fails, of course
cd ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/libv8-r5266-r0/trunk
USER=my-user-name \
CROSS_DIR=/home/${USER}/overo-oe/tmp/cross/armv7a/bin \
CC="${CROSS_DIR}/arm-angstrom-linux-gnueabi-gcc -march=armv7-a -mtune=cortex-a8" \
CXX="${CROSS_DIR}/arm-angstrom-linux-gnueabi-g++ -march=armv7-a -mtune=cortex-a8" \
scons arch=arm

Or without bitbake at all (you could even use your trusty arm-none-linux-gnueabi-xyz):

cd ~/
svn checkout svn://v8.googlecode.com/svn v8-read-only
cd v8-read-only
USER=my-user-name \
CROSS_DIR=/home/${USER}/overo-oe/tmp/cross/armv7a/bin \
CROSS_COMPILE=${CROSS_DIR}/arm-angstrom-linux-gnueabi- \
CC="${CROSS_COMPILE}gcc -march=armv7-a -mtune=cortex-a8" \
CXX="${CROSS_COMPILE}g++ -march=armv7-a -mtune=cortex-a8" \
scons arch=arm

And how to add an OS

cd 
git diff --no-prefix SConstruct.orig SConstruct > overo-opts.patch

TODO

Figure out which of these to use and which not to in SConstruct

I'm guessing I should set the LDFLAGS all the same for the overo libs, but leave the android optimized CFLAGS

BUILD_CFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/include -O2 -g'
BUILD_CPPFLAGS=-isystem/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/include
BUILD_CXXFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/include -O2 -g -fpermissive'
BUILD_LDFLAGS='-L/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/lib -Wl,-rpath-link,/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/lib -Wl,-rpath,/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/lib -Wl,-O1'
CFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3'
CPPFLAGS=-isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include
CXXFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3 -fpermissive -fvisibility-inlines-hidden'
EXTRA_OEMAKE=' -e MAKEFLAGS='
LDFLAGS='-L/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/lib -Wl,-rpath-link,/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/lib -Wl,-O1 -Wl,--hash-style=gnu'
SDK_CFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/include -isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3'
SDK_CPPFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/include -isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include'
SDK_CXXFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/include -isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3 -fpermissive'
SDK_LDFLAGS='-L/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/lib -Wl,-rpath-link,/home/${USER}/overo-oe/tmp/sysroots/i686-linux/usr/lib -Wl,-O1'
TARGET_CFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3'
TARGET_CPPFLAGS=-isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include
TARGET_CXXFLAGS='-isystem/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/include -fexpensive-optimizations -frename-registers -fomit-frame-pointer -O2 -ggdb3 -fpermissive'
TARGET_LDFLAGS='-L/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/lib -Wl,-rpath-link,/home/${USER}/overo-oe/tmp/sysroots/armv7a-angstrom-linux-gnueabi/usr/lib -Wl,-O1 -Wl,--hash-style=gnu'

bitbake node - Node.js on OpenEmbedded(View Stand-alone)

Goal

I would like to be able to cross-compile nodejs using bitbake. (I've already got it natively compiled on the Gumstix Overo)

bitbake node
opkg install node

Current Status

It compiles!!! Now I just have to finish packaging it as a bitbake recipe.

  1. setup your gumstix build environment
  2. Copy the recipe below and put it in the location specified, creating folders as necessary.
  3. run bitbake node
  4. once it fails, go in ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/node-0.1.104-r0/node-0.1.104/ and edit the files by hand.
  5. bitbake node again. It should succeed.
  6. copy the raw ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/node-0.1.104-r0/node-v0.1.104/node whereever you need it.

Files

These are the files I have so far. They still need a few tweaks before I create a bitbake recipe.

They do compile and leave the useable node binary in ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/node-0.1.104-r0/node-v0.1.104/node.

They don't create the ${OVEROTOP}/tmp/deploy/glibc/ipk/armv7a/node_0.1.104.ipk that you would hope for... yet.

${OVEROTOP}/user.collection/node/node_0.1.104.bb

DESCRIPTION = "nodeJS Evented I/O for V8 JavaScript"
PR = "r0"
DEPENDS = "openssl"
SRC_URI = " \
http://nodejs.org/dist/node-v${PV}.tar.gz \
"
#file://libev-arm-crass.patch;apply=yes \
#file://node-arm-cross.patch;apply=yes \
SRC_URI[md5sum] = "907fa1e0a2f1f0c3df5efc97fd05a7d2"
SRC_URI[sha256sum] = "a1c776f44bc07305dc0e56df17cc3260eaafa0394c3b06c27448ad85bec272df"
S = "${WORKDIR}/node-v${PV}"
do_configure () {
./configure
}
do_qa_configure () {
# skip false alarm
# ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/node-0.1.104-r0/node-v0.1.104/build/config.log
}
do_compile () {
make
}
do_install () {
install -d ${D}${bindir}/
install -m 0755 ${S}/node ${D}${bindir}/
}
FILES_${PN} = "${bindir}/node"

${OVEROTOP}/user.collection/node/node-static_0.1.104.bb

Same as above with one major change:

DEPENDS = "openssl-static"

./node-v0.1.104/deps/libev/wscript in the temp builddir

This will become files/libev-arm-cross.patch once packaged.

Currently you can modify the failed build in place from ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/node-0.1.104-r0/

--- a/deps/libev/wscript
+++ b/deps/libev/wscript
@@ -41,6 +41,7 @@ def configure(conf):
     conf.check_cc(header_name="sys/eventfd.h", function_name="eventfd")


+  ''' Can't run cross-binary code
   code = """
       #include <syscall.h>
       #include <time.h>
@@ -54,6 +55,8 @@ def configure(conf):
   """
   conf.check_cc(fragment=code, define_name="HAVE_CLOCK_SYSCALL", execute=True,
                 msg="Checking for SYS_clock_gettime")
+  '''
+  conf.define('HAVE_CLOCK_SYSCALL', 1)

   have_librt = conf.check(lib='rt', uselib_store='RT')
   if have_librt:

./node-v0.1.104/wscript in the temp builddir

This will become files/node-arm-cross.patch once packaged.

Currently you can modify the failed build in place from ${OVEROTOP}/tmp/work/armv7a-angstrom-linux-gnueabi/node-0.1.104-r0/

--- a/wscript
+++ b/wscript
@@ -319,11 +319,15 @@ def v8_cmd(bld, variant):
   if bld.env['DEST_CPU'] == 'x86_64':
     arch = "arch=x64"

+  if bld.env['AR'] == 'arm-angstrom-linux-gnueabi-ar': # TODO use -1 != str.find('arm-xxx-linux-gnueabi)
+    arch = "arch=arm"
+  
   if variant == "default":
     mode = "release"
   else:
     mode = "debug"

and another snippet:

-  cmd_R = 'python "%s" -j %d -C "%s" -Y "%s" visibility=default mode=%s %s library=static snapshot=on'
+  cmd_R = 'python "%s" -j %d -C "%s" -Y "%s" visibility=default mode=%s %s library=static'

Sharing project files with a team using ACLs on Ubuntu(View Stand-alone)

Goal

One installation of overo-oe that all team-members can have read-write access to.

Installation

The acl tools package

sudo apt-get install acl

This contains

acl
getfacl
setfacl

The gui acl package for nautilus

sudo apt-get install eiciel

Mounting with ACLs

Modify the / or /home partition (or wherever) to include ACL support

vim /etc/fstab

Just add acl after defaults

# /home was on /dev/sda5 during installation
UUID=488cd15e-8d2a-45e2-9ed0-00f9643e8cf2 /home           ext3    defaults,acl        0       2    

And then remount

sudo mount /home -o remount

Setting up a shared location

To keep things simple I create a directory /home/shared, owned by root and give all users rwx by default.

This means that any new file or directory created within this directory wil have rwx.

setfacl --physical --set default:other::rwx /home/shared/
# or in a more sensitive environment
# setfacl --recursive --set u:harry:rwx /home/shared

The caveat is that files copied or moved will have the same permission that they previously had. They will not get updated.

cd ~/
mv overo-oe/tmp /home/shared/overo-oe-tmp
ln -s /home/shared/overo-oe-tmp overo-oe/tmp
setfacl --recursive --set default:other::rwx /home/shared/overo-oe-tmp

Resources

Sharing a private git repository with a consultant(View Stand-alone)

Goal

Allow a consultant to access the source-code of a specific project for a limited time.

Background

Many consultants are hardware gurus or software gurus, but don't necessarily have proficiency with Linux, git, etc.

Pre-Requisites

  • Ubunut Server 9.04+
  • gitosis (see previous article)

Informing the consultant

Tom,

I'm giving you access to our codebase directly so that you can make changes and we can get frequent updates and review the changes (and see the comments).

I need you to e-mail me your public ssh key in order to give you access. You can find that in ~/.ssh/id_rsa.pub (or create it using ssh-keygen).

Alternatively, you can place the attached id_rsa in ~/.ssh/ and start right away.

Once we have the ssh keys you can access the repository like so:

sudo apt-get install git-core
cd ~/
git clone ssh://gitosis@git.example.com:22/project-name.git

That will create the project-name folder in your home directory.

Once you make changes you will need to need to add, commit, and then push them back to us.

git stat
git add file1 file2 file3
git commit -m "some helpful message"
git push origin master

You can make as many commits before the push as you'd like. The comments will help us as we look it over and test against it.

Thanks for you help on the project!

Nick Burns

Authorizing the consultant

Create a new private/public key pair from a guest-ish account and e-mail the pair to the consultant

ssh-keygen
cp ~/.ssh/id_rsa.pub /tmp/

Add the consultant to gitosis

git clone ssh://gitosis@git.example.com:22/gitosis-admin.git
cd gitosis-admin
KEY=/tmp/id_rsa.pub
KEYNAME=`cat ${KEY} | cut -d'=' -f3 | cut -d' ' -f2`
echo ${KEYNAME}
mv ${KEY} keydir/${KEYNAME}.pub
vim gitosis.conf

Add the consultant to the particular projects

[group project-name-team]
writable = project-module-1 project-module-2
members = keyname-existing-1 keyname-existing-2 consultant-new-1

Then commit the change and the consultant has access

git add gitosis.conf keydir
git commit -m "added tom as consultant on project-name"
git push origin master

Mark your calendar to delete this key after the contract period.

Set up a private git server on ubuntu(View Stand-alone)

Goal

git clone git://my-private-server.com/project.git

Setup

The server shall be called 'git.example.com'.

The clients shall be called 'The Client'

A note about clients

gitosis uses ssh keys rather than a password to verify identity.

For each client you will need to create an ssh key (if you don't already have one).

KEYFILE=~/.ssh/id_rsa
if [ ! -f "${KEYFILE}" ]
then
  ssh-keygen -f ${KEYFILE} -N ''
fi

Each client will also need to have it's public key listed for gitosis

/srv/gitosis/.ssh/authorized_keys

Getting Started

To make things simple this will all take place from the perspective of the client machine.

ssh mike@git.example.com
apt-get -y install git-core gitosis
exit

scp ~/.ssh/id_rsa.pub mike@git.example.com:/tmp

ssh mike@git.example.com
sudo -H -u gitosis gitosis-init < /tmp/id_rsa.pub
rm /tmp/id_rsa.pub
  # perform this step only if you don't already allow regular users in via ssh
  #   sudo vim /etc/ssh/sshd_config
  #   AllowUsers gitosis
  #   sudo /etc/init.d/sshd restart
exit

cd ~/ # or wherever you'd like
git clone ssh://gitosis@git.example.com:22/gitosis-admin.git
vim gitosis-admin/gitosis.conf

For each member of the project you must add their ssh key. If they were to have e-mailed you their public keys, the process might look like this this:

Tom, Dick, Harry

Please send me a copy of your ssh key via e-mail or by placing it in /tmp/keys on the server.

Thanks,
Nick Burns
ACME CTO

cd ~/
mv ~/Downloads/id_rsa.pub gitosis-admin/keydir/tom@tom-macbook-pro-17.local.pub
mv ~/Downloads/id_rsa.pub.1 gitosis-admin/keydir/dick@ubuntu-desktop.pub
mv ~/Downloads/id_rsa.pub.2 gitosis-admin/keydir/harry@git.example.com.pub

The name of the file must match the name inside, with the .pub extension.

cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3N[..omitted..]zafWw== dick@ubuntu-server    

An automated version of the process

ls ~/Downloads/*.pub | while read KEY
do
  KEYNAME=`cat ${KEY} | cut -d'=' -f3 | cut -d' ' -f2`
  mv ${KEY} gitosis-admin/keydir/${KEYNAME}.pub
done

Once you have the keyfiles in the right place, you must specify which keyfile has access to which project

[group team_foobars]
writable = project_baz project_plusplus
members = tom@tom-macbook-pro-17.local dick@ubuntu-desktop harry@git.example.com
description = A collection of fizzbuzz from all employees
owner = Nick Burns

Now you must commit your changes

cd ~/gitosis-admin
git status
git diff
git add gitosis.conf keydir
git commit -m "added project baz and its members"
git push origin master

Creating a new project

Let's say that project_baz (as described above) is a new project. We could add it like so:

mkdir project_baz
cd project_baz
git init
git remote add origin ssh://gitosis@git.example.com:22/project_baz.git

touch README
git add .
git commit -m "Initial import"

git push origin master

Resources

Troubleshooting bitbake(View Stand-alone)

Goal

Aleviate some of the bitbake headaches.

  • NOTE: ${OVEROTOP} refers to the actual environment variable
  • NOTE: ${PACKAGE} should be replaced with the name of the package you are trying to build.

Quick hacking without devshell

If the package that you're building doesn't build you can intercept manually build in the bitbake environment and then continue.

  1. bitbake ${PACKAGE}
  2. cd ${OVEROTOP}/tmp/work/${ARCH}/${PACKAGE}_${VER}_r${REV}/${BUILD}
    • ${ARCH} is probably armv7a-angstrom-linux-gnueabi
    • ${BUILD} is a directory which is not NOT src or temp such as the package name or git or trunk or svn
    • ${VER} and ${REV} - duh.
  3. cp ../temp/run.do_compile.${OLD_PID} ./
    • ${OLD_PID} is a number like 3597 or 4352
    • do_compile could be any task - do_install, etc
  4. vim run.do_compile.1234
    1. comment out the last line: do_compile() (or do_install() or whatever)
    2. add bash --norc
  5. ./run.do_compile.${OLD_PID} will put you in an environment with all variables set
  6. make (or whatever) to try to build, debug issues
  7. exit (when done to go back to shell without run.do_compile settings)
  8. bitbake ${PACKAGE}

devshell

devshell executes after do_patch() and will give you a shell with the environment variables you need for building the package.

Common Problems

bitbake is a headache. That's just the way it is. Sorry. It's a moving target, there are lots of changes committed every few days. The testing is perhaps substandard... but it is fast-moving.

bitbake -c clean ${PACKAGE} often - after each new thing you try in the trouble shooting procedure.

Be very careful to read the error messages. Many of these errors are result of simple copy/paste/delete typos and "could not find" xzy is simply a missing symlink or a file in the wrong place.

There are a number of problems that I run into over and over.

/bin/sh couldn't find xyz

Possibilities

NOTE: xyz refers to some other package, there is no package named xyz.

  • bitbake xyz-native - it may just be that the package maintainer left DEPENDS += "xyz-native" out of xyz-native_0.bb

    1. `bitbake xyz-native
    2. bitbake -c clean ${PACKAGE}
    3. exit the current shell or terminal (to reset environment variables) and reopen a new one
    4. bitbake ${PACKAGE}
  • xyz is a broken symlink

    • find ${OVEROTOP}/tmp/ -name 'xyz'
  • No, really, exit the current shell and reopen it. Maybe even reboot? (I've never had to do this)

md5sum mismatch

  • the download had a hiccup

    1. rm sources/${PACKAGE}*
    2. bitbake -c clean ${PACKAGE}; bitbake ${PACKAGE}
  • the download script can't get the file correctly

    1. look in ${OVERTOP}/org.openembedded.dev/recipes/${PACKAGE}_${VER}.bb
    2. wget http://example.com/xyz.tgz
    3. mv xyz.tgz ${OVEROTOP}/sources/
    4. bitbake -c clean ${PACKAGE}; bitbake ${PACKAGE}
  • the file has been updated, but the md5sum in ${PACKAGE}_${VER}.bb hasn't.

    1. follow steps 1 and 2 above
    2. md5sum xyz.tgz > sources/xyz.tgz.md5
    3. sha2sum xyz.tgz > sources/xyz.tgz.sha256
    4. add the checksums to ${OVERTOP}/org.openembedded.dev/recipes/${PACKAGE}_${VER}.bb
    5. bitbake ${PACKAGE}

couldn't download the package

Some commercially available apps (such as TI's dsplink) have bitbake packages, but you must manually download the source for various legal reasons.

Worst Case

Save your changes to user.collections and start afresh. If you're super lucky you can just rebuild everything over the next few days and not have to keep solving failed build problems. In the worst worst case you might want to wait a week for patches to come in.

rm ${OVEROTOP}/tmp -rf

or even

mkdir ${OVEROTOP}.bak
mv ${OVEROTOP}/user.collection ${OVEROTOP}.bak/
rm ${OVEROTOP} -rf

and just start from the gumstix documentation for installation all over again

Some of these worst case fixes are required when

  • ABI has changed
  • tmp directory has moved

Creating a custom board_overo.c(View Stand-alone)

Goal

Basically I've got a custom board (based on the tobi) for the overo and I want to create a custom build for it with a custom kernel.

bitbake custom-board-image

1000-foot overview

  • Choose a kernel that compiles
  • Use it as a base for your custom kernel
  • Copy the source with all Overo patches built-in
  • Make the changes
  • Test
  • Create the necessary bitbake patches and files

Copying the bitbake skeleton for the kernel

First test that the kernel you wish to use as your base bitbakes successfully

bitbake linux-omap-psp

Then copy that base

cd ~/overo-oe
mkdir -p user.collection/recipes/linux/
mkdir -p user.collection/recipes/linux/files/configs
touch user.collection/recipes/linux/files/configs/.empty
cp org.openembedded.dev/recipes/linux/linux.inc user.collection/recipes/linux/
cp org.openembedded.dev/recipes/linux/multi-kernel.inc user.collection/recipes/linux/
cp org.openembedded.dev/recipes/linux/linux-omap-psp_2.6.32 \
  user.collection/recipes/linux/linux-my-custom_2.6.32.bb
cp -a org.openembedded.dev/recipes/linux/linux-omap-psp-2.6.32 \
  user.collection/recipes/linux/linux-my-custom-2.6.32

That is everything necessary to start a custom kernel. Test that it will actually build

bitbake linux-my-custom

Using bitbake to get the source + patches

cd ~/overo-oe
bitbake linux-my-custom
cp -a ./tmp/work/overo-angstrom-linux-gnueabi/linux-my-custom-2.6.32-r81 ./linux-my-custom
sudo cp -a ./tmp/work/overo-angstrom-linux-gnueabi/linux-my-custom-2.6.32-r81/git/.pc ./linux-my-custom/
cd ./linux-my-custom/
git init
git add .
git commit -m "freshly patched kernel source from mainstream"

In the appendix I list a way which may work for manually getting the source + patches.

Making customizations

Let's say a handy-dandy friend has made some modifications to board-overo.c and created board-overo-camera.c.

I can grab his files from my e-mail and plop them into the mix.

I'll check to see that the changes are good and I understand them

diff -y --suppress-common-lines ~/Downloads/board-overo.c arch/arm/mach-omap2/board-overo.c

static struct platform_device my_custom_cam_device = { <
  .name           = "my_custom_cam",                   <
  .id             = -1,                                <
};                                                     <

Then I copy it over

cp ~/Downloads/board-overo.c arch/arm/mach-omap2/board-overo.c
cp ~/Downloads/board-custom-camera.c arch/arm/mach-omap2/board-custom-camera.c
cp ~/Downloads/board-custom-camera.h arch/arm/mach-omap2/board-custom-camera.h
cp ~/Downloads/custom-cam.c drivers/media/video/custom-cam.c
cp ~/Downloads/config arch/arm/configs/overo_defconfig
cp ~/Downloads/Makefile arch/arm/mach-omap2/Makefile

I can also check the differences now

git diff

And then I commit my changes with a comment

git status
git add ./arch ./drivers
git commit -m "added custom_cam support for custom_board"

Testing

PATH=~/overo-oe/tmp/sysroots/i686-linux/usr/bin/:$PATH
#cp ~/overo-oe/tmp/sysroots/i686-linux/usr/bin/mkimage /usr/bin/
#sudo apt-get install uboot-mkimage
make ARCH=arm CROSS_COMPILE=~/overo-oe/tmp/cross/armv7a/bin/arm-angstrom-linux-gnueabi- overo_defconfig
make ARCH=arm CROSS_COMPILE=~/overo-oe/tmp/cross/armv7a/bin/arm-angstrom-linux-gnueabi- menuconfig
make ARCH=arm CROSS_COMPILE=~/overo-oe/tmp/cross/armv7a/bin/arm-angstrom-linux-gnueabi- uImage modules
scp arch/arm/boot/uImage gumstix:/media/mmcblk0p1/

TODO: use my_custom_defconfig

Creating custom patches

Creating patches for the past two commits

git format-patch -2

TODO: to be continued

Resources

Appendix

Manually getting the source + patches

In linux-my-custom_2.6.32.bb I found the original kernel source and I'm going to clone that and add the patches I need.

cd ~/overo-oe
git clone git://arago-project.org/git/people/sriram/ti-psp-omap.git
mv ti-psp-omap linux-my-custom
cd linux-my-custom
mkdir patches
cp user.collection/recipes/linux/linux-my-custom-2.6.32/*.patch patches/
# You may also want additional board patches
cp -a user.collection/recipes/linux/linux-my-custom-2.6.32/overo/ patches/

Now we want to apply all of those patches - here's a miniscript for it

ls patches/*.patch | sort | while read PATCH
do
  echo $PATCH
  git apply --stat --apply --whitespace=fix $PATCH && rm $PATCH || break
done

In my case, a few patches didn't apply so I had to apply them by hand. No big deal - probably just a problem with whitespace and line numbers.

After all that, time to commit

rm -rf patches
git add .
git commit -m "brought kernel up to mainline"

Creating a raw capture driver

These are the files to start with

./drivers/media/video/Makefile
./drivers/media/video/Kconfig
./drivers/media/video/mt9t111_reg.h
./drivers/media/video/mt9t111.c

./include/media/mt9t111.h

./arch/arm/mach-omap2/board-omap3beagle-camera.c
./arch/arm/mach-omap2/board-overo-camera.c
./arch/arm/mach-omap2/board-overo.c
./arch/arm/mach-omap2/Makefile
./arch/arm/mach-omap2/board-omap3beagle.c
#./arch/arm/mach-omap2/board-overo-camera.h

./arch/arm/configs/overo_defconfig
./arch/arm/configs/omap3_beagle_cam_defconfig
./arch/arm/configs/omap3_beagle_defconfig

Installing OMAP DVSDK on Gumstix Overo(View Stand-alone)

Goal

Get the TI demos running on the gumstix.

OMAP & DaVinci Software for Dummies might be worth reading...

TI's DVSDK & EVM packages

According to TI's Getting Started Guide: OMAP35x DVEVM Software Setup, you'll need the following packages:

For the sake of getting started things, I recommend trying the TI way first. From those packages, we won't actually use codesourcery_tools since gumstix provides gcc-cross, which fulfills the same function.

You'll may also want dsplib64plus, dsplib64plus.h, dsplib64plus.lib

  • C64x+ DSP Library (DSPLIB) (direct link) local
    • C64x+DSPLIB-2.1-Linux-Install.bin is packaged incorrectly as sprc834.gz when it should be sprc834.tgz or sprc834.tar.gz... or C64x+DSPLIB-2.1-Linux-Install.tar.gz would have been best.
    • I don't know how you can actually include this library in a project. I posted to the TI forum about it... awaiting reply.

Installing

Unpacking

You'll need to unpackage the downloads in specific locations and also unpackage some of the sub-packages. Assuming that you've downloaded all of the above into ~/Downloads:

cd ~/Downloads

./dvsdk_3_01_00_10_Setup.bin # installs to ~/dvsdk

./cs1omap3530_setupLinux_1_01_00-prebuilt-dvsdk3.01.00.10.bin # Installs to ~/cs1omap3530
ln -s ~/cs1omap3530/cs1omap3530_1_01_00 ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00
sudo ./ti_cgt_c6000_6.1.12_setup_linux_x86.bin # Installs to /opt/TI/C6000CGT6.1.12
export C6X_C_DIR=/opt/TI/C6000CGT6.1.12/include:/opt/TI/C6000CGT6.1.12/lib
echo "export C6X_C_DIR=/opt/TI/C6000CGT6.1.12/include:/opt/TI/C6000CGT6.1.12/lib" >> ~/.bashrc

tar xf data_dvsdk_3_01_00_10.tar.gz -C ~/dvsdk/dvsdk_3_01_00_10/clips/

tar xf AM35x-OMAP35x-PSP-SDK-03.00.01.06.tar.gz -C ~/
cd ~/AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/kernel/
tar xf linux-03.00.01.06.tar.gz
cd ~/AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/u-boot/
tar xf u-boot-03.00.01.06.tar.gz
cd ~/AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/examples
tar xf examples.tar.gz

mv sprc834.gz sprc834.tar.gz
tar xf sprc834.tar.gz
./C64x+DSPLIB-2.1-Linux-Install.bin # Installs to ~/C64x+DSPLIB
sed -i 's,\\,/,g' ~/C64x+DSPLIB/dsplib_v210/dsplib64plus.h # convert from windows `\` to normal `/`
cp ~/C64x+DSPLIB/dsplib_v210/dsplib64plus.h /opt/TI/C6000CGT6.1.12/include/
cp -a ~/C64x+DSPLIB/dsplib_v210/src /opt/TI/C6000CGT6.1.12/include/
cp ~/C64x+DSPLIB/dsplib_v210/dsplib64plus.lib /opt/TI/C6000CGT6.1.12/lib/

Now that everything is installed you must configure ~/dvsdk/dvsdk_3_01_00_10/Rules.make. Here's an example of what the values that should probably be chaged:

* `DVSDK_INSTALL_DIR=$(HOME)/dvsdk/dvsdk_3_01_00_10`
* `CODEGEN_INSTALL_DIR=/opt/TI/C6000CGT6.1.12`
* `OMAP3503_SDK_INSTALL_DIR=$(HOME)/AM35x-OMAP35x-PSP-SDK-03.00.01.06`
* `CSTOOL_DIR=${OVEROTOP}/tmp/sysroots/i686-linux/usr/armv7a`
* `CSTOOL_PREFIX=$(CSTOOL_DIR)/bin/arm-angstrom-linux-gnueabi-`

Because some of the packages don't respect CSTOOL_PREFIX as they ought, also link the OpenEmbedded toolchain to arm-none-linux-gnueabi-

cd ${OVEROTOP}/tmp/sysroots/i686-linux/usr/armv7a/bin
ls | cut -d'-' -f5-99 | while read COMP
do
  ln -s arm-angstrom-linux-gnueabi-${COMP} arm-none-linux-gnueabi-${COMP} 
done

To test that everything is installed correctly, try to compile all of the TI packages (probably takes 30 min+).

cd ~/dvsdk/dvsdk_3_01_00_10
make help
make clobber # super clean
make everything
make

Using the overo-patched TI PSP Kernel

Now that everything is installed correctly enough to compile the vanilla TI demos, let's get the overo psp kernel

Get linux-omap-psp (or any omap-psp based-branch of the kernel) downloaded and patched for the overo.

cd ${OVEROTOP}
bitbake -c configure linux-omap-psp # Downloads and patches `git_arago-project.org.git.people.sriram.ti-psp-omap.git_a6bad4464f985fdd3bed72e1b82dcbfc004d7869.tar.gz`
ls ${OVEROTOP}/tmp/work/overo-angstrom-linux-gnueabi/linux-omap-psp-2.6.32-r81+gitra6bad4464f985fdd3bed72e1b82dcbfc004d7869/git

Right now /AM35x-OMAP35x-PSP-SDK-03.00.01.06/src/kernel/linux-03.00.01.06 is being used as the kernel dir in Rules.make. Change that to the desired kernel.

echo ${OVEROTOP}/tmp/work/overo-angstrom-linux-gnueabi/linux-omap-psp-2.6.32-r81+gitra6bad4464f985fdd3bed72e1b82dcbfc004d7869/git
cd ~/dvsdk/dvsdk_3_01_00_10/
vim Rules.make
#LINUXKERNEL_INSTALL_DIR=$(HOME)/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/linux-omap-psp-2.6.32-r81+gitra6bad4464f985fdd3bed72e1b82dcbfc004d7869/git

Also, the Makefile is configured to build with the omap3_evm_defconfig, but we want the overo_defconfig

cd ~/dvsdk/dvsdk_3_01_00_10/
vim Makefile
# edit near "ifeq ($(PLATFORM),omap3530)"
# LINUXKERNEL_CONFIG=overo_defconfig

And try to compile the kernel now

make linux_clean
make linux

And now everything

make clobber
make everything

And lastly, copy some of the demo files out to ~/workdir/filesystem

make install

Running the demos

TI's Build/Run Instructions for Codec Engine Examples

Configure u-boot

The example loadscript for OMAP3530 assumes 80mb of OS memory, so that's what we'll set.

  1. reboot the overo
  2. press the 'any' key to enter u-boot
  3. set it to boot with only 80mb allocated for the OS
    • setenv mmcargs ${mmcargs} MEM=80M mem=80M
    • saveenv
    • run mmcboot

Copy the dvsdk examples to the overo

  • scp -r ~/workdir/filesys/opt GUMSTIX_IP:/
  • Create a hybrid loadmodules.sh that will load all of the modules
    • ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/apps/system_files/OMAP3530/loadmodules.sh
    • ~/workdir/filesys/opt/dvsdk/omap3530/loadmodules.sh
  • ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/ti/sdo/ce/examples/

    • servers/all_codecs/bin/ti_platforms_evm3530/all.x64P
    • apps/video_copy/bin/ti_platforms_evm3530/app_remote.xv5T
    • apps/video_copy/bin/ti_platforms_evm3530/app_local.xv5T
    • apps/video_copy/in.dat
  • run cd /opt/dvsdk/omap3530

  • Create a new file loadmodules.works.sh
  • Copy the insmod cmemk.ko and settings from the one in ce examples
  • Copy the other insmod MODULE.ko settings from the one in workdir
  • run app_local.xv5T - works, but may not use ARM
  • run app_remote.xv5T - doesn't work yet for me

Modifying the examples

  • ~/dvsdk/dvsdk_3_01_00_10/codec_engine_2_25_02_11/examples/xdcpaths.mak

Appendix: Examining the TI Packages

dvsdk v3 (dvsdk_3_01_00_10_Setup.bin & data_dvsdk_3_01_00_10.tar.gz)

Unpacking:

  1. run ./dvsdk_3_01_00_10_Setup.bin and unpack as ~/dvsdk
  2. run tar xf data_dvsdk_3_01_00_10.tar.gz -C ~/dvsdk/dvsdk_3_01_00_10/clips
  3. run ls ~/dvsdk/dvsdk_3_01_00_10 to see that the results are as expected

This package contains these other packages:

  • bios_5_41_00_06
  • biosutils_1_02_02
  • ceutils_1_06
  • cg_xml_v2_12_00
  • codec_engine_2_25_02_11
  • dmai_2_05_00_12
  • dsplink_linux_1_65_00_02
  • dvsdk_demos_3_01_00_13
  • dvtb_4_20_05
  • edma3_lld_01_11_00_03
  • framework_components_2_25_01_05
  • linuxlibs_3_01
  • linuxutils_2_25_02_08
  • local_power_manager_linux_1_24_02_09
  • xdais_6_25_02_11
  • xdctools_3_16_01_27

It also contains these directories:

  • bin - check.sh info.sh
  • clips - the data files are in the package data_dvsdk_3_01_00_10.tar.gz
  • docs - lies, all lies (there aren't any docs there)
  • examples - has an example loadmodules.sh
  • kernel_binaries - pre-built binaries for the provided kernel
  • targetfs - for building with rootfs

And these files:

  • dvsdk_3_01_00_10_releasenotes.pdf
  • Makefile - make help to find out
  • Rules.make - edit this file to match your configuration. Example:
    • DVSDK_INSTALL_DIR=$(HOME)/dvsdk/dvsdk_3_01_00_10
    • CODEGEN_INSTALL_DIR=/opt/TI/C6000CGT6.1.12
    • OMAP3503_SDK_INSTALL_DIR=$(HOME)/AM35x-OMAP35x-PSP-SDK-03.00.01.06
    • CSTOOL_DIR=${OVEROTOP}/tmp/sysroots/i686-linux/usr/armv7a
    • CSTOOL_PREFIX=$(CSTOOL_DIR)/bin/arm-angstrom-linux-gnueabi-
  • uninstall

cs1omap3530 v1 (cs1omap3530_setupLinux_1_01_00-prebuilt-dvsdk3.01.00.10.bin)

Unpacking:

  1. run ./cs1omap3530_setupLinux_1_01_00-prebuilt-dvsdk3.01.00.10.bin and unpack to ~/cs1omap3530/
  2. run mv ~/cs1omap3530/cs1omap3530_1_01_00 ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00
  3. run ls ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00 to see that the results are as expected

This package contains an example codec server

  • ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00/
    • config.bld
    • cs1omap3530_release_notes.htm
    • csRules.mak
    • Makefile
  • ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00/packages/ti/sdo/codecs/
    • aachedec
    • deinterlacer
    • g711dec
    • g711enc
    • h264dec
    • h264enc
    • jpegdec
    • jpegenc
    • mpeg2dec
    • mpeg4dec
    • mpeg4enc
  • ~/dvsdk/dvsdk_3_01_00_10/cs1omap3530_1_01_00/packages/ti/sdo/server/cs/
    • bin
    • codec.cfg
    • docs
    • link.cmd
    • main.c
    • package
    • package.bld
    • package.mak
    • package.xdc
    • package.xs
    • server.cfg
    • server.tcf

TI-C6x-CGT v6

Unpacking:

  1. run ./TI-C6x-CGT-v6.1.12.bin and unpack as /opt/TI/C6000CGT6.1.12
  2. run ls /opt/TI/C6000CGT6.1.12 to see that the results are as expected

This package contains the DSP Toolchain: C6000 CodeGen Tools

  • bin - abs6x, ap6x, asm6x, ci6x, clist6x, dem6x, embed6x, ilk6x, lnk6x, load6xexe, nm6x, opt6x, pprof6x, strip6x, acp6x, ar6x, cg6x, cl6x, cmp6x, dis6x, hex6x, libinfo6x, load6x, mk6x, ofd6x, pdd6x, spkc6x.dll, xref6x
  • DefectHistory.txt
  • include - access.h, cctype, cpp_inline_math.h, cstring, fastmath67x.h, hash_map, iostream.h, linkage.h, mathl.h, rope, stddef.h, string, valarray, xiosbase, xmemory algorithm, cerrno, cpy_tbl.h, ctime, file.h, hash_set, isfuncdcl.h, list, memory, set, stdexcept, string.h, vector, xlocale, xstddef assert.h, cfloat, csetjmp, ctype.h, float.h, inttypes.h, isfuncdef.h, locale, new, setjmp.h, stdint.h, strstream, wchar.h, xlocinfo, xstring bitset, ciso646, csignal, cwchar, fmt_specifier.h, iomanip, iso646.h, locale.h, new.h, signal.h, stdio.h, strstream.h, wchar.hx, xlocinfo.h, xtree c60asm.i, climits, cstdarg, cwctype, fstream, iomanip.h, istream, lock.h, numeric, slist, stdiostream.h, time.h, wctype.h, xlocmes, xutility c6x.h, clocale, cstddef, deque, fstream.h, ios, iterator, map, ostream, sstream, stdlib.h, typeinfo, xcomplex, xlocmon, xwcc.h cargs.h, cmath, cstdio, errno.h, functional, iosfwd, limits, mathf.h, pprof.h, stack, stl.h, unaccess.h, xdebug, xlocnum, ymath.h cassert, complex, cstdlib, exception, gsm.h, iostream, limits.h, math.h, queue, stdarg.h, streambuf, utility, xhash, xloctime, yvals.h
  • lib - fastmath67xe.lib, libc.a, rts6200_eh.lib, rts6400e_eh.lib, rts6400.lib, rts64pluse.lib, rts6700_eh.lib, rts6740e_eh.lib, rts6740.lib, rts67pluse.lib, fastmath67x.lib, lnk.cmd, rts6200e.lib, rts6400_eh.lib, rts64pluse_eh.lib, rts64plus.lib, rts6700e.lib, rts6740_eh.lib, rts67pluse_eh.lib, rts67plus.lib, fastmath67x.src, rts6200e_eh.lib, rts6200.lib, rts6400e.lib, rts64plus_eh.lib, rts6700e_eh.lib, rts6700.lib, rts6740e.lib, rts67plus_eh.lib, rtssrc.zip
  • LINKER_README.txt
  • man
  • README.txt
  • uninstall_cgt_c6000.bin

Scratchpad (unorganized, unfinished)

bitbake -c clean linux-omap-psp
bitbake -c clean ti-dsplink
bitbake -c clean ti-linuxutils
bitbake -c clean ti-dvsdk-demos

bitbake linux-omap-psp # Downloads `git_arago-project.org.git.people.sriram.ti-psp-omap.git_a6bad4464f985fdd3bed72e1b82dcbfc004d7869.tar.gz`
bitbake ti-dsplink # Downloads `dsplink_linux_1_65_00_02.tar.gz`
bitbake ti-linuxutils # Downloads `linuxutils_2_25_01_06.tar.gz`
bitbake ti-dvsdk-demos

You should be able to build the kernel just fine, but you'll need extra files from TI. I'm not sure which all of these are needed, but here are some links to files that will prove useful.

Building DVSDK

What we don't need

  • MLO, boot_lcd.scr, boot_dvi.scr, sdimage_dvsdk_3_01_00_10.tar.gz - These are specific for the DVEVM board.

linux-omap-psp

This should build without issue.

If you get confused as to which of the lovely files in ~/overo-oe/tmp/deploy/glibc/images/ is the kerenl you're looking for, try ls -t which will list the most recenly built kernels first.

without bitbake

http://www.jumpnowtek.com/index.php?option=com_content&view=article&id=46&Itemid=54

bitbake -c configure linux-omap-psp
cd todo some directory
make menuconfig

no, really without bitbake

Grab the kernel source straight from the TI guy:

git clone git://arago-project.org/git/people/sriram/ti-psp-omap.git;protocol=git;branch=master

Set up a minimal set of env build variables

kernel.env:

CROSS_DIR=~/overo-oe/tmp/sysroots/i686-linux/usr/armv7a/bin
CROSS_PREFIX=arm-angstrom-linux-gnueabi-
export ARCH=arm
export CROSS_COMPILE=${CROSS_DIR}/${CROSS_PREFIX}

Configure the kernel

source kernel.env
make overo_defconfig
make menuconfig

kernel-dev.env:

if [[ -z "${KERNEL_CROSS_BUILD_ENVIRONMENT_SOURCED}" ]]; then

  # should work for MACHINE=beagleboard also, you will have to set OETMP correctly
  MACHINE=overo

  # Set OETMP to be your OE config TMPDIR. This is a configurable param for OE. 

  # For gumstix setups, look in ${OVEROTOP}/build/conf/site.conf
  # This is the gumstix default.
  OETMP=${OVEROTOP}/tmp

  # For beagleboard setups, look in ${OETREE}/build/conf/local.conf
  # This is the beagleboard default.
  # OETMP=${OETREE}/tmp

  SYSROOTSDIR=${OETMP}/sysroots
  STAGEDIR=${SYSROOTSDIR}/`uname -m`-linux
  CROSSBINDIR=${OETMP}/sysroots/i686-linux/usr/armv7a/bin

  export KERNELDIR=${SYSROOTSDIR}/${MACHINE}-angstrom-linux-gnueabi/kernel

  PATH=${STAGEDIR}/bin:${PATH}
  PATH=${STAGEDIR}/sbin:${PATH}
  PATH=${CROSSBINDIR}:${PATH}
  PATH=${STAGEDIR}/usr/bin:${PATH}
  PATH=${STAGEDIR}/usr/sbin:${PATH}
  PATH=${STAGEDIR}/usr/bin/armv7a-angstrom-linux-gnueabi:${PATH}

  unset CFLAGS CPPFLAGS CXXFLAGS LDFLAGS MACHINE

  export ARCH="arm"
  export CROSS_COMPILE="arm-angstrom-linux-gnueabi-"
  export CC="arm-angstrom-linux-gnueabi-gcc"
  export LD="arm-angstrom-linux-gnueabi-ld"
  export KERNEL_CROSS_BUILD_ENVIRONMENT_SOURCED="true"

  echo "Altered environment for cross building kernel/u-boot with OE tools."
else
  echo "Cross build environment already configured."
fi

To include that in the environment:

source kernel-dev.env
make overo_defconfig
make menuconfig

ti-linuxutils

cmemk.ko

insmod /lib/modules/2.6.32/kernel/drivers/dsp/cmemk.ko 
CMEMK module: built on Jul 26 2010 at 17:53:26
  Reference Linux version 2.6.32
  File /home/user/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c
no physical memory specified, continuing with no memory allocation capability...
cmemk initialized
rmmod cmemk.ko

Child Packages

A helpful FYI: Those two packages (ti-linuxutils, ti-dsplink) contain all of these:

./tmp/deploy/glibc/ipk/overo/
  kernel-firmware-ti-3410_2.6.33-r80.5_overo.ipk
  kernel-firmware-ti-5052_2.6.33-r80.5_overo.ipk
  kernel-module-ti-usb-3410-5052_2.6.33-r80.5_overo.ipk
  ti-biosutils-dbg_1_02_02-r1.5_overo.ipk
  ti-biosutils-dev_1_02_02-r1.5_overo.ipk
  ti-biosutils-sourcetree_1_02_02-r1.5_overo.ipk
  ti-biosutils_1_02_02-r1.5_overo.ipk
  ti-cgt6x-dbg_6_1_9-r4.5_overo.ipk
  ti-cgt6x-dev_6_1_9-r4.5_overo.ipk
  ti-cgt6x-sourcetree_6_1_9-r4.5_overo.ipk
  ti-cgt6x_6_1_9-r4.5_overo.ipk
  ti-codec-engine-dbg_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine-dev_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine-examples_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine-sourcetree_2_25_01_06-r5.5_overo.ipk
  ti-codec-engine_2_25_01_06-r5.5_overo.ipk
  ti-dspbios-dbg_5_41_02_14-r1.5_overo.ipk
  ti-dspbios-dev_5_41_02_14-r1.5_overo.ipk
  ti-dspbios-sourcetree_5_41_02_14-r1.5_overo.ipk
  ti-dspbios_5_41_02_14-r1.5_overo.ipk
  ti-dsplink-dbg_1_64-r80f.5_overo.ipk
  ti-dsplink-dev_1_64-r80f.5_overo.ipk
  ti-dsplink-examples_1_64-r80f.5_overo.ipk
  ti-dsplink-module_1_64-r80f.5_overo.ipk
  ti-dsplink-sourcetree_1_64-r80f.5_overo.ipk
  ti-dsplink_1_64-r80f.5_overo.ipk
  ti-edma3lld-dbg_01_11_00_03-r0.5_overo.ipk
  ti-edma3lld-dev_01_11_00_03-r0.5_overo.ipk
  ti-edma3lld-sourcetree_01_11_00_03-r0.5_overo.ipk
  ti-edma3lld_01_11_00_03-r0.5_overo.ipk
  ti-framework-components-dbg_2_25_01_05-r1.5_overo.ipk
  ti-framework-components-dev_2_25_01_05-r1.5_overo.ipk
  ti-framework-components-sourcetree_2_25_01_05-r1.5_overo.ipk
  ti-framework-components_2_25_01_05-r1.5_overo.ipk
  ti-local-power-manager-dbg_1_24_01-r80d.5_overo.ipk
  ti-local-power-manager-dev_1_24_01-r80d.5_overo.ipk
  ti-local-power-manager-sourcetree_1_24_01-r80d.5_overo.ipk
  ti-local-power-manager_1_24_01-r80d.5_overo.ipk
  ti-lpm-module_1_24_01-r80d.5_overo.ipk
  ti-lpm-utils_1_24_01-r80d.5_overo.ipk
  ti-xdais-dbg_6_25_01_08-r1.5_overo.ipk
  ti-xdais-dev_6_25_01_08-r1.5_overo.ipk
  ti-xdais-sourcetree_6_25_01_08-r1.5_overo.ipk
  ti-xdais_6_25_01_08-r1.5_overo.ipk
  ti-xdctools-dbg_3_16_01_27-r2.5_overo.ipk
  ti-xdctools-dev_3_16_01_27-r2.5_overo.ipk
  ti-xdctools-sourcetree_3_16_01_27-r2.5_overo.ipk
  ti-xdctools_3_16_01_27-r2.5_overo.ipk

The individual bitbake files are these:

find ${OVEROTOP}/org.openembedded.dev/recipes/ | grep '\<ti\>' | grep bb | cut -d'/' -f3-99 | cut -d'_' -f1 | sort -u
org.openembedded.dev/recipes/
  firmwares/firmware-ti-wl1251.bb
  images/ti-codec-engine-test-image.bb
  images/ti-demo-x11-image.bb
  julius/ti-julius-demo
  tasks/task-gstreamer-ti.bb
  ti/am-benchmarks
  ti/am-sysinfo
  ti/bitblit
  ti/gstreamer-ti
  ti/matrix-gui
  ti/matrix-gui-common
  ti/matrix-gui-e
  ti/matrix-tui
  ti/ti-audio-soc-example
  ti/ti-biospsp
  ti/ti-biosutils
  ti/ti-cgt6x
  ti/ti-codec-engine
  ti/ti-codecs-dm355
  ti/ti-codecs-dm365
  ti/ti-codecs-dm6446
  ti/ti-codecs-dm6467
  ti/ti-codecs-omap3530
  ti/ti-codecs-omapl137
  ti/ti-codecs-omapl138
  ti/ti-devshell.bb
  ti/ti-dm355mm-module
  ti/ti-dm365mm-module
  ti/ti-dmai
  ti/ti-dspbios
  ti/ti-dsplib
  ti/ti-dsplink
  ti/ti-dvsdk-demos
  ti/ti-edma3lld
  ti/ti-framework-components
  ti/ti-linuxutils
  ti/ti-local-power-manager
  ti/ti-msp430-chronos
  ti/ti-sysbios
  ti/ti-xdais
  ti/ti-xdctools

Errors

If you try to compile from the default overo kernel (or your haven't cleaned your previous attempt of ti-xzy) you're likely to run into these errors:

bitbake ti-linuxutils
  |   CC [M]  /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.o
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c:65:2: warning: #warning *** not a warning *** Note: LINUX_VERSION_CODE >= 2.6.26
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c: In function 'ioctl':
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c:1530: error: implicit declaration of function 'dmac_clean_range'
  | /home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.c:1541: error: implicit declaration of function 'dmac_inv_range'
  | make[4]: *** [/home/tom/overo-oe/tmp/work/overo-angstrom-linux-gnueabi/ti-linuxutils-1_2_25_01_06-r80c/linuxutils_2_25_01_06/packages/ti/sdo/linuxutils/cmem/src/module/cmemk.o] Error 1

According to the e2e forum it's possible to patch the kernel (essentially adding a http:// entry to the linux-omap3_2.6.33.bb (which has been removed, btw). The question remains: what replaces dmac_clean_range? and wouldn't it be better to patch cmemk with the update?, but judging by linux-ti-omap4 I'm guessing that the revert patch is pretty popular and perhaps the removal was premature.

WAF on OpenEmbedded(View Stand-alone)

Update: Jul 27th 2010: Works!

desired result

bitbake hello-world-waf

~/overo-oe/tmp/deploy/glibc/ipk/overo/hello-world-waf.ipk

waf.bbclass

~/overo-oe/user.collection/classes/waf.bbclass

modeled after

~/overo-oe/org.openembedded.dev/classes/autotools.bbclass

# WAF project class.

DEPENDS += python

# Conditionally set the verbose option.
# WAF_VERBOSE="-v"

waf_do_compile() {
  ./waf ${WAF_VERBOSE} build 
}

waf_do_clean() {
  ./waf ${WAF_VERBOSE} clean
}

waf_do_configure() {
  if [ -x ${S}/waf ]; then
    ${S}/waf ${WAF_VERBOSE} configure --prefix=${prefix} ${EXTRA_OECONF} "$@"
  else
    oefatal "executable waf script not found"
  fi
}

waf_do_install() {
  ./waf ${WAF_VERBOSE} install --destdir="${D}" "$@"
}

EXPORT_FUNCTIONS do_compile do_clean do_configure do_install 

hello-world-waf.bb

~/overo-oe/user.collection/recipes/hello-world-waf/hello-world-waf_1.0.bb

DESCRIPTION = "Hello World (bitbake remix) feat. WAF"
PR = "r0"
DEPENDS = ""
LICENSE = "GPL"
SRC_URI = " \
file://hello-world-waf.c \
file://wscript \
file://waf \
"
S = "${WORKDIR}"
FILES_${PN} = "${bindir}/hello-waf"

inherit waf

hello-world-waf.c

~/overo-oe/user.collection/recipes/hello-world-waf/files/hello-world-waf.c

#include <stdio.h>

int main (int argc, char** argv) {
  printf("Hello World!\n");
  return 0;
}

wscript

~/overo-oe/user.collection/recipes/hello-world-waf/files/wscript

top = '.'
out = 'build'

def set_options(opt):
    opt.tool_options('compiler_cc')

def configure(conf):
    conf.check_tool('compiler_cc')

def build(bld):
    main = bld.new_task_gen()
    main.features = 'cc cprogram'
    main.source = 'hello-world-waf.c'
    main.target = 'hello-waf'
    main.install_path = '${PREFIX}/bin'
    main.chmod = 0755

waf

wget http://waf.googlecode.com/files/waf-1.5.18
chmod a+x waf-1.5.8
cp -a waf-1.5.8 ~/overo-oe/user.collection/recipes/hello-world-waf/files/waf

Resources

Build node.js on OpenEmbedded (natively, not cross-compiled, no bitbake)(View Stand-alone)

Node.js on OpenEmbeded

The successful build instructions in a nutshell:

opkg install python python-modules python-distutils python-misc
opkg install task-sdk-native
opkg install openssl openssl-dev
wget http://nodejs.org/dist/node-v0.1.102.tar.gz
tar xf node-v0.1.102.tar.gz
cd node-v0.1.102
export CC='gcc -march=armv7-a -mtune=cortex-a8' # -march=armv5te works for older systems
export CXX='g++ -march=armv7-a -mtune=cortex-a8'
./configure
make
make install

Tracing Errors

There are a number of DIY kits for embedded development which support OpenEmbedded. BeagleBoard and Gumstix are two that have a growing community and a good name for themselves.

Over the weekend I had the pleasure of borrowing a Gumstix Overo Earth with the Tobi expansion board to see if I could get Node.js running on it before I bought my own. I'm going to give you the red-green step-through starting with a bitbake build of a console-image using the default gumstix opkg repository (I believe this is a clone of the Angstrom repo - the same as BeagleBoard, etc - with a few tweaks), but assuming you have the OpenEmbedded environment of your choice up and running, the instructions should be pretty much the same.

Prerequisits:

Note on Rolling your own

Rolling your own is always optional and is done on your host system (the x86 or x86-84 box you cross-compile from, not the OpenEmbedded device). You will need to find the ipk files in a sub-directory of ./tmp/deploy/glibc/ipk/, copy them over with scp, and install them with opkg install _package-name_.ipk

Red

cd ~/
wget http://nodejs.org/dist/node-v0.1.102.tar.gz
tar xf node-v0.1.102.tar.gz
cd node-v0.1.102
./configure
make

And we see that we don't have gcc...

task-sdk-native: The native arm compiler

Rolling your own: several hours

bitbake task-sdk-native

On some Linuxes (Ubuntu pre-10.04, for example) you will get [an error][xz-error]

/bin/sh: xz: command not found 
tar: This does not look like a tar archive 
tar: Exiting with failure status due to previous errors 
NOTE: Task failed: 
ERROR: TaskFailed event exception, aborting 
ERROR: Build of /home/mark/overo-oe/org.openembedded.dev/recipes/grep/grep_2.6.3.bb do_unpack failed 
ERROR: Task 1727 (/home/mark/overo-oe/org.openembedded.dev/recipes/grep/grep_2.6.3.bb, do_unpack) failed 
NOTE: Tasks Summary: Attempted 2437 tasks of which 2411 didn't need to be rerun and 1 failed. 
ERROR: '/home/mark/overo-oe/org.openembedded.dev/recipes/grep/grep_2.6.3.bb' failed 

This is because lzma has been replaced by xz-utils. You can run apt-get install xz-utils and safely ignore the warning that by uninstalling lzma that You are about to do something potentially harmful. and enter Yes, do as I say!.

Installing from the repo: several minutes

opkg install task-sdk-native

Now let's try again.

cd ~/node-v0.1.102
make

And we see that we don't have python

python: runs the WAF compiler tools

This first error is that python isn't installed, that seems intuitive enough to fix

./configure 
/usr/bin/env: python: No such file or directory
opkg install python

Next is a BOM enocding error. This has to do with utf-8 / unicode / ISOxxxx stuff.

./configure
  File "/home/root/node-v0.1.102/tools/waf-light", line 2
SyntaxError: encoding problem: with BOM    
# edit /home/root/node-v0.1.102/tools/waf-light
# change `# encoding: ISO8859-1` to `# encoding: utf-8`

shutil is missing. After some hunting, I found it.

./configure 
Traceback (most recent call last):
  File "/home/root/node-v0.1.102/tools/waf-light", line 157, in <module>
    import Scripting
  File "/home/root/node-v0.1.102/tools/wafadmin/Scripting.py", line 7, in <module>
    import os, sys, shutil, traceback, datetime, inspect, errno
ImportError: No module named shutil
opkg install python-modules

The next error is quite interesting. You'd think string would be part of python

./configure
ImportError: No module named string
opkg install python-distutils

We find that the gcc compiler isn't installed, which almost seems like we're getting out of the python errors... but not quite

./configure 
Checking for program g++ or c++          : not found 
Checking for program icpc                : not found 
Checking for program c++                 : not found 
/home/root/node-v0.1.102/wscript:130: error: could not configure a cxx compiler!
opkg install task-sdk-native

Finally our last python error - python doesn't know which platform we're on. I would like to note that misc, util, modules, and tools are terrible names for packages...

./configure
/home/root/node-v0.1.102/deps/c-ares/wscript: error: Traceback (most recent call last):
  File "/home/root/node-v0.1.102/tools/wafadmin/Utils.py", line 274, in load_module
    exec(compile(code, file_path, 'exec'), module.__dict__)
  File "/home/root/node-v0.1.102/deps/c-ares/wscript", line 2, in <module>
    import platform
ImportError: No module named platform
opkg install python-misc

And now on to compiler errors...

v8: the engine behind node

I knew that the OMAP3530 has thumb support, so this was confusing

/home/root/node-v0.1.101/deps/v8/src/arm/macro-assembler-arm.cc:59:3: error: #error "For thumb inter-working we require an architecture which supports blx"
scons: *** [obj/release/arm/macro-assembler-arm.o] Error 1
scons: building terminated because of errors.
Waf: Leaving directory `/home/root/node-v0.1.101/build'
Build failed:  -> task failed (err #2): 
        {task: libv8.a SConstruct -> libv8.a}
make: *** [all] Error 1

At first I thought the best course of action was to fake CAN_USE_THUMB_INSTRUCTIONS by manually defining it in the code

g++ -o obj/release/platform-linux.o -c -Wall -W -Wno-unused-parameter -Wnon-virtual-dtor -pedantic -O3 -fomit-frame-pointer -fdata-sections -ffunction-sections -ansi -fno-rtti -fno-exceptions -Wall -W -Wno-unused-parameterc
/tmp/ccNcgrdW.s: Assembler messages:
/tmp/ccNcgrdW.s:150: Error: bad instruction `int $3'
scons: *** [obj/release/platform-linux.o] Error 1
scons: building terminated because of errors.
Waf: Leaving directory `/home/root/node-v0.1.101/build'
Build failed:  -> task failed (err #2): 
        {task: libv8.a SConstruct -> libv8.a}
make: *** [all] Error 1

But that wasn't enough so I figured ARM_V7_A should be faked too

/tmp/ccxCSjUb.s: Assembler messages:
/tmp/ccxCSjUb.s:47: Error: selected processor does not support `bkpt 0'
scons: *** [obj/release/arm/cpu-arm.o] Error 1
scons: building terminated because of errors.
Waf: Leaving directory `/home/root/node-v0.1.101/build'
Build failed:  -> task failed (err #2): 
  {task: libv8.a SConstruct -> libv8.a}
make: *** [all] Error 1

Further investigation revealed that the compiler was faking (and forcing) the platform to appear as an ARMv4:

touch foo.cc
g++ foo.cc -dM -E | grep ARM
#define __ARMEL__ 1
#define __ARM_ARCH_4T__ 1
#define __ARM_EABI__ 1

I found that the way to fix this is to use -march, -mtune, and -mcpu flags:

touch foo.cc
g++ foo.cc -march=armv7-a -mtune=cortex-a8 -dM -E | grep ARM
#define __ARMEL__ 1
#define __ARM_ARCH_7A__ 1
#define __ARM_EABI__ 1

I couldn't figure out how to pass compiler arguments directly to WAF

./configure -march=armv7-a
waf-light: error: no such option: -march

I did find that WAF respects environment variables.

export CC='gcc -march=armv7-a'
export CXX='g++ -march=armv7-a'

Viola!

make
#... lots of successful output
Waf: Leaving directory `/home/root/node-v0.1.101/build'
'build' finished successfully (40m36.030s)

Other Notes

production: node.js - without python and gcc

I believe the binary node is the only thing necessary to be able to run node, assuming that the shared libraries that it is linked against are present - those being openssl and optionally v8, libev, libio.

You shouldn't need python, or g++. However, you will need libcstd++

overo-oe/tmp/work/armv7a-angstrom-linux-gnueabi/gcc-cross-4.3.3-r12.1/staging-pkg/deploy/glibc/ipk/armv7a/libstdc++6_4.3.3-r12.1.5_armv7a.ipk

openssl support

opkg install openssl
opkg install openssl-dev

running on other distros

librt.so.1 => /lib/librt.so.1 (0x40026000)
libssl.so.0.9.8 => /usr/lib/libssl.so.0.9.8 (0x40035000)
libcrypto.so.0.9.8 => /usr/lib/libcrypto.so.0.9.8 (0x4007c000)
libdl.so.2 => /lib/libdl.so.2 (0x401a3000)
libm.so.6 => /lib/libm.so.6 (0x401ae000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x40221000)
libpthread.so.0 => /lib/libpthread.so.0 (0x40233000)
libc.so.6 => /lib/libc.so.6 (0x40252000)
/lib/ld-linux.so.3 (0x40000000)

Leftover warnings

I'm pretty sure that sync_file_range is a fairly new operation that isn't implemented in all file io libraries yet.

default/deps/libeio/eio_1.o: In function `eio__sync_file_range':
/home/root/node-v0.1.102/build/../deps/libeio/eio.c:872: warning: warning: sync_file_range is not implemented and will always fail

creating a static binary

And the solution is to add conf.env["FULLSTATIC"] = True to the wscript

TODO: create a patch for this and post it to the mailing list

vim wscript

  opt.add_option( '--shared-libev-libpath'
                , action='store'
                , default=False
                , help='A directory to search for the shared libev DLL'
                , dest='shared_libev_libpath'
                )

+  opt.add_option( '--static'
+                , action='store'
+                , default=False
+                , help='Whether to compile node statically'
+                , dest='full_static'
+                )

def configure(conf):
  conf.check_tool('compiler_cxx')
  if not conf.env.CXX: conf.fatal('c++ compiler not found')
  conf.check_tool('compiler_cc')
  if not conf.env.CC: conf.fatal('c compiler not found')

  o = Options.options

  conf.env["USE_DEBUG"] = o.debug

  # TODO --static = o.static
+  conf.env["FULLSTATIC"] = o.full_static
  conf.env["USE_SHARED_V8"] = o.shared_v8 or o.shared_v8_includes or o.shared_v8_libpath or o.shared_v8_libname
  conf.env["USE_SHARED_CARES"] = o.shared_cares or o.shared_cares_includes or o.shared_cares_libpath
  conf.env["USE_SHARED_LIBEV"] = o.shared_libev or o.shared_libev_includes or o.shared_libev_libpath

You can't link static libraries against dynamic libraries, so your friendly error might look like:

/arm-angstrom-linux-gnueabi/bin/ld: cannot find -lssl
opkg install openssl-static
make

Leftover warnings

I'm not sure if these matter or not, but they're the warnings I got

root/node-v0.1.102/build/default/node -pthread -rdynamic /home/root/node-v0.1.102/build/default/libv8.a -static -lrt -lssl -lcrypto -ldl
default/src/node_4.o: In function `node::DLOpen(v8::Arguments const&)':
/home/root/node-v0.1.102/build/../src/node.cc:1271: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
default/src/node_4.o: In function `node::SetGid(v8::Arguments const&)':
/home/root/node-v0.1.102/build/../src/node.cc:1099: warning: Using 'getgrnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
default/src/node_4.o: In function `node::SetUid(v8::Arguments const&)':
/home/root/node-v0.1.102/build/../src/node.cc:1134: warning: Using 'getpwnam_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
default/src/node_net_4.o: In function `node::Resolve(eio_req*)':
/home/root/node-v0.1.102/build/../src/node_net.cc:1165: warning: Using 'getaddrinfo' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
default/deps/c-ares/ares_getnameinfo_1.o: In function `lookup_service':
/home/root/node-v0.1.102/build/../deps/c-ares/ares_getnameinfo.c:310: warning: Using 'getservbyport_r' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking

Other Resources

  • http://www.mail-archive.com/v8-users@googlegroups.com/msg01519.html

hicolor-icon-theme

There's this rather annoying (but benign) error that pops up on console systems. For some reason consolekit depends on hicolor-icon-theme, which isn't correctly installed on the console system.

Configuring hicolor-icon-theme.
//usr/lib/opkg/info/hicolor-icon-theme.postinst: line 7: can't create /etc/gtk-2.0/gdk-pixbuf.loaders: nonexistent directory
//usr/lib/opkg/info/hicolor-icon-theme.postinst: line 7: gdk-pixbuf-query-loaders: not found
//usr/lib/opkg/info/hicolor-icon-theme.postinst: line 13: gtk-update-icon-cache: not found
Configuring openssl-dev.
Collected errors:
 * pkg_run_script: postinst script returned status 127.
 * opkg_configure: hicolor-icon-theme.postinst returned 127.
opkg remove --force-depends hicolor-icon-theme
Removing package hicolor-icon-theme from root...
//usr/lib/opkg/info/hicolor-icon-theme.postrm: line 6: gtk-update-icon-cache: not found
Collected errors:
 * pkg_run_script: postrm script returned status 127.

The last error is also meaningless.

opkg remove --force-depends hicolor-icon-theme
No packages removed.