Productivity Sync Just another WordPress weblog

March 24, 2009

Arduino-isms

Filed under: Uncategorized — admin @ 10:19 am
  • readAnalog(int pin) : pin is misleading it should be adcChannel and BTW it gets masked by 0x0F.
  • $HOME/.arduino/preferences.txt file and change build.verbose=true
  • The Arduino GUI munges the *.pde file to make a *.cpp file.  see http://arduino.cc/en/Hacking/BuildProcess

March 22, 2009

Teensy++, Arduino and Makefiles

Filed under: Uncategorized — admin @ 6:58 pm

Teensy++ and Arduino use from a Makefile

Teensy++ is an AVR based SBC that has a nice bootloader and interesting features.  Features like price its < 25$!, and no need for additional programming hardware.

The software form the Teensy++ vender works well, but you need to be sure to read the 2 small pages of info he sends with the hardware.  I missed a few of the must do things the first time I set up my environment 😉  Included with the software is a patch to the Arduino that provides some compatibility with the Arduino IDE and the Teensy++.  It took me a while to get used to the “magic” he coded up, but after I understood the fact that the loader application opens a localhost socket for the Arduino tool to talk over to inform the loader application a new hex file was available, then I felt ok about how things where working.

After a while you may get sick of the the Arduino IDE and want to go hunting down whoever wrote that thing and dope slap them for not using a make file.  I know I sure do.  Hiding the make operations within a bunch of Java really is not cool for my style of development.  And that IDE really sucks as UI and code editor.  So I started out to find a Makefile that can be used for the samples and example code that is included with the Arduino.  The following is a derivative of the Makefile that can be found at the Arduino-0012/hardware/core/arduino/Makefile.

Arduino tips:

  • edit the $HOME/.arduino/preferences.txt file and change build.verbose=true
  • look in /tmp/build*.tmp for the build directory.
  • The Arduino java code munges the *.pde files to wedge in c/c++ prototypes into the top of the file as it cat’s it with some C++ main.cpp boiler plate code.  What other “help” is the java code doing?  A: none.  Why even do this?  Its dumb and not maintainable, having that type of logic hidden within the Java code. see http://arduino.cc/en/Hacking/BuildProcess

The TODO’s are:

  • fix the ASM out put and LST out puts such that they build (done)
  • dump the compile time target files into the applet directories
  • test HEX file output to see that it actually works
  • Automate the installation of the Makefile and running of make across the arduino code base (DONE with a python program.)
  • test on the SVN tips of the Arduino code base. (DONE 0015, compiles as well as 0012)
  • test with other Arduino hardware targets.
  • post Makefile to Arduino list?
TARGET = $(notdir $(CURDIR))
#TARGET = Blink
AVR_TOOLS_PATH = /usr/bin
INSTALL_DIR = /home/mgross/dev/test/test
PORT = /dev/tty.usb*
UPLOAD_RATE = 19200
AVRDUDE_PROGRAMMER = stk500v1
MCU = at90usb646
F_CPU = 16000000

# Hack to get around some crap not toching a lot of src files:
# EXTRACDEFS = -D__AVR_ATmega168__

############################################################################
# Below here nothing should be changed...
ARDUINO = $(INSTALL_DIR)/hardware/cores/teensy_serial
SRC =  $(ARDUINO)/pins_teensy.c \
       $(ARDUINO)/wiring.c \
       $(ARDUINO)/wiring_analog.c \
       $(ARDUINO)/wiring_digital.c \
       $(ARDUINO)/wiring_pulse.c \
       $(ARDUINO)/wiring_serial.c \
       $(ARDUINO)/wiring_shift.c \
       $(ARDUINO)/WInterrupts.c \
       $(ARDUINO)/usb_serial.c \
       $(ARDUINO)/delay_us.c \
       $(ARDUINO)/pins_usb162.c

CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WMath.cpp \
	 $(ARDUINO)/USBserial.cpp $(ARDUINO)/Print.cpp

