From Zero to main(): Bare metal C (2019)
interrupt.memfault.com
interrupt.memfault.com
We ported a rarely heard of RTOS to this chip (TNEO), and one of the most difficult parts was running tickless with sleepable states. The difficulty (discovered only by blood, sweat, tears, wtf oscope moments, dumb luck, and a random comment found on some obscure forum, definitely not in the data sheets) was that accessing certain registers (in our case RTC.CNT) would cause the chip to go in to a different clock domain temporarily and suddenly take as much as 300 usecs to read. Just this line:
uint currentClock = RTC.CNT;
That's all it took. Whereas most store some register into some local variable took nanoseconds, this one took a long long time.My experience in this world of embedded chips, is that many of the tutorials you read do not deal with power consumption really. They assume that you're playing with a dev board. Or that your application has copious amounts of power. But if you live in a battery powered world, your entire game lies around navigating between sleep and wake states on the chip.
This has been my experience so far trying to build my own devices at home. They all assume I’ll connect things to a USB port or have a power adapter. Material on how to deal with battery voltage dropping over time, determining battery level, etc. is really scattered. Makes me wish I was an EE major instead of CS.
That said, we're still in that early-ish phase. Four-ish years from now, there's probably going to be a post where I start off with something like
"Ahh the Nordic NRF52832. Of all the chips to show up on HN today. This chip I know not half as much as I'd like to and half as much I wish I didn't have to..."
It's sort of a vicious cycle.
It's...kinda fun? Perhaps more so as I only have to please myself rather than an employer or client. You can just query the ESP32 about battery voltage/current/charge state/temperature which of course makes things very easy. On the assumption that specifications and quality vary a lot and that voltage doesn't fall off in a convenient linear fashion, I've just been experimenting with it like any other environmental variable to decide between performance, economy, or panic modes.
Set it up to wake from sleep on some interrupt, do your processing, then go back to sleep. You can setup a timer interrupt to wake periodically to do processing as well.
I got mine to last about a week on the stock battery, i know of people who have done better but being a minute-resolution clock helps a lot.
Is this true of every chip, or are there eco-systems where it's documented better, or less of an issue for other reasons?
CppCon 2018: Matt Godbolt “The Bits Between the Bits: How We Get to main()”
Isn't that last part a bad assumption since it could be arbitrary values as well? Because people expecting a default zero value might be surprised otherwise.
• if it has pointer type, it is initialized to a null pointer;
• if it has arithmetic type, it is initialized to (positive or unsigned) zero;
[end quote]
—C99 Standard, §6.7.8
EDIT: That said, it can only relied upon to be zero at the first call of the function.
I mean, they can do things that make it easier or harder, but satisfying a language spec isn't what they do (unless you want to count an ISA as a language spec, which it kind of is).
1) 'Is main() a required startup function?' & 'Is standard library initialization required for main() startup?'
2) But sdiff -s of answer from [1] to 'Is a dynamic linker required for startup page alignement?' with 'Is a dynamic linker required for startup page alignment?' is kinda bit verbose.
3) 'Is standard library initialization required for main() startup? How much resources should be allocated to startup libraries?' [1] answer sounds like to overly broad an approach.