Author here, thrilled to see this post on lobste.rs! I hope this it inspires you to look under the hood, you’ll be surprised at what you find. Manufacturer supplied startup scripts aren’t always great.
Drop me a note if there are other topics in embedded you’d love to read about!
Welcome to Lobsters! Nice of you to offer your time teaching us about this stuff. One thing that I wanted to collect resources on was programming 8- and 16-bitters. General practices, tricks of the trade, optimizations, etc. Do you know any such resources?
Unfortunately there really isn’t much content out there. My experience is that 8/16 bit architectures are being replaced by small 32 bit cores (e.g. cortex m0) in new projects.
If you counted how many instances of UB are in that code, you’d see that the intent of the current C standard is to provide a completely useless unsafe Java instead of what practioners consider to be C.
If you have 1-2 notes on what I need to fix, I’d appreciate it. Even 1-2 bullet points would help!
You’ll find me firmly in the camp of folks saying C isn’t the right tool for the job - or any job really - any more. On embedded, we don’t have much choice. Rust, Ada, Nim all are making progress but are a long way from receiving the MCU vendor support needed to become practical options.
I don’t think you need to fix anything - your code is K&R C, but the current Standard, for example, would not like setting address 0 (start of vector table) with a value or or-ing in low bit 1s to make pointers to functions execute in thumb mode or reading uninitizialized memory or … and when you get to copying text!
It certainly isn’t K&R C, but I would hope it is idiomatic C99! All those other things are, for better or for worse, required by the ARM ABI.
The current C standard has a category error - by trying to impose some improvised typed abstract machine model on C it breaks the core design of the language. Your code to clear the bss and assign static variables is perfectly idiomatic C, but it’s possible UB since it is very much running apointer over the boundary of multiple objects.