CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Any ideas on technique?
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

Any ideas on technique?
PostPosted: Sun Jan 15, 2012 2:47 pm     Reply with quote

The issue is about a way to easily remove debug statements from the code when versioning
...I have been wrapping each debug trace in #IFDEF DEBUG_ENABLED
#ENDIF
I can also use a text editor and remove all debugging statements but it has the small disadvantage of keeping to source code versions one with debug statements the other without

Is there a better way to make the debug trace statement mute in a release version and still keep it embedded in the code?

Example code
Code:

#define DEBUG_ENABLED
#IFDEF DEBUG_ENABLED   
#use rs232(debugger,STREAM=MONITOR) //// debug to MONITOR via  pin b3
#define debug(x)   fprintf(MONITOR,"%s = %d\r\n",#x,x);
#ENDIF
main()
{
int8 myvariable=8;
#IFDEF DEBUG_ENABLED                                           
 debug(myvariable); /// prints to the console "myvariable=8"
#ENDIF
while(1);
}

Specific compiler versions or PIC devices are omitted since this is a generic question about technique.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Sun Jan 15, 2012 3:15 pm     Reply with quote

Leave them in!.....
Use this approach instead:
Code:

#define DEBUG_ENABLED
#IFDEF DEBUG_ENABLED
#define debug(x) fprintf(MONITOR,"%s = %d\r\n",#x,x);
#ELSE
#define debug(x) ;
#ENDIF

void main(void) {
   int8 myvariable=8;
   debug(myvariable); /// prints to the console "myvariable=8"
   while(1);
}


when 'DEBUG_ENABLED' is not defined, all the debug statements just get replaced with a single ; which does nothing. Smile

Best Wishes
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Jan 15, 2012 3:27 pm     Reply with quote

Thanks
It makes so much sense I missed it.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun Jan 15, 2012 4:58 pm     Reply with quote

