Perplexity AI recently open-sourced Bumblebee, a read-only supply chain scanner written in Go 1.25 that audits MCP servers, dependencies, and editor extensions.
Great read. The core premise hits hard: modern capitalism isn't about rewarding production anymore - its about rent-seeking middlemen (Amazon, giant supermarkets, Uber...) extracting wealth by acting as gatekeepers.
At $0.20 in 1k quantities, this is TI's answer to the CH32V003, Puya PY32, and the STM32C0 series. It's great to see tier-1 silicon vendors participating in the race to the bottom for jellybean microcontrollers.
The 1KB of SRAM is admittedly very tight (even WCH's 10-cent RISC-V parts usually give you 2KB), so you are strictly in bare-metal, carefully-managing-your-stack territory.
1KB isn't so bad unless you are making something complicated or need large buffers. You can do quite a bit of nontrivial stuff with it. Years ago I made universal remote with ATtiny13 + external EEPROM for storing remote data. It has only 64 bytes of RAM, that's what I would call very tight. Was still able to program it in C, 1KB flash and number of pins were bigger limiting factor than ram.
Plenty of DIY projects used ATtiny2313 with V-USB. That's a pure software USB implementation bit banging the IO pins (not a USB stack on top of hardware USB support)+ your application logic squeezed into 2K of flash + 128 bytes of ram.
Chips like this are great for digital glue logic. Read a sensor, read a button press, blink some LEDs with simple state machine or control loop.
It's been long enough ago that I don't use it as an interview answer anymore, but one of the most interesting things I built (technique-wise) was a Z-80 based serial multiplexer with no RAM. The only volatile memory it used was the device registers. The fun part was handling subroutine calls without a stack. The Z-80 has an indexed jump mode, so before calling a subroutine, I'd fill the jump register with the statement after the subroutine call, and when the subroutine was done, execute the jump with the (return) address prefilled.
Anything to save a few bucks on a 6264 SRAM component :-)
Yes, that's "bare metal" as opposed to programming in MicroPython, Javascript with Espruino, Lua/NodeMCU, Rust, or adding your C application on top of an off-the-shelf RTOS.
C support is basically universal these days, very few chips require you to program in only assembly anymore.
It also supports running in freestanding setups without an OS, and quite a lot of the language's features still work.
I was extremely surprised by how much functionality is packed into "core", and runs without an OS when using freestanding rust. Even stuff that requires an allocator can run provided you provide your own heap!
A cool example of this was implementing fmt::Write for a memory mapped uart console thing. Then implementing a kprintln! macro that supports all of the formatting machinery that you are use to. This worked without even a heap available.
That's exactly what I said. Rust compiles to binary opcodes. Assembly is not an rtos, and does not require one. ASM isn't a standard "language". It's literally a fancy display of opcodes and registers that the CPU reads to execute operations. C does the exact same thing, ie compile to opcodes. You can convert binary back and forth from ASM to opcodes with a lookup table. At its core, ASM is just a convenient way to read and write cpu opcodes. I misspoke saying "to assembly" when I meant "to binary opcodes", but such a minor pedantic misspeak I didn't think anyone who understood embedded systems would not understand the meaning. Sorry about that.
Rust does not rely on syscalls or libraries on embedded targets, which is what the #![no_std] marker at the top of the project indicates. On some platforms, like ESP32, Rust can make calls into the RTOS and don't need that marker, but other embedded targets don't provide access to the std crate and you need to interact with peripherals from Rust or by interfacing with C or assembly.
Either you do not understand what assembly is, or you are being pedantic about the very thin abstraction between assembly and opcodes. Just in case you didn't know, assembly is a convenient way to read the binary opcodes that the cou uses to move data between registers and execute logic.
Yes, I should have said binary opcodes instead of assembly. I just assumed anyone discussing embedded systems would know they are practically interchangeable.
The other commenters are referring to bare metal interpreted Forth with no OS, or bare metal ROM Basic with no OS, as opposed to machine code with no OS.