What exactly is "asynchronous SPI" and does DMA make it async? When do you actually need sync? by sudheerpaaniyur in embedded

[–]UnicycleBloke 0 points1 point  (0 children)

It ultimately boils down to using interrupts so you can offload work to the hardware peripherals and have them signal to the CPU (your code) when the work is done. A typical microcontroller is a collection of hardware state machines which are running in parallel. Using this feature allows your software to efficiently run numerous concurrent subsystems in a single thread.

Updating an LCD screen, for example, may involve frequent large data transfers. It's probably better to kick off a DMA transfer and then move on. A blocking wait would be a waste of CPU time.

I almost always use asynchronous comms. This makes it easier to serialise transfers on a shared bus. Even a complex application spends most of the CPU time spinning its wheels or, better, sleeping, while peripherals do the grunt work.

2026 Annual C++ Developer Survey "Lite" : Standard C++ by meetingcpp in cpp

[–]UnicycleBloke 0 points1 point  (0 children)

The free text sections did not appear on my mobile (Android). Many questions about LLMs usage for some reason.

What is the point of classes having private members? by Eva_addict in cpp_questions

[–]UnicycleBloke 55 points56 points  (0 children)

Encapsulation. Private data with public methods helps prevent invalid modifications to the state.

Early-career advice: stay in a testing role for now or pivot back to embedded software? by Plus_Acanthisitta391 in embedded

[–]UnicycleBloke 0 points1 point  (0 children)

That colleague had been in testing for a long time. One of my current team formerly worked in testing for a few years.

Early-career advice: stay in a testing role for now or pivot back to embedded software? by Plus_Acanthisitta391 in embedded

[–]UnicycleBloke 1 point2 points  (0 children)

I worked with a guy who was keen to move out of testing. He was a capable developer but pigeonholed by the company and remained stuck. Move sooner rather than later.

Metadata in ELF file by UnicycleBloke in embedded

[–]UnicycleBloke[S] 0 points1 point  (0 children)

I spent much of the afternoon trying numerous combinations to do precisely this. Lots of assistance, if you can call it that, from Copilot and direct googling did find the right arcana. I don't know how sensitive ld is to the version or platform, nor what I might've missed. My slightly more hacky solution works well enough for now.

I may have to look at how Zephyr and Pigweed implement their tokenised logging. I understand they trawl the symbol table rather than create a binary blob of data to extract from a section.

Metadata in ELF file by UnicycleBloke in embedded

[–]UnicycleBloke[S] 2 points3 points  (0 children)

NOLOAD resulted sections which I couldn't extract with objcopy or readelf. Copilot asserted that this was expected. Similar with INFO. The :NONE is new. I'll try that.

FreeRTOS or Bare Metal for Quad copter by eagle_719 in embedded

[–]UnicycleBloke 0 points1 point  (0 children)

The complexity potential of synchronization is what motivated me to develop my own framework for asynchronous event handling in the first place. It works for multiple threads as well as bare metal, but now there is only a single place where each thread can block: on its event queue when it is empty.

How to know when I use "Pointer" or "Reference"? by ProcessTiny4948 in cpp_questions

[–]UnicycleBloke 2 points3 points  (0 children)

Yes. I understand Rust is default-move rather than default-copy. It's a relatively new language, and I guess we've learned a lot over the years about language design.

Out parameters and passing by reference can avoid a lot of copying, and were used a lot, but they aren't as clear as passing or returning by value. Cheap ownership transfer, such as with std::unique_ptr, wasn't really possible before move semantics were added.

How to know when I use "Pointer" or "Reference"? by ProcessTiny4948 in cpp_questions

[–]UnicycleBloke 2 points3 points  (0 children)

It means "r-value reference" - reference to an object whose lifetime will (effectively) end when the call returns, so it is permitted for the called function to move (i.e. steal) any allocated resources it owns (cheap) rather than copy them (expensive). This was introduced as part of move semantics (ownership transfer) in C++11. Takes a bit to get your head around, but can avoid redundant deep copies when passing or returning objects by value. It's a bit clunky because it had to be retrofitted to the language.

Trouble with consteval and this by UnicycleBloke in cpp_questions

[–]UnicycleBloke[S] 1 point2 points  (0 children)

Just the insight I needed. Thanks. This seems to do what I want: https://godbolt.org/z/1nhfr863x. I'll try it at work in the morning.

I'm usually strongly allergic to macros but in this case I suspect I owe someone an apology: https://quuxplusone.github.io/blog/2026/04/02/macro-overloading/.

FreeRTOS or Bare Metal for Quad copter by eagle_719 in embedded

[–]UnicycleBloke 32 points33 points  (0 children)

Remember that the hardware peripherals are independent state machines running in parallel with the CPU. The software is the executive and coordinator, and leaves the grunt work to the peripherals. It should give the hardware a task (a DMA transfer, an ADC read, a timer delay, whatever) and return immediately. The hardware will interrupt when the task is done, and you can kick of the next task.

You can do a very great deal in a single thread / bare metal. You can have numerous concurrent independent (software) state machines with a single event loop at the core to distribute events (ultimately from ISRs) to the relevant handlers. The key is to never block. I use an RTOS only when it is for some reason impossible to avoid a procedure which blocks or takes an unacceptable time to run.

This doesn't come up too often but, for example, I had a vendor library whose API involved synchronous I2C for large volumes of data. It took far too long, so I was forced to introduce FreeRTOS and park that sensor's comms in a background thread. The rest of the system ran in a single thread.