ARDUINOLIB = $(INSTALL_DIR)/hardware/libraries
EXTRACXX = $(ARDUINOLIB)/Servo/Servo.cpp \
	$(ARDUINOLIB)/Stepper/Stepper.cpp \
	$(ARDUINOLIB)/Ethernet/Server.cpp \
	$(ARDUINOLIB)/Ethernet/Client.cpp \
	$(ARDUINOLIB)/Ethernet/Ethernet.cpp  \
	$(ARDUINOLIB)/Matrix/Matrix.cpp \
	$(ARDUINOLIB)/Sprite/Sprite.cpp \
	$(ARDUINOLIB)/SoftwareSerial/SoftwareSerial.cpp \
	$(ARDUINOLIB)/Firmata/Firmata.cpp \
	$(ARDUINOLIB)/SoftwareSerial/SoftwareSerial.cpp \
	$(ARDUINOLIB)/LiquidCrystal/LiquidCrystal.cpp \
	$(ARDUINOLIB)/EEPROM/EEPROM.cpp \
	$(ARDUINOLIB)/Wire/Wire.cpp

EXTRAC = $(ARDUINOLIB)/Ethernet/utility/w5100.c \
	 $(ARDUINOLIB)/Ethernet/utility/socket.c \
	 $(ARDUINOLIB)/Wire/utility/twi.c

# Define all object files.
OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) $(EXTRACXX:.cpp=.o) $(EXTRAC:.c=.o)

# Define all listing files.
LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)

FORMAT = ihex

# Name of this Makefile (used for "make depend").
MAKEFILE = Makefile

# Debugging format.
# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
DEBUG = stabs

OPT = s

# Place -D or -U options here
CDEFS = -DF_CPU=$(F_CPU) $(EXTRACDEFS)
CXXDEFS = -DF_CPU=$(F_CPU)  $(EXTRACDEFS)

INCLUDE = -I$(ARDUINO) \
	  -I$(ARDUINOLIB)/EEPROM \
	  -I$(ARDUINOLIB)/Firmata \
	  -I$(ARDUINOLIB)/Servo \
	  -I$(ARDUINOLIB)/Ethernet \
	  -I$(ARDUINOLIB)/Sprite \
	  -I$(ARDUINOLIB)/LiquidCrystal \
	  -I$(ARDUINOLIB)/Matrix \
	  -I$(ARDUINOLIB)/Stepper \
	  -I$(ARDUINOLIB)/Wire \
	  -I$(ARDUINOLIB)/Ethernet/utility \
	  -I$(ARDUINOLIB)/Wire/utility

# Place -I options here
CINCS = $(INCLUDE)
CXXINCS =

# Compiler flag to set the C Standard level.
# c89   - "ANSI" C
# gnu89 - c89 plus GCC extensions
# c99   - ISO C99 standard (not yet fully implemented)
# gnu99 - c99 plus GCC extensions
CSTANDARD = -std=gnu99
CDEBUG = -g$(DEBUG)
CWARN = -Wall -Wstrict-prototypes
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CEXTRA = -Wa,-adhlns=$@.lst

CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
CXXFLAGS = $(CDEFS) $(CXXINCS) $(CINCS) -O$(OPT)
ASFLAGS = -Wa,-adhlns=$@.lst,-gstabs
LDFLAGS = -lm

# Programming support using avrdude. Settings and variables.
AVRDUDE_PORT = $(PORT)
AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
AVRDUDE_FLAGS = -V -F -C $(INSTALL_DIR)/hardware/tools/avr/etc/avrdude.conf \
-p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
-b $(UPLOAD_RATE)

# Program settings
CC = $(AVR_TOOLS_PATH)/avr-gcc
CXX = $(AVR_TOOLS_PATH)/avr-g++
OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
AR  = $(AVR_TOOLS_PATH)/avr-ar
SIZE = $(AVR_TOOLS_PATH)/avr-size
NM = $(AVR_TOOLS_PATH)/avr-nm
AVRDUDE = $(AVR_TOOLS_PATH)/avrdude
REMOVE = rm -f
MV = mv -f

# Define all object files.
OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o) $(EXTRAC:.c=.o) $(EXTRACXX:.cpp=.o)

# Define all listing files.
LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)

# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)

# Default target.
all: applet_files build sizeafter

build: elf hex lss sym

