Skip to content

Posts from the ‘Embedded’ Category

6
Sep

6 km Flight Video, New UAV Parts Ordered

We had several successes this weekend, with longer-range flights. We flew the small wing out 2 km, and it successfully returned and landed. A couple days later, we flew out to 3 km. We started to lose telemetry at that range with the rubber ducky antenna, but the plane flew without trouble. Here’s a video of a successful flight with autoland:

The wing above is the red one in this photo. The new wing is the black one:

The 2.1 m Wing

The new wing will use an E-flight Power 32 motor, shown here on the test stand:

New UAV Parts

I had a flurry of buying activity this weekend, after seeing the new wing. The thing is huge: 2.1 m. I decided to build one, too. The wing it self will take the longest to arrive, some time next week, but I ordered everything else in the mean time, which should arrive before the weekend.

Here’s the list of stuff:

Item Source Price
Wing Flying Foam Mothership 2.1 m $145
Motor Power 32 Brushless Outrunner Motor, 770 Kv $74.99
ESC Castle Creations Phoenix ICE Lite 75 $110.95
Autopilot ArduPilot $250.00
Airspeed Airspeed Kit $24.95
Communications XtreamBee Board $24.95
XtreamBee USB Adapter $24.95
Digi XBP09-DPSIT-156 SMA Connector $42
Digi XBP09-DPWIT-156 Wire Antenna $42
Lighting Numerous bright LEDs from SparkFun $72.50
12
Apr

Trouble with Static C++ Constructors in ChibiOS/ARM

For the last few days I’ve been troubleshooting a problem with a C++ thread class I created to aid in the static allocation of threads under ChibiOS.

The problem boiled down to the fact that the ChibiOS ARM port (specifically, the ARM7 port, but it’s probably true for most ports) isn’t properly executing the constructors for statically (globally) allocated class objects. To clean up the other post, I moved the troubleshooting material to this post.

Note: I’ve discussed this with the author of ChibiOS, and he hopes to resolve the issue in ChibiOS version 2.3.2.

When any object with a vtable pointer is allocated on the stack (i.e. at run time), it works. But when it is allocated as a global variable, the vtable pointer is NULL. Here’s the test code and output:

As you can see, the constructor isn’t getting called, (and vtable initialization isn’t happening) for the statically-allocated object f, but does get called for object g, allocated on the stack.

This is a GCC issue. It needs to call static ctors (and dtors, theoretically), but it’s failing to do so. It could be a mis-configured build of the toolchain, or a bug in the run-time library, or something else along those lines.

Thoughts While Troubleshooting

It currently fails on ARM (on an AT91SAM7X). The symptom is typical of exceeding the allocated stack space: the processor appears to reset (that is, it re-starts execution from the start of code).

There are two failure modes: in the first, it fails in ThreadEntry(), where the the thread context is cast to a pointer to the BaseThread class, and the virtual entry() method is called, executing the CThread subclass’ implementation. If I remove the call to entry() and just implement some code directly in ThreadEntry(), it works fine.

The second failure mode has to do with what I put in the modified ThreadEntry(). Although it executes, subsequent execution later in the program fails (by failure, it is meant that the processor appears to reset).

At this point, I’m not sure what is wrong. Code seems well-enough aligned, when the GCC .map file is examined. The self/this pointer in ThreadEntry() has the correct value. I’ve tried with very large stacks to ensure I’m not overrunning the stack. I’ve tried a non-template class hierarchy to be sure virtual method dispatch works correctly (it does).

I’m going to try twiddling some outputs on the MCU (instead of calling the stdlib routines I have been). Without JTAG debugging, it’s going to be difficult to figure this out.

11
Apr

Using Templates to Statically Allocate Thread Working Area in ChibiOS

On both 8-bit AVR and 32-bit ARM (AT91SAM7X and SAM3S), I’ve been using ChibiOS. It’s a nifty little OS that supports fully-static operation. That is to say, it’s possible to allocate all OS structures statically, at compile time, so none need be allocated dynamically at run-time, an operation that can possibly fail. This also allows the exact memory requirements to be known before loading the code onto the target.

I wrote a CThread class (so named to avoid conflict with the OS Thread object) that wraps the allocation of the thread working area and OS thread creation. To do this, CThread is a template class, parameterizing the stack size. Clients subclass CThread and implement the virtual msg_t entry() method.

Note: If you’re looking for the description of what goes wrong when the compiler fails to properly initialize static C++ object instances, I moved that material to a new post, Trouble with Static C++ Constructors in ChibiOS/ARM.

ChibiOS Threads

In ChibiOS, to create a thread, you allocate the thread working area with a macro provided by the OS, and call chThdCreateStatic():

The last parameter to chThdCreateStatic() is passed into the thread’s entry point. We use it later to pass a reference to the thread class.

As soon as chThdCreateStatic() is called, the thread begins executing. ChibiOS provides numerous synchronization primitives, but we won’t get into those here.

CThread Class

The idea with the CThread wrapper is to provide a class to be subclassed to tidy up the creation of a thread. It would be used like this:

And the implementation:

Finally, the thread is allocated as a global (as before), and started:

Considerably tidier, isn’t it?

Pulling this off requires two classes: A non-template BaseThread class that provides the basic thread functionality, and the CThread template class that derives from it. Note that I do this to try to avoid redundant code generation, which can probably be done using partial specialization or a smart compiler, but I wasn’t sure how much luck I would have. The approach does result in a an extra member variable in the base class: the working area size from construction to be used when the thread is started.

BaseThread::entry() should be pure virtual, but I had link errors on AVR with that.

Here’s the complete implementation.

CThread.h:

And the implementation:

What you see above is a little messier than it could be, given a number of issues I ran into while developing it, and concerns about code bloat. But it works reasonably well.