Important safety tip: Desperado got cumbersome enough that it is no longer under development. But much of it was so useful that it was forked into Desperadito. Almost everything described below, plus the non-S3 portions of Hayloft, were ported into Desperadito.
Desperado is a library of reusable object-oriented components written in C++ and C. It was developed as a reference implementation of some of the useful design patterns I encountered in embedded applications and found myself re-implementing from project to project, while (I hope) not falling prey to the not-invented-here syndrome. It requires a ANSI C99 and ANSI C++ compiler to build. This version runs under Linux and Cygwin, but it is simple to port to other operating systems. It is licensed from Digital Aggegates under a modified Lesser GNU Public license (LGPL) that allows it to be used in statically linked executables without any viral licensing implications. What small amount of Java code there is in Desperado is licensed in the Apache License, Version 2.0, and is only needed if you want to use the Java Native Interface tools.
Desperado includes the following components:
- FiclShell provides a FORTH-based programmable command-line shell that can access variables and functions with C bindings in the underlying application. It uses Ficl, John Sadler's embeddable, small-footprint FORTH interpreter. It can read and write C variables and call C functions with as many as ten integer arguments. The FORTH data stack can be accessed by the application.
- BandwidthThrottle, CellRateThrottle, and GeometricThrottle are used for rate control. The various throttle classes implement several rate control strategies, many of which are based on the Generic Cell Rate Algorithm (GCRA).
- Dump displays memory in hexadecimal word or byte format. It sounds mundane, but we use it frequently.
- Input and Output functors offer an consistent abstraction for binary and character I/O. BufferInput/Output, DescriptorInput/Output, FileInput/Output, PathInput/Output, and SocketInput/Output are among the I/O functors implemented..
- Print provides formatted output through any output functor.
- Ram is a template that generates efficient hardware memory tests for memory width of any integer data type. It is based an article by Michael Barr in Embedded Systems Programming magazine.
- Crc is a template that generates parameterized sixteen or thirty-two bit cyclic redundancy check algorithms. It is based on the work of Ross Williams at Rocksoft.
- CommonEra, LocalTime, AtomicSeconds, LeapSeconds, TimeZone, DaylightSavingTime and others handle the conversion of time values between seconds with nanoseconds, Coordinated Universal Time (UTC), International Atomic Time (TAI), and Local Time, relative to an arbitary time and date in the Common Era. For example, these components can generate a time stamp in UTC or local time using a time duration relative to when a embedded device was reset. It includes support for time zones, different daylight saving time algorithms, and leap seconds.
- Chain, Link and the template LinkType are a family of classes that support a simple, efficient, data structure that implements doubly linked lists. It implements FIFO, LIFO, and circular linked lists. In O(1) time it can perform operations like insert, remove, push, pop, and getting the head of the list. The Link node an be embedded inside an object, just like a pointer, or used independently, in a manner similar to the structures in the Standard Template Library. An object can be easily managed on multiple chains of links simultaneously. This data structure is useful in real-time applications where the use of the STL might be problematic.
- Number is a template that generates a number parser for any integer type. The base of the input number string is derived from context. The parser is similar to, but more flexible than, the libc functions strtol and strtoul.
- Platform provides an abstract interface to the small number of operating system services needed by Desperado. Linux and Cygwin are derived classes.
- JavaVirtualMachine and com.diag.desperado.Platform extend the Desperado Platform abstraction into the Java realm using the Java Native Interface.
- Heap is a malloc-like interface to the C++ heap. malloc is in turn a POSIX-compliant C-binding interface to Heap. This design simplifies introducing a common alternative heap manager into both C++ and C code in a single application.
- Transliterator provides a mechanism for implementing simple time and space efficient table-driven parsers. The examples Word and Attribute are implemented.
- Escape expands and collapses C-style escape sequences. Encode expands and collapses URL-style escape sequences.
- generics is a collection of well tested preprocessor macros that automatically generate handy values, like minimum and maximum signed numbers, for any integer data type. These simplify generic programming, for example when using C++ templates, but are very useful in C as well.
- cxxcapi is a collection of macros and other preprocessor symbols that simplify writing components that can be used with either C or C++ translation units.
- Desperado incorporates many useful architecture patterns. It contains numerous examples of how to incrementally introduce C++ into legacy C code bases, and how to effectively use C++ objects directly from C code. It shows how to abstract out operating system and input/output details to defer their implementation, allowing greater parallel development and easier application porting. It illustrates how to use templates to avoid allocating and freeing memory from the heap in real-time and embedded code. It uses templates to create efficient type-safe variable sized data structures.
- Unit tests are included which serve as coding examples and use cases. They can be run as main programs, from the FiclShell, or called as functions, enabling them to be run on an embedded target to verify the library's correct operation on the actual hardware.
N.B. Desperado originated way back in 2005 when I was doing a lot of work on non-Linux/GNU systems (vxWorks, pSOS, C-Executive, etc.) that didn't necessarily use GNU compilers or GNU make. Trying to accomodate all those different platforms has gotten a little unwieldly. I'm slowly moving the components of Desperado that I use on other projects into a subset called Desperadito that has a smaller footprint and a simplified build environment. However, Desperado remains the main code line for both development and unit testing.
Here are some articles that my alter-ego Chip Overclock has written about Desperado:
- Does anybody really know what time it is?
- Rate Control using Throttles
- Generic Embedded Programming Using Templates
- Generic Embedded Programming Using the C Preprocessor
- Can't We All Just get Along, C++ and C?
- Up the Source Code Organization
- Abstraction in C++ using I/O Functors
In addition, the subset Desperadito is used extensively in Hayloft, which Chip has also written about.