HNHacker News
TopNewBestAskShowJobs

msarnoff

735 karma · joined November 24, 2010

f"{firstname[0:4]}{lastname}@proton.me"

@msarnoff@mastodon.social @msarnoff.bsky.social

Old twitter: http://twitter.com/txsector (Inactive since 2022)

http://youtube.com/user/74hc595

http://github.com/74hc595

submissionscomments
msarnoff··on Less Slow C++
I’ve done C++ on a Cortex-M0+ with 8KB of flash. Code size is a big issue. You have to disable a bunch of stuff (no exceptions, nothing that does dynamic allocation) but you can still use classes, virtual methods, templates, constexpr, etc. These are all things that are a pain to do in C and usually require a bunch of gross macros.
msarnoff··on Garfield Minus Garfield
I always liked Realfield better.

https://www.reddit.com/r/comics/comments/7zfbr3/realfield/

msarnoff··on Four Lectures on Standard ML (1989) [pdf]
My favorite bit of SML trivia: the infix function composition operator is “o” — lowercase letter o — so you can write ‘(f o g)(x)’ just like mathematical notation.
msarnoff··on They Might Be Giants Flood EPK Promo (1990) [video]
When I was in kindergarten or very early elementary school (maybe 1991/1992) there was an episode of Tiny Toon Adventures with animated music videos for Particle Man and Istanbul. It still lives in my head today.

I didn’t even know they were a real band until I was older and knew I recognized those songs from somewhere.

msarnoff··on My Favorite C++ Pattern: X Macros (2023)
That's been my primary usage of them. Another is to create a list of config file options (or command line arguments) like

  X(foo,      int,         "set the number of foos")
  X(filename, std::string, "input filename")
  X(verbose,  bool,        "verbose logging")
which can then be used to (a) generate the fields of a config struct, define the mapping from string to field (using the stringifying macro operators), define what functions to use for parsing each field, create the help message, etc. Basically like `argparse` or `clap` but much hackier.

As gross as they are, the ability to define one table of data that's used multiple ways in multiple places is handy.

msarnoff··on Everything Is Broken: Shipping Rust-Minidump at Mozilla (2022)
A minidump on its own will not symbolicate functions from shared libraries linked in by your program. If you want fully symbolicated backtraces, you need a symbol file for every single .so your binary links against.

I work in the embedded Linux space and recently discovered that Yocto has pretty nice Breakpad integration. Since it’s building all dynamic libraries in your system from scratch, it can generate symbol databases for each of them. At the end, you can have your build tar them all up as an artifact.

It’s pretty magical seeing a crash report that provides backtraces symbolicated all the way up to libc.

msarnoff··on Yocto, RockPi and SBOMs: Building modern embedded Linux images
I think, in a lot of cases, the choice between Buildroot and Yocto comes down to "which one does the SoC vendor support."
msarnoff··on Yocto, RockPi and SBOMs: Building modern embedded Linux images
Yocto error messages are absurdly awful. Hope you like fishing out the one gcc error out of 10,000 lines of garbage output.

There's nothing as disappointing as starting a build, going out for a couple hours, and coming back to a terminal full of red.

But when it works, it works.

msarnoff··on Yocto, RockPi and SBOMs: Building modern embedded Linux images
The one thing I still don't like about Yocto is the setup process. You need to check out multiple layer repositories, make sure you check out the right commit from each repository (need reproducibility!), put everything in the correct directory structure, and then set up `bblayers.conf` and `local.conf`.

I've got a script that does all this, but it's still a pain.

I've been thinking about putting everything in a monorepo, and adding poky, the third-party layers, and my proprietary layers as submodules. Then, when the build server needs to check out the code or a new developer needs to be onboarded, they just `git clone` and `git submodule update`. When it's time to update to the latest version of Yocto, update your layer submodules to the new branch. If you need to go back in time and build an older version of your firmware image, just roll back to the appropriate tag from your monorepo.

Anyone else have another solution to this issue?

Oh yeah, and the build times. It's crazy disk I/O bound. But if you're using something like Jenkins on an AWS instance with 96GB of RAM, set up your build job to use `/tmp` as your work directory and you can do a whole-OS CI build in minutes.

msarnoff··on Reverse-engineering and analysis of SanDisk High Endurance microSDXC card (2020)
Probably the same reason microcontrollers have OTP fuses—to prevent accidental corruption in the field or from buggy programming.
msarnoff··on Reverse-engineering and analysis of SanDisk High Endurance microSDXC card (2020)
Yup. mmc-utils is the way to go. Note that this change is irreversible once you send the command to finalize the settings.