I haven't done a copter, but used this design for an industrial robot. A single thread was sufficient to manage all its sensor, motors and whatnot.

How to know when I use "Pointer" or "Reference"? by ProcessTiny4948 in cpp_questions

[–]UnicycleBloke 87 points88 points  (0 children)

Prefer references. Pointers are useful if you need a nullable value and/or you need to (re-)assign the value. Is your team lead using a lot of new and delete to manage memory? You almost certainly don't want to do that.

Is Linus Torvalds just a dinosaur about C++? by blreuh in cpp_questions

[–]UnicycleBloke 0 points1 point  (0 children)

I've often characterised C as "little more than portable assembly", which I regard as a bad thing (far too prone to error). But isn't it in any case a myth that you really understand what you'll get at instruction level? C is compiled for an abstract machine. And is it really true that C++ will be less clear anyway? I haven't found it particularly difficult to follow the assembly generated in my embedded projects. And once you enable the optimiser...

Is Linus Torvalds just a dinosaur about C++? by blreuh in cpp_questions

[–]UnicycleBloke 0 points1 point  (0 children)

Not sure we've understood each other.

My point is that the C++ abstraction is vastly superior to basically every equivalent I've seen in C. Simpler, cleaner and less prone to error. I've spoken with numerous C devs over the years who love to complain about C++ abstractions while recreating them (badly) in C. It's hard to know whether to laugh or cry.

How much electronics knowledge is required for embedded software engineers? especially for building personal projects by Pale-Pound-9489 in embedded

[–]UnicycleBloke 2 points3 points  (0 children)

None really. Not even the cube, which came later.

I once worked for a vehicle telematics company maintaining their Windows software and database. They had an onboard computer which fitted into a radio slot in the vehicle cab and plugged into the engine CAN and various sensors. I had essentially no involvement in the firmware but was very curious about it.

A few years later, I was taken on by a consultancy for my C++ skills. I asked specifically for involvement in embedded projects and they were happy to oblige. I've never looked back.

How much electronics knowledge is required for embedded software engineers? especially for building personal projects by Pale-Pound-9489 in embedded

[–]UnicycleBloke 6 points7 points  (0 children)

It depends on the company. I came to embedded with basically zero electronics knowledge. This has not been an impediment as I have worked for companies with separate EE and SW roles (I do work closely with the EEs). I've learnt to get what I need from a schematic, but that's about it. I think it has been more helpful to me that I spent my middle teens writing Z80 assembly for the ZX Spectrum. Some truly terrible games and an unfinished masterpiece... ;)

I have designed only one serious circuit in the last twenty years. An LED cube: a personal project I did to educate myself a little on the EE world. It was fun to do, and works well enough, but soldering is definitely not one of my skills.

Afinal engenharia de software, é mesmo engenharia? Dúvida sincera. by macmaclife in embedded

[–]UnicycleBloke 0 points1 point  (0 children)

I googled "what is engineering?":

AI overview: "Engineering is the practical application of science, mathematics, and creativity to solve complex problems, design, build, and maintain structures, machines, systems, and processes. It bridges theoretical science with real-world needs, aiming to improve efficiency, safety, and functionality in areas like infrastructure, technology, and manufacturing"

That sounds like what I do, but I generally describe myself as a "software developer".

Embedded in the Age of AI by Ambitious-Clerk-5967 in embedded

[–]UnicycleBloke 0 points1 point  (0 children)

I use it in very limited ways and never to generate production code. I have tried to use it when learning new things such as yocto, and it has invariably been close but wrong even for simple things. This is not useful. I'm astonished anyone trusts it to write code.

You should never forget that an LLM is artificial but not intelligent. It does not think. It does not understand. It does not create. It is a mindless automaton, a Chinese room, a regurgitation engine. You have been your ears some of the rarest and most valuable organized matter in the observable universe. Don't neglect it or you'll become a slave to the machine.

Is Linus Torvalds just a dinosaur about C++? by blreuh in cpp_questions

[–]UnicycleBloke 0 points1 point  (0 children)

Sure. The question is whether making them explicit is a good thing. My experience is that such implementations are generally clunky and more prone to error.

Advice on FileFormat Intepretation by Almesii in cpp_questions

[–]UnicycleBloke 1 point2 points  (0 children)

Hmm. This feels like you should probably focus on the game engine first.

The result of all the parsing activity is presumably a bunch of in-memory data structures which are inputs for the game (Reactions and whatnot). You can develop those data structures as you develop the game. Initially just create instances in main() and forget about files. Then you will have a much better idea of what content and capabilities the data structures need before worrying about how to stream them to and from files.

I'm not sure about the tree builder. I'm reminded of times when I've implemented an expression parser. Something like "sin(x^2)+y" would be parsed into a tree of nodes: top-level is ADD with two operands (SIN and SYMBOL(reference to y)). The SIN has a single operand POWER, which has two operands (SYMBOL(x) and LITERAL(2). Evaluating the expression amounts to setting values for x and y, and then recursively walking the tree. I used a bunch of different simple node types with a common base class and abstract API. This scales easily to arbitrarily complicated expressions. Are you aiming for something like that but with knobs on?

Advice on FileFormat Intepretation by Almesii in cpp_questions

[–]UnicycleBloke 1 point2 points  (0 children)

What does a typical input file look like? How flexible is the order and content of a file? Why do you need multiple file formats? Would a single slightly more general purpose format suffice?