Monday, April 23, 2007

ZX Spectrum dreams

Got to mention this post on Slashdot:

http://games.slashdot.org/games/07/04/23/1214256.shtml

Although this the Sinclair ZX Spectrum was not my first computer, it was an (large) extension of my first (ZX81) and had a huge impact in my programming and game playing habits.

I also wrote an article about games on the machine ages ago:

http://www.lightsoft.co.uk/PD/rob/speccy_g.html

Monday, April 09, 2007

What Next Robot?

Guess I missed telling you about a decision on the robot project.

We'd been doing mostly motor control and related sensing and got the robot to move a fixed distance and turn (albeit with less accuracy than in a straight line).

Rather than make the position control really, really good, I thought we should work on something we don't know whether will work at all; the camera.

Most of the maze solving robots use simple infra-red sensors either along the tops of walls or, more likely, pointed the side walls (which is better for angular momentum reasons) with, sometimes, some not so simple processing. I fancied using a camera. Cameras have been talked about a lot but in reality machine vision is not an overly simple problem for individuals, especially spare-time hobbyists, to tackle - but not impossible. For us an additional problem is that adding infra-red sensors as well as the camera would require input/output expansion on our current microcontroller and extra mechanical work that I'm not overly keen to do.

There are several really big unknowns with the camera solution:
  1. Can we communicate with the camera? (both the serial and parallel interface)
  2. Can we perform the algorithm to know where we are when stationary? (the camera is probably useless without this ability)
  3. Can we get a picture to know where we are when moving? (might need IR sensors that we don't currently have if we can't do this)
  4. Is the angle of view good enough? (might well need a wide-angle lens as it stands)
To do this, we would require at least a single picture off the camera of the maze - to which we can evaluate all of the above points. So that's what I'm working on.

Doing this now rather than later will allow us to know if the current philosophy behind the robot is possible and if we require hardware adjustments or extra sensors to compensate for what we can't do with the camera. We are effectively bringing the risk earlier in the project to allow us more time to compensate if the camera does not work in some way.

At some point I'll detail what the theory behind the camera position sensing is.

Robot Camera Commands

(Hopefully this won't end up as a robot blog!)

I've been working on the camera command interface, which is a I2C serial interface.

I've split this into two sections:

1. A lower part that communicates with the on-board i2c peripheral registers and just reads or writes a data stream (although it also handles the device address and read/write bit). As with all low level drivers, this turns out more complicated than it first appeared - especially since I need multiple state machines.

2. A camera specific controller that read and writes to specific camera registers and uses (1) above to do that without knowing about the serial interface. This is the bit I'm doing at the moment.

This division simplifies each section and focuses it on being good at the work at hand.

Wednesday, February 21, 2007

Talking only makes yourself look stupid

On Saturday I blogged about not needing new and delete. However it turns out that on Sunday I found out a use for new and delete. Typical.

I have a command line interpreter that has various control and testing commands. It's very simple (and was fairly fast to write) but it's really proven it's worth in testing. So much so that (together with the ability to write back to the PC terminal via the serial port - effectively print) that I haven't bothered to get the GDB debug stub up and running.

Anyhow, I wanted to test out a new class I'd written independently from the classes that use it. Sort of 'unit test an instance of that class'. Obviously with procedural code you just patch in the functions. Not so simple with OO because you need to create one somewhere first. Since it's not in the scope of one function (several commands to exercise it) the stack (i.e. an automatic) wasn't an option. And I don't want the object hanging around as a static either together with it's construction bindings to various input objects.

I guess I could have made it an optional compile as a static - but that means all the compile in and out whenever I make a minor change and want to retest. That isn't ideal.

I looked at what might be involved and it looked fairly trivial. Additionally the dynamic memory allocation might be useful for other things as well. Embedded programmers tend to be very wary - but I guess if either (a) memory usage is fully analysed, or (b) only non-critical (or extra) services use the memory, then there is no reason why dynamic memory shouldn't be included.

I'm still mostly using static objects and automatic-based objects in the design and the dynamic stuff uses any spare RAM, however much there is left ... from end of compiler used memory to end of RAM.

So, on Sunday I started implementing tiny but fully functional chained-list type allocator / deallocator.

On Monday I realised didn't really need that yet. So #if-0'd that out and wrote a braindead allocator based on the article here. It's a very simple allocation scheme ... no free function, just chews up the RAM. Turns out that is absolutely fine - especially with how much this robot gets reset (and hence the memory 'deallocated').

Simple.

Got it working Tuesday. Minor problem with getting access to linker variables from C++ without then being indirected twice ... had to get the address of the extern unsigned int in order to get the actual value I was after ... bizarre, but it works and the assembler listing from the compiler looks OK and it means no need to do anything in the assembler source. Wrote some debug words to test allocator (and return interesting info).

Then I wrote some test words to actually create, use and delete a test object. All works fine! Amazing. As it stands I have over 60K of free store RAM!!! No doubt that will go down as the project progress, but still.

Now I can get one with debugging that new class I wrote to do speed control... oh well, interesting diversion.

Saturday, February 17, 2007

GCC C++ Link problems on small embedded target

Thought someone might be interested in this...

I spent Thursday night and Friday night investigating some link errors I was getting on my robot project, which is small embedded ARM7 target compiling C++ code under GCC.

So here is the detail of the errors:

speed_control.o: In function `~Speed_Control':
source/speed_control.cpp:35: undefined reference to `operator delete(void*)'
speed_control.o: In function `~Sensing_Callback':
source/motor_sensing.h:38: undefined reference to `operator delete(void*)'
speed_control.o:(.rodata._ZTI13Speed_Control[typeinfo for Speed_Control]+0x0): undefined reference to `vtable for __cxxabiv1::__vmi_class_type_info'
speed_control.o:(.rodata._ZTI16Sensing_Callback[typeinfo for Sensing_Callback]+0x0): undefined reference to `vtable for __cxxabiv1::__class_type_info'
speed_control.o:(.rodata._ZTV16Sensing_Callback[vtable for Sensing_Callback]+0x8): undefined reference to `__cxa_pure_virtual'


All of these problems were caused by the fact that I'm not using the C++ libraries - either the compiler C++ support libraries or the standard libraries. And the very summarized version is that none of them were particularly hard to overcome - once you knew why they were happening! This post is about what they are.

Why aren't I using the standard stuff? This is because I don't have much flash or RAM. Well, actually I have 128K of Flash (which I expect I won't use up) and 60K of RAM (which I'm going use a significant fraction for a large data store ... all will be revealed in a later blog entry). It's quite common for embedded systems to roll their own nearly everything. I do link against certain libraries. But certainly nothing like heap management, cout or printf.

Undefined References to class_type_info

Starting with with the undefined references to
`vtable for __cxxabiv1::__vmi_class_type_info'
and
`vtable for __cxxabiv1::__class_type_info'
- these are related to RTTI (run-time type information) as suspected, and are functions patched into the RTTI table. There is a pointer to this from the vtable.

This is the vtable:

507 _ZTV16Sensing_Callback:
508 0000 00000000 .word 0
509 0004 00000000 .word _ZTI16Sensing_Callback
510 0008 00000000 .word __cxa_pure_virtual
511 000c 00000000 .word _ZN16Sensing_CallbackD1Ev
512 0010 00000000 .word _ZN16Sensing_CallbackD0Ev


As you can see, address 4 points at the type table.

492 _ZTI16Sensing_Callback:
493 0000 08000000 .word _ZTVN10__cxxabiv117__class_type_infoE+8
494 0004 00000000 .word _ZTS16Sensing_Callback


Obviously those are mangled names ... and I've left off a whole other block - this is the pure abstract base class, effectively an interface, part of a concrete class.

Since I'm not using rtti at all, we can get rid of this by adding "-fno-rtti" to the gcc command line options. Both errors go away.


Undefined Reference to `__cxa_pure_virtual'

This one is interesting. Effectively it's a function that is called if you actually (somehow) call a pure virtual member function. Remember that you don't give them a definition (by putting =0) in the class after the member function definition. As you know - this does two things, forces you to define it in any derived classes and stop you making a concrete version of that base class.

I guess you've have to be hacking the vtable or doing some very bizarre casting to get this at all without the compiler spotting it. Either way, I think it's part of the language standard I think - I believe gcc's standard lib does an abort.

eCos has some information on it, as does the OS Dev Wiki.

http://sourceware.org/ml/ecos-patches/2003-03/msg00209.html

http://www.osdev.org/wiki/C_PlusPlus

We just sit in a loop, because I think it will never happen to us.

extern "C" void __cxa_pure_virtual(void)
{
// call to a pure virtual function happened ... wow, should never happen ... stop
while(1)
;
}



Undefined Reference to operator delete(void *)

The final ones quite good ... and Google really didn't help direct me to the information in any sort of quick way.

So, I don't use new and delete - because we haven't got a heap, and the memory on the single-chip microcontroller is not really large enough to use that type memory management (certainly not with my usage). It's all stack based and static objects for us. But that's ok.

So why is gcc generating a delete? Turns out there is more than one destructor in gcc (and there also can be two types of constructor as well - but I'll just cover destructors here). If the destructors are virtual they will appear in the vtable (there are two in the vtable one above - but another class has three). How gcc decides to generate 2 or 3, I haven't found out.

In summary, these three are:
  • in-charge deleting (the destructor also deletes the memory space) ... has D0Ev at the end of the mangled name.
  • in-charge (the destructor is allowed call other destructors) ... has D1Ev at the end of the mangled name.
  • not-in-charge (the destructor is NOT allowed to call other destructors ... and this has D2Ev at the end of the mangled name.
(v means void (i.e. no parameters) by the way).

So why the difference between in-charge and not-in-charge? Well, it's got to do with virtual inheritance (as opposed to virtual member functions). The summarised version is that these are multiple inherited classes that have a single base class at some point where we want one object copy rather than a copy for each derived path.

The rules say, to avoid trying to 'destruct' these common base classes multiple times, that only the most-derived class can sort out calling the destructors (and this is probably the simplest method, anyhow).

Also note that multiple destructors is not the only way of handling this ... earlier versions of gcc passed parameters into the destructor and generated code to select the desired operation. However, you get this speed overhead all the time. Extra entries removes this problem - because you can call the one you want directly.

The 'in-charge deleting' version is, I'm guessing, when you destroy an object by calling delete on it. Therefore gcc only needs to arrange to call the destructor. Of course this will always be "in-charge", since it's likely to be at the top of a hierarchy ("most-derived").

Some more information for this topic, mainly about virtual inheritance:

The OS Dev Wiki touches on the solution: http://www.osdev.org/wiki/C_PlusPlus

This GNU list describes the virtual inheritance stuff, what's called when: http://lists.gnu.org/archive/html/bug-gnu-utils/2004-07/msg00042.html

Notes about the implementation: http://gcc.gnu.org/ml/gcc-patches/2000-04/msg00403.html

Actual details of what's called when from the closed items of a bug tracking system. Search for C-5 and C-6 - there are quite a few more details. C-4 is interesting as well. http://www.codesourcery.com/cxx-abi/cxx-closed.html

My actual solution? Added this to my project...


void operator delete(void *)
{
// should never get here ... we don't use new
while(1)
;
}



And now it builds.

Tuesday, October 31, 2006

Halloween

Nothing really happening.

Logging objective-C message sends. Trying to figure out how to log only a small subset before a crash. Not really a problem, just a bit of thinking. Plenty of blogs about various details. No complete solutions for exactly what I want. So thinking and understanding is required.

Just saw a tv program about the Robot cars making it across the desert. Very cool.

Reading "Death March" by Ed Yourdon. Mostly unsurprising so far (I've been involved in several of those projects). However, it's quite readible and funny. Also Reading "Growing A Business" by Paul Hawken. Also quite readable and also funny.

Thinking about various new business ideas. Quite a few ideas. Nothing that is as good as current shareware work.

Saturday, September 30, 2006

Programming Paradigms - don't be popular

Why does OO have a list of critism (and also mention lack of Evidence) but the other programming Paradigms don't on Wikipedia?

http://en.wikipedia.org/wiki/Object-oriented_programming

Surely the 'others' don't have good evidence they make programming faster/better either?

Some examples:

http://en.wikipedia.org/wiki/Functional_programming
http://en.wikipedia.org/wiki/Procedural_programming
http://en.wikipedia.org/wiki/Logic_programming
http://en.wikipedia.org/wiki/Imperative_programming
http://en.wikipedia.org/wiki/Reflective_programming
http://en.wikipedia.org/wiki/Relational_database (ok, not strictly a programming paradigm)
I agree Relational databases are much more popular than OODB and therefore must be better ;-)

I guess some of the reasons are that (a) it's being applied everywhere, even when it's not applicable, (b) no proof of being better, (c) other good reasons.

But mostly, I suspect, it's hated because it's popular.

I expect, in reality, programming efficiency is more "fitting people's minds" than "less lines of code" or "better speed efficiency" (take functional vs. imperative, for instance).

Are Design Patterns (mostly) not needed in "high-level" languages?

Sunday, September 17, 2006

BASIC, kids, programming.

Good article about the inaccessibility of programming as relating to kids:

http://www.salon.com/tech/feature/2006/09/14/basic/index.html

I’m glad he mentioned Python and Chipmunk basic. Otherwise I was going to dismiss him as a crank.

Some language (say that could be used in the command prompt) would be a better than the current situation on Windows (and let’s not talk about batch files :-D ). At least you've got some programming languages with MacOSX (e.g. Python/Perl from the terminal, Xcode with C/C++/ObjC/Java on CD).

The most powerful invention of the 20th century is the programmable computer and the one that will have the most impact of the 21st century.

Sunday, August 27, 2006

Current Coding Book Being Read

Head First Design Patterns, Freeman & Freeman, Published by O'Reilly.

For a design patterns book it's very readable. You need to understand some Java (no hard problems) and it's an introductory text (to medium level) - but that's ok I'm still learning some of the patterns.

Lots of fun examples (e.g. Pizza shop, chocolate company, duck simulation package) code and pseudo-UML diagrams. Multiple ways of explaining stuff.

Overall: Good read and a book that is actually very readable.
Newer›  ‹Older