The single biggest thing you can do to improve the reliability of your embedded system is to use eMMC’s built-in hardware partitioning.

- Each hardware partition is a separate block device. A firmware update cannot corrupt the device by overwriting a partition table.

- There are two small boot partitions, and they can be made permanently read-only after programming, thus preventing corruption of your bootloader. You can also use the other one read-write for your uboot environment.

- You can easily have two OS partitions for A/B firmware updates. In addition to mounting them readonly, temporary write protection can be enabled on a per-partition basis and disabled when needed for fw updates.

- If you can’t afford the capacity hit from pSLC, I believe it can be enabled on a per-partition basis. (Don’t quote me on this, it could be wrong).

All these settings can be configured with either mmc-utils or u-boot. In volumes, programming houses can take care of this for you. (You’ll have to list all the registers out very specifically in an Excel spreadsheet)

The downside is that calculating all the correct register values is not a simple process, and you’ll have to spend a bit of time reading the eMMC spec.

msarnoff··on Reverse-engineering and analysis of SanDisk High Endurance microSDXC card (2020)
Most eMMC chips (basically the chip version of an SD card) can be configured to work in pseudo-SLC (pSLC) mode. This halves the capacity but improves the write endurance by several times.
msarnoff··on Understanding Memory Management, Part 1: C
re: the bitwise representation of NULL, evaluating a pointer in a Boolean context has the intended behavior regardless of the internal representation of a null pointer.

See the C FAQ questions 5-3 and 5-10, et al. https://c-faq.com/null/

msarnoff··on The XOR Texture (2004)
A similar effect, when animated with a function like `color = (y == (x ^ t))` for varying values of t, is called “munching squares.”

It was originally written for the PDP-1 in the early sixties. I’ve seen it demonstrated on the Computer History Museum’s PDP-1. I always wondered how the characteristic “XOR texture” could be produced if the PDP-1’s display can only plot points and does not use a bitmapped framebuffer.

Turns out it takes advantage of the long persistence of the screen’s phosphor, and the brightness of each point decreases over time.

The CHM has a video of it running online, but it does not capture the effect of the phosphor persistence: https://www.computerhistory.org/collections/catalog/10266415...

Edit: here’s a video of it running in MAME that somewhat shows how phosphor persistence creates the XOR texture: https://youtu.be/AxJzUiaQ7xM?si=X9K47c4WyD6AisUp

msarnoff··on Making Screenshots of Test Equipment Old and New
Trivia: I looked through old sales brochures and did the math and calculated that the price of that HP 16500C new, adjusted for inflation, would be over $80,000. I paid $200, and I’m sure there are plenty that people have just given away for free.
msarnoff··on Making Screenshots of Test Equipment Old and New
I work on old systems with big parallel buses, so a while ago I bought a big HP 16500C chassis with something like 128 logic analyzer channels.

It can handle a full 68000 bus no problem, but it’s cumbersome and unwieldy. (The X11 interface mentioned in the article is nifty though, I remember having the same issue with fonts.)

I love my Saleae and even the cheap USB logic analyzers work fine with Sigrok. But everything is either 8 or 16 channels.

I realize it’s a niche-of-a-niche use case, but is anyone making USB logic analyzers with 64+ channels at a hobbyist price point (or DIY)?

msarnoff··on James Gleick's Chaos: The Software
Is this where XaoS (long time open source fractal generator) got its name from?

https://xaos-project.github.io/

msarnoff··on Nixie Tubes (2015)
Numitrons are another option; they only require 5V to light the segments. They have a very strange, almost steampunk aesthetic (though Technology Connections is not a fan…) Unlike Nixies or VFDs, they emit a broad spectrum of light, so you can put any color filter you like in front of them (red, green, blue)

I made an alarm clock from some unusual Soviet 9-segment Numitrons a while ago. The code/design is in GitHub as well as a link to a video. https://github.com/74hc595/Numitron-Clock

msarnoff··on Nixie Tubes (2015)
Agreed. I bought a set of IN-18s for 30USD each back in 2009, now they go for over $100.

I finally designed and built a clock for them about 3 years ago, and it sits right under my main monitor. They are captivating. I added “tasteful” (IMHO) digit cycling effects and a PIR sensor to turn off the display when no one is around to prolong the lifetime of the tubes, but your experience with the longevity of your IN-18s is remarkable.

I’ve always wondered what equipment they were originally designed for, given their size. Most likely military I imagine, or maybe public signage?

