Arduino/AVR Hardware-based Debugging on the Cheap

113 views
Skip to first unread message

wayne.holder

unread,
Feb 1, 2018, 7:07:22 PM2/1/18
to Developers

I’ve developed an Arduino sketch that runs on one Arduino and allows it to control and debug another Arduino or an AVR-Series micro-controller, such as an ATTiny85.  With some limitations, you can use the controlling Arduino to disassemble code, single step code, inspect and modify the current value of registers. I/O ports and SRAM and run code with a hardware breakpoint set.


The code I've developed is still rather unpolished and assumes the user has a basic understanding of AVR assembly language in order to benefit from using it.  However, I think parts of it, such as the ability to set hardware and software break points could benefit a larger audience if integrated properly into the Arduino IDE. 


I've done some experiments with writing my own, Arduino-like IDE for the ATTiny10 series and, from this, I've learned how to get the GNU compiler to emit interlaced C and ASM code.  I believe this could be parsed to find the corresponding ASM starting addresses for lines of C code such that a user could set breakpoints for them.  I think it also might be possible to parse the symbol table combine this with other parts of my debugger in order to inspect and modify at least the non register-based variables.  However, this is just conjecture on my part at this point.


I'm posting here on the off chance that my work might be of some use to the Arduino community and that perhaps other developers might want to adapt, or contribute to what I've produced so far.  Any type of constructive feedback would be appreciated.  At the moment, I'm working to integrate portions of the "Arduino ISP" sketch into my code so it can both upload to and debug code on the target device.


You can read more about my project at https://sites.google.com/site/wayneholder/debugwire and/or watch a short, demo video at https://youtu.be/kI_Z78a_0y0


Wayne

Bob Godzicz

unread,
Feb 2, 2018, 4:28:29 AM2/2/18
to devel...@arduino.cc

Hi All

  I am a recent Arduino user after an enforced break of many years due to my career.  Prior to that I developed many 8 bit systems, based mainly on the Intel 8051 family and latterly its derivatives, with a mixture of Hitachi, Zilog and Molorola  8 and 16 bit devices for embedded control projects using plain ‘C’.

 

My current project, which is near completion, is a GPS navigation aid for sailors with visual impairment based on the 328 processor. I did all my initial research and  development using standard UNO module with a range of breakout modules until I converged on the final design.  This will become a custom PCB.

 

Being focused on the task in hand, I did not have much time to develop ‘development tools’ to ease my research.  However, I did make my own ICSP which has been modified to exactly suit my development environment.  This automatically handles program download, the setting of the fuses and security bits and also sets the OSCCAL automatically.  I also believe that I could easily modify my ISCP to perform the debugging function that Wayne has mentioned, if I had the time.

 

For me, the major omissions from the IDE is the ability to automatically (and easily) generate:-

                1) Mixed C and ASM listings

                2) Easy to view Symbol Table

                3) Memory Map

These are features which are common in virtually all of the development systems I have used in the past, but are probably not a requirement for the ‘Hobbyist’ user.  Thus have been overlooked in the IDE development.  The Forums have numerous requests on how to generate the above information, and many responders have avoided giving a clear answer/tutorial for a complete, easy to use solution.  I have found ways of generating the information but it is tiresome and thus grossly underused.  One tends to use the ‘I hope it is OK’ approach.

 

I do like Wayne’s work and ideas and if it was finalised and issued, would have got me out of many a ‘hole’ that I fell into.  I would be willing to help if I had time, which currently looks like next winter.  If Wayne were to PM me, I would happily discuss it with him in the near future.

 

In addition, my preferences  are:-

                1) The ability to set a breakpoints

                2) A simple Single-Step and/or TRACE function would be nice.  (However, this has limited usage in a highly Interrupt driven system)

                3) I have rarely found a dis-assembler to be of any use, other than trying to hack someone else’s system.

 

I realise that what I am doing is beyond the scope of the average ‘Arduino User’.  The Arduino concept is excellent and meets the needs of most Hobbyist users and novices.  I just wish a similar system was available when I started with the Motorola 6800 and twin cassette tape development system back in the mid 70’s.

If my preferences were included, or a tutorial was developed to provide the information I desire, then it would become a truly excellent low cost development system.

 