applet_files: $(TARGET).pde
	# Here is the "preprocessing".
	# It creates a .cpp file based with the same name as the .pde file.
	# On top of the new .cpp file comes the WProgram.h header.
	# At the end there is a generic main() function attached.
	# Then the .cpp file will be compiled. Erors during compile will
	# refer to this new, automatically generated, file.
	# Not the original .pde file you actually edit...
	test -d applet || mkdir applet
	echo '#include "WProgram.h"' > applet/$(TARGET).cpp
	cat $(TARGET).pde >> applet/$(TARGET).cpp
	cat $(ARDUINO)/main.cxx >> applet/$(TARGET).cpp

elf: applet/$(TARGET).elf
hex: applet/$(TARGET).hex
eep: applet/$(TARGET).eep
lss: applet/$(TARGET).lss
sym: applet/$(TARGET).sym

# Program the device.
upload: applet/$(TARGET).hex
	$(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)

	# Display size of file.
HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex
ELFSIZE = $(SIZE)  applet/$(TARGET).elf
sizebefore:
	@if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi

sizeafter:
	@if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi

# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
COFFCONVERT=$(OBJCOPY) --debugging \
--change-section-address .data-0x800000 \
--change-section-address .bss-0x800000 \
--change-section-address .noinit-0x800000 \
--change-section-address .eeprom-0x810000

coff: applet/$(TARGET).elf
	$(COFFCONVERT) -O coff-avr applet/$(TARGET).elf $(TARGET).cof

extcoff: $(TARGET).elf
	$(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf $(TARGET).cof

.SUFFIXES: .elf .hex .eep .lss .sym

.elf.hex:
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@

.elf.eep:
	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
	--change-section-lma .eeprom=0 -O $(FORMAT) $< $@

# Create extended listing file from ELF output file.
.elf.lss:
	$(OBJDUMP) -h -S $< > $@

# Create a symbol table from ELF output file.
.elf.sym:
	$(NM) -n $< > $@

	# Link: create ELF output file from library.
applet/$(TARGET).elf: $(TARGET).pde applet/core.a
	$(CC) $(ALL_CFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS)

applet/core.a: $(OBJ)
	@for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done

# Compile: create object files from C++ source files.
.cpp.o:
	$(CXX) -c $(ALL_CXXFLAGS) $< -o $@

# Compile: create object files from C source files.
.c.o:
	$(CC) -c $(ALL_CFLAGS) $< -o $@

# Compile: create assembler files from C source files.
.c.s:
	$(CC) -S $(ALL_CFLAGS) $< -o $@

# Assemble: create object files from assembler source files.
.S.o:
	$(CC) -c $(ALL_ASFLAGS) $< -o $@

# Target: clean project.
clean:
	$(REMOVE) applet/$(TARGET).hex applet/$(TARGET).eep applet/$(TARGET).cof applet/$(TARGET).elf \
	applet/$(TARGET).map applet/$(TARGET).sym applet/$(TARGET).lss applet/core.a \
	$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)

depend:
	if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
	then \
		sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
			$(MAKEFILE).$$$$ && \
		$(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
	fi
	echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
		>> $(MAKEFILE); \
	$(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)

.PHONY:	all build elf hex eep lss sym program coff extcoff clean depend applet_files sizebefore sizeafter

March 15, 2009

Playing with Python perforomance

Filed under: Uncategorized — admin @ 9:55 pm

Some random tidbits about python:

using cProfile:

import cProfile
cProfile.run("p.main(10)")

or

import cProfile
cProfile.run("p.main(10)","filename") <-- builds profile database in filename
import pstats
stats = pstats.Stats('filename')
stats.print_stats()

The profiler is an absolute deterministic profiler and give statistics and call graph information built from a low level. It only profiles the python code. and does not profile the python interpreter.

Using Psyco can give a 9x performance gain for an algorithmic operation repeated many times. See:

# PEuler number 15.
# takes
#import psyco
#psyco.full()

count = 0

def flood(i,j,max):
    global count

    if i == max and j == max:
        count += 1
    if i < max:
        flood(i+1,j,max)
    if j < max:
        flood(i, j+1, max)

def main(n):
    global count

    count = 0
    flood(0,0,n)
    print count

if __name__ == "__main__":
    main(20)
#In [2]: time p.main(20) = 40 choose 20
#
#137846528820
#CPU times: user 211856.08 s, sys: 63.24 s, total: 211919.32 s
#Wall time: 212,542.87

#using psyco: ~9x speed up
#time python euler15.py
#137,846,528,820
#
#real	380m56.568s = 23,369.57 sec
#user	379m38.020s
#sys	0m3.700s

#C version:
#mgross@mgross-test:~/euler$ time ./a.out 20
#starting flood with n= 20
#count = 137846528820
#
#real	28m40.817s = 1,720.817 sec 123X faster than plain python
#user	28m33.980s
#sys	0m0.510s

# C version with removal of MAX parrameter:
#mgross@mgross-test:~/euler$ gcc -O3 euler15.c
#mgross@mgross-test:~/euler$ time ./a.out 20
#starting flood with n= 20
#count = 137846528820
#
#real	22m3.937s = 1,323.937 sec 160.6X faster than plain python
#user	22m3.580s
#sys	0m0.290s

The equivalent C program runs 160x faster:

/* recursive flood fill euler problem 15 solution in C */

#include<stdio.h>
#include<stdlib.h>

long long count = 0;
int max = 0;

void flood(int i,int j)
{
	if (i==max && j==max)
		count +=1;
	else {
		if (i<max)
			flood(i+1,j);
		if (j<max)
			flood(i,j+1);
	}
}

int main(int arvc, char *argv[])
{
	int n;

	count = 0;
	n = atoi(argv[1]);
	printf ( "starting flood with n= %d \n",n);
	max = n;
	flood(0,0);
	printf ("count = %lld \n", count);

	return count;

}
/*

mgross@mgross-test:~/euler$ gcc -O3 euler15.c
mgross@mgross-test:~/euler$ time ./a.out 20
starting flood with n= 20
count = 137846528820

real	22m3.937s
user	22m3.580s
sys	0m0.290s

 *
 */

Looking at how to run C code from python there are a number of ways to do it. SWIG, ctypes and others. I only looked at ctypes this weekend but SWIG looks pretty cool.

ctypes: lets me call C library calls from python.

from ctypes import *
i =c_int()
f = c_float()
s = create_string_buffer('\000' * 32)
print i.value, f.value, repr(s.value)
libc = CDLL("libc.so.6")
libc.sscanf("1 3.14 Hello", "%d %f %s",byref(i), byref(f), s)
print i.value, f.value, repr(s.value)

I’m wondering how I can easily suck in structs like sched_parm and call functions like sched_setscheduler from python easily.

Building python from source on Ubuntu:

sudo apt-get build-dep python2.5
sudo apt-get install libncursesw5-dev libreadline5-dev libssl-dev libgdbm-dev libbz2-dev libc6-dev libsqlite3-dev tk-dev
CC="gcc -pg" ./configure --prefix=/opt/local --with-tsc
or
./configure --prefix=/opt/local
works well too and saves goes faster.

The python source has some interesting directories.

Tools/pybench is the one that interested me the most. I’m wondering how to profile the python interpreter to understand the 160x delta in runtimes for the above programs.

March 10, 2009

playing with KVM

Filed under: Uncategorized — admin @ 10:29 am

Create a kvm disk to build your image too.:

kvm-img create lfs.img 20G

load KVM driver :

modprobe kvm

start the kvm:

kvm -m 1024 -hda lfs.img -cdrom lfslivecd-x86_64-6.3-r2160.iso -boot d -smp 2

left “Ctrl-Alt” will release focus from the guest window if its been captured.  Other than that is behaves just like a stand alone computer.  There is some default networking between the guest and the host.  You can ping and scp to the host’s network adapter’s IP from the guest with this default config.  Network stuff has a lot of options I’ve not yet used.

March 5, 2009

Linux disk partition UUID’s

Filed under: Uncategorized — admin @ 12:28 pm

blkid and vol_id are your friends.

see /dev/disk/by-uuid and for device node aliases.

assinging uuid’s to partitions use tune2fs -U

Get your uuid’s from uuidgen

Powered by WordPress