msarnoff··on Nixie Tubes (2015)
4) Salvage a broken piece of test equipment like a frequency counter or multimeter. If the tubes light up, swap out the control circuitry for an Arduino or your microcontroller of choice. It’ll already have the high voltage DC supply and maybe even some 74141 decoder/driver chips. (Just don’t spend a lot of money on something that deserves to be restored.)
msarnoff··on Nixie Tubes
Not sure what equipment these were used in, but

X, Y, Z for a digital readout on a CNC machine

M, G, T are SI prefixes

S, F, N, H are units

It’s also likely that they have meanings in German or another language I’m not familiar with. Large tubes like these have been used in elevators, so they could be floor designations.

msarnoff··on JSON for Classic C++
I've only used it in an application where we ensure the data is ASCII-only. The only issue is that I've had to write a bunch of wrapper code around it (for looking up object properties by key, iterating over key/value pairs or array elements, etc.)
msarnoff··on Smaller Than Pixel Art: Sub-Pixel Art [video]
I’m the original millitext creator and I’m very happy to see that someone made a new web-based generator. I wrote my original one in Ruby in 2008 and then stopped writing Ruby soon after that, leaving it to decay as the language’s ecosystem evolved.
msarnoff··on JSON for Classic C++
Yes, that’s exactly what I’ve done.
msarnoff··on JSON for Classic C++
If you want to go extremely lightweight, there’s jsmn: https://github.com/zserge/jsmn

It does no dynamic memory allocation, which is a plus in constrained IoT/embedded applications. But it’s really only a tokenizer. For example, if you want to parse fields out of a map, you have to write your own wrappers to iterate over key/value pairs. Since no data is copied out of the original buffer, all the “tokens” are given as byte offsets and lengths, not null-terminated strings, so you can’t just do printf(“%s”).

If you can’t (or don’t want to) malloc, it gets the job done. Not sure I’d recommend it for other applications though.

msarnoff··on Why systemd is a problem for embedded Linux
I’ve never used it as an init replacement, but runit (https://smarden.org/runit/runit.8) is great for supervising applications and services.

- It’s built into BusyBox and is very lightweight - Configuration is dead simple (everything is basically shell scripts in the filesystem; no special config language) - Includes logging functionality with rotation - Easily controllable from other applications using named pipes - It’s an almost perfect embodiment of the Unix philosophy: a series of small, single-purpose executables (svlogd, runsv, runsvdir, etc), with no strange config file formats or protocols.

Regarding udev, it’s entirely possible to run an embedded system without it if your device has a fixed set of peripherals, doesn’t need to handle hotplugged hardware, and uses a fixed set of kernel modules. In Yocto, you can define a dummy device manager recipe and boom, no udev. As a bonus, removing udev can shave several seconds off your boot time.

msarnoff··on Defender Sound Studio
I have 2 kids now (a toddler and a newborn) so I don’t get to hack on stuff anymore like I used to. I’m teaching my oldest about all the classic retro games though… if I ever get my Mac LC back from my parents’ house I’ll introduce him to Glider :)
msarnoff··on Defender Sound Studio
(Not a typo: 6800 with two zeros, not the 68000 of Mac and Amiga fame. The 8-bit 6800 is mainly famous for getting completely undercut by the 6502 and thus never making it into any home computers.)
msarnoff··on Defender Sound Studio
“A friend made a 1-bit synthesizer”

Hi John :) https://github.com/74hc595/1-Bit-AVR-Synthesizer

I also spent a good chunk of time reverse engineering and reimplementing the 6800 machine code* a while back. It’s pretty brilliant. No hardware timers, everything is software delay loops with controllable cycle counts. (Which is why it’s a bit of a challenge to emulate these sounds; there’s no fixed sample rate other than the CPU clock frequency!)

There are several algorithms. One uses a wavetable approach and then evolves the timbre of the sound by subtracting part of it gradually, until things wrap around and start going crazy. And then there’s one algorithm (which makes the coolest sounds) that is basically two pulse width modulators that interact in some very weird way that I could never figure out.

I got to talk to Sam Dicker and Eugene Jarvis about the sound code when they were at California Extreme many years ago. They brought a printout of the original source code on tractor feed paper.

*The games ran on 6809 processors but the sound boards used a 6800.

msarnoff··on Inkscape 1.4
I love Inkscape. I’ve been using it for 20 years. But it boggles my mind how it’s still so horribly laggy on macOS. At least they got rid of the Xquartz dependency though.
← PreviousPage 2 of 5Next →