It gets a bit more tricky.
What if fprintf(MONITOR, has several variables which vary between fprintf statements
Ex
Code:

fprintf(MONITOR," 0x%x\n\r",var);
fprintf(MONITOR," 0x%x 0x%x\n\r",var1,var2);
fprintf(MONITOR," 0x%x 0x%x 0x%x\n\r",var1,var2,var3);
int8 var[5]={1,2,3,4,5};
i=2;
fprintf(MONITOR," 0x%x 0x%x 0x%x\n\r",var[i]);


Is there a technique to mute them as easily as
Code:

#define debug(x);

did in Ttelmah's reply?
ckielstra



Joined: 18 Mar 2004
Posts: 3680
Location: The Netherlands

View user's profile Send private message

PostPosted: Mon Jan 16, 2012 5:38 am     Reply with quote

On a PC I would use a generic debug function like:
Code:
void debug_print(const char *format, ...)
{
#ifdef DEBUG
    va_list   args;
   
    va_start(args, format);
    fprintf(MONITOR, format, args);
    va_end(args);
#endif
}

Usage:
Code:
#define DEBUG    TRUE

debug_print("My hyperfantastic debug facility, version %d\n", 1.23);


A good optimizing compiler will remove the empty function in the release version. I don't have the CCS compiler here so can not test how good CCS does the job. Maybe some #inline addition is necessary.

Here are more similar answers, but I don't know how well CCS supports them: http://stackoverflow.com/questions/1941307/c-debug-print-macros
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Mon Jan 16, 2012 10:59 am     Reply with quote

Code:

#include <stdarg.h>
void debug_print(const char *format, ...)
{
#ifdef DEBUG_TRACE
    va_list   args;// create special argument pointer

   
    va_start(args, format); // initialize argptr starting after format

    fprintf(MONITOR, format, args);
    va_end(args);
#endif
}

This was a really good idea but the CCS 4.124 compiler
errors out on *format ...expecting an identifier
Now having trace printf in the code must be useful to others hopefully someone has a cool way of muting them short of wrapping each one in #IFDEF DEBUG_TRACE statements
Now,often times the code reads nicer if the printf is spread over several lines
Code:

fprintf(MONITOR," some text  %d %d %d",
         My_verbose_variable1,
         My_verbose_variable2,
         My_verbose_variable3);

Any ideas on muting this multiple line construct?
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Jan 16, 2012 3:36 pm     Reply with quote

In over 30 projects, some of of considerable complexity - involving as many as 3 pics interacting - I have NEVER used "debug", as other hardware/software analysis has always done the trick.

Perhaps someone could tell me the attraction /benefit pf debug insertion??
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Mon Jan 16, 2012 4:12 pm     Reply with quote

I often have a "sync" pin that I will pulse to trigger a scope or logic analyzer at certain times. I may give it a single, double, tripple, or even quadruple pulse to mark up to 4 different points in the code. Printing out ASCII messages usually takes too much time.

Many years ago I bought a bondout ICE from Microchip. It cost a lot of money but found I rarely used it. It doesn't support any of the newer chips now.

I don't use MPLAB anymore either.
_________________
The search for better is endless. Instead simply find very good and get the job done.
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Mon Jan 16, 2012 5:05 pm     Reply with quote

Sherpadoug 's methods of debug find a lot of resonance with me...
my favorite tools for debug are external instruments ( of which I have great choices, in depth - in any area I need ).

When I think about it - my debug tools are

* pin toggles -
* rs-232 messages
* canned routines that I use to do postmortem AND activity updates.

The overhead and code alteration ( time domain especially ) introduced by MPLAB - and especially dreadful pic circuit SIMULATION ala Proteus make no sense to me at all.

I just assume if my overall design, code included, is not working - and the LST file looks right -- then there is a circuit or conceptual problem - && it MUST be my problem - and I just dig in and experiment with the code till I suss it out.

That approach and the odd tip on this forum - has never failed yet
You could say I never go the debug habit Very Happy Very Happy Very Happy Very Happy
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Mon Jan 16, 2012 5:13 pm     Reply with quote

This project involves radio communications between several transceivers in a mesh network.
Each transceiver has a FSM . Some states are forced by asynchronous interrupts. When the mesh network has issues it often is a function of one or more transceivers being in the wrong state with respect to its FSM or in the right state just at the wrong time. I find it useful to debug this via a logging aka tracing of the FSM states. The CCS debugger programmer has the capability thru a single pin and without any additional hardware being required on the target boards to display data on a monitor. That's why the compiler has the debugger parameters in the #use RS232 statement. Further the printf to the monitor can be used via the CCS ICD and also at run time via CCS load. If the code holds up in real testing the debugging code is removed. Anyway the reason I do this isn't that relevant since my request was for ideas on technique.


Last edited by Douglas Kennedy on Mon Jan 16, 2012 7:21 pm; edited 2 times in total
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Jan 16, 2012 5:19 pm     Reply with quote

Quote:

Perhaps someone could tell me the attraction /benefit pf debug insertion??

His "debug" statements are printfs. He's not doing anything materially
different than you are, he's just leaving the printf code in there, and
deactivating it for production with a #define statement. This is done for
convenience, so he doesn't have to examine the program at the end of
the development cycle, and comment out each individual diagnostic printf
line. That's what this thread is all about - the fine points of how to do this.
Ttelmah



Joined: 11 Mar 2010
Posts: 19498

View user's profile Send private message

PostPosted: Tue Jan 17, 2012 3:01 am     Reply with quote

My own technique is to start by putting all the actual debug defines, into a file 'debug.h'.
The has at it's start the test for the debugging indicator (whatever you want to use - I tend to do this the opposite way round, and have the debugging code load by default, and have an indicator 'PRODUCTION', which is set to turn off the debugging). The first 90% will be the definitions for the various routines, while the second part has the 'null' definitions that do nothing when debugging is disabled.
Then I'll have perhaps a define for 'debug_pulse', which toggles a pin, or generates a short pulse, together with a few defines for whatever type of variable displays/output I want. Typically 'debug_int' which displays one int variable, and sometimes some others that display other variable types, or multiple variables. I'll also sometimes use a 'debug_eeprom' definition, that writes a value to a location in the EEPROM. All 'debug' definitions begin with the word debug, so can easily be found if required.

Now, the generic function suggested by Ckielstra won't work on CCS, because printf, is parsed at compile time, and is not a included in the code as a 'universal' function. The compiler works out what subsections are needed and only includes these in the final code, so can't handle variables being handed to this function.

Realistically the multi-version debug that Douglas wants can be handled by the wrapper approach just as easily as the single line, by having two or three debug variants, something like 'debug_one_var', and debug_three_vars' for example. Avoid having too many versions though....

Best Wishes
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Tue Jan 17, 2012 9:34 am     Reply with quote

Ttelmah thanks for the excellent idea on technique. I've been using the text editor replacing debug with //debug and reversing it //debug to debug. I'm switching to PRODUCTION rather than DEBUG in the directive.....PRODUCTION is a much more positive.

Now is there was a way for #DEFINE to do pure text editor replacement
as follows?

Code:

IFDEF PRODUCTION
  #DEFINE debug   //fprintf
#ELSE
   #DEFINE debug  fprintf
#ENDIF

//// in the code

debug(MONITOR," var1=%d  var2=%d",var1,var2);
asmboy



Joined: 20 Nov 2007
Posts: 2128
Location: albany ny

View user's profile Send private message AIM Address

PostPosted: Tue Jan 17, 2012 11:15 am     Reply with quote

now that i see what is being discussed, this approach has always been simple enough for me to deal with and the structure i have fallen into is this:

Code:

// in header area set=1  for test set=0 for release compilation

#define debug 1

// wherever i inserted some trashy debug code
#if (debug)
  // any and all locally created debug code NOT desired on release
#endif

// lastly in the early stages of main() after RS232 init
#if (debug)
    printf("** WARNING DEBUG ** \r\n");
#end

let no mistake of mine go unpunished --
as always - i am happy to learn the deficiencies of the method .


Last edited by asmboy on Tue Jan 17, 2012 11:31 am; edited 1 time in total
SherpaDoug



Joined: 07 Sep 2003
Posts: 1640
Location: Cape Cod Mass USA

View user's profile Send private message

PostPosted: Tue Jan 17, 2012 11:30 am     Reply with quote

If you want to keep doing it your old way you can replace

#if (1==debug)

with

#if (debug)

That saves the PIC doing a subtraction in the if() statement, and makes more liguistic sense.
_________________
The search for better is endless. Instead simply find very good and get the job done.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group