Has anyone ever seen an authoritative document on using debug functions in uVision3? It could be a powerful tool if I knew how to use it, but what little information I have come across is scattered across 2 hardcopy manuals, a bit more in the help file system, and smatterings in the Keil Knowledgebase. Here are clues, not documented anywhere, that I have discovered by trial and error: - If the last line of a .ini file containing function definitions does not end in a CR/LF, you get a "syntax error". - The "Breakpoint Set (BS), and "Go" (GO) commands may be executed from the command line, but not inside a function. - If you access program variables from the function, you must halt execution at a point in the program where they are all in scope before you load the function with an "include" command. Otherwise you get another "syntax error." - When you define and/or when you invoke a function, you must terminate its name with a pair of parentheses. When you "kill" the function, you must omit the parentheses. Otherwise, you get another one of those ubiquitous "syntax errors". - It could be that everything is a syntax error in this domain. The messages are that useful. :-} Perhaps if we all pool our insights, we will have a running start on a manual. ============================================================ Gary Lynch | To send mail, no$pam in domain name lynchg@no$pam.com | must be changed to stacoenergy.
I must admit that sometimes I have spent more time debugging my signal functions than my controller code.
Thanks for telling us the manual and tools weaknesses. We have tried to improve it by new examples. Did you saw already: http://www.keil.com/support/man/docs/uv3/uv3_simulation.htm Reinhard
We may have a semantic gap here. The material you reference seems to be about signal functions, which as best I understand, are only available in the simulator. They are used to generate input numbers that look like peripheral ports to the application. I am using what the manual calls the "target hardware debugger" running on my own board (flash programmed via JTAG interface). My signals come directly from the hardware itself. I have never used the simulator at all. Is a user function something I can use with the hardware debugger capability, or am I trying to force my cat to haul a piano upstairs? It isn't obvious from the manual. ============================================================ Gary Lynch | To send mail, no$pam in domain name lynchg@no$pam.com | must be changed to stacoenergy.
Way back on Dec 5, 2005; I posted to this forum under the aforementioned subject line: > > Has anyone ever seen an authoritative document on using > debug functions in uVision3? It could be a powerful tool if > I knew how to use it, but what little information I have > come across is scattered across 2 hardcopy manuals, a bit > more in the help file system, and smatterings in the Keil > Knowledgebase. >
I issued a challenge to all users to share what they had figured out around this topic, hoping our combined knowledge could be compiled into our own, home-grown user's manual. From the deafening silence, I concluded there wasn't much knowledge to go around.
On Friday, August 04, 2006 9:46 AM; I received a message from fellow forum denizen, Petter Gran-Jansen: > > Hello Gary. > > My name is Petter Gran-Jansen and working with uVision3, > ARM, Agsi, signals and functions. > > I have read your Forum mail "User defined functions > uVision3" dated 12/6/05. > > I agree. ... >
This was followed, approximately 2-1/2 hours later, by a message from Reinhard Keil: > > Hello Petter, > > well it is sometimes good to tell others your frustration. I > also agree that documentation can be improved a lot and we > are actually hiring in the moment people for doing this. >
I would like to extend a warm "Danke schön" to Herr Keil for taking notice, and look forward to seeing what he comes up with.
For Petter and fellow suffers of this documentation dearth, I have not been sitting on my hands in the 9 months since my original rant, and have had some success solving problems with user-defined functions, which I share with you all.
You are going to have to read it piecemeal as the server prohibits me from saying all I want to in one breath. If you are reading this with Internet Explorer and the preformatted sections have white bands running across the width, try re-sizing the window.
This info came from:
Getting Started User's Guide +--Introduction +--Creating Applications +--Testing Programs | +--Tips and Tricks # | | +--Command Input from File # | | +--Write Debug Output to a File +--Sample Programs +--Using On-Chip Peripherals +--RTX51 Tiny Real-Time Operating Systems uVision (R) IDE User's Guide +--uVision3 Overview +--User Interface +--Creating Applications +--Utilities +--Debugging | +--Debug Windows and Dialogs # | | +--Output Window-Command | +--Tips and Tricks | | +--Command Input from File | | +--Write Debug Output to a File +--Debug Commands # | +--INCLUDE # | +--KILL # | +--LOG +--Debug Functions # | +--Creating Functions # | +--Invoking Functions # | +--Predefined Functions # | +--User Functions # | +--Differences Between uVision3 and C +--Simulation +--Flash Programming +--Dialogs +--Example Programs +--Command Line +--Appendix
User-defined functions are a powerful debugging tool, but they are also wretchedly difficult to master. The following guidelines aim to make this process easier.
[continued in part 2]
func1() +--func2() | +--func3() func4()
they must be declared in inverse call order.
FUNC void func4(void) { .... } FUNC void func3(void) { .... } FUNC void func2(void) { .... func3(); } FUNC void func1(void) { .... func2(); func4(); }
- BIT - INT - UINT - CHAR - LONG - ULONG - FLOAT - UCHAR - VOID
Case is not supposed to matter, but I have only tried the upper-case versions.
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* */ /* dumpIoPorts.ini */ /* Version of 08/06/06 */ /* */ /* Debug script to dump content of all I/O port config */ /* SFRs */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ FUNC void dumpIoPorts(void) { INT ri, ci; exec("log > dumpIoPorts.log"); /* + + + + + + + + + + + + + + + + */ /* */ /* Output template of SFR dump: */ /* Input Output */ /* Port Data Mode Mode */ /* ---- ---- ---- ---- */ /* P0 00 .. 00 */ /* P1 00 00 00 */ /* P2 00 00 00 */ /* P3 00 00 00 */ /* P4 00 .. 00 */ /* P5 00 .. 00 */ /* P6 00 .. 00 */ /* P7 00 .. 00 */ /* + + + + + + + + + + + + + + + + */ printf(" Input Output\n"); printf("Port Data Mode Mode\n"); printf("---- ---- ---- ----\n"); printf(" P0 %02X .. %02X\n", P0, P0MDOUT); printf(" P1 %02X %02X %02X\n", P1, P1MDIN, P1MDOUT); printf(" P2 %02X %02X %02X\n", P2, P2MDIN, P2MDOUT); printf(" P3 %02X %02X %02X\n", P3, P3MDIN, P3MDOUT); printf(" P4 %02X .. %02X\n", P4, P4MDOUT); printf(" P5 %02X .. %02X\n", P5, P5MDOUT); printf(" P6 %02X .. %02X\n", P6, P6MDOUT); printf(" P7 %02X .. %02X\n", P7, P7MDOUT); exec("log off"); }
[continued in part 3]
You can work around the 3rd item by creating a function inside your target application, declare a bunch of automatics, and copy all globals of interest to one of the automatics before you hit the breakpoint from which you define your function:
int glob1, glob2; void main(void) { int lclMn1, lclMn2; uV3Break(lclMn1, lclMn2); } void uV3Break(int parm1, int parm2); int glbuV1, glbuV2; int dummy; glbuV1 = glob1; glbuV2 = glob2 dummy = 0; return; }
At this point: parm1, parm2, glbuV1, glbuV2 are all in scope and can be used by a user-defined function.
Here the statement "dummy = 1" gives me a place to set a breakpoint, from which to launch my command file.
exec("#define NO_OF_SAMPLES 12");
include dumpIoPorts.ini
DIR UFUNC
command. If your function does not appear in the list, it failed.
dumpIoPorts();
You may invoke it from inside a command file, too, but I haven't found that particularly useful.
KILL FUNC dumpIoPorts
before you can read the next version back in.
Note that in the definition and invocation of my function, I have adhered to strict C syntax for the function name, including parentheses that surround a parameter list (even if you use no parameters), and the terminating semi-colon. Note also that I DO NOT use the latter 2 elements with the KILL command. Try that and you run afoul of the infamous ....
<drum roll>
Aw, never mind. You know the routine by now.
and I recommend it over the manual methods.
============================================================ Gary Lynch | To send mail, no$pam in domain name lynchg@no$pam.com | must be changed to stacoenergy.