you dont expect greybearded just came out of a womb in an instance right?
Good point!
Maybe I can help you because my beard is still dark brown. So I remember my beginner days as they are not too far in the past. I remember the phases of getting a better embedded programmer. And the process is still going.
And: I never did that debugger thing, really. The problem is, debugger with all its fancy features seems very convenient, compared to actual printf debugging. I can't prove it, but I suspect many who start that way early get stuck with the debuggers. Being able to connect an existing tool to your code and single-step through it and examine memory causes certain mindset of writing the software.
Compare this to not having a debugger and resorting to
printf debugging. At very first, it is literally just
printf("place A\n");
...
printf("place B\n");
...
This is not very powerful. Finding bugs is a struggle. But it sets you on the right track because:
* It teaches you that finding bugs is difficult, because it will always be no matter what tools,
* It teaches you, piece by piece, to write better instrumentation. Because you see, this is easy to improve:
printf("place A\n");
becomes:
printf("i=%5d, coords=(%5d,%5d)\n", i, x, y);
Then it becomes:
if(loglevel > 5) fprintf(log, __FUNCTION__ ":" __LINE__ "i=%5d, coords=(%5d,%5d)\n", i, x, y);
Then you understand to add:
assert(x > y);
Or in MCU ISR, you understand to do this:
if(logging && cur_trace_idx < NUM_ELEM(trace))
trace[cur_trace_idx++] = latest_measurement;
because this is all you have, you have to work with the code.
And it grows to a mindset of writing robust, self-checking, instrumented code. Which is a very good target, and while it sounds fancy, you can easily grab the low hanging fruits instead of going super complex with this.
And at the end of the day, you may still connect the JTAG and debugger. Last time I did was in 2020.