Embedded Systems Can't Be Too Rich or Too Thin
One of the fun things about building embedded hardware is that it has more of the flavor of the computers of my youth. That is, they aren't nearly as fast as my 4GHz six-core desktop. Nor do they have the 16 GB of RAM or multi-terrabyte storage array that my desktop machine enjoys. OK, so maybe I have an odd sense of fun.
I remember years ago talking to a guy who ran a company that sold disk compression hardware and software. The idea was you'd connect the board to a 20-MB hard drive and it would sort of become a 40-MB hard drive. Assuming, of course, you stored a lot of compressible data. He had big plans of compressing everything (or, perhaps that's small compressed plans). He envisioned compressing network cards, for example.
In reality, a lot of compression products got most of their space increase by managing slack space (the wasted space at the end of files). But they also compressed data using traditional algorithms and gained space that way, too.
Eventually, disk compression made its way into operating systems, although these days I doubt many people care. Things like jpeg and video are typically already compressed, and modern filesystems manage slack space better anyway. Most compression algorithms, I think, are under user control (like using a zip tool) and not built into things.
What about in the embedded world though? It surprises me I don't see more compression being used to trade off speed for space. Sure, it eats some CPU time to do decompression (and compression, but depending on what you are doing, you may not need compression).
I actually brought this up earlier this year using base 40 encoding to compact strings stored in EPROM. Base 40 is a good technique because it is very simple to implement on a small CPU. Of course, you can do better.
For example, if you have a reasonably robust C-language environment (including malloc and free) you can probably use zlib. It is patent-free, portable, never makes the data bigger in degenerate cases, and can operate with fairly small memory footprints.
Not to work my friend Mark Nelson's side of the street, of course (Mark wrote The Data Compression Book, and has doubtlessly forgotten more than I know about the subject). A library like zlib can be useful for several things in an embedded system.
Clearly, if you have disk or flash storage for data, you can compress it. This is good for data loggers, for example. The key is usually to compress large amounts of data at once, though, so that's RAM intensive. Most compression schemes don't work well on small runs of data.
Another idea for systems that can run code out of RAM is to store compressed code, decompress it, and execute it. You can do the compression on the PC. You have to weigh, of course, how much the compression code itself takes (unless you already have it for another reason). It doesn't make sense to compress 50K of code to 30K with a 100K library.
Other likely candidates for compression include strings and FPGA bitstreams. A lot of systems serve web pages these days, and those pages are good candidate s for compression.
Naturally, zlib is only one way to compress. There are many other libraries and ad hoc solutions you can use just as well.
The key to compressing or decompressing with zlib, however, is a z_stream structure. You initialize it, point it to your input and output buffers, and call
deflate(). Uncompressing is similar, but you use a different initialize call and call
inflate(). You can find a fairly clear file-based example at http://www.zlib.net/zlib_how.html. Just remember, the file calls are not required — they are just part of the example program. There's no reason you could not read data into buffers from anywhere (say, a EEPROM) and inflate it.
Where have you used compression? Or where will you? Leave a comment with your ideas.