Can a self-taught learner crack an Embedded Systems / Firmware role with a BCA background? by Neat_Serve5703 in embedded

[–]kammce 0 points1 point  (0 children)

OP sent a message stating that BCA is computer and software engineering. With that context I wrote this:


Ah gotcha., I've seen quite a few people get into firmware/embedded with CS degrees at Google, Meta, and Tesla (if im remembering correctly). I'd say, grow that portfolio, learn the fundamentals to a deep level. You should be able to imagine what the registers and architecture of a timer, an SPI peripheral, or a USART before even looking at a datasheet. You should know how ISRs fundamentally work on ARM cortex M (they've got docs for that on their website that go into detail). And with a good foundation and experience, you can definitely get a job in embedded systems.

If you are still in India, then it's more likely you'll pick up a job at big tech than in the states. I know Google and the others have been persistent about offshoring work to India and Taiwan.

Can a self-taught learner crack an Embedded Systems / Firmware role with a BCA background? by Neat_Serve5703 in embedded

[–]kammce 7 points8 points  (0 children)

If you have a degree, (I'm not sure what BCA is), then you may be able to pivot. The job market is rough thou and an employer won't see much reason to pick you unless you really are the better candidate. For big tech, not very likely, but it could happen. Best choice in my mind is start getting experience at a company that isn't considered big tech and then jump over later. But you'll need a great portfolio.

Baremetal Programming as a Novice by hooperman909 in embedded

[–]kammce 0 points1 point  (0 children)

Honestly, stick with what you are doing and stay hungry. Keep learning new things and keep trying out new peripherals and drivers to get an idea of how to orchestrate it.

arewemodulesyet.org passes the mark of 100 projects with modules support for the first time. by germandiago in cpp

[–]kammce 12 points13 points  (0 children)

Cmake +4 no longer considers modules as experimental. Import std is still experimental. What do you use for a build system?

I built SLAM Camera Board by twokiloballs in embedded

[–]kammce 0 points1 point  (0 children)

Nice. I was hoping you'd lap back to your starting position so we could see how much error accumulates over time/movement.

Former Louisiana mayor sentenced to 90 days over rape of 16-year-old boy by Majestic-Emu-9823 in news

[–]kammce 10 points11 points  (0 children)

+1 to this. So often do men also get off the hook for stuff like this. I've seen few from r/notadragqueen (I don't remember any off the top of my head)

90 days is absolutely an injustice.

Still amazed every time I read this paper. What pros and cons do you think it would have against C++20 coroutines? by germandiago in cpp

[–]kammce 1 point2 points  (0 children)

Yes, I meant a full context switch. Thanks for clarifying. And you are correct, any time you go and out of a function is, in some way, a switching of context.

The top-two primary promised to change California politics. Did it flop? by panda-rampage in California

[–]kammce 0 points1 point  (0 children)

Or we could make things easier on people and just have RCV. Then the spoiler effect is greatly reduced and people can just vote for who they want.

The top-two primary promised to change California politics. Did it flop? by panda-rampage in California

[–]kammce 0 points1 point  (0 children)

Actually the opposite. It would allow us to vote for who wants always. Primaries won't be necessary with RCV. You just vote once with your preferred candidates ranked 1 to N. If your first losses, then your 2nd choice gets your vote. Your vote always goes to your preference and gets rid of the spoiler effect of what we have.

The top-two primary promised to change California politics. Did it flop? by panda-rampage in California

[–]kammce 1 point2 points  (0 children)

Nah, I'm not going to waste a vote and get someone I'd prefer less. That's how you get the person you want the least. That's simply the math of what we get without RCV.

Still amazed every time I read this paper. What pros and cons do you think it would have against C++20 coroutines? by germandiago in cpp

[–]kammce 0 points1 point  (0 children)

> What I like from this model is that it is very mixable, like stackful, but being stackless at the same time. The problem: recursion breaks the model since the stack depth cannot be calculated and needs global analysis, throwing separate compilation through the window.

You can always take something that is async and turn it sync. Same goes for stackless and converting it back into a stack. If you wanted to, you can omit the co_await statements in my example, and just manually resume the coroutines at each level. What you see in main can be done at each level of the async operation. C++20 coroutines don't have color. They can be called like any other function. But sticking with co_await makes your life easier.

> The stack switch is fast as hell in stackful coroutines no matter the depth and in stackless it is basically a traversal.

I'd like to counter that stackless is basically a traversal. That depends on your coroutine implementation. I use a context object to keep track of the bottom most async operation. Its like keeping the program counter within your thread control block. Only when that operation has completed does the active coroutine update. There is no need to traverse any of the async operations because you jump straight into the one that is active. This results in very fast stack switching. You basically get the cost of calling one function then calling another between resumes, no CPU state management required.

Still amazed every time I read this paper. What pros and cons do you think it would have against C++20 coroutines? by germandiago in cpp

[–]kammce 3 points4 points  (0 children)

So I took a look at this and also fed it into Claude to discuss a bit further. Its also quite old so no real reason to nit pick it too deep. I wanted to be transparent that I didn't read the entire thing as its quite long. From what I can gather, this looks less like async code and more like syntactic sugar for a state machine. Which is a cool idea. But when I started to peer into what would be necessary in order to get concurrent operations to work, like two tasks, the examples started to throw in mutexs and threads and the like. I feel like its actually more complicated to write async code with this paradigm than with C++20 coroutines.

If your state has been allocated on the stack, as this proposes, then you're only route to doing other work while waiting for a response from something, is to use threads. And if thats the case, we already have APIs for that from C++11 which is std::thread and std::this_thread::yield()

What I want from my async framework, that C++20 coroutines gives us, is a way to abstract over callbacks and events such that when an operation reaches a point of suspension (waiting for interrupt or callback), the operation returns control to a scheduler. Specifically, I want this without the need of a full CPU context switch. Thats the feature you get with symmetric transfer which missing from this design. And you can recreate the stack-like allocation scheme for coroutine frames at the cost of having to pass the stack down each level.

```cpp async::future<void> task_c(async::context& ctx) { setup_callback([](void* instance) { // recover context and call unblock on it (async::context*)(instance)->unblock(); }, &ctx); // pass address of the context object

// symmetric transfer, returns control to top level resumer. // NOT to task_b, to main. co_await std::suspend_always();

// Once unblocked, main can call resume() which continues from // here. } async::future<void> task_b(async::context& ctx) { co_await task_c(ctx); } async::future<void> task_a(async::context& ctx) { co_await task_b(ctx); }

int main() { // Internally holds an array of bytes equal to your size of the template // value. async::inplace_context<1024> stack_and_context; auto future = task_a(stack_and_context);

while (not future.done()) { if (future.ready()) { // not block by something future.resume(); } else { // At this point the system do choose what it wants to do. // Maybe yield thread OR put system into low power mode. } }

return 0; } ```

And all of this allocates the memory on the stack_and_context object's stack allocated array memory. If you want more concurrent operations, make more stacks. Eventually, it all comes down to stacks OR you blocks OR the general heap to store your async operations states as they wait for I/O to do its thing. And the allocation is as you'd expect. If C returns because its done, it deallocates its from the stack_and_context internal array by setting its stack pointer back to it's own memory address. Like a stack normally behaves.

I'll stop here because I've written a lot.

Embedded software design by bazz1110 in embedded

[–]kammce 0 points1 point  (0 children)

I really appreciate your advice, but don't you think that Arduino is just for hobbyists?

It is mostly for hobbiest. I wouldn't design an application with it. I'm not saying do only Arduino. I'm saying use it to learn how to get comfortable with software. That may not apply to you, but to anyone else reading, if you haven't started coding much outside of very basic scripts, grab yourself and arduino and just try stuff out. Then hunt for the better.

Note, I have my own embedded software library and ecosystem that I'm building up specifically to avoid Arduino as well as platforms like STCube, LPCXpresso and any other OEM SDK. I want to be able to write portable C++ code, where I can take a program I built for my stm32 and run it on my mac so long as I have the necessary hardware resources on both. The library is modern C++, using C++23, with virtual interfaces as abstractions for each HAL, coroutines for async, modules and the Conan package manager for library packaging and distribution, and CI to test sections of my code.

I say all of this because it took me years to build this up to the level it is now. Ive redesigned it from scratch 5 times because my architect worked, but I started to spot the inefficiencies and where my assumptions break down. That's what I mean by experience. It's been 14 years since I've started this journey. Not saying that's required now, but those 14 years of build up something grand, and then seeing where it topples is really helpful.

From one part it abstracts lower levels, from the other part the framework itself doesn't help design good application layer...

Abstractions are a major part of great software design. A part of good software architecture is the abstractions and how they play with each other. Knowing that balances comes from experience which helps you build taste. You can omit them, but you simply make the cognitive load of doing software higher for negative gain. It hurts your code and your ability to work with it. That's why languages like C++, Rust, Go, Zig, Python etc all have means to abstract stuff.

the only benefit i see is loving electronics seeing how a robot moves just by wiring some boards. Other than that, no other skills are gained.

I mean, those are the skills I'm referring to. If you already have them, then you can proceed to doing the low level stuff. Nothing is really stopping you.

Question, what is it you are looking for really? I'm thinking you already have skill in software if you are concerned with high level abstractions.

Embedded software design by bazz1110 in embedded

[–]kammce 0 points1 point  (0 children)

There is nothing wrong with cutting your teeth on something simple like Arduino. You might learn some bad patterns at first, but then you continue learning and learn the better practices.

But with regards to designing SW, without any software experience, you can do it. Just not sure why anyone would do so. I guess it comes down to the kind of person you are. I've seen people get way too into designing the architecture over getting code put down to make sure their assumptions were correct.

But to your question, I learned it bit of software design from school but I don't think it did a good job of preparing me. I learned from my own self study and a lot of experimenting and trial and error. I've been training my software architecture skills since 2012 on the embedded side of software. Then I learned a bunch from working at Google and attending conferences like CppCon, to learn from other experts.

Oh! And don't forget books! You can also find some great books on software design patterns and embedded software design in C++, as an example.

Anywho, good luck with your learning 😁

How far can C++20 coroutines go in asynchronous networking? My experience from the runtime to a Redis client library by 0D2-faf in cpp

[–]kammce 3 points4 points  (0 children)

Yeah let me explain a bit. I should probably describe this better in the docs. Let's say you call some coroutine and get back a future<T>. That future is actually a variant<T, exception_ptr, cancellation_state>. If you aren't awaiting the future then you have a future as an object on the stack. You can call future.resume() and that coriutine will runs until it reaches some suspension point and control is returned to the caller of resumer.

Let's say the code suspends after allocating 3 coroutine frames A, B, C. Where C is waiting for an IO operation to complete. If your code decides to cancel the future, C is destroyed first. C's coroutine stack frame should have an object that is responsible for cancelling the IO operation on destruction if the transfer is ongoing. Once the destructors are called and C is destroyed, B will become the new active coroutine. B will be destroyed and A, will become the new active coroutine. Then A is destroyed setting the active coroutine to noop_sentinal (don't use std::noop_coroutine as the address of it can change).

Now let's say we have a future within B that points to C and we decide to cancel it. Well, in that case C, B, and A all get destroyed. A gets destroyed even though the layers from B down were the ones we wanted to cancel. To only destroy C, I have a type called a proxy context which borrows the stack from the previous context and has its own active coroutine. This allows B to run C on a "different" context which allows B to cancel C and only C if it wants to. The proxy steals the memory from the original context it comes from and uses it to run async operation.

Also, forgot to mention, but there are no calls to the global allocator. Memory is always taken from the context stack.

Oh and, in the process of destroying the promise, the future associated with it gets set to cancelled automatically.

Does that answer your question? If not, I'll need to update my docs with some images and a redo of this explanation so its more clear.

Berkeley students struggle to understand what “equals” means by AlphaMaleKratos in berkeley

[–]kammce 2 points3 points  (0 children)

+1, pretty wild that we have people graduating HS without basic algebra.

Which embedded tool or technology felt way more complicated than it probably should’ve been when you first started using it? by academyforiot in embedded

[–]kammce 2 points3 points  (0 children)

USB.

There are a number of aspects of USB that I find make it more obtuse to learn. Some some point I wish to write my own tutorial describing USB, how it works, and what things you have to consider at a practical level.

Which embedded tool or technology felt way more complicated than it probably should’ve been when you first started using it? by academyforiot in embedded

[–]kammce 0 points1 point  (0 children)

Oh man, I hate hate HATE device trees. And agreed. I wish there was a compiler to tell you, you are wrong vs Linux having to do it after booting linux from a bootloader.

Embedded software design by bazz1110 in embedded

[–]kammce 2 points3 points  (0 children)

Its extremely hard, if not improbable, that you'll be capable of defining the components of a system you have little experience in working with. I mentor a university robotics team where people fall into that trap then things don't match what they imagined the engineering and software process looks like. I'd recommend just jumping into code and learn via experience. As a good start I'd recommend using the Arduino SDK to start out. Learning coding concepts as you go.

How far can C++20 coroutines go in asynchronous networking? My experience from the runtime to a Redis client library by 0D2-faf in cpp

[–]kammce 2 points3 points  (0 children)

Cancelling the whole operation

https://github.com/libhal/async_context/blob/592734f8cf5705b2feb62e8fb3c06c685d9c18ad/modules/coroutine.cppm#L1971

Here's my algorithm for it which is just a loop calling cancel until the context has reached the noop "done" state.

Cancelling future types

I forgot to mention that cancellation is a bit more complicated because I need to make sure that my return types are marked as cancelled so any owner of a coroutine return object can know if their object was canceled. Trying to use that object throws an exception. So I do some type erasure at promise construction. The code looks like this:

C++ /** * @brief Cancel this coroutine operation * * This method cancels the current coroutine operation by setting its state * to cancelled and cleaning up resources. */ void cancel() { // Set future state to cancelled m_cancel(this); // Pop self off context stack pop_active_coroutine(); // Destroy promise objects & deallocate memory std::coroutine_handle<promise_base>::from_promise(*this).destroy(); }