As I am a sole developer, using my own money, an Arduino system, my own ISCP and a digital storage scope and I am highly unlikely to make any profit, the following phrase applies:-

When you're up to your neck in alligators, it's easy to forget that the initial objective was to drain the swamp’

 

Keep up the good work Wayne, and feel free to contact me.

 

Cheers

Bob G.

--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

William Westfield

unread,
Feb 3, 2018, 3:31:49 AM2/3/18
to devel...@arduino.cc

> 3) I have rarely found a dis-assembler to be of any use, other than trying to hack someone else’s system.

A disassembler is pretty essential when you’re single-stepping one instruction at a time, instead of one line of source code. (Not the sort of disassembler that we already have in objdump, but something capable of decoding a single instruction at a time.)


> You can read more about my project at https://sites.google.com/site/wayneholder/debugwire


Thank you for working on this. I’ve been frustrated for a long time by the lack of information about debugwire, and things along the lines of this work are highly necessary if we’re ever to have the sort of “simplified debugging environment” that Arduino needs…

BillW/WestfW

Bob Godzicz

unread,
Feb 3, 2018, 5:03:04 AM2/3/18
to devel...@arduino.cc
I have always found the mixed C and Asm listing to be more than adequate  for your situation.  If for some reason the listing and the stored code don't match, then you have a hardware problem.  Usually low supply voltage.  Then other anomalies will be happening.  A digital storage scope will then be or more use than a disassembled.
I wouldn't waste much effort on writing a disassembler

From my Samsung Phone






Thank you for working on this.  I’ve been frustrated for a long time by the lack of information about debugwire, and things along the lines of this work are highly necessary if we’re ever to have the sort of “simplified debugging environment” that Arduino needs…

BillW/WestfW

-- 
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

Wayne Holder

unread,
Feb 3, 2018, 5:55:54 AM2/3/18
to Arduino Developers
Thanks for positive feedback.  On the topic of the "disassembler" it was actually the addition of the single step feature that led me to add it, so I agree with your opinion on this.  I find that, even if you have a listing that interleaves Asm and C, having the disassembled output makes it easier to locate the correct line in the mixed listing.

As I mentioned in my first pst, I think the the best solution is to have the debugWire interface portion hand off the majority of the work to an IDE supporting it, which is my eventual goal.  But, baby steps for now.

BTW, I've just posted an update to the code that's now able to debug an ATTiny85 running at 8 MHz.

Wayne

--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.

Bob Godzicz

unread,
Feb 3, 2018, 7:15:44 AM2/3/18
to devel...@arduino.cc
I would be interested in including the Debug facility into my ICSP.  I had a quick look at the protocol required when I built the ICSP and it seemed a fairly easy extension to the the ICSP code.  But at the time I was trying to drain the swamp, not stroke the alligators.
My current project uses a 328 processor at 8MHz, with a GPS module, Flash ROM and a class D amplifier for speech generation.  The whole lot being powered by a 3.7V Li-ion battery.  I am just about to start sea trails next week.

In the late summer I should become free and have some time for R&D.  Upgrading my ICSP to include a Debug facility sounds like a good idea.  I write all my Arduino code in plain 'C' .  The PC end is written in Delphi.

From my Samsung Phone




To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

Andrew Kroll

unread,
Feb 3, 2018, 7:28:41 AM2/3/18
to Arduino Developers
Perhaps makr it work with avarice, then you get gdb like on avr dragon ;-)

To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.

wayne.holder

unread,
Feb 13, 2018, 2:30:33 PM2/13/18
to Developers

