I've been using Arduinos for a while now, but I want to start using AVRs directly without the "crutch" of Arduino.
One of the issues I've run into is debugging my programs when programming them with an ISP. How does one get feedback when using an ISP, they don't have any kind of serial interface.
For example, with Arduino, I'd just print stuff to the screen using the serial interface and that would give me visibility into what it's doing. How would I replicate that workflow with an ISP?
Thanks!
First thing: Set up the clocks/dividers and then get the UART to send a character by writing the code for putchar(). Now write the code for puts() using putchar().
Just write error free code - what's the problem?!?
First thing: Set up the clocks/dividers and then get the UART to send a character by writing the code for putchar(). Now write the code for puts() using putchar().You've just described debugging circa 1976. The world has moved on since then and now uses on-chip debugging aids like JTAG to do source-level debugging. This is the professional standard--every company I've worked for in the last 25 years has done it this way. Sure, there are still a few grizzled holdouts that insist on debugging by sprinkling printfs in their code, but that's not the norm.
I've been using Arduinos for a while now, but I want to start using AVRs directly without the "crutch" of Arduino.
One of the issues I've run into is debugging my programs when programming them with an ISP. How does one get feedback when using an ISP, they don't have any kind of serial interface.
For example, with Arduino, I'd just print stuff to the screen using the serial interface and that would give me visibility into what it's doing. How would I replicate that workflow with an ISP?
Thanks!
Just write error free code - what's the problem?!?
[...]
I don't really like single stepping even with a really nice source level debugger. It just doesn't seem productive.
[...]
Get yourself an Atmel ICE and experience the power of proper source level debugging. By Arduino standards it might look expensive, but by professional debugger standards it's very cheap.
A budget solution might be the ATmega328P Xplained board which has an integrated Atmeol Studio compatible debugger, though I've never used it.
The dowside of these is the number of pins required on a device that already starts with relatively few pins.
Get yourself an Atmel ICE and experience the power of proper source level debugging. By Arduino standards it might look expensive, but by professional debugger standards it's very cheap.
A budget solution might be the ATmega328P Xplained board which has an integrated Atmeol Studio compatible debugger, though I've never used it.
The dowside of these is the number of pins required on a device that already starts with relatively few pins.
Are you referring to this? https://www.digikey.com/product-detail/en/microchip-technology/ATATMEL-ICE/ATATMEL-ICE-ND/4753379
Get yourself an Atmel ICE and experience the power of proper source level debugging. By Arduino standards it might look expensive, but by professional debugger standards it's very cheap.
A budget solution might be the ATmega328P Xplained board which has an integrated Atmeol Studio compatible debugger, though I've never used it.
The dowside of these is the number of pins required on a device that already starts with relatively few pins.
Are you referring to this? https://www.digikey.com/product-detail/en/microchip-technology/ATATMEL-ICE/ATATMEL-ICE-ND/4753379There are cheaper options like buying only the PCB if you can make 1.27mm pitch to 2.54mm header cables. It is called Atmel ICE PCBA or they also have a Basic option that comes with the case but not many adapters, only the basic cable
[...]
I don't really like single stepping even with a really nice source level debugger. It just doesn't seem productive.
[...]
Single stepping is OK for assembler, but only occasionally useful with higher level languages, in my experience.
First thing: Set up the clocks/dividers and then get the UART to send a character by writing the code for putchar(). Now write the code for puts() using putchar().
You've just described debugging circa 1976. The world has moved on since then and now uses on-chip debugging aids like JTAG to do source-level debugging. This is the professional standard--every company I've worked for in the last 25 years has done it this way. Sure, there are still a few grizzled holdouts that insist on debugging by sprinkling printfs in their code, but that's not the norm.
First thing: Set up the clocks/dividers and then get the UART to send a character by writing the code for putchar(). Now write the code for puts() using putchar().
You've just described debugging circa 1976. The world has moved on since then and now uses on-chip debugging aids like JTAG to do source-level debugging. This is the professional standard--every company I've worked for in the last 25 years has done it this way. Sure, there are still a few grizzled holdouts that insist on debugging by sprinkling printfs in their code, but that's not the norm.
When I came back to embedded programming 5 years ago, I was horrified and delighted about now quickly I picked it up at again.
1982: 8 bit micros with ADCs and DACs, C, cross compilation plus download and run, in circuit emulators (same as JTAG). The only significant difference is that back then the tools would have cost a years salary!
But the key point is to learn to use whatever tools are available. Printf or waggle an I/o pin are always available, and are one of the tools in a toolbox.
First thing: Set up the clocks/dividers and then get the UART to send a character by writing the code for putchar(). Now write the code for puts() using putchar().
You've just described debugging circa 1976. The world has moved on since then and now uses on-chip debugging aids like JTAG to do source-level debugging. This is the professional standard--every company I've worked for in the last 25 years has done it this way. Sure, there are still a few grizzled holdouts that insist on debugging by sprinkling printfs in their code, but that's not the norm.
First thing: Set up the clocks/dividers and then get the UART to send a character by writing the code for putchar(). Now write the code for puts() using putchar().
You've just described debugging circa 1976. The world has moved on since then and now uses on-chip debugging aids like JTAG to do source-level debugging. This is the professional standard--every company I've worked for in the last 25 years has done it this way. Sure, there are still a few grizzled holdouts that insist on debugging by sprinkling printfs in their code, but that's not the norm.
When I came back to embedded programming 5 years ago, I was horrified and delighted about now quickly I picked it up at again.
1982: 8 bit micros with ADCs and DACs, C, cross compilation plus download and run, in circuit emulators (same as JTAG). The only significant difference is that back then the tools would have cost a years salary!
But the key point is to learn to use whatever tools are available. Printf or waggle an I/o pin are always available, and are one of the tools in a toolbox.
Tiny bit confused: How is printf "always available"? Don't you need serial or something set up to be able to see the output?
Tiny bit confused: How is printf "always available"? Don't you need serial or something set up to be able to see the output?
Tiny bit confused: How is printf "always available"? Don't you need serial or something set up to be able to see the output?
You're right. You do indeed need serial or something, to be able to see the output.
In extreme circumstances (no other equipment available, and mcu doesn't even have any serial capabilities), you can bit-bang (i.e. write software which turns the port pins on and off, as if you had a proper serial capability), and then read it with an oscilloscope or some kind of serial adaptor.
The printf method, is useful, up to around 90% of time, depending on programmers experience level. But, 10% or more, the bug(s), can easily make that method very inefficient. Especially when the software mysteriously crashes, in random places, or seems to have weird data corruption etc.
You are likely to learn far more, if you can see the source code, running. Line by line, and be able to examine ram (variables), to see what values they have. Not to mention the hardware I/O registers and things, which can easily get confusing.
E.g. You setup the PWM to output a 2 KHz signal, and nothing happens.
Why ?
Being able to see the registers getting the right values, and checking/watching the software, helps narrow down, what has gone wrong.
The latter can easily be implemented by having a 'mem' command together with a command line interface.
Stepping through code sounds nice but for realtime processes (like on a microcontroller) it runs out of steam quickly. What I have been doing for the past 20 years:
- have a command line interface on a UART
- have status commands which shows stuff like character received, number of interrupts
- if available, implement hard fault handlers and make these print a stack dump
- add extra commands to query status or dump memories (think about an eeprom for example; how can you be sure the correct data is written to it?)
- write complicated routines on a PC first + use a test bench to verify
- allow to dump measured and status data in CSV format for analysis
Once you have a basic command line interface going you have a very simple eco system which is portable as well. There are debuggers which allow to read variables realtime over JTAG/SWD but these aren't very cheap. And they won't do you any good solving problems in the field. If you have a problem in the field (IOW: a board mounted somewhere in a machine far away from you) you can ask a field engineer to connect to the serial port and query the status of the device or just dump data.