Handling variable number of arguments in Lua


Here’s a quick example of how variable number of arguments can be handled in Lua. It has been tested with Lua 5.1 and 5.2.

function SomeFunction(...)
    local list = {...}
    print(string.format("Received %d arguments:", #list))

    -- print all arguments
    print(...)

    -- print all arguments again using a for loop
    for i = 1, #list, 1 do
        print(list[i])
    end
end

SomeFunction("hello", "world", 10)
Posted in Lua

Upgrade to Ubuntu 14.04 on Parallels Desktop 9


Ubuntu 13.10 is no longer officially supported so decided to bite the bullet and go ahead with the upgrade to Ubuntu 14.04, on Parallels Desktop 9. I’m running Parallels on an early 2013 MackBook Pro with Retina Display. The MAC OS X version is 10.10 (Yosemite) Public Beta. I installed the public beta after encountering problems running Parallels with Developer Preview beta 6.

Originally, I started with an Ubuntu 13.04 VM that Parallels officially supports, and at some point upgraded to 13.10. Ubuntu’s Unity interface does not work at all after that upgrade. I don’t get the taskbar or the menu bar at the top. I gave up on Unity, and followed instructions from Parallels to install and enable GNOME Flashback. All working right after that, even after upgrading to 14.04.

Posted in Miscellaneous

Integer division and timer resolution


I have this very specific need to send a list of pre-timed messages from an embedded system. Each message has a specific time when it needs to be sent out. The time is specified in milliseconds (ms) with respect to the previous message in the list. The first message being at time zero.

The algorithm to send messages out is very simple. I send out the first message, and arm a timer with the time of the second message. As soon as the timer expires, I send out the second message, and rearm the timer to send the third message, and so on. Thus, it is pretty clear that timer resolution is very important. Since the smallest integer time interval I require is 1 ms, a timer resolution of 1 ms or less would be ideal.

The embedded system I am dealing with, has a timer resolution of 2.5 ms i.e. 1 tick of the timer is 2.5 ms long. The timer routine does not accept a time of 0, 1 tick is the smallest integer value the routine expects. To convert time in milliseconds to ticks, I need a routine that can convert milliseconds to ticks. The conversion routine, putting it simply, would receive time in milliseconds, divide it by 2.5, and round the result to an integer value. I don’t have access to floating point math though, so the routine I’ve developed looks like this

typedef unsigned int uint32_t;
const unsigned short MULTIPLY_BY = 2;
const unsigned short DIVIDE_BY = 5; // never ever set to zero

uint32_t MillisToTicks(uint32_t timeInMillis, int *remainder)
{
    uint32_t timesTwo;
    uint32_t result;

    timesTwo = timeInMillis * MULTIPLY_BY;
    result =  timesTwo / DIVIDE_BY;
    *remainder += timesTwo % DIVIDE_BY;
    if (*remainder >= DIVIDE_BY)
    {
        result += 1;
        *remainder -= DIVIDE_BY;
    }
    else if(*remainder <= -1 * DIVIDE_BY && result > 1)
    {
        result -= 1;
        *remainder += DIVIDE_BY;
    }
    else if (result == 0)
    {
        result = 1;
        *remainder -= DIVIDE_BY - result;
    }
    return result;
}

MillisToTicks never returns zero. Dividing by 2.5 is the same as multiplying by 2 and dividing by 5. 2 is read from a constant called MULTIPLY_BY and 5 from another constant called DIVIDE_BY. Since the integer division will produce a remainder, MillisToTicks requires a pointer to integer where it can store the remainder of the integer division. That remainder is updated and checked during each call. If it exceeds DIVIDE_BY, the result is incremented by one, and remainder decremented by DIVIDE_BY.

If the result of integer division is zero, I force it to a value of 1, and decrement remainder by DIVIDE_BY. Next time MillisToTicks gets called, if remainder is less than or equal to -DIVIDE_BY, I decrement result by 1, and increment remainder by DIVIDE_BY. Putting it simply, there will be moments when I’ll stray away from timing the messages perfectly, but given enough messages, I’ll stray back on track. To test that, I have implemented the following code

int remainderMillisToTicks = 0;

uint32_t times1[] = {6, 6, 6, 2, 6, 6, 2, 2, 6, 6, 7, 8, 1, 1, 2, 3, 6, 20, 30, 9, 30, 100, 3000, 1, 1, 8000, 10000, 23, 1, 1, 19, 6, 5, 26, 201, 503, 901};

uint32_t times2[] = {6, 6, 6, 2, 6, 6, 2, 2, 6, 6, 7, 8, 503, 901, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 6, 20, 30, 9, 30, 100, 3000, 1, 1, 8000, 10000, 23, 1, 1, 19, 6, 5, 26, 201, 503, 901};

uint32_t times3[] = {6, 6, 6, 2, 6, 6, 2, 2, 6, 6, 7, 8, 1, 1, 2, 3, 6, 20, 30, 9, 30, 100, 3000, 8000, 10000, 23, 19, 6, 5, 26, 201, 503, 901, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1};

void test(uint32_t *times, unsigned short size)
{
    int i;
    uint32_t totalMillis = 0;
    uint32_t ticks = 0;
    double ticksToMillis = 0;
    double totalTicksToMillis = 0;

    for (i = 0; i < size; i++)
    {
        totalMillis += times[i];
        ticks = MillisToTicks(times[i], &remainderMillisToTicks);
        ticksToMillis = ((double)ticks*DIVIDE_BY) / MULTIPLY_BY;
        totalTicksToMillis += ticksToMillis;
        //printf("%d\t%f\t%d\t%d\t%f\n", times[i], ticksToMillis, remainderMillisToTicks, totalMillis, totalTicksToMillis);
    }
    printf("Ideal total time required: %d, time achieved: %f\n", totalMillis, totalTicksToMillis);
}

int main()
{
    test(times1, sizeof(times1) / sizeof(uint32_t));
    remainderMillisToTicks = 0;
    test(times2, sizeof(times2) / sizeof(uint32_t));
    remainderMillisToTicks = 0;
    test(times3, sizeof(times3) / sizeof(uint32_t));
}

Here’s how the output of that test code looks like

Ideal total time required: 22953, time achieved: 22952.500000
Ideal total time required: 24363, time achieved: 24362.500000
Ideal total time required: 22965, time achieved: 22985.000000

Enable the commented printf statement in test and you’ll see a call by call log. At times, when the time value requested is too small, you’ll see the messages stray away from perfect timing, and stray back to a normal cadence later. The overall time is thus unaffected or affected only slightly. The last call to test represents a failure condition that can only be avoided by using a higher resolution timer.

Posted in C and C++, Software Design

Adding Node.js to Buildroot


I successfully built an embedded Linux system for Raspberry Pi using Buildroot recently, and decided it was time to add some useful packages to it. The first that came to mind is Node.js. Having that on the Linux system will allow me to serve an HTML5 UI to any computer with a browser, on the same network.

Invoke

make menuconfig 

in buildroot folder to obtain the configuration UI. Node.js requires IPv6 support so I enabled that in the Toolchain menu thus

buildroot_ipv6

Then I enabled Node.js and npm from the Target packages menu thus

buildroot_nodejs

buildroot_npm

I followed that up by issuing a full build thus

make clean
make

Buildroot stores all downloads in the dl folder, so it will only download whatever isn’t already there. It will build the host cross-compilation toolchain from scratch though, since that is available under output, and make clean removes everything there.

I’ve now got Node.js 0.10.12 working successfully on the Linux system.

Posted in Linux, Raspberry Pi

SparkFun FTDI Basic with Raspberry Pi


Here’s how you can connect a FTDI Basic (USB to serial) breakout board to Raspberry Pi’s GPIO connector.

pi-ftdi-basic

Here’s how cmdline.txt in the boot partition of my Raspberry Pi looks like

dwc_otg.fiq_fix_enable=1 sdhci-bcm2708.sync_after_dma=0 dwc_otg.lpm_enable=0 console=ttyAMA0,115200 root=/dev/mmcblk0p2 rootwait

For the kernel log to appear on the serial port, console should be set to ttyAMA0.

To get a login prompt /etc/inittab should contain a line such as

ttyAMA0::respawn:/sbin/getty -L ttyAMA0 115200 vt100 # GENERIC_SERIAL
Posted in Linux, Raspberry Pi

What woes Samsung?


Samsung announced a rather lackluster quarter (compared to last year). What woes it? I am willing to hazard it is software. I was recently in the market for a cheap Android phone. Even though Samsung had an impressive lineup of hardware, none had Android 4.4 (KitKat) on it.

Low-end hardware requires Android KitKat due to improvements in how it supports low memory. The only phones that were touting Android 4.4 were from LG and Motorola. Motorola was still slightly costlier and Moto E hand’t arrived yet. Guess which I bought?

Posted in Android, Business

Custom embedded Linux system for Raspberry Pi with Buildroot


This post shows how easy it is to make a custom embedded Linux system for Raspberry Pi using Buildroot. I used an Ubuntu 13.04 VM for Parallels Desktop 9 to perform the build.

The Ubuntu VM required only two dependencies and I could go ahead with the build. These I installed by executing

sudo apt-get install ncurses-dev git g++

I then obtained Buildroot release buildroot-2014.05.tar.gz and extracted it to a local folder using tar xvzf buildroot-2014.05.tar.gz. The procedure to perform the build and prepare an SD card is well documented in file board/raspberrypi/readme.txt.

I headed into the buildroot-2014.05 folder and prepared the appropriate .config file required by buildroot

cd buildroot-2014.05
make raspberrypi_defconfig

Since I wanted to generate a persistent root file system, I followed that by executing

make

The build takes a while to finish. Once done, I followed the steps in readme.txt mentioned above to prepare an SD card. I already had an appropriately formatted SD card so I copied the relevant output files

rm /media/parallels/boot/*
cp output/images/rpi-firmware/* /media/parallels/boot/
cp output/images/zImage /media/parallels/boot/
sudo rm -rf /media/parallels/fc254b57-8fff-4f96-9609-ea202d871acf/*
sudo tar xf output/images/rootfs.tar -C /media/parallels/fc254b57-8fff-4f96-9609-ea202d871acf/

I was able to boot Raspberry Pi with the newly minted headless embedded Linux system, use an HDMI display to log in, and bring up the ethernet interface eth0.

Posted in ARM, Linux, Raspberry Pi
Follow

Get every new post delivered to your Inbox.

Join 63 other followers

%d bloggers like this: