|
|
||||||||||||||||||||||||||||
You may redistribute this newsletter for noncommercial purposes. For commercial use contact jack@ganssle.com. To subscribe or unsubscribe go to https://www.ganssle.com/tem-subunsub.html or drop Jack an email. |
||||||||||||||||||||||||||||
Contents | ||||||||||||||||||||||||||||
Editor's Notes | ||||||||||||||||||||||||||||
I'd like to wish a Happy New Year to all of the Muse readers, and express thanks for all of the submissions, ideas and critiques you offered in 2013. Keep 'em coming! Chuck Petras sent this interesting link to a 1965 book about the the development of punch card tabulation. A couple of readers pointed to The Night Watch by James Mickens, which is a longish but funny and wonderfully-written story about the "joys" of system programming. |
||||||||||||||||||||||||||||
Quotes and Thoughts | ||||||||||||||||||||||||||||
Pat Little sent this quote from the FORTRAN manual for Xerox computers: The primary purpose of the DATA statement is to give names to constants; instead of referring to pi as 3.141592653589793 at every appearance, the variable PI can be given that value with a DATA statement and used instead of the longer form of the constant. This also simplifies modifying the program, should the value of pi change. |
||||||||||||||||||||||||||||
Tools and Tips | ||||||||||||||||||||||||||||
Please submit neat ideas or thoughts about tools, techniques and resources you love or hate. |
||||||||||||||||||||||||||||
An Ancient Scope | ||||||||||||||||||||||||||||
Succumbing to the wiles of eBay, I recently became the owner of a 1946 Philco 7019 oscilloscope, and thought some readers might be interested in how much test equipment has changed. Targeted originally at hobbyists and repair people, this device offers little in the way of performance. Rated with a 100 kc (kilocycle, used before KHz was common) bandwidth, strangely at -2 dB, and with 1 volt/inch of vertical and horizontal sensitivity.
The Philco 7019 trying to display a 1 KHz sine wave Notice the lack of any scale on the 2" CRT. It's impossible to make any sort of quantitative measurements. The time base is a free-running ramp. This predates trigger circuits; to freeze the waveform on the screen one adjusts the time base frequency, which is uncalibrated. A sync circuit feeds some of the signal to the time base to try and make the oscillator sync to the signal's frequency, but it can be hard or impossible to get a stable display. Note that there seems to be a DC line below the sine wave. That's because there's no horizontal blanking; that line is the sweep returning from right to left. The following shows the ramp that drives the beam from left to right.
The Philco's horizontal oscillator. The ramp is rounded so the sweep isn't constant, as indicated by the squished sine wave display shown previously. I guess there are parasitics causing the nasty little pseudo-ramps. And look at the amplitude! That's over 200 volts, and I think it's the first time my Agilent has measured anything over 15V.
Scope guts The unit has only 4 vacuum tubes: the CRT of course, one in the power supply, one for the time base (a dual triode 6J6) and finally a 6AU6 single pentode for the vertical amplifier. Though the performance is terrible the design is quite ingenious, and uses custom selector switches to minimize the number of capacitors required. Amazingly, the capacitors haven't dried out after 68 years. It's AC coupled so can't display the DC component of a signal. There are neither vertical nor horizontal position controls. Instead, one moves a magnet around inside the cabinet to direct the electron beam! It sold for $66 in 1946, which is about $790 in today's shrunken currency. That was probably a good deal back then; today, for the same price, one can get a pretty good Rigol digital scope, or even a decent brand-new 40 MHz Tektronix. You can find some pretty good eBay deals on used scopes, but other than for historical interest, stay away from anything like this Philco. Triggered sweep and the ability to make amplitude and time measurements are both absolutely required for any sort of serious or even hobbyist work. But this bit of history is certainly fun! |
||||||||||||||||||||||||||||
On Cosmic Rays in Embedded Systems | ||||||||||||||||||||||||||||
In response to my comments in the last issue about cosmic-ray induced failures, Bruce Wedding sent this:
Harold Kraus had some interesting information:
|
||||||||||||||||||||||||||||
Printing Pi to a Billion Digits | ||||||||||||||||||||||||||||
Larry Marks had and engineering analysis of the joke in the last issue about printing pi to a billion digits:
|
||||||||||||||||||||||||||||
A Firmware Engineer's New Year's Resolutions | ||||||||||||||||||||||||||||
1) I will work hard to elicit correct specifications, insofar as humanly possible, before starting a project. 2) I will work with the hardware people to produce firmware-friendly hardware. 3) I will carefully document all of my code, including tests and prototypes, as prototypes have a nasty habit of becoming products. 4) I will collect metrics about bugs and examine their root causes. 5) I will carefully measure the real-time behavior of real-time code, like interrupt handlers, to ensure adequate margin and to improve my time-domain estimates. 6) My tests will be extremely comprehensive, and will check boundary conditions. 7) I will petition management for funds for high-quality tools. 8) I will write warning-free code. 9) I will not use global variables unless there is no alternative. 10) I will continue to study the fascinating world of software engineering. 11) I'll keep having fun! |
||||||||||||||||||||||||||||
Jobs! | ||||||||||||||||||||||||||||
Let me know if you’re hiring embedded engineers. No recruiters please, and I reserve the right to edit ads to fit the format and intents of this newsletter. Please keep it to 100 words. |
||||||||||||||||||||||||||||
Joke For The Week | ||||||||||||||||||||||||||||
Note: These jokes are archived at www.ganssle.com/jokes.htm. John Black sent in this oldy but goody:
10 PRINT "HELLO WORLD" 20 END First year in College: program Hello(input, output) begin writeln('Hello World') end. Senior year in College: (defun hello (print (cons 'Hello (list 'World)))) New professional: #include <stdio.h> void main(void) { char *message[] = {"Hello ", "World"}; int i; for(i = 0; i < 2; ++i) printf("%s", message[i]); printf("\n"); } Seasoned professional: #include <iostream.h> #include <string.h> class string { private: int size; char *ptr; string() : size(0), ptr(new char[1]) { ptr[0] = 0; } string(const string &s) : size(s.size) { ptr = new char[size + 1]; strcpy(ptr, s.ptr); } ~string() { delete [] ptr; } friend ostream &operator <<(ostream &, const string &); string &operator=(const char *); }; ostream &operator<<(ostream &stream, const string &s) { return(stream << s.ptr); } string &string::operator=(const char *chrs) { if (this != &chrs) { delete [] ptr; size = strlen(chrs); ptr = new char[size + 1]; strcpy(ptr, chrs); } return(*this); } int main() { string str; str = "Hello World"; cout << str << endl; return(0); } Master Programmer: [ uuid(2573F8F4-CFEE-101A-9A9F-00AA00342820) ] library LHello { // bring in the master library importlib("actimp.tlb"); importlib("actexp.tlb"); // bring in my interfaces #include "pshlo.idl" [ uuid(2573F8F5-CFEE-101A-9A9F-00AA00342820) ] cotype THello { interface IHello; interface IPersistFile; }; }; [ exe, uuid(2573F890-CFEE-101A-9A9F-00AA00342820) ] module CHelloLib { // some code related header files importheader(<windows.h>); importheader(<ole2.h>); importheader(<except.hxx>); importheader("pshlo.h"); importheader("shlo.hxx"); importheader("mycls.hxx"); // needed typelibs importlib("actimp.tlb"); importlib("actexp.tlb"); importlib("thlo.tlb"); [ uuid(2573F891-CFEE-101A-9A9F-00AA00342820), aggregatable ] coclass CHello { cotype THello; }; }; #include "ipfix.hxx" extern HANDLE hEvent; class CHello : public CHelloBase { public: IPFIX(CLSID_CHello); CHello(IUnknown *pUnk); ~CHello(); HRESULT __stdcall PrintSz(LPWSTR pwszString); private: static int cObjRef; }; #include <windows.h> #include <ole2.h> #include <stdio.h> #include <stdlib.h> #include "thlo.h" #include "pshlo.h" #include "shlo.hxx" #include "mycls.hxx" int CHello::cObjRef = 0; CHello::CHello(IUnknown *pUnk) : CHelloBase(pUnk) { cObjRef++; return; } HRESULT __stdcall CHello::PrintSz(LPWSTR pwszString) { printf("%ws", pwszString); return(ResultFromScode(S_OK)); } CHello::~CHello(void) { // when the object count goes to zero, stop the server cObjRef--; if( cObjRef == 0 ) PulseEvent(hEvent); return; } #include <windows.h> #include <ole2.h> #include "pshlo.h" #include "shlo.hxx" #include "mycls.hxx" HANDLE hEvent; int _cdecl main( int argc, char * argv[] ) { ULONG ulRef; DWORD dwRegistration; CHelloCF *pCF = new CHelloCF(); hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); // Initialize the OLE libraries CoInitializeEx(NULL, COINIT_MULTITHREADED); CoRegisterClassObject(CLSID_CHello, pCF, CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE, &dwRegistration); // wait on an event to stop WaitForSingleObject(hEvent, INFINITE); // revoke and release the class object CoRevokeClassObject(dwRegistration); ulRef = pCF->Release(); // Tell OLE we are going away. CoUninitialize(); return(0); } extern CLSID CLSID_CHello; extern UUID LIBID_CHelloLib; CLSID CLSID_CHello = { /* 2573F891-CFEE-101A-9A9F-00AA00342820 */ 0x2573F891, 0xCFEE, 0x101A, { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 } }; UUID LIBID_CHelloLib = { /* 2573F890-CFEE-101A-9A9F-00AA00342820 */ 0x2573F890, 0xCFEE, 0x101A, { 0x9A, 0x9F, 0x00, 0xAA, 0x00, 0x34, 0x28, 0x20 } }; #include <windows.h> #include <ole2.h> #include <stdlib.h> #include <string.h> #include <stdio.h> #include "pshlo.h" #include "shlo.hxx" #include "clsid.h" int _cdecl main( int argc, char * argv[] ) { HRESULT hRslt; IHello *pHello; ULONG ulCnt; IMoniker * pmk; WCHAR wcsT[_MAX_PATH]; WCHAR wcsPath[2 * _MAX_PATH]; // get object path wcsPath[0] = '\0'; wcsT[0] = '\0'; if( argc > 1) { mbstowcs(wcsPath, argv[1], strlen(argv[1]) + 1); wcsupr(wcsPath); } else { fprintf(stderr, "Object path must be specified\n"); return(1); } // get print string if(argc > 2) mbstowcs(wcsT, argv[2], strlen(argv[2]) + 1); else wcscpy(wcsT, L"Hello World"); printf("Linking to object %ws\n", wcsPath); printf("Text String %ws\n", wcsT); // Initialize the OLE libraries hRslt = CoInitializeEx(NULL, COINIT_MULTITHREADED); if(SUCCEEDED(hRslt)) { hRslt = CreateFileMoniker(wcsPath, &pmk); if(SUCCEEDED(hRslt)) hRslt = BindMoniker(pmk, 0, IID_IHello, (void **)&pHello); if(SUCCEEDED(hRslt)) { // print a string out pHello->PrintSz(wcsT); Sleep(2000); ulCnt = pHello->Release(); } else printf("Failure to connect, status: %lx", hRslt); // Tell OLE we are going away. CoUninitialize(); } return(0); } Apprentice Hacker: #!/usr/local/bin/perl $msg="Hello, world.\n"; if ($#ARGV >= 0) { while(defined($arg=shift(@ARGV))) { $outfilename = $arg; open(FILE, ">" . $outfilename) || die "Can't write $arg: $!\n"; print (FILE $msg); close(FILE) || die "Can't close $arg: $!\n"; } } else { print ($msg); } 1;
#include <stdio.h> #define S "Hello, World\n" main(){exit(printf(S) == strlen(S) ? 0 : 1);} Seasoned Hacker: % cc -o a.out ~/src/misc/hw/hw.c % a.out Guru Hacker: % echo "Hello, world." New Manager: 10 PRINT "HELLO WORLD" 20 END Middle Manager: mail -s "Hello, world." bob@b12 Bob, could you please write me a program that prints "Hello, world."? I need it by tomorrow. ^D Senior Manager: % zmail jim I need a "Hello, world." program by this afternoon. Chief Executive: % letter letter: Command not found. % mail To: ^X ^F ^C % help mail help: Command not found. % damn! !: Event unrecognized % logout |
||||||||||||||||||||||||||||
Advertise With Us | ||||||||||||||||||||||||||||
Advertise in The Embedded Muse! Over 23,000 embedded developers get this twice-monthly publication. . |
||||||||||||||||||||||||||||
About The Embedded Muse | ||||||||||||||||||||||||||||
The Embedded Muse is Jack Ganssle's newsletter. Send complaints, comments, and contributions to me at jack@ganssle.com. The Embedded Muse is supported by The Ganssle Group, whose mission is to help embedded folks get better products to market faster. |