My journey into embedded systems began with a critical role in enhancing a scanning monochromator, a scientific instrument designed to measure light spectra after passing through various mediums—in this case, liquids. This device processes vast arrays of spectral data by computing logarithms of light intensity readings, where the speed of computation directly influences the turnaround time from raw data to actionable insights.
The primary challenge stemmed from the slow performance of the C compiler’s log10 function, which significantly hampered the device’s utility. An opportunity for optimization appeared in the form of a photocopied article from an embedded systems journal, detailing a Motorola 68000 assembly routine designed to compute log2. This routine held promise for improving processing speeds, as it was already partially integrated into our software framework by a colleague.
Given my background in mathematics, I recognized the potential to adapt the log2 calculation to compute log10 by applying the relationship:
log10(x) = log2(x)×log10(2)
This transformation was theoretically simple, as the multiplier, log10(2), is a constant, and the 68000’s ‘muls’ instruction could seamlessly integrate this constant into the routine. The complexity arose in handling floating-point representations, a new territory for me at the time. The log2 result—a 32-bit number—required precise manipulation to convert into a floating-point format compatible with our system, using a series of shifts, byte swaps, and integer multiplications.
The final output was formatted and sent through an RS232C serial port for visualization on a PC. This laborious process involved iterative coding and testing cycles, with EEPROMs frequently erased and reprogrammed—a cycle that took upwards of 20 minutes for each iteration due to the EEPROMs’ ultraviolet light erasure requirements.
As we neared product launch, with our marketing team of scientists conducting final tests, an unexpected error manifested as mysterious notches on the output graphs. Initially deemed unrelated to my modifications, it eventually became apparent that a transcription error from the original assembly code was the culprit. Correcting this resolved the issue, clearing the path for commercial release.
This experience imparted several invaluable lessons about embedded software development: never assume your code is faultless, rigorously test and retest with extensive data, and ensure precise transcription and implementation of code from external sources. Today, my approach would include comprehensive unit testing for every routine to forestall such issues, underscoring the continual evolution of best practices in embedded systems development.