I’ve posted a new, part 3 article on my debugger project, along with new code and an overview video.  The new code  is now able debug an Arduino UNO running at 16 MHz and also includes some bug fixes and enhancements.


 [url=https://sites.google.com/site/wayneholder/debugwire3]https://sites.google.com/site/wayneholder/debugwire3[/url]

 [url=https://youtu.be/F1202b0l5D]https://youtu.be/F1202b0l5DA[/url]


Wayne

newc...@flounder.com

unread,
Feb 14, 2018, 9:19:44 AM2/14/18
to devel...@arduino.cc
There are a couple typos, or copy-and-pastos, in your article.

At one point, you say

Type '-' (minus symbol) and press Send to disable the DWEN Fuse

and at another you say

Type '+' (minus symbol) and press Send to disable the DWEN Fuse

when I think you meant to say

Type '+' (plus symbol) and press Send to enable the DWEN Fuse

Similarly, you have these two lines adjacent:

+ - Enable debugWire DWEN Fuse
- - Enable debugWire DWEN Fuse

I think they should have been

+ - Enable debugWire DWEN Fuse
- - Disable debugWire DWEN Fuse

My experience with timing loops is that you should never, ever rely on
compiler-generated code for these; all such code is Subject To Change
Without Notice, and cannot be trusted, especially if someone turns on
optimization. For example, I have seen a compiler take
for(int i = 0; i < us10; i++) ;
and, legitimately, in one version put i in a register, which change the
loop timing, and with full optimization on realize that the loop is doing
nothing, and (equally legitimately) simply generate no code at all. You
simply cannot rely on the code. We wrote a subroutine and had a macro,
Wait_us(n), which generated (and here I have to use assembler pseudo-code
since I don’t know AVR code that well:

#define Wait_us(us) \
__asm(push32 us); \
__asm(call waiter_us); \
__asm(add sp, 4)

we had originally done it by making Wait_us the subroutine, but with a new
release of the compiler, the compiler cleverly put “us” in a register
instead of putting it on the stack.

__option(bare) void waiter_us() // bare: no prolog or epilog code
{
__asm(mov r0,4(sp)); // r0 = us
L: __asm(loopne r0, L); // r0--; if(r0 != 0) goto L;
__asm(ret)
}

It is the nature of optimizing compilers to never optimize __asm
insertions, or do code motion around them. So the call sequence was not
subject to optimization. All we had to do was twiddle the values like
us10 to be large enough to get 10 us delay out of the loop. We chose to
use a full 32-bit int so we could have spin delays.

We did the equivalent of

#define us10 (COMPUTEus(10))

where COMPUTEus was a macro that used our equivalent of F_CPU, the fixed
cost of the call (push, call, add, mov, ret) and the speed of the loopne
to compute the “magic number” for the loop.

We tried

#pragma(push, optimize(off))
void waiter_us(int us)
{
for(register int i = us; i > 0; --i) { }
}
#pragma(pop, optimize())

but found that newer releases of the compiler changed the prolog code.
For example, in debug mode the compiler called a stack-limit-check
subroutine, which it hadn’t done before, so it took too long to get to the
loopne instruction. Then we discovered, in a newer release, it had code
to initialize local variables, even though there weren’t any. We thought.

We found that in debug mode, the “register int” was considered a
suggestion, and it put i on the stack, and the prolog had code to
initialize it to a bogus value, but in production mode it put it in a
register.

That was when I said “enough is enough”, added the “bare” option to
eliminate all prolog and epilog code, and I put in the __asm inserts that
constituted the entire body of the function. Moral here: never rely on
what the compiler generates if you want a timing loop. What you get is
indeterminate.

My pseudo-asm code is a blend of instructions from a variety of machines,
and is a suggested model, not AVR assembly code itself (in 54 years as a
professional, there were only three machines that I never learned assembly
code for, and that may be reduced to one soon: The IBM RISC/6000
workstation, the AVR, and the Cortek M-series. The latter two I expect to
know within the next 12 months.)

I would suggest figuring out the symbol tables. gdb uses them, and for
some environments I have found that there are often symbol table
libraries, where you can do things like
LoadSymbols();
FindName(void * address, char * buffer, size_t buflrn);
void * FindAddress(const char * name);

An unfortunate feature is that you have to know the “mangled name” of a
function to find its address (to handle overloading and templates).

void * addr = FindAddress(“_function$1YZ”)

One symbol table library I used had a function “Unmangle” of the form

void Unmangle(const char * mangled, char * plaintext, size_t length);

so if you passed it a pointer to “_function$1YZ”, it would fill the
paintext buffer with

int function(const char *)

If gdb has a library that it uses for its symbol table, you should be able
to load that. However, it really requires that the host Arduino either
have a multi-hundred-megabyte SD card, a communication protocol with the
deveopment computer to download new copies of the symbol table, or, better
still, talk directly to the development machine and implement the
equivalent of Remote Procedure Call, so the giant symbol tables stay on
your desktop/laptop, and the functions like FindAddress simply send the
request to the development machine, and it sends the answer back. You
could use serial port, blutooth, wifi, etc., but I would suggest wifi for
the bandwidth, a way to know if the symbol table is in sync with the
executable (the number of times my students who were doing similar remote
debugging on Windows machines did a compilation but forgot to download the
new code was amazingly high. I did it an embarrassingly frequent number
of times. Then Microsoft updated their debuuger, and it would check the
timestamp of the module being debugged and compare it to the timestamp of
the latest compilation, according a directory path the user configured,
and if the binary on the target machine was older than the desigated
version, it would actually download the new code and replace the code in
the target.
>
>
> I’ve posted a new, part 3 article on my debugger project, along with new
> code and an overview video. The new code is now able debug an Arduino
> UNO
> running at 16 MHz and also includes some bug fixes and enhancements.
>
>
> [url=https://sites.google.com/site/wayneholder/debugwire3]https://sites.google.com/site/wayneholder/debugwire3[/url]
>
> [url=https://youtu.be/F1202b0l5D]https://youtu.be/F1202b0l5DA[/url]
>
>
> Wayne
>
> On Thursday, February 1, 2018 at 4:07:22 PM UTC-8, wayne.holder wrote:
>>
>> I’ve developed an Arduino sketch that runs on one Arduino and allows
>> it to
>> control and debug another Arduino or an AVR-Series micro-controller,
>> such
>> as an ATTiny85. With some limitations, you can use the controlling
>> Arduino
>> to disassemble code, single step code, inspect and modify the current
>> value
>> of registers. I/O ports and SRAM and run code with a hardware breakpoint
>> set.
>>
>>
>> The code I've developed is still rather unpolished and assumes the user
>> has a basic understanding of AVR assembly language in order to benefit
>> from
>> using it. However, I think parts of it, such as the ability to set
>> hardware and software break points could benefit a larger audience if
>> integrated properly into the Arduino IDE.
>>
>>
>> I've done some experiments with writing my own, Arduino-like IDE for the
>> ATTiny10 series <https://github.com/wholder/ATTiny10IDE> and, from this,
>> I've learned how to get the GNU compiler to emit interlaced C and ASM
>> code.
>> I believe this could be parsed to find the corresponding ASM starting
>> addresses for lines of C code such that a user could set breakpoints for
>> them. I think it also might be possible to parse the symbol table
>> combine
>> this with other parts of my debugger in order to inspect and modify at
>> least the non register-based variables. However, this is just
>> conjecture
>> on my part at this point.
>>
>>
>> I'm posting here on the off chance that my work might be of some use to
>> the Arduino community and that perhaps other developers might want to
>> adapt, or contribute to what I've produced so far. Any type of
>> constructive feedback would be appreciated. At the moment, I'm working
>> to
>> integrate portions of the "Arduino ISP" sketch into my code so it can
>> both
>> upload to and debug code on the target device.
>>
>>
>> You can read more about my project at
>> https://sites.google.com/site/wayneholder/debugwire and/or watch a
>> short,
>> demo video at https://youtu.be/kI_Z78a_0y0
>>
>>
>> Wayne
>>
>
> --
> You received this message because you are subscribed to the Google Groups
> "Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to developers+...@arduino.cc.
>

Matthijs Kooijman

unread,
Feb 14, 2018, 9:31:10 AM2/14/18
to devel...@arduino.cc
Hi folks,

> My experience with timing loops is that you should never, ever rely on
> compiler-generated code for these; all such code is Subject To Change
> Without Notice, and cannot be trusted, especially if someone turns on
> optimization.
Another testament to this is the Arduino delayMicroseconds function,
which turns out to delay too short in recent (more optimizing) Arduino
releases. See the github issue for some examples and measurements, if
this sounds interesting:

https://github.com/arduino/Arduino/issues/7181

If you have constant delays, the _delay_us from <util/delay.h> is ideal,
since that generates perfect delays (it can not do variable delays,
however).

Gr.

Matthijs
signature.asc

Wayne Holder

unread,
Feb 14, 2018, 2:32:06 PM2/14/18
to Arduino Developers
Thanks for pointing out the typos.  The second case was from an error in a string in the code from which these messages were copied that I didn't notice, either.  These have now been fixed.

As to the timing loop issue, I started with the code for standard Arduino SoftwareSerial library, which calls a "tunedDelay()" function which, in turn, calls _delay_loop_2() in the util/delay_basic.h from the Standard C library for AVR-GCC.  Since all timing is based on a standard AVR-GCC library function which is, itself, coded in AVR assembly, the core timing of this function can't really change with a compiler change.

My main "tweak" was to unroll the receive loop which then let me add enough assembly language code to toggle an extra I/O line at the bit sample point so that I could then measure the timing with an oscilloscope.  Using this, I was able to adjust the timing for the special case of a target running at 16 MHz.  Then, I replaced the code that toggled the bit for the oscilloscope with an equivalent number of AVR "nop" instructions to keep the timing the same as the bit toggle code.  I actually put this code under conditional compilation in the OnePinSerial.cpp file so that I could revisit this in the future should I want to attempt to make this code run on another processor type.

Wayne



> email to developers+unsubscribe@arduino.cc.

>

--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.

Matthijs Kooijman

unread,
Feb 14, 2018, 3:04:25 PM2/14/18
to devel...@arduino.cc
Hey Wayne,

> Since all timing is based on a standard AVR-GCC
> library function which is, itself, coded in AVR assembly, the core timing
> of this function can't really change with a compiler change.
Not sure if this actually applies to your code, but in the case of
delayMicroseconds, this was not enough, since the code assumed that
calculating the number of loops took a certain amount of time, which
turned out to be incorrect with recent optimization improvements
(optimizing down to 2 cycles when the number of loops could be
calculated at compiletime).

Just FYI :-)

Gr.

Matthijs
signature.asc

newc...@flounder.com

unread,
Feb 15, 2018, 11:11:28 AM2/15/18
to devel...@arduino.cc
Back In The Day, when the 8088 chip ruled, the 286 was for Power Users,
and the 386 was emerging, back before there was an instruction that
returned the CPU speed, we had to manage some equivalent to bitbanging
across all platforms. So we had an array of NOP instructions and “tuning”
gave us an offset into the array. So for an 8088, the offset was higher,
and the table was long enough to accomodate our delay for a 20MHz 386.
The code was
mov AX, offset
call delay[AX]

delay: nop
nop
...
nop
ret

The 386 was the last Intel chip you could do this on. The 486 had caches,
and Pentium and beyond have instruction pipes and are all nondeterministic
opportunistic asynchronous RISC architectures, but the programmer sees
only the CISC instruction set from the Intel manual. It can dispatch
between 2 and, I think, 7, instructions concurrently, and each instruction
will be delayed until its data arrives. Then add speculative execution,
multilevel caching, and branch prediction, and there is no effective way
to build timing loops for fine-grain timings. Sadly, this fact is lost
for many hardware designers, as well as the concept of “operating system”.
In Arduino and other microcontrollers I find it somewhat refreshing to
have deterministic instruction timing again.

The challenges of limited memory are less fun, but new young programmers
don’t understand this. So I’ve gone from the “old programmer” to “the guy
who knows how to fit it all in”.

I mentioned RPC in my note. Would anyone be interested in working with me
to embed an RPC mechanism into the Serial Monitor? This would give us
awesome power. Imagine Adafruit_GFX_RPC, which could do graphics from the
Serial Monitor, or a way for your debugging Arduino to query the Symbol
Manager that handled all the symbol tables. Then, instead of just Serial
Monitor or Serial Plotter, we could have Serial Anything, and the
programmer could write Java code, compile it, and have the compiled entity
loaded in dynamically. So it would not be necessary to rebuild the entire
Arduino app to add new kinds of functionality. You could even write a
socket-based extension, invoked from the Serial Monitor RPC, which could
handle BlueTooth, BLE, or WiFi RPC. OMG! I’ve just reinvented plugins!

With the right plugin, and some suitable interfaces to the source editor,
you could have Arduino IDE source language debugging using your debugging
host as the interface. Now I’m getting seriously excited.
joe

Dennis Lee Bieber

unread,
Feb 15, 2018, 12:15:59 PM2/15/18
to devel...@arduino.cc
On Thu, 15 Feb 2018 11:11:24 -0500 (EST),
newc...@flounder.com declaimed the following:


>
>The challenges of limited memory are less fun, but new young programmers
>don’t understand this. So I’ve gone from the “old programmer” to “the guy
>who knows how to fit it all in”.
>
If you mean RAM, somewhat... But... Consider that an Uno has 32kB for
code storage, when many of the 8080/Z80/6800/6502 based computers of the
end of the 70s supported minimal OSs on systems with between 16-48kB
(allowing for a 16kB ROM).

>I mentioned RPC in my note. Would anyone be interested in working with me
>to embed an RPC mechanism into the Serial Monitor? This would give us
>awesome power. Imagine Adafruit_GFX_RPC, which could do graphics from the
>Serial Monitor, or a way for your debugging Arduino to query the Symbol
>Manager that handled all the symbol tables. Then, instead of just Serial
>Monitor or Serial Plotter, we could have Serial Anything, and the
>programmer could write Java code, compile it, and have the compiled entity
>loaded in dynamically. So it would not be necessary to rebuild the entire
>Arduino app to add new kinds of functionality. You could even write a
>socket-based extension, invoked from the Serial Monitor RPC, which could
>handle BlueTooth, BLE, or WiFi RPC. OMG! I’ve just reinvented plugins!
>

Sounds a bit like an extension of the Firmata library.

--
Wulfraed Dennis Lee Bieber AF6VN
wlf...@ix.netcom.com HTTP://wlfraed.home.netcom.com/

Bob Godzicz

unread,
Feb 15, 2018, 1:34:04 PM2/15/18
to devel...@arduino.cc
> If you mean RAM, somewhat... But... Consider that an Uno has 32kB for code storage, when many of the 8080/Z80/6800/6502 based computers of the
> end of the 70s supported minimal OSs on systems with between 16-48kB (allowing for a 16kB ROM).

Re above processors:- What OS?
if 'Round Robin Polling' with 'State Machine' written tasks was an OS, then I have only learnt one OS (for embedded controllers). It still works very well today and is Reliable, Predictable, has minimal hardware requirements and easy to debug with a 'Scope, unlike many OSs I have seen and reluctantly used in the past.
(PS you missed out the Z8, H8, PIC16s, 8051 and its many derivatives up to the 80535. The AT328 is a brilliant embedded controller)

Cheers
A Dinosaur!
--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+...@arduino.cc.

newc...@flounder.com

unread,
Feb 15, 2018, 2:22:50 PM2/15/18
to devel...@arduino.cc
Well, RAM is a problem, especially if it fragments. Not all AVR
processors have 32K of flash; the 167, for example, has only 16K, and for
a variety of technical reasons that is the one we chose for our project.
This is why I want clickable options for such things as producing a link
map or getting a source-and-assembly listing.

An app which ran well on the UNO R3 would not even fit into the 167.

Our “operating system” will be the DeepSleepScheduler library. We are
using a 125mAh battery, whose lifetime is a couple days without using deep
sleep, Back-of-the-envelope calculations suggest that with deep sleep,
waking up for tens of milliseconds every two minutes, the battery lifetime
will be about three months.

The ultimate problem was a bloated library, which we were able to
eliminate. Having a link map, early, would have made this apparent. But
nobody seemed to have an answer to the question “how do I get a link
map?”. A feature I would love to add. The build system for the IDE seems
fairly complex, and I have no idea how I would do debugging. I have done
all my Java work in Eclipse, for the last 15 years. Just finding out what
I need to install is challenging; the build instructions need a list of
evey component we need, and, ideally, a link
[x] source/assembly listing
[x] link map
[x] debug symbols
Predefined symbols
[_Debug ][v] [add new] [remove]
Other compiler options
[ --whatever ]

My scarcest resource right now is time. I’m retired, but I’m thinking of
coming out of retirement and taking a full-time job. When I had a
full-time job, I seemed to have more spare time.
joe
> --
> You received this message because you are subscribed to the Google Groups
> "Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to developers+...@arduino.cc.
>


newc...@flounder.com

unread,
Feb 15, 2018, 2:22:50 PM2/15/18
to devel...@arduino.cc
> --
> You received this message because you are subscribed to the Google Groups
> "Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to developers+...@arduino.cc.
>


newc...@flounder.com

unread,
Feb 15, 2018, 3:00:44 PM2/15/18
to devel...@arduino.cc
My email system is messed up. Not only did it send the message twice, but
parts of it had been deleted. Possibly the hazards of using an iPad.
Sorry to be repetious, but as sent out, some of it didn’t make sense.

Well, RAM is a problem, especially if it fragments. Not all AVR
processors have 32K of flash; the 167, for example, has only 16K, and for
a variety of technical reasons that is the one we chose for our project.
This is why I want clickable options for such things as producing a link
map or getting a source-and-assembly listing.

An app which ran well on the UNO R3 would not even fit into the 167.

Our “operating system” will be the DeepSleepScheduler library. We are
using a 125mAh battery, whose lifetime is a couple days without using deep
sleep, Back-of-the-envelope calculations suggest that with deep sleep,
waking up for tens of milliseconds every two minutes, the battery lifetime
will be about three months.

The ultimate problem was a bloated library, which we were able to
eliminate. Having a link map, early, would have made this apparent. But
nobody seemed to have an answer to the question “how do I get a link
map?”. A feature I would love to add. The build system for the IDE seems
fairly complex, and I have no idea how I would do debugging. I have done
all my Java work in Eclipse, for the last 15 years. Just finding out what
I need to install is challenging; the build instructions need a list of
evey component we need, and, ideally, a link to the download page.

I want to add acmenu item
Tools>Build options
which would pop up a dialog of the general form
============================================
[x] source/assembly listing
[x] link map
[x] debug symbols
Predefined symbols
[_Debug ][v] [add new] [remove]
Other compiler options
[ --whatever ]
============================================

There would be a dropdown list of predefined symbols, which might also
display the symbols defined already (possibly in the “disabled text”
color). I was a Windows application developer for 25 years, and could
write this in under an hour without consulting a manual. I have never
built a GUI in Java, so the learning curve is a bit steep.

It would be nice to have a list of all the predefined symbols. When I’m
writing #ifdefs, I would like to know what symbols I should be using. I
could write a program that could scan all the boards files and extract the
options and create a table.

My scarcest resource right now is time. I’m retired, but I’m thinking of
coming out of retirement and taking a full-time job. When I had a
full-time job, I seemed to have more spare time. So anything you guys can
do to help me get into this quickly would be greatly appreciated.
joe

> On Thu, 15 Feb 2018 11:11:24 -0500 (EST),
> newc...@flounder.com declaimed the following:
>
>
>>
>>The challenges of limited memory are less fun, but new young programmers
don’t understand this. So I’ve gone from the “old programmerâ€
to
>> “the guy
>>who knows how to fit it all in†.
>>
> If you mean RAM, somewhat... But... Consider that an Uno has 32kB for
> code storage, when many of the 8080/Z80/6800/6502 based computers of the
end of the 70s supported minimal OSs on systems with between 16-48kB
(allowing for a 16kB ROM).
>
>>I mentioned RPC in my note. Would anyone be interested in working with
>> me
>>to embed an RPC mechanism into the Serial Monitor? This would give us
awesome power. Imagine Adafruit_GFX_RPC, which could do graphics from
>> the
>>Serial Monitor, or a way for your debugging Arduino to query the Symbol
Manager that handled all the symbol tables. Then, instead of just
Serial Monitor or Serial Plotter, we could have Serial Anything, and the
programmer could write Java code, compile it, and have the compiled
>> entity
>>loaded in dynamically. So it would not be necessary to rebuild the
>> entire
>>Arduino app to add new kinds of functionality. You could even write a
socket-based extension, invoked from the Serial Monitor RPC, which could
handle BlueTooth, BLE, or WiFi RPC. OMG! I’ve just reinvented

William Westfield

unread,
Feb 16, 2018, 12:32:24 AM2/16/18
to devel...@arduino.cc

> The 386 was the last Intel chip you could do this on. The 486 had caches,
> and Pentium and beyond have instruction pipes and are all nondeterministic
> opportunistic asynchronous RISC architectures, but the programmer sees
> only the CISC instruction set from the Intel manual.

Surely the caches showed up at the same time as instructions that specifically bypass the cache, and/or high-resolution cycle counters that allow you to be deterministic within about the same timeframes as earlier chips, when you really want to (possibly at the risk of hurting performance on the code you don’t care about being deterministic.) RDTSC (ReaD Time Stamp Counter) is the current x86 magic instruction (increments at full clock rate!) Making a large chunk of code be deterministic is more difficult, of course.


> Having a link map, early, would have made this [bloated library] apparent. But nobody seemed to have an answer to the question “how do I get a link map?”.

I find the gnu link maps to be pretty useless, especially when all the files it references are buried deep in some tmp directory (as is the case with the Arduino IDE. But it’s not much better from Atmel Studio. However, the SAM and SAMD builds have been creating map files (in the build directory) for a while now.

I’d prefer output from “nm” - it can dump symbol value and size information, but not source filename.
Likewise, output from “objdump” seems far more useful than the compilers -S output (although, it includes all the core function code as well. (which may be unavoidable with lto anyway.))

BillW/WestfW

William Westfield

unread,
Feb 16, 2018, 12:54:55 AM2/16/18
to devel...@arduino.cc
On Feb 15, 2018, at 12:00 PM, newc...@flounder.com wrote:

> Predefined symbols

See https://stackoverflow.com/questions/2224334/gcc-dump-preprocessor-defines

The list of all pre-defined symbols is pretty substantial (more than 400 symbols!), once you include base gcc predefines, the avr-specific defines, and the ones added by the Arduino build system. The Arduino symbols are quite few:

-DF_CPU=16000000L
-DARDUINO=10805
-DARDUINO_AVR_UNO
-DARDUINO_ARCH_AVR

One reason for not having a bunch of build options is to KEEP that number small. The idea of helping beginners and having to go through the list of options present in (for example) the Atmel Stdio project option is … unpleasant.

BillW/WestfW

William Westfield

unread,
Feb 16, 2018, 2:20:37 AM2/16/18
to devel...@arduino.cc

> Arduino IDE source language debugging

I would be extremely interested in any thoughts that people might have about how to make a debugger more "beginner friendly.”

I mean, I’ve used essentially two kinds of debuggers in my career:

1) command-line debuggers: Things like DDT, MSDOS Debug, and gdb. I think we can immediately reject the idea of a CLI debugger for Arduino. And they only worked “well” when you were writing code a a very low level (preferably in the assembly language that could be singlestepped by the hardware, and easily decoded…)

2) GUI debuggers, all with the same breakpoint/watch, step into/out-of/over (maybe sort-of at source-code level) sort of model. Which I think is too complex for most Arduino users.

But I don’t really have any alternatives, and I’ve only come up with one obvious idea: “you only get to step through non-core, non-library code.”

I think… we could make used of -finstrument-functions (on the user sketch files) to do … something (breakpoint instruction, perhaps?) It’s a little expensive, but not compared to actually hitting a breakpoint and talking over the debug connection. Or maybe the same pre-processing code that generates prototypes could add debugging hooks?

BillW/WestfW

Andrew Kroll

unread,
Feb 16, 2018, 2:21:27 AM2/16/18
to Arduino Developers
Which is why I say "to heck with that" and use Netbeans with a touch of customized settings to end up with something that just uses GNU make and stays Arduino compatible.
All the "settings" just go into the makefile and done, and those settings simply consist of the fully qualified board string, and anything extra I wish to pass to the compiler. Arduino builder then takes care of the rest.


After that, for AVR, I use the AVR dragon with avarice and gdb under control of gnu ddd.... like so....


ddd --debugger "avr-gdb -x gdb.conf"

Of course avarice must be running for this to work, and the gdb.conf needs to point to the elf file being debugged!

Similar is done for ARM and PIC16/32...





 

--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.



--
Visit my github for awesome Arduino code @ https://github.com/xxxajk

Andrew Kroll

unread,
Feb 16, 2018, 2:27:11 AM2/16/18
to Arduino Developers
ddd plus a way to interface to GDB works well.
All you would need to do is be able to talk to GDB. How to do that is fully open source.
ddd would take care of any GUI wants.... personally, I like ddd, while not perfect, and requiring a few patches to work, once it works, it gets the job done.
It allows watching variables, stopping on a variable getting changed, code stepping, break points, and displays the source in C and ASM as it steps, but best of all, you still get the CLI from GDB.


--
You received this message because you are subscribed to the Google Groups "Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to developers+unsubscribe@arduino.cc.



--
Reply all
Reply to author
Forward
0 new messages