You are currently browsing the Sticky Bits blog archives for July, 2012.

The changing face of programming abstraction in C++

July 27th, 2012

Iterating through containers… options, options options.

Iterating through a container of objects is something we do a lot.  It’s boilerplate code.  It’s also a nice indicator of how C++ is raising the level of abstraction in programming.

So let’s start with a simple container of ADTs:

image

Now let’s iterate through them, calling the mf() method on each object in turn.  First, we’ll ‘roll our own’ loop.

image

That’s imperative programming in action; and has the warm, fuzzy feeling of recognition for all C programmers.

Modern C++, however, favours a more declarative style of programming (even though, under the hood, it’s all imperative!)  Typically, you’d use an algorithm to declare what you want to happen (in this case, iterate across a range of objects in a container, doing ‘something’ to each one) rather than how:

image

This is certainly more abstract, but I’m not sure it’s much more readable (am I the only person who feels the member function adapters are named the wrong way round?)

A brief look at the code for for_each reveals that it pretty much does what your hand-rolled code would do.

With the release of C++11 we have new options available to us.  First up is the lambda:

image

The syntax for lambdas tends to provoke upset in more-sensitive souls but once you’re used to it the algorithms become quite elegant: I define what I want to happen exactly at the point I need it.  Now I’m specifying what I want to achieve, and how I want to achieve it all in one one lovely confection of declarative and imperative code!

Finally, in a random act of good sense the C++ committee realised that iterating through containers is such a common thing to do it should be added to the language rather than being relegated to a library function – just like in other modern programming languages:

image

The range-for statement provides a single (compound) statement solution to accessing each element of a container.  And it works with all the standard containers – even good ol’ fashioned arrays.

But surely, such an abstract statement will be woefully inefficient; or put another way: “it can’t possibly be as efficient as my hand-rolled loop”.  I did a quick comparison:

image

Hand-rolled loop:

  • 35 lines of assembler, including:
  • 8 function calls
    • std::vector<T>::begin
    • std::vector<T>::end
    • std::vector<T>::iterator::operator ++
    • std::vector<T>::iterator::operator !=
    • std::vector<T>::iterator::operator –>
    • std::vector<T>::iterator::~iterator (called in two places)
    • The member function call

Range-for statement:

  • 34 lines of assembler, including:
  • 8 function calls:
    • std::vector<T>::begin()
    • std::vector<T>::end()
    • std::vector<T>::iterator::operator ++
    • std::vector<T>::iterator::operator !=
    • std::vector<T>::iterator::operator *
    • std::vector<T>::iterator::~iterator (called in two places)
    • The member function call.

So, to all practical intents and purposes the code is the same.  So, with C++11 there really is no compelling reason for rolling your own iteration loops.

Embedded System Conference – India

July 13th, 2012

 

This year I have honour of being invited to present at the Embedded Systems Conference in Bengaluru (Bangalore), India. Based on previous visits these classes are very well attended and always generate a lot of post-class discussions.

This year I’ve extended my previous 1/2 day class to a full day titled “Programming in C for the ARM Cortex-M Microcontroller”. Having a full day allows me to delve in too much greater detail. The class is broken down in to four subsections:

  • Cortex-M Architecture
  • C Programming and the Cortex-M
  • CMSIS (including CMSIS-RTOS)
  • Debug (including CoreSight)

An overview is covered here.

The other class is one I have presented at ESC in the US before but not in India; Understanding Mutual Exclusion: The Semaphores vs. the Mutex. This presentation is based around much of the material in some of my previous postings (see RTOS related blog postings ). I still find this class really interesting. In general, whenever you bring up the mutex/semaphore discussion most people jump to a per-conceived idea that they know the differences; by the end of this class most understand that their mental model was incorrect.

If anyone is attending then please come and say hello.

Creating a Linux Live USB Thumbstick (The Hard Way)

July 6th, 2012

Introduction

So recently I needed to create a live system and I had a spare 8 GB USB drive on which to do it.

Looking around the net there’s a lot of solutions to doing this but I needed something that would be independent of the host distribution – I used Fedora 17 in this instance but it might not be in the future – and would work quickly and easily.

This article seeks to document what I did in order to accomplish this – whether it could be done better is for you to sort out in the comments!

Getting Started

You will need the CD ISO of the distribution you want to use (I used Ubuntu 10.04.4 LTS) and an inserted but unmounted thumb drive.

1. Using the Disk Utility, partition the disk such that the first partition is as big as it can be – minus 750MB – set it as bootable and format it as Fat (FAT32 LBA)

2. Create an additional partition of unformatted space up until the end of the drive to take up the 750MB.

3. Mount the first partition from the command prompt, note my device came up as /dev/sdc, yours may differ:

sudo mount /dev/sdc1 /mnt

4. Install grub2 onto the windows partition. You will need to have this package installed (either yum install grub2 on Fedora or sudo apt-get install grub2 on a Debian/Ubuntu system).

sudo grub2-install --no-floppy --root-directory=/mnt /dev/sdc

5. Copy over the kernel and initrd (initial RAM disk) over from the ISO. To do this I double clicked the ISO, let it automount, grabbed the files vmlinuz and initrd.lz from /casper/ and copied them over to my home directory. I then copied them to the drive.

sudo cp ~/{vmlinux,initrd.lz} /mnt/boot/

6. Create a file to be used as the persistent file-system – I have chosen to create mine as 2GB here but you can choose whatever you like bearing in mind you can’t have a file larger than 4GB on a FAT32 partition.

sudo dd if=/dev/zero of=/mnt/casper-rw bs=1M count=2048

7. Format the persistent filesystem file

sudo mkfs.ext4 -F /mnt/casper-rw

8. Write your Linux ISO to the second partition

sudo dd if=~/ubuntu-10.04.4-desktop-i386.iso of=/dev/sdc2

9. Create a grub2 boot menu

Create/Open up the file /mnt/boot/grub2/grub.conf in your favourite editor and make it look like this:

set default=0
set timeout=10
menuentry “Ubuntu Live” {
set root=(hd0,1)
linux /boot/vmlinuz boot=casper file=/preseed/ubuntu.seed persistent rw noprompt noeject
initrd /boot/initrd.lz
}

10. Unmount and sync the drive

sudo umount /mnt
sudo sync

11. Reboot your system (safely!)

12. Choose the correct option to boot from USB and enjoy your new Linux environment.

And that’s it. You now have a USB live CD that should allow you to create live environments for a wide variety of distros whilst also  requiring no disto specifics tools.

 

Nb. As a former Ubuntu guy I was really chuffed to find out about the command ‘yum provides <binary|file>’ which causes yum to go off and find a package that provides that a file by that name for example:

[nick@slimtop ~]$ yum provides grub2-install
Loaded plugins: downloadonly, langpacks, presto, refresh-packagekit
1:grub2-2.0-0.25.beta4.fc17.i686 : Bootloader with support for Linux, Multiboot and more
Repo        : fedora
Matched from:
Filename    : /usr/sbin/grub2-install

Very cool – on Debian you can install the apt-file package which will let you accomplish the same thing.

%d bloggers like this: