Archive for category Development
It Literally Pays Off to Do Homework in Cambridge
Posted by Manfredas Zabarauskas in Development, Education, Life on November 24th, 2009
"Well done! - joint shortest traditional (and practical :-) sort for the OS1a prize tick". Cambridge, 2009.
45 minutes, 28 MIPS instructions and £25.
Computer Science FTW.
# Copyright Manfredas Zabarauskas, 2009.
# MIPS routine that reads an array of ten integers
# and prints the sorted array to console.
.text
main: sub $t7, $sp, 40
l_read: li $v0, 5
syscall
sw $v0, 0($t7)
add $t7, $t7, 4
bne $t7, $sp, l_read
l_out: sub $t8, $sp, 36
sub $t7, 40
l_inn: add $t8, $t8, 4
lw $t2, -8($t8)
lw $t3, -4($t8)
ble $t2, $t3, no_swp
sw $t2, -4($t8)
sw $t3, -8($t8)
move $t7, $sp
no_swp: bne $t8, $sp, l_inn
beq $t7, $sp, l_out
l_prnt: li $v0, 11
li $a0, 10
syscall
li $v0, 1
lw $a0, 0($t7)
syscall
add $t7, $t7, 4
bne $t7, $sp, l_prnt
li $v0, 10
syscall
Eigenfaces Tutorial
Posted by Manfredas Zabarauskas in Development on October 2nd, 2009
The main purpose behind writing this tutorial was to provide a more detailed set of instructions for someone who is trying to implement an eigenface based face detection or recognition systems. It is assumed that the reader is familiar (at least to some extent) with the eigenface technique as described in the original M. Turk and A. Pentland papers (see “References” for more details).
Introduction
The idea behind eigenfaces is similar (to a certain extent) to the one behind the periodic signal representation as a sum of simple oscillating functions in a Fourier decomposition. The technique described in this tutorial, as well as in the original papers, also aims to represent a face as a linear composition of the base images (called the eigenfaces).
The recognition/detection process consists of initialization, during which the eigenface basis is established and face classification, during which a new image is projected onto the “face space” and the resulting image is categorized by the weight patterns as a known-face, an unknown-face or a non-face image.
Demonstration
To download the software shown in video for 32-bit x86 platform, click here. It was compiled using Microsoft Visual C++ 2008 and uses GSL for Windows.
Establishing the Eigenface Basis
First of all, we have to obtain a training set of
grayscale face images
. They should be:
- face-wise aligned, with eyes in the same level and faces of the same scale,
- normalized so that every pixel has a value between 0 and 255 (i.e. one byte per pixel encoding), and
- of the same
size.
So just capturing everything formally, we want to obtain a set:
, where
and 
Once we have that, we should change the representation of a face image
from a
matrix, to a
point in
-dimensional space. Now here is how we do it: Read the rest of this entry »
SMRP6400/SMDK64X0 IIC synchronization problems
Posted by Manfredas Zabarauskas in Development on July 7th, 2009
Debugging Samsung SMRP6400
Since last week we have spent quite some time debugging Samsung SMRP6400/SMDK64X0 IIC drivers, I thought I might share with one particular example here. It is both a good showcase of the hardware/software synchronization issues and since the bugs are in the latest version of the drivers shipped together with the development platforms, it might save someone from additional headaches.
So, while working on the drivers for IIC one of our automated tests to make sure that IIC still works was to write some data on the bus, do an immediate read-back and verify that both data written and read back matches; something similar to this:
UCHAR outData[3] = { REGISTER, DATA_BYTE_1, DATA_BYTE2 };
UCHAR inData[2] = { 0, 0 };
IIC_Write(SLAVE_ADDRESS, outData, 3);
IIC_Read(SLAVE_ADDRESS, REGISTER, inData, 2);
if ((inData[0] != DATA_BYTE_1) || (inData[1] != DATA_BYTE_2))
{
DEBUGMSG(ERROR_MSG,
(TEXT("Immediate write/read data mismatch: data sent [0x%X " \
"0x%X] differs from the data received [0x%X, 0x%X]."),
DATA_BYTE_1, DATA_BYTE_2, inData[0], inData[1]));
}
However, after we added some IIC read calls from another hardware driver it started spitting fire throwing the following error message:
Immediate write/read data mismatch: data sent [0xCA, 0xFE] differs from the data received [0xCA, 0xFE].
Now this clearly meant we had a serious problem: the error message was saying that the data does not match, which obviously was not the case as shown by the message text!
Since we were pretty confident about our side of things, as well as the readings from the scope, it seemed like a good time to start looking at the Samsung IIC drivers (and especially s3c64X0_iic_lib.cpp). The driver structure there is pretty straightforward: the first read/write byte on the bus triggers the hardware IRQ, which is mapped to SysIntr triggering a transfer event; then any subsequent call to a read/write function blocks waiting for a transfer-done event, which is triggered when the last byte is read/written in the IST.
Everything looks sane up to the point where a transfer-done event is signalled from the IST (pseudocode, not the original code below, due to the legal issues):
static HANDLE ghTransferEvent;
static HANDLE ghTransferDone;
static DWORD IICSysIntr;
...
static DWORD IST(LPVOID lpContext)
{
BOOL bTransferDone = FALSE;
while (TRUE) {
WaitForSingleObject(ghTransferEvent, INFINITE);
switch (IIC_BUS_STATUS) {
case MASTER_RECEIVE:
// receive bytes and store them in the buffer
break;
case MASTER_TRANSMIT:
// transmit bytes from the buffer in memory
if (LAST_BYTE) bTransferDone = TRUE;
break;
InterruptDone(IICSysIntr);
if (bTransferDone) {
SetEvent(ghTransferDone);
}
}
}
}
Two major problems with this code are:
- The
bTransferDonevariable is never set from the IIC read, and hence thetransfer-doneevent for bus reads is never triggered, - After the
bTransferDoneis set from the IIC write, it is never reset, hence thetransfer-doneevent is triggered after reading/writing single byte on the bus in all subsequent transactions.
That explains the initial test case failure: during the write/immediate read data comparison the data arrives exactly between the if statement and the following printout, thus triggering the error message, but printing the correct data to the output due to the early signal of the event.
The way to solve this is also straightforward: make sure that the bTransferDone variable is cleared after the transfer-done event is triggered, and make sure that master-receive mode sets the bTransferDone variable after reading the last byte of the transaction from the IIC bus.
In pseudocode it would look similar to:
static DWORD IST(LPVOID context)
{
BOOL bTransferDone = FALSE;
while (TRUE) {
WaitForSingleObject(ghTransferEvent, INFINITE);
switch (IIC_BUS_STATUS) {
case MASTER_RECEIVE:
// receive bytes and store them in the buffer
if (LAST_BYTE) bTransferDone = TRUE;
break;
case MASTER_TRANSMIT:
// transmit bytes from the buffer in memory
if (LAST_BYTE) bTransferDone = TRUE;
break;
InterruptDone(IICSysIntr);
if (bTransferDone) {
bTransferDone = FALSE;
SetEvent(ghTransferDone);
}
}
}
}
The lesson of the day (quoting my colleague) is: “The first rule about multithreading – you’re wrong“.

At work. Wolfson Microelectronics PLC, 2009
